From 62317f2ad72b5054ea06ff40b19448fb045ac96d Mon Sep 17 00:00:00 2001 From: Dinawo Date: Mon, 4 May 2026 22:07:57 +0200 Subject: [PATCH] =?UTF-8?q?chore:=20initial=20DSMMG=20v0.2=20=E2=80=94=20r?= =?UTF-8?q?efonte=20architecturale=20compl=C3=A8te?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mise en place du Design System ManageMate Group v0.2 — refonte du système de tokens (préfixe --mmg-color-*), 9 presets accent user-themable validés WCAG AA, overlays Radix UI + Floating UI, Storybook 8 + Vitest + axe-core en CI, doc Astro Starlight, DESIGN.md (format google-labs-code) et exports tokens DTCG/CSS/ TS/Figma/Tailwind v3 et v4. - 4 packages monorepo pnpm : @managemate/{tokens,css,react,icons} - 62 composants React headless-first (Sheet, HoverCard, ContextMenu, Slider, ToggleGroup, AvatarGroup, UserCard, ProfileHeader, MetricCard, PricingCard, FeatureCard, Text/Display/Eyebrow/Lead…) - Lint contraste WCAG : 37/37 paires AA, branché CI - Toast pile Sonner-style avec ResizeObserver - Theming user (9 presets) sans casser sémantique fixe - Identité Synapse (rose #D12B6A) préservée Co-Authored-By: Claude Opus 4.7 (1M context) --- .changeset/0001-architectural-rewrite.md | 37 + .changeset/README.md | 30 + .changeset/config.json | 11 + .github/workflows/ci.yml | 71 + .github/workflows/release.yml | 49 + .gitignore | 46 + .size-limit.json | 32 + DESIGN.md | 468 + README.md | 88 +- demo/index.html | 13 + demo/package.json | 25 + demo/src/App.tsx | 1853 +++ demo/src/main.tsx | 11 + demo/tsconfig.json | 20 + demo/vite.config.ts | 8 + docs/astro.config.mjs | 72 + docs/package.json | 19 + docs/src/assets/logo.svg | 4 + docs/src/content/docs/a11y/engagement.md | 38 + docs/src/content/docs/a11y/keyboard.md | 39 + docs/src/content/docs/a11y/tests.md | 54 + docs/src/content/docs/components/button.md | 71 + docs/src/content/docs/components/index.md | 21 + docs/src/content/docs/contrib/how.md | 47 + docs/src/content/docs/contrib/rfc.md | 50 + docs/src/content/docs/contrib/versioning.md | 44 + docs/src/content/docs/fondations/colors.md | 39 + docs/src/content/docs/fondations/density.md | 30 + docs/src/content/docs/fondations/motion.md | 24 + docs/src/content/docs/fondations/spacing.md | 44 + docs/src/content/docs/fondations/tokens.md | 55 + .../src/content/docs/fondations/typography.md | 53 + docs/src/content/docs/index.mdx | 45 + docs/src/content/docs/intro/index.md | 29 + docs/src/content/docs/intro/installation.md | 83 + docs/src/content/docs/intro/migration.md | 60 + docs/src/content/docs/patterns/index.md | 18 + docs/src/content/docs/theming/architecture.md | 102 + docs/src/content/docs/theming/dark-mode.md | 39 + docs/src/content/docs/theming/presets.md | 36 + docs/src/styles/custom.css | 8 + package.json | 40 + packages/css/package.json | 43 + packages/css/postcss.config.mjs | 19 + packages/css/src/base.css | 177 + packages/css/src/components/advanced.css | 467 + packages/css/src/components/article.css | 428 + packages/css/src/components/avatar.css | 108 + packages/css/src/components/button.css | 260 + packages/css/src/components/chrome.css | 926 ++ packages/css/src/components/extras.css | 133 + packages/css/src/components/feature-card.css | 123 + packages/css/src/components/feedback.css | 529 + packages/css/src/components/form.css | 257 + packages/css/src/components/hover-card.css | 51 + packages/css/src/components/layout.css | 453 + packages/css/src/components/metric-card.css | 109 + packages/css/src/components/overlays.css | 289 + packages/css/src/components/pricing-card.css | 130 + .../css/src/components/profile-header.css | 112 + packages/css/src/components/sheet.css | 164 + packages/css/src/components/slider.css | 102 + packages/css/src/components/theme-picker.css | 107 + packages/css/src/components/toggle-group.css | 75 + packages/css/src/components/typography.css | 218 + packages/css/src/components/user-card.css | 85 + packages/css/src/index.css | 35 + packages/css/src/tokens.css | 10 + packages/css/src/tokens/accent.css | 209 + packages/css/src/tokens/primitives.css | 205 + packages/css/src/tokens/semantic.css | 181 + packages/css/src/tokens/system.css | 98 + packages/css/src/utilities.css | 141 + packages/icons/build.mjs | 191 + packages/icons/package-lock.json | 21 + packages/icons/package.json | 35 + packages/react/package.json | 63 + packages/react/src/Accordion.tsx | 32 + packages/react/src/AppShell.tsx | 70 + packages/react/src/ArticleAside.tsx | 81 + packages/react/src/ArticleCallout.tsx | 27 + packages/react/src/ArticleFooter.tsx | 110 + packages/react/src/ArticleHeader.tsx | 37 + packages/react/src/ArticlePage.tsx | 29 + packages/react/src/ArticleTOC.tsx | 45 + packages/react/src/Avatar.tsx | 89 + packages/react/src/AvatarGroup.tsx | 56 + packages/react/src/Banner.tsx | 21 + packages/react/src/Breadcrumb.tsx | 22 + packages/react/src/Button.test.tsx | 75 + packages/react/src/Button.tsx | 139 + packages/react/src/Callout.tsx | 19 + packages/react/src/Combobox.test.tsx | 74 + packages/react/src/Combobox.tsx | 189 + packages/react/src/CommandMenu.tsx | 223 + packages/react/src/ConfirmDialog.tsx | 65 + packages/react/src/ContextMenu.tsx | 68 + packages/react/src/DataTable.tsx | 315 + packages/react/src/DatePicker.tsx | 241 + packages/react/src/DateRangePicker.tsx | 248 + packages/react/src/Dialog.test.tsx | 64 + packages/react/src/Dialog.tsx | 72 + packages/react/src/Drawer.tsx | 71 + packages/react/src/EmptyState.tsx | 61 + packages/react/src/Extras.tsx | 166 + packages/react/src/Fab.tsx | 22 + packages/react/src/FeatureCard.tsx | 61 + packages/react/src/Feedback.tsx | 253 + packages/react/src/FileUpload.tsx | 53 + packages/react/src/Footer.tsx | 76 + packages/react/src/Form.tsx | 252 + packages/react/src/Header.tsx | 247 + packages/react/src/Highlight.tsx | 12 + packages/react/src/HoverCard.tsx | 57 + packages/react/src/Icon.tsx | 40 + packages/react/src/IconBlock.tsx | 54 + packages/react/src/Layout.tsx | 225 + packages/react/src/Menu.tsx | 99 + packages/react/src/MetricCard.tsx | 114 + packages/react/src/Pagination.tsx | 50 + packages/react/src/Pictogram.tsx | 696 + packages/react/src/Popover.tsx | 55 + packages/react/src/PricingCard.tsx | 90 + packages/react/src/ProfileHeader.tsx | 92 + packages/react/src/Progress.tsx | 37 + packages/react/src/Quote.tsx | 17 + packages/react/src/SearchBar.tsx | 39 + packages/react/src/Sheet.tsx | 90 + packages/react/src/Shortcut.tsx | 364 + packages/react/src/SkipLink.tsx | 14 + packages/react/src/Slider.tsx | 79 + packages/react/src/Slot.tsx | 130 + packages/react/src/Stat.tsx | 26 + packages/react/src/Stepper.tsx | 38 + packages/react/src/Tabs.tsx | 30 + packages/react/src/Tag.tsx | 30 + packages/react/src/Text.tsx | 135 + packages/react/src/ThemePicker.test.tsx | 76 + packages/react/src/ThemePicker.tsx | 108 + packages/react/src/Toast.tsx | 392 + packages/react/src/ToggleGroup.tsx | 81 + packages/react/src/Tooltip.tsx | 66 + packages/react/src/UserCard.tsx | 93 + packages/react/src/cva.ts | 116 + packages/react/src/index.tsx | 174 + packages/react/src/test-setup.ts | 50 + packages/react/src/useAccent.ts | 95 + packages/react/src/useFocusTrap.ts | 76 + packages/react/src/useTheme.ts | 56 + packages/react/src/utils.ts | 31 + packages/react/tsconfig.json | 27 + packages/react/tsup.config.ts | 24 + packages/react/vitest.config.ts | 24 + packages/tokens/README.md | 55 + packages/tokens/build.mjs | 196 + packages/tokens/package.json | 36 + packages/tokens/src/tokens.json | 173 + pnpm-lock.yaml | 11621 ++++++++++++++++ pnpm-workspace.yaml | 5 + scripts/lint-contrast.mjs | 180 + scripts/migrate-tokens.mjs | 191 + storybook/.storybook/main.ts | 27 + storybook/.storybook/preview.css | 3 + storybook/.storybook/preview.ts | 126 + storybook/package.json | 33 + storybook/stories/Button.stories.tsx | 79 + storybook/stories/Combobox.stories.tsx | 46 + storybook/stories/Dialog.stories.tsx | 64 + storybook/stories/Intro.mdx | 58 + storybook/stories/ThemePicker.stories.tsx | 43 + storybook/stories/Tokens.stories.tsx | 160 + storybook/stories/Tooltip.stories.tsx | 47 + 172 files changed, 31397 insertions(+), 1 deletion(-) create mode 100644 .changeset/0001-architectural-rewrite.md create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100644 .gitignore create mode 100644 .size-limit.json create mode 100644 DESIGN.md create mode 100644 demo/index.html create mode 100644 demo/package.json create mode 100644 demo/src/App.tsx create mode 100644 demo/src/main.tsx create mode 100644 demo/tsconfig.json create mode 100644 demo/vite.config.ts create mode 100644 docs/astro.config.mjs create mode 100644 docs/package.json create mode 100644 docs/src/assets/logo.svg create mode 100644 docs/src/content/docs/a11y/engagement.md create mode 100644 docs/src/content/docs/a11y/keyboard.md create mode 100644 docs/src/content/docs/a11y/tests.md create mode 100644 docs/src/content/docs/components/button.md create mode 100644 docs/src/content/docs/components/index.md create mode 100644 docs/src/content/docs/contrib/how.md create mode 100644 docs/src/content/docs/contrib/rfc.md create mode 100644 docs/src/content/docs/contrib/versioning.md create mode 100644 docs/src/content/docs/fondations/colors.md create mode 100644 docs/src/content/docs/fondations/density.md create mode 100644 docs/src/content/docs/fondations/motion.md create mode 100644 docs/src/content/docs/fondations/spacing.md create mode 100644 docs/src/content/docs/fondations/tokens.md create mode 100644 docs/src/content/docs/fondations/typography.md create mode 100644 docs/src/content/docs/index.mdx create mode 100644 docs/src/content/docs/intro/index.md create mode 100644 docs/src/content/docs/intro/installation.md create mode 100644 docs/src/content/docs/intro/migration.md create mode 100644 docs/src/content/docs/patterns/index.md create mode 100644 docs/src/content/docs/theming/architecture.md create mode 100644 docs/src/content/docs/theming/dark-mode.md create mode 100644 docs/src/content/docs/theming/presets.md create mode 100644 docs/src/styles/custom.css create mode 100644 package.json create mode 100644 packages/css/package.json create mode 100644 packages/css/postcss.config.mjs create mode 100644 packages/css/src/base.css create mode 100644 packages/css/src/components/advanced.css create mode 100644 packages/css/src/components/article.css create mode 100644 packages/css/src/components/avatar.css create mode 100644 packages/css/src/components/button.css create mode 100644 packages/css/src/components/chrome.css create mode 100644 packages/css/src/components/extras.css create mode 100644 packages/css/src/components/feature-card.css create mode 100644 packages/css/src/components/feedback.css create mode 100644 packages/css/src/components/form.css create mode 100644 packages/css/src/components/hover-card.css create mode 100644 packages/css/src/components/layout.css create mode 100644 packages/css/src/components/metric-card.css create mode 100644 packages/css/src/components/overlays.css create mode 100644 packages/css/src/components/pricing-card.css create mode 100644 packages/css/src/components/profile-header.css create mode 100644 packages/css/src/components/sheet.css create mode 100644 packages/css/src/components/slider.css create mode 100644 packages/css/src/components/theme-picker.css create mode 100644 packages/css/src/components/toggle-group.css create mode 100644 packages/css/src/components/typography.css create mode 100644 packages/css/src/components/user-card.css create mode 100644 packages/css/src/index.css create mode 100644 packages/css/src/tokens.css create mode 100644 packages/css/src/tokens/accent.css create mode 100644 packages/css/src/tokens/primitives.css create mode 100644 packages/css/src/tokens/semantic.css create mode 100644 packages/css/src/tokens/system.css create mode 100644 packages/css/src/utilities.css create mode 100644 packages/icons/build.mjs create mode 100644 packages/icons/package-lock.json create mode 100644 packages/icons/package.json create mode 100644 packages/react/package.json create mode 100644 packages/react/src/Accordion.tsx create mode 100644 packages/react/src/AppShell.tsx create mode 100644 packages/react/src/ArticleAside.tsx create mode 100644 packages/react/src/ArticleCallout.tsx create mode 100644 packages/react/src/ArticleFooter.tsx create mode 100644 packages/react/src/ArticleHeader.tsx create mode 100644 packages/react/src/ArticlePage.tsx create mode 100644 packages/react/src/ArticleTOC.tsx create mode 100644 packages/react/src/Avatar.tsx create mode 100644 packages/react/src/AvatarGroup.tsx create mode 100644 packages/react/src/Banner.tsx create mode 100644 packages/react/src/Breadcrumb.tsx create mode 100644 packages/react/src/Button.test.tsx create mode 100644 packages/react/src/Button.tsx create mode 100644 packages/react/src/Callout.tsx create mode 100644 packages/react/src/Combobox.test.tsx create mode 100644 packages/react/src/Combobox.tsx create mode 100644 packages/react/src/CommandMenu.tsx create mode 100644 packages/react/src/ConfirmDialog.tsx create mode 100644 packages/react/src/ContextMenu.tsx create mode 100644 packages/react/src/DataTable.tsx create mode 100644 packages/react/src/DatePicker.tsx create mode 100644 packages/react/src/DateRangePicker.tsx create mode 100644 packages/react/src/Dialog.test.tsx create mode 100644 packages/react/src/Dialog.tsx create mode 100644 packages/react/src/Drawer.tsx create mode 100644 packages/react/src/EmptyState.tsx create mode 100644 packages/react/src/Extras.tsx create mode 100644 packages/react/src/Fab.tsx create mode 100644 packages/react/src/FeatureCard.tsx create mode 100644 packages/react/src/Feedback.tsx create mode 100644 packages/react/src/FileUpload.tsx create mode 100644 packages/react/src/Footer.tsx create mode 100644 packages/react/src/Form.tsx create mode 100644 packages/react/src/Header.tsx create mode 100644 packages/react/src/Highlight.tsx create mode 100644 packages/react/src/HoverCard.tsx create mode 100644 packages/react/src/Icon.tsx create mode 100644 packages/react/src/IconBlock.tsx create mode 100644 packages/react/src/Layout.tsx create mode 100644 packages/react/src/Menu.tsx create mode 100644 packages/react/src/MetricCard.tsx create mode 100644 packages/react/src/Pagination.tsx create mode 100644 packages/react/src/Pictogram.tsx create mode 100644 packages/react/src/Popover.tsx create mode 100644 packages/react/src/PricingCard.tsx create mode 100644 packages/react/src/ProfileHeader.tsx create mode 100644 packages/react/src/Progress.tsx create mode 100644 packages/react/src/Quote.tsx create mode 100644 packages/react/src/SearchBar.tsx create mode 100644 packages/react/src/Sheet.tsx create mode 100644 packages/react/src/Shortcut.tsx create mode 100644 packages/react/src/SkipLink.tsx create mode 100644 packages/react/src/Slider.tsx create mode 100644 packages/react/src/Slot.tsx create mode 100644 packages/react/src/Stat.tsx create mode 100644 packages/react/src/Stepper.tsx create mode 100644 packages/react/src/Tabs.tsx create mode 100644 packages/react/src/Tag.tsx create mode 100644 packages/react/src/Text.tsx create mode 100644 packages/react/src/ThemePicker.test.tsx create mode 100644 packages/react/src/ThemePicker.tsx create mode 100644 packages/react/src/Toast.tsx create mode 100644 packages/react/src/ToggleGroup.tsx create mode 100644 packages/react/src/Tooltip.tsx create mode 100644 packages/react/src/UserCard.tsx create mode 100644 packages/react/src/cva.ts create mode 100644 packages/react/src/index.tsx create mode 100644 packages/react/src/test-setup.ts create mode 100644 packages/react/src/useAccent.ts create mode 100644 packages/react/src/useFocusTrap.ts create mode 100644 packages/react/src/useTheme.ts create mode 100644 packages/react/src/utils.ts create mode 100644 packages/react/tsconfig.json create mode 100644 packages/react/tsup.config.ts create mode 100644 packages/react/vitest.config.ts create mode 100644 packages/tokens/README.md create mode 100644 packages/tokens/build.mjs create mode 100644 packages/tokens/package.json create mode 100644 packages/tokens/src/tokens.json create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 scripts/lint-contrast.mjs create mode 100644 scripts/migrate-tokens.mjs create mode 100644 storybook/.storybook/main.ts create mode 100644 storybook/.storybook/preview.css create mode 100644 storybook/.storybook/preview.ts create mode 100644 storybook/package.json create mode 100644 storybook/stories/Button.stories.tsx create mode 100644 storybook/stories/Combobox.stories.tsx create mode 100644 storybook/stories/Dialog.stories.tsx create mode 100644 storybook/stories/Intro.mdx create mode 100644 storybook/stories/ThemePicker.stories.tsx create mode 100644 storybook/stories/Tokens.stories.tsx create mode 100644 storybook/stories/Tooltip.stories.tsx diff --git a/.changeset/0001-architectural-rewrite.md b/.changeset/0001-architectural-rewrite.md new file mode 100644 index 0000000..fa811a7 --- /dev/null +++ b/.changeset/0001-architectural-rewrite.md @@ -0,0 +1,37 @@ +--- +"@managemate/css": major +"@managemate/react": major +"@managemate/icons": major +--- + +# DSMMG 0.2 — refonte architecturale + +**Breaking changes :** + +- **Tokens couleur** : tous les tokens couleur passent sous le préfixe `--mmg-color-*`. + - `--mmg-bg-*` → `--mmg-color-bg-*` + - `--mmg-text-1/2/3/4` → `--mmg-color-text-{primary,secondary,tertiary,quaternary}` + - `--mmg-border-*` → `--mmg-color-border-*` + - `--mmg-brand-*` → `--mmg-color-accent-*` + - `--mmg-success/warning/danger/info-*` → `--mmg-color-*` + - `--mmg-art-*` → `--mmg-color-art-*` + - `--mmg-state-*` → `--mmg-color-state-*` +- **Tokens typographie** : `--mmg-text-{xs..5xl}` → `--mmg-font-size-*`, `--mmg-leading-*` → `--mmg-line-height-*`, `--mmg-weight-*` → `--mmg-font-weight-*`. +- **Suppression `[data-mmg-product]`** : remplacé par presets utilisateur via `[data-mmg-accent]`. +- **Composants splittés** : `Advanced.tsx`, `Chrome.tsx`, `Article.tsx` éclatés en un fichier par composant. Imports inchangés via le barrel `index.tsx`. +- **Build** : packages désormais distribués via `dist/` (ESM + CJS + types). Les imports depuis `src/` ne sont plus supportés. + +**Nouveautés :** + +- **9 presets accent** utilisateur (`synapse`, `rose`, `blue`, `violet`, `green`, `amber`, `red`, `cyan`, `slate`) avec rampes complètes et variantes dark. +- Composant `ThemePicker` + hooks `useAccent`, `useTheme`. +- Cascade `@layer reset, tokens, base, components, utilities` pour permettre les surcharges sans `!important`. +- Utilitaires CSS `mmg-u-*` (stack, flex, grid, text, bg, padding, margin…). + +**Migration :** + +Lancer le codemod fourni pour migrer ton codebase consommateur : + +```sh +node scripts/migrate-tokens.mjs +``` diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..26047db --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,30 @@ +# Changesets + +Ce dossier contient les "changesets" — des fichiers Markdown qui décrivent les changements à publier. + +## Workflow + +1. Pour chaque PR qui modifie un package versionné, ajouter un changeset : + ```sh + pnpm changeset + ``` +2. Sélectionner les packages impactés et le bump (patch / minor / major). +3. Décrire le changement (1-2 phrases, orienté consommateur). +4. Commit le `.changeset/*.md` généré avec ta PR. + +## Release + +Sur `main` : +```sh +pnpm version-packages # consume les changesets, bump les versions, met à jour CHANGELOG +pnpm release # build + publish (registre privé) +``` + +## Politique de versioning (SemVer strict) + +- **major** : breaking change API publique (rename/suppression d'export, signature de prop modifiée, token renommé). +- **minor** : nouveau composant, nouvelle prop, nouveau token, nouvelle variante. +- **patch** : bugfix, doc, perf interne sans surface publique. + +Les 4 packages versionnés sont **fixed** (même version) pour éviter les +incompatibilités de tokens entre `@managemate/css` et `@managemate/react`. diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..212d667 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [["@managemate/css", "@managemate/react", "@managemate/icons", "@managemate/tokens"]], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": ["demo", "storybook", "docs"] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..66a461d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,71 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + CI: true + HUSKY: 0 + +jobs: + build: + name: Build, typecheck, test, a11y + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: pnpm/action-setup@v4 + with: + version: 10 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Install + run: pnpm install --frozen-lockfile + + - name: Build tokens (Style Dictionary) + run: pnpm --filter @managemate/tokens build + + - name: Build icons + run: pnpm --filter @managemate/icons build + + - name: Build CSS + run: pnpm --filter @managemate/css build + + - name: Build React + run: pnpm --filter @managemate/react build + + - name: Typecheck + run: pnpm --filter @managemate/react typecheck + + - name: Test (Vitest + axe-core) + run: pnpm --filter @managemate/react test + + - name: Lint contraste WCAG AA + run: pnpm lint:contrast + + - name: Build Storybook + run: pnpm --filter storybook build + + - name: Bundle size budget + run: pnpm size + + - name: Upload Storybook artifact + if: github.event_name == 'pull_request' + uses: actions/upload-artifact@v4 + with: + name: storybook-static + path: storybook/storybook-static + retention-days: 7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..edfc6c6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,49 @@ +name: Release + +on: + push: + branches: [main] + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: false + +permissions: + contents: write + pull-requests: write + packages: write + +jobs: + release: + name: Release / open changeset PR + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: pnpm/action-setup@v4 + with: + version: 10 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + registry-url: https://npm.pkg.github.com + + - run: pnpm install --frozen-lockfile + + - run: pnpm build + + - name: Create release PR or publish + uses: changesets/action@v1 + with: + publish: pnpm release + version: pnpm version-packages + commit: "chore(release): version packages" + title: "chore(release): version packages" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e1f4d85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +# Dependencies +node_modules +.pnpm-store + +# Build outputs +dist +build +*.tsbuildinfo +.turbo + +# Environment +.env +.env.local +.env.*.local + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# IDE +.vscode +.idea +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Storybook +storybook-static +.storybook/dist + +# Test artifacts +coverage +.nyc_output + +# Demo specifics +demo/_dev.log + +# Misc +.cache +.pnpm-debug.log diff --git a/.size-limit.json b/.size-limit.json new file mode 100644 index 0000000..50a318a --- /dev/null +++ b/.size-limit.json @@ -0,0 +1,32 @@ +[ + { + "name": "@managemate/react — full barrel (ESM)", + "path": "packages/react/dist/index.js", + "limit": "60 KB", + "ignore": ["react", "react-dom", "react/jsx-runtime"] + }, + { + "name": "@managemate/react — single Button (tree-shake)", + "path": "packages/react/dist/index.js", + "import": "{ Button }", + "limit": "5 KB", + "ignore": ["react", "react-dom", "react/jsx-runtime"] + }, + { + "name": "@managemate/react — Dialog + ConfirmDialog (Radix)", + "path": "packages/react/dist/index.js", + "import": "{ Dialog, ConfirmDialog }", + "limit": "30 KB", + "ignore": ["react", "react-dom", "react/jsx-runtime"] + }, + { + "name": "@managemate/css — full bundle", + "path": "packages/css/dist/index.css", + "limit": "40 KB" + }, + { + "name": "@managemate/icons — full bundle (192 classes)", + "path": "packages/icons/dist/icons.css", + "limit": "120 KB" + } +] diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 0000000..7f6dafb --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,468 @@ +--- +version: "0.2" +name: DSMMG +description: > + Design System ManageMate Group — référence pour Synapse, HRTime, Forge, + Orbit, MSLM, Espace-Client et sites publics. Headless-first sur Radix UI, + RGAA 4.1 / WCAG 2.2 AA, theming utilisateur via 9 presets accent. + +# ═══════════════════════════════════════════════════════════════════ +# COULEURS — primitives → semantic → accent (user-themable) +# ═══════════════════════════════════════════════════════════════════ +colors: + # — Neutrals (warm-cool mix : frais en light, neutre en dark) —————— + neutral-0: "#FFFFFF" + neutral-50: "#F7F6FB" + neutral-100: "#F0EFF9" + neutral-150: "#EDEDFA" + neutral-200: "#E4E3F4" + neutral-300: "#C9C7E0" + neutral-400: "#AAA8C9" + neutral-500: "#7875A1" + neutral-600: "#56557A" + neutral-700: "#3B3A56" + neutral-800: "#1F1E32" + neutral-900: "#111120" + + # — Synapse (rose corporate ManageMate, défaut accent) —————— + synapse-50: "#FEF0F4" + synapse-100: "#FCE0EA" + synapse-200: "#FAD0DF" + synapse-300: "#F4A0BD" + synapse-400: "#ED608E" + synapse-500: "#D12B6A" # ★ marque ManageMate + synapse-600: "#BA245F" + synapse-700: "#A82257" + synapse-800: "#831B45" + synapse-900: "#5A132F" + + # — Presets accent user (8 alternatives au synapse) —————— + rose-500: "#E11D48" + blue-500: "#2563EB" + violet-500: "#7C3AED" + green-500: "#0E9F6E" + amber-500: "#D97706" + red-500: "#DC2626" + cyan-500: "#0891B2" + slate-500: "#475569" + + # — Sémantique fixe (NE CHANGE JAMAIS avec l'accent user) —————— + success: "#059669" + warning: "#D97706" + danger: "#DC2626" + info: "#2563EB" + + # — Active accent (alias dynamique, par défaut synapse) —————— + primary: "{colors.synapse-500}" + secondary: "{colors.neutral-600}" + tertiary: "{colors.neutral-300}" + +# ═══════════════════════════════════════════════════════════════════ +# TYPOGRAPHIE — Figtree partout, 3 échelles selon contexte +# ═══════════════════════════════════════════════════════════════════ +typography: + # — Display (landings produits — HRTime, Synapse, Forge, Orbit) —— + display-2xl: + fontFamily: Figtree + fontSize: 72px + fontWeight: 800 + letterSpacing: "-0.035em" + lineHeight: 1.0 + display-xl: + fontFamily: Figtree + fontSize: 60px + fontWeight: 800 + letterSpacing: "-0.03em" + lineHeight: 1.05 + display-lg: + fontFamily: Figtree + fontSize: 48px + fontWeight: 700 + letterSpacing: "-0.025em" + lineHeight: 1.1 + display-md: + fontFamily: Figtree + fontSize: 36px + fontWeight: 700 + letterSpacing: "-0.02em" + lineHeight: 1.15 + + # — Headlines (apps métier — h1 → h6 sémantiques) ———————— + h1: + fontFamily: Figtree + fontSize: 36px + fontWeight: 700 + letterSpacing: "-0.02em" + lineHeight: 1.2 + h2: + fontFamily: Figtree + fontSize: 30px + fontWeight: 700 + letterSpacing: "-0.015em" + lineHeight: 1.25 + h3: + fontFamily: Figtree + fontSize: 24px + fontWeight: 700 + letterSpacing: "-0.01em" + lineHeight: 1.3 + h4: + fontFamily: Figtree + fontSize: 20px + fontWeight: 600 + letterSpacing: "-0.005em" + lineHeight: 1.35 + h5: + fontFamily: Figtree + fontSize: 17px + fontWeight: 600 + lineHeight: 1.4 + h6: + fontFamily: Figtree + fontSize: 15px + fontWeight: 600 + lineHeight: 1.45 + + # — Body ———————————————————————————————————————— + body-lg: + fontFamily: Figtree + fontSize: 17px + lineHeight: 1.6 + body: + fontFamily: Figtree + fontSize: 15px + lineHeight: 1.55 + body-sm: + fontFamily: Figtree + fontSize: 13px + lineHeight: 1.5 + body-xs: + fontFamily: Figtree + fontSize: 11px + lineHeight: 1.45 + + # — Auxiliaires ———————————————————————————————— + eyebrow: + fontFamily: Figtree + fontSize: 13px + fontWeight: 600 + letterSpacing: "0.06em" + textTransform: uppercase + lead: + fontFamily: Figtree + fontSize: 20px + fontWeight: 400 + letterSpacing: "-0.005em" + lineHeight: 1.5 + overline: + fontFamily: Figtree + fontSize: 11px + fontWeight: 600 + letterSpacing: "0.08em" + textTransform: uppercase + caption: + fontFamily: Figtree + fontSize: 11px + lineHeight: 1.4 + code: + fontFamily: "JetBrains Mono" + fontSize: 13px + +# ═══════════════════════════════════════════════════════════════════ +# RAYONS — pill par défaut sur interactifs et conteneurs +# ═══════════════════════════════════════════════════════════════════ +rounded: + none: 0 + sm: 8px + md: 12px + card: 20px + panel: 24px + icon: 12px + pill: 9999px + +# ═══════════════════════════════════════════════════════════════════ +# ESPACEMENT — grille 4pt (multiples de 4 ou 8 exclusivement) +# ═══════════════════════════════════════════════════════════════════ +spacing: + "0": 0 + "1": 4px + "2": 8px + "3": 12px + "4": 16px + "5": 20px + "6": 24px + "7": 32px + "8": 40px + "9": 48px + "10": 64px + "11": 80px + "12": 120px + +# ═══════════════════════════════════════════════════════════════════ +# MOTION — animation = feedback fonctionnel, jamais décoratif +# ═══════════════════════════════════════════════════════════════════ +motion: + duration: + fast: 120ms # micro-interactions (hover, focus) + base: 200ms # transitions UI standard + slow: 320ms # navigation (modals, drawers) + easing: + default: "cubic-bezier(0.4, 0, 0.2, 1)" # matériel, doux + emphasis: "cubic-bezier(0.2, 0.8, 0.2, 1)" # rebond léger + +# ═══════════════════════════════════════════════════════════════════ +# DENSITÉ — 3 modes adaptables par préférence user +# ═══════════════════════════════════════════════════════════════════ +density: + comfortable: + rowHeight: 44px + inputHeight: 40px + paddingX: 16px + paddingY: 12px + cozy: + rowHeight: 36px + inputHeight: 36px + paddingX: 12px + paddingY: 8px + compact: + rowHeight: 28px + inputHeight: 30px + paddingX: 8px + paddingY: 4px + +# ═══════════════════════════════════════════════════════════════════ +# COMPOSANTS — extraits clé. Liste exhaustive : @managemate/react +# ═══════════════════════════════════════════════════════════════════ +components: + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.neutral-0}" + typography: "{typography.body-sm}" + fontWeight: 600 + rounded: "{rounded.pill}" + padding: "10px 22px" + minHeight: 40px + + button-tonal: + backgroundColor: "{colors.synapse-50}" + textColor: "{colors.synapse-800}" + typography: "{typography.body-sm}" + fontWeight: 600 + rounded: "{rounded.pill}" + padding: "10px 22px" + + button-ghost: + backgroundColor: transparent + textColor: "{colors.neutral-700}" + typography: "{typography.body-sm}" + fontWeight: 600 + + card: + backgroundColor: "{colors.neutral-0}" + rounded: "{rounded.card}" + padding: "{spacing.6}" + borderColor: "{colors.neutral-200}" + + input: + backgroundColor: "{colors.neutral-0}" + textColor: "{colors.neutral-900}" + borderColor: "{colors.neutral-200}" + rounded: "{rounded.md}" + padding: "10px 14px" + minHeight: 40px + + badge: + backgroundColor: "{colors.neutral-150}" + textColor: "{colors.neutral-700}" + typography: "{typography.body-xs}" + fontWeight: 600 + rounded: 6px + padding: "2px 8px" + + toast: + backgroundColor: "{colors.neutral-0}" + borderColor: "{colors.neutral-200}" + rounded: 14px + padding: "14px 14px 14px 16px" + + tile: + backgroundColor: "{colors.neutral-0}" + borderColor: "{colors.neutral-200}" + rounded: "{rounded.card}" + padding: "{spacing.6}" +--- + +# DSMMG — Design System ManageMate Group + +> **Version 0.2** · La source de vérité visuelle, comportementale et accessible pour les produits ManageMate (Synapse, HRTime, Forge, Orbit, MSLM, Espace-Client, sites publics). + +## Overview + +Le DSMMG est un design system **headless-first** construit sur Radix UI. Trois mots : + +- **Cohérence** — un bouton dans n'importe quel produit ManageMate a la même structure et la même couleur de base. La différenciation se fait par contenu, pas par couleur. +- **Accessibilité** — RGAA 4.1 / WCAG 2.2 AA non-négociable. Validé `axe-core` en CI. Plusieurs clients (collectivités, opérateurs publics) sont soumis au RGAA par la loi. +- **Theming utilisateur** — 9 presets accent (rose Synapse par défaut), chaque utilisateur choisit dans ses préférences. La sémantique (success/danger/warning/info) reste fixe. + +## Colors + +Trois couches verticales : + +``` +primitives → semantic → accent (user-themable) +``` + +1. **Primitives** — rampes brutes (`neutral-0..900`, `synapse-50..900`, et 8 presets). Ne JAMAIS référencer directement dans les composants. +2. **Sémantiques** — `bg-page`, `text-primary`, `border`, `success/warning/danger/info`. **Stables, ne changent pas avec l'accent user.** +3. **Accent** — `--mmg-color-accent-*`. Posé par `[data-mmg-accent=""]` sur ``. SEUL token couleur user-themable. + +### Presets accent disponibles + +`synapse` (défaut), `rose`, `blue`, `violet`, `green`, `amber`, `red`, `cyan`, `slate`. + +Chaque preset a sa version dark adaptée (saturation -2pts, luminosité +3pts) pour confort visuel. + +### Règle absolue + +- ❌ **Aucun hex en dur dans les composants.** +- ❌ **Jamais de `--mmg-color-synapse-*` direct** dans un composant — toujours via `--mmg-color-accent-*`. + +## Typography + +**Figtree** partout (Google Fonts, sans-serif géométrique). 3 échelles selon contexte : + +| Famille | Cas d'usage | Tailles | +|---|---|---| +| **Display** | Hero des landings produits (HRTime, Synapse…) | 36px → 72px | +| **Headlines** | Apps métier (h1-h6 sémantiques) | 15px → 36px | +| **Body** | Texte courant et UI | 11px → 17px | +| **Auxiliaires** | eyebrow, lead, overline, caption | 11px → 20px | + +**Modificateurs** : `mono`, `tabular`, `balance` (titres), `pretty` (body), `italic`, `emphasis` (italique + accent), `highlight`, `underline`, `strike`, `gradient`, `rainbow`. + +> **Choisir le tag (`as`) selon la SÉMANTIQUE, pas selon la taille.** Un titre de page reste `

` même si visuellement il s'affiche en `display-xl`. + +## Layout & Spacing + +Grille **4 points** stricte. Multiples de 4 ou 8 uniquement. Aucune valeur intermédiaire (10, 14, 22) qui casse l'alignement vertical. + +12 niveaux : `0` (0) → `12` (120px). + +**Densité** adaptable par utilisateur via `[data-mmg-density="comfortable|cozy|compact"]`. Touch target minimum **44×44** quel que soit le mode (WCAG SC 2.5.5). + +## Elevation & Depth + +Light mode : +- `shadow-1` — 0 1px 4px ink + 1px ring +- `shadow-2` — 0 4px 16px ink + 1px ring +- `shadow-3` — 0 12px 32px ink (modals, dropdowns) +- `shadow-elevated` — neutre, pour boutons elevated + +Dark mode : +- Ombres = noir + halo blanc subtil 4-6 % (jamais "noir s'évapore") +- backdrop-filter blur 12-14px sur overlays/popovers/toasts pour effet verre dépoli + +Ombres teintées accent via `color-mix(in srgb, var(--mmg-color-accent) X%, transparent)` — s'adaptent automatiquement au preset user. + +## Shapes + +Pill par défaut sur **interactifs** (buttons, inputs, badges-pills) et **conteneurs principaux** (Tile, Card, Hero). + +| Token | Valeur | Usage | +|---|---|---| +| `rounded-sm` | 8px | inputs, badges-discrets | +| `rounded-md` | 12px | cards compact, popover, menu | +| `rounded-card` | 20px | cards principales, tiles | +| `rounded-panel` | 24px | modals, sheets | +| `rounded-pill` | 9999px | boutons, badges-pills | + +## Motion + +Animation = **feedback fonctionnel**, jamais décoratif. Trois durées : + +- 120ms — micro-interactions (hover, focus, ripple) +- 200ms — transitions UI standard +- 320ms — navigation (modals, drawers, sheets) + +`prefers-reduced-motion: reduce` désactive tout (durée 0.001ms). WCAG SC 2.3.3 AAA. + +## Components + +Catalogue complet (~62 composants) dans `@managemate/react`. Les principaux : + +**Forms** : Button, Input, Textarea, Select, Combobox, Checkbox, Radio, Switch, Slider, ToggleGroup, FileUpload. + +**Layout** : Container, Section, Stack, Inline, Card, Tile, Hero. + +**Feedback** : Alert, Notice, Banner, Badge (avec dot indicator + pulse), Spinner, Skeleton, Toast (pile Sonner-style empilable). + +**Overlays** : Tooltip, Popover, Menu, Dialog, ConfirmDialog, Sheet (4 sides × 5 sizes), Drawer, HoverCard, ContextMenu — **tous Radix-backed**. + +**Navigation** : Header (mega-menu DSFR-style), Footer, Breadcrumb, Tabs, Pagination, AppShell, Sidebar, Topbar, SkipLink. + +**Profile & Cards** : Avatar (status indicator + auto-color), AvatarGroup, UserCard, ProfileHeader (cover + débord), MetricCard (KPI avec trend), PricingCard, FeatureCard, Stat. + +**Article** : ArticlePage, ArticleHeader, ArticleAside, ArticleFooter, ArticleCallout, ArticleTOC. + +**Theming** : ThemePicker (radiogroup avec navigation flèches/Home/End). + +## Do's and Don'ts + +### ✅ Do + +- Utiliser les **tokens sémantiques** (`--mmg-color-text-primary`, `--mmg-color-bg-surface`). +- Choisir le tag HTML selon **la sémantique**, pas selon la taille visuelle. +- Tester en clavier : Tab, Shift+Tab, Esc, flèches, Enter, Espace. +- Tester en zoom 200 % et reflow 320px. +- Tester avec `prefers-reduced-motion: reduce` activé. +- Préférer les composants Radix-backed (Tooltip, Menu, Dialog…) aux implémentations custom. +- Documenter le composant dans Storybook + MDX avant de le livrer. + +### ❌ Don't + +- **Aucun hex en dur** dans les composants. +- **Aucune référence directe** à `--mmg-color-synapse-*` — toujours via `--mmg-color-accent-*`. +- **Pas de couleur seule** porteuse d'info (RGAA 9). Toujours redonder avec icône, texte ou pattern. +- **Pas de placeholder** en remplacement de label (RGAA 11.1). +- **Pas de focus invisible** ni `outline: none` sans alternative. +- **Pas de `
`** au lieu de ` +``` + +### React (recommandé) + +```tsx +import "@managemate/css"; +import "@managemate/icons"; +import { Button, Hero, Header, Footer } from "@managemate/react"; + + +``` + +## Composants v0.1 + +| Catégorie | Composants | +|---|---| +| **Layout** | Container, Section, Stack, Inline, Card, Tile, Hero, Grid (`.mmg-col-*`) | +| **Boutons** | Button (6 variants × 5 sizes, icon, loading, block) | +| **Forms** | Field, Input, Textarea, Select, Checkbox, Radio, Switch | +| **Feedback** | Alert, Notice, Badge, Modal, ToastRegion, Spinner, Skeleton | +| **Chrome** | Header, Footer, Breadcrumb, Sidebar, Topbar, Tabs, Pagination, AppShell, Avatar, Stat, SkipLink | +| **Icônes** | 49 icônes via `mmg-icon-` | + +## Tokens + +Tous les tokens sont des CSS custom properties préfixées `--mmg-*`. Light + dark mode via `[data-mmg-theme]`. + +**Couleur de marque** : rose `#D12B6A` corporate, partagée par tous les produits. + +## TODO v0.2 + +- [ ] Tooltip +- [ ] Stepper +- [ ] DatePicker +- [ ] DataTable avancée (tri, filtres, pagination intégrée) +- [ ] Combobox / Autocomplete +- [ ] FileUpload +- [ ] CommandMenu (cmd+k) +- [ ] Storybook +- [ ] Tests visuels +- [ ] Variants line/fill pour toutes les icônes (Remix Icon) +- [ ] Détection Wappalyzer (PR sur webappanalyzer) + +## Wappalyzer + +Pour la détection automatique : +1. Ajouter `` dans le `` des sites. +2. Ouvrir une PR sur https://github.com/enthec/webappanalyzer avec un fichier qui matche `class*="mmg-"` + le meta tag. + +## Licence + +Privée — usage interne ManageMate Group uniquement. diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..82c8df1 --- /dev/null +++ b/demo/index.html @@ -0,0 +1,13 @@ + + + + + + DSMMG — ManageMate Design System + + + +
+ + + diff --git a/demo/package.json b/demo/package.json new file mode 100644 index 0000000..765ca7f --- /dev/null +++ b/demo/package.json @@ -0,0 +1,25 @@ +{ + "name": "demo", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@managemate/css": "workspace:*", + "@managemate/icons": "workspace:*", + "@managemate/react": "workspace:*", + "react": "^19.2.5", + "react-dom": "^19.2.5" + }, + "devDependencies": { + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "typescript": "~6.0.2", + "vite": "^8.0.10" + } +} diff --git a/demo/src/App.tsx b/demo/src/App.tsx new file mode 100644 index 0000000..0e02a9e --- /dev/null +++ b/demo/src/App.tsx @@ -0,0 +1,1853 @@ +import { useMemo, useState } from "react"; +import { + Header, Footer, Hero, Container, Section, Stack, Inline, + Card, Tile, Button, Notice, Alert, Badge, Modal, Input, Select, + Checkbox, Switch, Tabs, Stat, Avatar, + Icon, Spinner, IconBlock, + Stepper, Accordion, Tooltip, Tag, Progress, + Highlight, Quote, Callout, Banner, FileUpload, SearchBar, + DataTable, type DataTableColumn, + CommandMenu, useCommandMenu, type Command, + DatePicker, DateRangePicker, type DateRange, + ToastProvider, useToast, + EmptyState, + SegmentedControl, DescriptionList, Sparkline, Kbd, + Pictogram, + ArticlePage, ArticleHeader, ArticleAside, ArticleFooter, ArticleCallout, ArticleTOC, + ThemePicker, TooltipProvider, Popover, Dialog, ConfirmDialog, + Sheet, HoverCard, ContextMenu, Slider, ToggleGroup, + AvatarGroup, UserCard, ProfileHeader, MetricCard, PricingCard, FeatureCard, + Text, Display, Eyebrow, Lead, + type HeaderNavItem, +} from "@managemate/react"; +import iconsData from "../../packages/icons/dist/icons.json"; +const iconNames = iconsData as string[]; + +type Employee = { + id: number; + nom: string; + poste: string; + contrat: "CDI" | "CDD" | "Stage"; + entreeLe: string; + statut: "actif" | "absent" | "conge"; + salaire: number; +}; + +const EMPLOYEES: Employee[] = [ + { id: 1, nom: "Lohann Bouveresse", poste: "CEO", contrat: "CDI", entreeLe: "2018-04-01", statut: "actif", salaire: 95000 }, + { id: 2, nom: "Marie Dupont", poste: "Lead Developer", contrat: "CDI", entreeLe: "2020-09-14", statut: "actif", salaire: 72000 }, + { id: 3, nom: "Jean Martin", poste: "Designer", contrat: "CDI", entreeLe: "2021-02-22", statut: "absent", salaire: 54000 }, + { id: 4, nom: "Sophie Bernard", poste: "Product Manager", contrat: "CDI", entreeLe: "2022-06-01", statut: "actif", salaire: 68000 }, + { id: 5, nom: "Thomas Legrand", poste: "DevOps", contrat: "CDI", entreeLe: "2023-01-10", statut: "actif", salaire: 64000 }, + { id: 6, nom: "Emma Rousseau", poste: "QA Engineer", contrat: "CDD", entreeLe: "2024-09-01", statut: "conge", salaire: 48000 }, + { id: 7, nom: "Lucas Martin", poste: "Junior Dev", contrat: "Stage", entreeLe: "2025-09-01", statut: "actif", salaire: 13000 }, + { id: 8, nom: "Camille Moreau", poste: "Sales", contrat: "CDI", entreeLe: "2019-11-03", statut: "actif", salaire: 58000 }, +]; + +function AppInner() { + const [open, setOpen] = useState(false); + const [tab, setTab] = useState("apercu"); + const [theme, setTheme] = useState<"light" | "dark">("light"); + const [showAccentPanel, setShowAccentPanel] = useState(false); + const [confirmOpen, setConfirmOpen] = useState(false); + const [sheetOpen, setSheetOpen] = useState(false); + const [sheetSide, setSheetSide] = useState<"right" | "left" | "top" | "bottom">("right"); + const [volume, setVolume] = useState([62]); + const [priceRange, setPriceRange] = useState([800, 2400]); + const [viewMode, setViewMode] = useState("list"); + const [filters, setFilters] = useState(["actif"]); + const [iconFilter, setIconFilter] = useState(""); + const [stepperStep, setStepperStep] = useState(2); + const [selectedRows, setSelectedRows] = useState<(string | number)[]>([]); + const [date, setDate] = useState(null); + const [range, setRange] = useState({ start: null, end: null }); + const [period, setPeriod] = useState<"day" | "week" | "month" | "year">("month"); + const [view, setView] = useState<"grid" | "list">("grid"); + const cmd = useCommandMenu(); + const { toast } = useToast(); + + const toggleTheme = () => { + const next = theme === "light" ? "dark" : "light"; + setTheme(next); + document.documentElement.dataset.mmgTheme = next; + }; + + const filteredIcons = iconNames.filter((n) => + n.includes(iconFilter.toLowerCase()), + ); + + const columns: DataTableColumn[] = useMemo(() => [ + { + key: "nom", + header: "Collaborateur", + sortable: true, + cell: (r) => ( + + s[0]).join("")} size="sm" /> + {r.nom} + + ), + }, + { key: "poste", header: "Poste", sortable: true }, + { + key: "contrat", + header: "Contrat", + sortable: true, + cell: (r) => {r.contrat}, + }, + { + key: "entreeLe", + header: "Entrée", + sortable: true, + cell: (r) => new Date(r.entreeLe).toLocaleDateString("fr-FR"), + }, + { + key: "statut", + header: "Statut", + sortable: true, + cell: (r) => { + const map = { actif: "success", absent: "danger", conge: "warning" } as const; + const label = { actif: "Actif", absent: "Absent", conge: "En congé" } as const; + return {label[r.statut]}; + }, + }, + { + key: "salaire", + header: "Salaire annuel", + sortable: true, + align: "right", + cell: (r) => r.salaire.toLocaleString("fr-FR") + " €", + }, + ], []); + + const commands: Command[] = useMemo(() => [ + { id: "home", label: "Aller à l'accueil", icon: "home-4-line", group: "Navigation", shortcut: ["G", "H"], onSelect: () => setTab("apercu") }, + { id: "tab-buttons", label: "Voir les boutons", icon: "checkbox-circle-line", group: "Navigation", onSelect: () => setTab("boutons") }, + { id: "tab-forms", label: "Voir les formulaires", icon: "edit-line", group: "Navigation", onSelect: () => setTab("forms") }, + { id: "tab-data", label: "Voir le tableau de données", icon: "dashboard-line", group: "Navigation", onSelect: () => setTab("data") }, + { id: "tab-icons", label: "Voir les icônes", icon: "magic-line", group: "Navigation", onSelect: () => setTab("icons") }, + { id: "tab-iconblocks", label: "Voir les IconBlocks", icon: "palette-line", group: "Navigation", onSelect: () => setTab("iconblocks") }, + { id: "theme-toggle", label: "Basculer le thème clair / sombre", icon: theme === "light" ? "moon-line" : "sun-line", group: "Préférences", shortcut: ["⌘", "T"], onSelect: toggleTheme }, + { id: "modal", label: "Ouvrir une modale d'exemple", icon: "error-warning-line", group: "Démo", onSelect: () => setOpen(true) }, + { id: "toast-success", label: "Toast — succès", icon: "checkbox-circle-line", group: "Démo", onSelect: () => toast({ title: "Modifications sauvegardées", description: "Les 3 collaborateurs sélectionnés ont été mis à jour.", severity: "success" }) }, + { id: "toast-info", label: "Toast — info", icon: "information-line", group: "Démo", onSelect: () => toast({ title: "Maintenance prévue dimanche", severity: "info", action: { label: "En savoir plus", onClick: () => alert("doc") } }) }, + { id: "toast-error", label: "Toast — erreur", icon: "error-warning-line", group: "Démo", onSelect: () => toast({ title: "Échec de la synchronisation", description: "Vérifiez votre connexion réseau.", severity: "danger", duration: 0 }) }, + ], [theme, toast]); + + return ( + <> + + DSMMG v0.2 — Refonte tokens (--mmg-color-*), 9 presets accent user-themable, overlays Radix, Storybook, Style Dictionary, doc Starlight. ⌘ K pour la palette. + + +
+ + + + + } + /> + + + + + + } + /> + +
+ + 0 ? `(${selectedRows.length})` : ""}` }, + { id: "dates", label: "Dates" }, + { id: "icons", label: `Icônes (${iconNames.length / 2})` }, + { id: "iconblocks", label: "IconBlocks" }, + { id: "extras", label: "Extras" }, + { id: "article", label: "Article" }, + { id: "modern", label: "Sheet · HoverCard · Slider" }, + { id: "cards", label: "Cards & Profile" }, + { id: "typo", label: "Typographie" }, + ]} + /> + + {tab === "apercu" && ( + +
+

Que souhaitez-vous faire aujourd'hui ?

+

+ Les actions les plus fréquentes sur votre espace ManageMate. +

+
+
+
+
+
+
+ +

Tuiles cliquables — 3 tailles

+

+ La même <Tile> en taille sm (au-dessus, dense), md (défaut) et lg (CTA pleine largeur, marketing). +

+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
+ +

Activité — vue {period === "day" ? "quotidienne" : period === "week" ? "hebdomadaire" : period === "month" ? "mensuelle" : "annuelle"}

+ +
+
+
+ + +
+
Collaborateurs
+
1 247
+ +12 ce mois +
+ +
+ +
+
+
+ + +
+
SLA respecté
+
98%
+ +2 pts +
+ +
+ +
+
+
+ + +
+
MRR
+
32 K€
+ +8.2% +
+ +
+ +
+
+
+ + +
+
Alertes ouvertes
+
3
+ 2 critiques +
+ +
+ +
+
+
+
+ +
+

Suite ManageMate

+

+ Quatre produits, un seul écosystème. Pictogrammes 80×80 dédiés. +

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+

Capacités transverses

+

+ Ce qui distingue chaque produit ManageMate. +

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ + + Voir le changelog + + } + /> +
+ )} + + {tab === "boutons" && ( + + +
VariantesInspiré Material 3 (tonal, elevated) + Fluent 2 (subtle).
+ + + + + + + + + + +
+ +
Tailles & formesPill par défaut · `square` pour radius modéré (DSFR/Fluent).
+ + + + + + + + + + + + +
+ + Avec icône / loading + + + + + + +
+ )} + + {tab === "forms" && ( + +
+
+ + Connexion + + + + + + + +
+
+ + Profil + + + + + +
+
+ + Recherche & upload + + + + + +
+ )} + + {tab === "feedback" && ( + + Maintenance prévue dimanche 7 mai de 2h à 4h. + Vos modifications ont bien été enregistrées. + Votre quota approche des 90%. + Impossible de joindre le serveur. + + + Cohérence d'écosystème. Le DSMMG garantit que vos collaborateurs retrouvent les mêmes patterns sur tous les produits ManageMate. + + + Les utilisateurs passent la majorité de leur temps sur d'autres sites. Ils s'attendent à ce que le vôtre fonctionne comme ceux-là. + + + + EmptyState (état vide) + Ajouter un collaborateur} + secondaryAction={} + /> + + + + + ToastProvider — pile empilable façon Sonner + Survolez la pile pour la déployer. Pause des timers au hover/focus, reprise à la sortie. + + + + + + + + + + + + + Tooltip — auto-positionnement + + + + + + + + + + + + + + + + + + Nouveau + En ligne + En attente + Échec + Beta + Pro + + + Sans action + {}} icon="filter-3-line">Filtre + {}} selected icon="check-line">Sélectionné + + + + + + + + + + + + + )} + + {tab === "navigation" && ( + + + Stepper + + + + + + + +
Foire aux questionsLe DSMMG en quelques questions essentielles.
+ +

Le Design System ManageMate Group fournit une bibliothèque de composants visuels et d'interactions partagés par tous nos produits. Objectif : qu'un utilisateur de ManageMate Paie retrouve les mêmes patterns dans ManageMate SIRH ou Plannings — moins d'apprentissage, plus de confiance.

+
+ +

Importez @managemate/css et @managemate/icons, puis utilisez les composants @managemate/react. Toutes les classes sont préfixées mmg- pour éviter les conflits avec d'autres bibliothèques (Tailwind, Bootstrap…).

+
+ +

Oui. Tous les composants sont conçus pour respecter WCAG 2.1 AA : contraste minimum 4.5:1, focus visible (anneau rose 2px), navigation clavier complète, attributs ARIA appropriés, support des lecteurs d'écran.

+
+ +

Les tokens CSS sont surchargeables : redéfinissez --mmg-color-accent et ses variantes (--mmg-color-accent-soft, --mmg-color-accent-strong) dans un sélecteur racine de votre app. Mais nous recommandons de garder le rose corporate pour préserver l'identité d'écosystème.

+
+ +

Via l'attribut data-mmg-theme="light|dark" sur l'élément <html>. Sans attribut, le DS suit la préférence système de l'utilisateur. Tous les tokens couleurs ont une variante dark validée WCAG AA.

+
+ +

Ouvrez une issue sur le repo interne managemate-ds avec un cas d'usage concret. Si plusieurs produits expriment le besoin, le composant rejoint la roadmap. Évitez les composants ad-hoc dans vos apps : préférez une PR sur le DS.

+
+
+
+ )} + + {tab === "data" && ( + + + {selectedRows.length > 0 ? ( + <> + + + + ) : ( + <> + + + + + )} + + } + /> + + )} + + {tab === "dates" && ( +
+
+ + DatePicker + + + d < new Date()} + /> + + +
+
+ + DateRangePicker + + + {range.start && range.end && ( + {Math.ceil((range.end.getTime() - range.start.getTime()) / (1000 * 60 * 60 * 24)) + 1} jour(s) sélectionné(s) + )} + + +
+
+ )} + + {tab === "icons" && ( + + +
+ Icônes Remix ({iconNames.length / 2} × 2 variants) + Classes mmg-icon-<name>-line et -fill +
+ setIconFilter(e.target.value)} + prefixIcon="search-2-line" + style={{ minWidth: 280 }} + /> +
+ {filteredIcons.length === 0 ? ( + setIconFilter("")}>Réinitialiser} + /> + ) : ( +
+ {filteredIcons.map((n) => ( +
+ +
{n}
+
+ ))} +
+ )} +
+ )} + + {tab === "article" && ( + + + Lecture 6 min + Par Marie Dupont, Lead Platform + 28 avril 2026 + + } + /> + } + aside={ + + + + + + + + + + } + footer={ + + } + > +

+ Quand j'ai rejoint l'équipe en septembre 2024, la CI mettait 14 minutes entre le moment où une PR était poussée et celui où elle était mergeable. Sur une équipe de 18 développeurs qui pousse en moyenne 30 PR par jour, ça représente 7 heures de temps machine quotidien et un coût d'attente humain difficile à chiffrer mais réel : context-switching, perte de flow, frustration. +

+ + + En 18 mois on est passé de 14 min à 3 min 20. Les gains : Turborepo (-40%), tests parallélisés sur 8 workers (-25%), suppression du linter en CI au profit du pre-commit hook (-15%). Ce qui n'a rien changé : migration vers Bun (gain marginal), Docker layer caching (cassé en pratique). + + +

Le contexte : pourquoi c'était bloquant

+

+ Notre produit est un monorepo de 84 packages, environ 320 000 lignes de TypeScript. Tout le monde dépend de tout le monde — bibliothèque UI, hooks partagés, types métier. La moindre PR déclenchait : +

+
    +
  • Install des dépendances (3 min)
  • +
  • Build complet du monorepo (5 min)
  • +
  • Tests unitaires (4 min)
  • +
  • Linter + type-check (1 min)
  • +
  • Déploiement preview (1 min)
  • +
+

+ Chaque étape était séquentielle. La plupart du travail effectué était inutile : on rebuildait des packages qui n'avaient pas changé depuis trois mois. +

+ +

Diagnostic : où passait le temps

+

+ Premier réflexe : mesurer. On a instrumenté la CI avec des spans OpenTelemetry sur chaque étape. La répartition réelle du temps était surprenante. +

+ + L'équipe pensait que l'install était le bottleneck. En réalité c'était le build, qui prenait 38% du temps total. Sans mesure, on aurait optimisé la mauvaise chose pendant 3 mois. + + +

Les six décisions qui ont fait la différence

+

1. Migration vers Turborepo (gain : -5 min 40)

+

+ Turborepo invalide intelligemment le cache au niveau du package. Une PR qui ne touche que le package @app/billing ne déclenche que son build et celui des packages qui en dépendent. Sur 84 packages, on rebuildait en moyenne 6 packages par PR, contre 84 avant. +

+ +

3. Tests parallélisés sur 8 workers (gain : -3 min 30)

+

+ Vitest peut paralléliser sur N workers via --reporter=verbose --pool=threads. Le sweet spot pour notre runner GitHub Actions ubuntu-latest-4core est 6 workers — au-delà, l'overhead d'orchestration grignote les gains. +

+ +

5. Suppression du linter en CI

+

+ Décision controversée. On a déplacé ESLint en pre-commit hook côté local (via husky + lint-staged). La CI ne fait plus que le type-check (qui est strictement nécessaire et ne peut pas tourner localement sans contexte). +

+
+ Si un dev pousse du code non-linté, c'est un problème de discipline d'équipe, pas un problème à 1 minute par PR pour les 17 autres. +
+ +

Ce qui n'a rien changé (et qu'on pensait magique)

+
    +
  • Migration vers Bun : -3 secondes sur l'install. Pas significatif vu le risque.
  • +
  • Docker layer caching : marche en théorie, cassé en pratique sur GitHub Actions à cause du cache éphémère entre runners.
  • +
  • Self-hosted runners : 2× plus rapides mais 5× plus chers en ops. ROI négatif pour notre taille.
  • +
+ + + Sur les 6 décisions appliquées, 3 ont eu un impact significatif (>3 min de gain) et 3 ont été des déceptions (<30 sec). Sans mesure préalable et postérieure systématique, on aurait perdu des semaines d'ingénierie. + + +

Résultats mesurés

+

Trois métriques suivies en continu depuis le début du chantier :

+
    +
  • P50 du temps de CI : 14:023:20 (-76%)
  • +
  • P95 (cas pathologiques) : 22:185:45
  • +
  • Taux de re-runs flaky : 11% → 1.2% (gros effet de bord positif)
  • +
+

+ Au-delà de la performance pure, la satisfaction de l'équipe s'est nettement améliorée : enquête interne trimestrielle, item "satisfaction CI" passée de 4.2/10 à 8.7/10. +

+ +

Et maintenant ?

+

+ On continue à mesurer. Les prochaines pistes : tests d'intégration sur Playwright qui prennent encore 1 min 40 — possiblement parallélisables sur des shards. Et un système de preview deploys partagés pour éviter de redéployer une preview pour chaque commit quand l'UI n'a pas bougé. +

+

+ Si vous travaillez sur un monorepo et que votre CI prend plus de 10 minutes, c'est probablement votre plus grand levier de productivité d'équipe. Mesurez avant d'optimiser. Investissez sur les bons gains. +

+
+
+ )} + + {tab === "extras" && ( + + + +
+ SegmentedControl + Choix exclusif court — Apple HIG. Préférable au Radio quand 3-5 options et espace horizontal disponible. +
+
+ + + + {}} + /> + +
+ + + +
+ DescriptionList + Pattern clé-valeur structuré. Sémantique <dl>/<dt>/<dd> — natif a11y. +
+
+ + VF33CNFUC84063345 }, + { label: "Date de 1ère immatriculation", value: "19/04/2005" }, + { label: "Date de l'immatriculation", value: "14/06/2025" }, + { label: "Statut", value: Actif sans gage }, + ]} + /> + +
+ + + +
+ Sparkline + Micro-graphe inline pour stat cards. SVG pur, accessible (rôle img + aria-label). +
+
+ + + Effectifs : 1 247 + + + + SLA : 98% + + + + Tickets : 14 + + + +
+ + + +
+ Kbd + Raccourcis clavier inline. Sémantique <kbd>. +
+
+

+ Appuyez sur + K pour ouvrir la palette de commandes. + Sauvegardez avec Ctrl + S. Naviguez avec et validez avec ↵ Entrée. +

+
+ + + +
+ Modal — focus trap actif + Ouvrez la modale et tabuler : le focus reste piégé à l'intérieur, retourne au bouton à la fermeture. +
+
+ + + +
+
+ )} + + {tab === "iconblocks" && ( + + +
IconBlock — variantes & couleursPattern Linear/Vercel : icône Remix sur fond coloré. Remplace les pictogrammes hand-codés.
+ +
+

Soft (défaut)

+ + + + + + + + +
+
+

Filled (CTA)

+ + + + + + + +
+
+

Gradient (premium)

+ + + + + + +
+
+

Tailles

+ + + + + + + +
+
+
+
+ )} + + {tab === "modern" && ( + + + +
+ Sheet — panneau latéral (Radix Dialog) + Glisse depuis un bord. Focus trap, scroll lock, restitution focus, Esc — tout natif. 4 côtés × 5 tailles. +
+
+ + v && setSheetSide(v as typeof sheetSide)} + items={[ + { value: "right", label: "Droite", icon: "arrow-right-line" }, + { value: "left", label: "Gauche", icon: "arrow-left-line" }, + { value: "top", label: "Haut", icon: "arrow-up-line" }, + { value: "bottom", label: "Bas", icon: "arrow-down-line" }, + ]} + /> + + + + +
+ + + +
+ HoverCard — preview riche au survol + Pour les fiches utilisateur, aperçus produit, métadonnées de lien. Hover-bridge gérée par Radix. +
+
+ + + @marie.dupont + + } + > + + +
+
Marie Dupont
+
Lead Developer · Synapse
+
+ Rejointe en sept. 2020. Lead frontend, mainteneuse du DSMMG. +
+
+ 184 commits + 23 reviews + 5 ans +
+
+
+
+ + Synapse v4.2.1 + } + > +
Synapse v4.2.1
+
Sortie le 24 avril 2026
+
    +
  • Fix : duplication de tickets sur conflit réseau
  • +
  • UX : raccourci Cmd+Shift+L pour archiver
  • +
  • Perf : DataTable +40% sur 10k rows
  • +
+
+
+
+ + + +
+ ContextMenu — clic droit + Menu contextuel. Clic droit sur la zone ci-dessous (ou long-press tactile). +
+
+ toast({ title: "Voir détail" }) }, + { label: "Modifier", icon: "edit-line", shortcut: "E", onSelect: () => toast({ title: "Modifier" }) }, + { label: "Dupliquer", icon: "file-copy-line", shortcut: "⌘D", onSelect: () => toast({ title: "Dupliqué" }) }, + { type: "divider" }, + { type: "label", label: "Visibilité" }, + { label: "Partager", icon: "share-line", onSelect: () => toast({ title: "Partagé" }) }, + { label: "Archiver", icon: "inbox-line", onSelect: () => toast({ title: "Archivé", severity: "info" }) }, + { type: "divider" }, + { label: "Supprimer", icon: "delete-bin-line", danger: true, shortcut: "⌫", onSelect: () => toast({ title: "Supprimé", severity: "danger" }) }, + ]} + > +
+ Clic droit ici +
+
+
+ + + +
+ Slider — sélecteur de valeur + Single (volume) ou range (fourchette de prix). Clavier : flèches, Page Up/Down, Home/End. +
+
+ +
+ + +
+
+ + +
+
+
+ + + +
+ ToggleGroup — single & multiple + Single = SegmentedControl. Multiple = filtres composables. Roving tabindex géré par Radix. +
+
+ +
+
Vue
+ v && setViewMode(v)} + items={[ + { value: "list", label: "Liste", icon: "menu-line" }, + { value: "grid", label: "Grille", icon: "apps-2-line" }, + { value: "kanban", label: "Kanban", icon: "stack-line" }, + { value: "calendar", label: "Calendrier", icon: "calendar-line" }, + ]} + /> +
+
+
Filtres (multiple)
+ +
+ Sélection : {filters.length === 0 ? "aucune" : filters.join(", ")} +
+
+
+
+
+ )} + + {tab === "cards" && ( + + + +
+ ProfileHeader + Cover image + avatar en débord. LinkedIn / GitHub pattern. +
+
+ + + + Disponible + + + + Owner DSMMG + + Frontend · React + Paris + + } + actions={ + <> + + + + } + stats={[ + { label: "Commits", value: "184" }, + { label: "Reviews", value: "23" }, + { label: "Tickets résolus", value: "412" }, + { label: "Ancienneté", value: "5 ans" }, + ]} + /> +
+ + + +
+ UserCard — différentes tailles + Card cliquable compacte. Avec status indicator + actions. +
+
+ + + + } + /> + + + + + } + /> + +
+ + + +
+ AvatarGroup — empilement avec overflow + Pattern Slack / Linear / GitHub. Hover pour identifier qui est qui. +
+
+ + + + 5 participants + + + + 12 reviewers + + + + + + + + + + + +
+ + + +
+ MetricCard — KPI dashboard + Valeur + delta coloré + tendance + sparkline. Pattern Linear / Vercel / Stripe Dashboard. +
+
+
+
+ } + /> +
+
+ +
+
+ +
+
+ +
+
+
+ + + +
+ FeatureCard — landing produit + Icône colorée + titre + description + lien. Variante "glow" pour bordures animées au hover (Vercel-style). +
+
+
+
+ +
+
+ +
+
+ +
+
+
+ + + +
+ PricingCard — landing tarifs + 3 plans avec mise en avant du tier "Pro". Features avec check / cross. +
+
+
+
+ Démarrer l'essai} + /> +
+
+ Choisir Pro} + /> +
+
+ Contacter les sales} + /> +
+
+
+
+ )} + + {tab === "typo" && ( + + + +
+ Display — pages marketing / landing produits + 72px → 36px, extra-bold, letter-spacing serré. Pour les hero de HRTime / Synapse / Forge / Orbit. +
+
+ +
+ Display 2XL · 72px + Le SIRH simple, vraiment. +
+
+ Display XL · 60px + + Le temps de vos équipes, au cordeau. + +
+
+ Display LG · 48px + + Construit pour les équipes qui livrent. + +
+
+ Display MD · 36px + Sous-section marketing +
+
+
+ + + +
+ Headlines — apps métier + Hiérarchie h1 → h6 sémantique. Pour Synapse, HRTime app, Forge, Orbit, Espace-Client. +
+
+ + H1 — titre de page (36px) + H2 — section (30px) + H3 — sous-section (24px) + H4 — groupe / card title (20px) + H5 — sub-card (17px) + H6 — label fort (15px) + +
+ + + +
+ Body & auxiliaires + Tailles courantes pour le texte courant et les annotations. +
+
+ + + Body LG (17px) — pour les paragraphes de pages marketing aérées, + où l'utilisateur lit le texte sans contrainte de densité. + + + Body (15px, défaut) — texte courant, doc, articles. C'est la taille + qu'on devrait utiliser dans 80 % des cas dans une app. + + + Body SM (13px) — UI dense, hint sous un input, légende secondaire. + + + Body XS (11px) — métadonnées, footnotes, timestamps. À éviter pour le texte courant. + +
+ + Lead (20px) — chapô sous un Hero. Plus long que le titre, moins + long que le body principal. Souvent en text-secondary pour + laisser le titre dominer. + + + SIRH + Section overline + + + Caption (11px) — légende d'image, timestamp d'un message, "il y a 3 minutes". + +
+
+ + + +
+ Italique, emphase, surligneur + Pour mots étrangers, citations, mots-clefs sémantiquement à part. Sémantique : <em> sort italique automatiquement. +
+
+ + + Italique sobre : il faut savoir choisir ses combats. Le tag <em> natif sort en italique sans décoration supplémentaire. + + + Italique via prop : terme étranger, nom d'une œuvre, ou citation courte. + + + Emphase éditoriale (italique + accent) : vraiment nouveau, simple, cohérent. + + + Surligneur subtil : le mot-clef qui compte dans un paragraphe long. + + + Souligné fort : fonctionnalité critique pour focus l'œil. + + + Barré (prix, élément déprécié) : 49 € / mois 29 € / mois. + + +
+ + + +
+ Modificateurs décoratifs (à dose homéopathique) + Gradient et rainbow disponibles mais à utiliser parcimonieusement — un seul gradient par page, jamais de rainbow sur du texte courant. +
+
+ +
+ Gradient (accent → accent-strong) + Texte avec gradient +
+
+ Rainbow animé — un par page max + Réservé au hero principal +
+
+
+ + + +
+ Cas d'usage type — landing HRTime + Comment composer ces variantes pour une page produit. +
+
+
+ SIRH simple + + Le temps de vos équipes, au cordeau. + + + Plannings, congés, paie. Une seule plateforme, sans surprise. Connectez votre paie en 7 jours, sans data engineer. + + + + + +
+
+ + + +
+ Helpers raccourcis + Composants Display, Eyebrow, Lead = wrappers de Text avec defaults. +
+
+ + +{`SIRH simple +Le temps de vos équipes +Plannings, congés, paie. Une seule plateforme.`} + + +
+
+ )} +
+
+ + + + + + } + > + + + + = 0 && filtered[activeIndex] + ? `${id}-opt-${filtered[activeIndex].value}` + : undefined + } + value={query} + placeholder={placeholder} + onChange={(e) => { + setQuery(e.target.value); + setOpen(true); + setActiveIndex(-1); + }} + onFocus={() => setOpen(true)} + onBlur={() => setTimeout(() => setOpen(false), 100)} + onKeyDown={onKey} + /> + {open && ( +
{ + refs.setFloating(el); + listRef.current = el; + }} + id={`${id}-list`} + role="listbox" + className="mmg-menu mmg-combobox__list" + style={floatingStyles} + > + {filtered.length === 0 ? ( +
{emptyMessage}
+ ) : ( + filtered.map((o, i) => ( + + )) + )} +
+ )} +
+ ); +} diff --git a/packages/react/src/CommandMenu.tsx b/packages/react/src/CommandMenu.tsx new file mode 100644 index 0000000..13baca3 --- /dev/null +++ b/packages/react/src/CommandMenu.tsx @@ -0,0 +1,223 @@ +import { useEffect, useMemo, useRef, useState, type ReactNode } from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type Command = { + id: string; + label: ReactNode; + /** Texte indexable pour la recherche (par défaut = label si string). */ + keywords?: string; + icon?: IconName; + group?: string; + shortcut?: string[]; // ex. ["⌘", "K"] + onSelect: () => void; +}; + +export function CommandMenu({ + open, + onClose, + commands, + placeholder = "Tapez une commande ou un mot-clé…", + emptyMessage = "Aucun résultat. Essayez un autre mot.", +}: { + open: boolean; + onClose: () => void; + commands: Command[]; + placeholder?: string; + emptyMessage?: string; +}) { + const [query, setQuery] = useState(""); + const [activeIdx, setActiveIdx] = useState(0); + const inputRef = useRef(null); + const listRef = useRef(null); + + // Reset à l'ouverture + useEffect(() => { + if (open) { + setQuery(""); + setActiveIdx(0); + setTimeout(() => inputRef.current?.focus(), 50); + } + }, [open]); + + // ESC pour fermer + useEffect(() => { + if (!open) return; + const onKey = (e: KeyboardEvent) => { + if (e.key === "Escape") onClose(); + }; + document.addEventListener("keydown", onKey); + return () => document.removeEventListener("keydown", onKey); + }, [open, onClose]); + + // Block scroll + useEffect(() => { + if (!open) return; + const prev = document.body.style.overflow; + document.body.style.overflow = "hidden"; + return () => { + document.body.style.overflow = prev; + }; + }, [open]); + + const filtered = useMemo(() => { + const q = query.trim().toLowerCase(); + if (!q) return commands; + return commands.filter((c) => { + const txt = ( + (typeof c.label === "string" ? c.label : "") + + " " + + (c.keywords ?? "") + + " " + + (c.group ?? "") + ).toLowerCase(); + // Matching simple : tous les mots de q doivent être présents + return q.split(/\s+/).every((w) => txt.includes(w)); + }); + }, [commands, query]); + + // Groupes + const groups = useMemo(() => { + const map = new Map(); + for (const c of filtered) { + const g = c.group ?? "Commandes"; + if (!map.has(g)) map.set(g, []); + map.get(g)!.push(c); + } + return [...map.entries()]; + }, [filtered]); + + // Navigation clavier + useEffect(() => { + if (!open) return; + const onKey = (e: KeyboardEvent) => { + if (e.key === "ArrowDown") { + e.preventDefault(); + setActiveIdx((i) => Math.min(filtered.length - 1, i + 1)); + } else if (e.key === "ArrowUp") { + e.preventDefault(); + setActiveIdx((i) => Math.max(0, i - 1)); + } else if (e.key === "Enter") { + e.preventDefault(); + const cmd = filtered[activeIdx]; + if (cmd) { + cmd.onSelect(); + onClose(); + } + } + }; + document.addEventListener("keydown", onKey); + return () => document.removeEventListener("keydown", onKey); + }, [open, filtered, activeIdx, onClose]); + + // Scroll into view + useEffect(() => { + const el = listRef.current?.querySelector('[aria-selected="true"]'); + el?.scrollIntoView({ block: "nearest" }); + }, [activeIdx]); + + if (!open) return null; + + let runningIdx = 0; + + return ( +
{ + if (e.target === e.currentTarget) onClose(); + }} + > +
+
+ + { + setQuery(e.target.value); + setActiveIdx(0); + }} + placeholder={placeholder} + aria-label="Recherche" + /> + esc +
+ +
+ {filtered.length === 0 ? ( +
{emptyMessage}
+ ) : ( + groups.map(([group, items]) => ( +
+
{group}
+ {items.map((c) => { + const isActive = filtered[activeIdx]?.id === c.id; + const idx = runningIdx++; + return ( +
{ + c.onSelect(); + onClose(); + }} + onMouseEnter={() => setActiveIdx(filtered.indexOf(c))} + > + {c.icon && } + {c.label} + {c.shortcut && ( + + {c.shortcut.map((k, i) => ( + {k} + ))} + + )} +
+ ); + })} +
+ )) + )} +
+ +
+ + + naviguer + + + sélectionner + + + esc fermer + +
+
+
+ ); +} + +/** Hook pour ouvrir la palette via Cmd/Ctrl+K. */ +export function useCommandMenu() { + const [open, setOpen] = useState(false); + useEffect(() => { + const onKey = (e: KeyboardEvent) => { + if (e.key === "k" && (e.metaKey || e.ctrlKey)) { + e.preventDefault(); + setOpen((v) => !v); + } + }; + document.addEventListener("keydown", onKey); + return () => document.removeEventListener("keydown", onKey); + }, []); + return { open, setOpen, close: () => setOpen(false), toggle: () => setOpen((v) => !v) }; +} diff --git a/packages/react/src/ConfirmDialog.tsx b/packages/react/src/ConfirmDialog.tsx new file mode 100644 index 0000000..2fcdb59 --- /dev/null +++ b/packages/react/src/ConfirmDialog.tsx @@ -0,0 +1,65 @@ +import type { ReactNode } from "react"; +import { Dialog } from "./Dialog"; +import { Button } from "./Button"; + +export type ConfirmDialogProps = { + open: boolean; + onOpenChange: (open: boolean) => void; + title: ReactNode; + description?: ReactNode; + confirmLabel?: ReactNode; + cancelLabel?: ReactNode; + /** Variante destructive : bouton rouge. */ + destructive?: boolean; + onConfirm: () => void | Promise; + /** Affiche un loader pendant onConfirm. */ + loading?: boolean; +}; + +/** + * Boîte de dialogue de confirmation. Pattern destructive : confirm rouge, + * focus initial sur le bouton d'annulation (sécurité). Cf. heuristique + * Nielsen #5 : prevention of errors. + */ +export function ConfirmDialog({ + open, + onOpenChange, + title, + description, + confirmLabel = "Confirmer", + cancelLabel = "Annuler", + destructive, + onConfirm, + loading, +}: ConfirmDialogProps) { + return ( + + + + + } + > + {null} + + ); +} diff --git a/packages/react/src/ContextMenu.tsx b/packages/react/src/ContextMenu.tsx new file mode 100644 index 0000000..55cb438 --- /dev/null +++ b/packages/react/src/ContextMenu.tsx @@ -0,0 +1,68 @@ +import { type ReactNode } from "react"; +import * as RadixContextMenu from "@radix-ui/react-context-menu"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type ContextMenuItem = + | { + type?: "item"; + label: ReactNode; + icon?: IconName; + onSelect?: () => void; + danger?: boolean; + disabled?: boolean; + shortcut?: string; + } + | { type: "divider" } + | { type: "label"; label: ReactNode }; + +export type ContextMenuProps = { + /** Zone qui déclenche le menu au clic-droit / long-press. */ + children: ReactNode; + items: ContextMenuItem[]; +}; + +/** + * ContextMenu — menu contextuel au clic-droit (ou long-press tactile). + * + * Wrapper Radix : ouvre sur clic-droit, navigation flèches, type-ahead, + * Escape, focus management. Aucun appel a11y custom. + */ +export function ContextMenu({ children, items }: ContextMenuProps) { + return ( + + {children} + + + {items.map((item, i) => { + if (item.type === "divider") { + return ; + } + if (item.type === "label") { + return ( + + {item.label} + + ); + } + const { label, icon, onSelect, danger, disabled, shortcut } = item; + return ( + + {icon && } + {label} + {shortcut && {shortcut}} + + ); + })} + + + + ); +} + +export { RadixContextMenu as ContextMenuPrimitive }; diff --git a/packages/react/src/DataTable.tsx b/packages/react/src/DataTable.tsx new file mode 100644 index 0000000..8eba298 --- /dev/null +++ b/packages/react/src/DataTable.tsx @@ -0,0 +1,315 @@ +import { useMemo, useState, type ReactNode } from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; +import { Pictogram, type PictogramName } from "./Pictogram"; +import { Button } from "./Button"; + +export type DataTableColumn = { + key: string; + header: ReactNode; + /** Accesseur ; par défaut row[key] */ + accessor?: (row: T) => unknown; + /** Render personnalisé ; par défaut texte */ + cell?: (row: T) => ReactNode; + /** Trie cliquable sur la colonne */ + sortable?: boolean; + /** Largeur CSS (ex. "120px", "1fr") */ + width?: string | number; + /** Alignement du contenu */ + align?: "left" | "right" | "center"; +}; + +type SortState = { key: string; dir: "asc" | "desc" } | null; + +export type DataTableProps = { + data: T[]; + columns: DataTableColumn[]; + /** Colonne identifiante (par défaut "id") */ + rowKey?: keyof T | ((row: T) => string | number); + /** Active la sélection multiple */ + selectable?: boolean; + selectedKeys?: (string | number)[]; + onSelectionChange?: (keys: (string | number)[]) => void; + /** Recherche dans toutes les colonnes */ + searchable?: boolean; + searchPlaceholder?: string; + /** Pagination cliente */ + pageSize?: number; + /** Densité des lignes */ + dense?: boolean; + /** État vide personnalisable */ + emptyTitle?: ReactNode; + emptyDescription?: ReactNode; + emptyPictogram?: PictogramName; + emptyAction?: ReactNode; + /** Loading */ + loading?: boolean; + /** Actions de la barre d'outils */ + toolbarActions?: ReactNode; + className?: string; + onRowClick?: (row: T) => void; +}; + +export function DataTable>({ + data, + columns, + rowKey = "id", + selectable, + selectedKeys, + onSelectionChange, + searchable, + searchPlaceholder = "Rechercher…", + pageSize, + dense, + emptyTitle = "Aucun résultat", + emptyDescription = "Aucun élément ne correspond à votre recherche.", + emptyPictogram = "search", + emptyAction, + loading, + toolbarActions, + className, + onRowClick, +}: DataTableProps) { + const [sort, setSort] = useState(null); + const [search, setSearch] = useState(""); + const [page, setPage] = useState(1); + + const getKey = (row: T): string | number => + typeof rowKey === "function" ? rowKey(row) : (row[rowKey as string] ?? ""); + + const accessor = (col: DataTableColumn, row: T) => + col.accessor ? col.accessor(row) : row[col.key]; + + const filtered = useMemo(() => { + if (!searchable || !search.trim()) return data; + const q = search.toLowerCase(); + return data.filter((row) => + columns.some((c) => { + const v = accessor(c, row); + return v != null && String(v).toLowerCase().includes(q); + }), + ); + }, [data, search, searchable, columns]); + + const sorted = useMemo(() => { + if (!sort) return filtered; + const col = columns.find((c) => c.key === sort.key); + if (!col) return filtered; + const sign = sort.dir === "asc" ? 1 : -1; + return [...filtered].sort((a, b) => { + const va = accessor(col, a); + const vb = accessor(col, b); + if (va == null) return 1; + if (vb == null) return -1; + if (typeof va === "number" && typeof vb === "number") return sign * (va - vb); + return sign * String(va).localeCompare(String(vb)); + }); + }, [filtered, sort, columns]); + + const pageCount = pageSize ? Math.max(1, Math.ceil(sorted.length / pageSize)) : 1; + const paged = pageSize + ? sorted.slice((page - 1) * pageSize, page * pageSize) + : sorted; + + const allKeys = paged.map(getKey); + const allSelected = allKeys.length > 0 && allKeys.every((k) => selectedKeys?.includes(k)); + const someSelected = !allSelected && allKeys.some((k) => selectedKeys?.includes(k)); + + const toggleAll = () => { + if (!onSelectionChange) return; + if (allSelected) { + onSelectionChange(selectedKeys?.filter((k) => !allKeys.includes(k)) ?? []); + } else { + onSelectionChange([...new Set([...(selectedKeys ?? []), ...allKeys])]); + } + }; + + const toggleOne = (k: string | number) => { + if (!onSelectionChange) return; + const set = new Set(selectedKeys ?? []); + set.has(k) ? set.delete(k) : set.add(k); + onSelectionChange([...set]); + }; + + const onSort = (col: DataTableColumn) => { + if (!col.sortable) return; + setSort((cur) => + cur?.key === col.key + ? cur.dir === "asc" + ? { key: col.key, dir: "desc" } + : null + : { key: col.key, dir: "asc" }, + ); + }; + + const showToolbar = searchable || toolbarActions || (selectable && (selectedKeys?.length ?? 0) > 0); + + return ( +
+ {showToolbar && ( +
+ {selectable && (selectedKeys?.length ?? 0) > 0 ? ( + + {selectedKeys?.length} sélectionné{(selectedKeys?.length ?? 0) > 1 ? "s" : ""} + + ) : searchable ? ( +
+ + { + setSearch(e.target.value); + setPage(1); + }} + /> +
+ ) : ( + + )} + {toolbarActions &&
{toolbarActions}
} +
+ )} + +
+ + + + {selectable && ( + + )} + {columns.map((col) => { + const isSorted = sort?.key === col.key; + return ( + + ); + })} + + + + {!loading && paged.length > 0 && ( + + {paged.map((row) => { + const k = getKey(row); + const selected = selectedKeys?.includes(k); + return ( + onRowClick(row) : undefined} + style={onRowClick ? { cursor: "pointer" } : undefined} + > + {selectable && ( + + )} + {columns.map((col) => ( + + ))} + + ); + })} + + )} +
+ { + if (el) el.indeterminate = someSelected; + }} + onChange={toggleAll} + aria-label="Tout sélectionner" + /> + onSort(col)} + style={{ + width: col.width, + textAlign: col.align, + }} + > + {col.header} + {col.sortable && ( + + + + )} +
e.stopPropagation()}> + toggleOne(k)} + aria-label={`Sélectionner ${k}`} + /> + + {col.cell ? col.cell(row) : String(accessor(col, row) ?? "—")} +
+ + {loading && ( +
+ + Chargement… +
+ )} + + {!loading && paged.length === 0 && ( +
+ +

{emptyTitle}

+

{emptyDescription}

+ {emptyAction} +
+ )} +
+ + {pageSize && pageCount > 1 && ( +
+ + Page {page} / {pageCount} — {sorted.length} résultat + {sorted.length > 1 ? "s" : ""} + +
+
+
+ )} +
+ ); +} diff --git a/packages/react/src/DatePicker.tsx b/packages/react/src/DatePicker.tsx new file mode 100644 index 0000000..7b18bd2 --- /dev/null +++ b/packages/react/src/DatePicker.tsx @@ -0,0 +1,241 @@ +import { + useEffect, + useId, + useMemo, + useRef, + useState, + type ReactNode, +} from "react"; +import { cx } from "./utils"; +import { Icon } from "./Icon"; +import { Button } from "./Button"; + +const MONTHS = [ + "janvier", "février", "mars", "avril", "mai", "juin", + "juillet", "août", "septembre", "octobre", "novembre", "décembre", +]; +const WEEKDAYS = ["lun", "mar", "mer", "jeu", "ven", "sam", "dim"]; + +const fmt = (d: Date | null) => + d + ? d.toLocaleDateString("fr-FR", { + day: "2-digit", + month: "2-digit", + year: "numeric", + }) + : ""; + +const sameDay = (a: Date, b: Date) => + a.getFullYear() === b.getFullYear() && + a.getMonth() === b.getMonth() && + a.getDate() === b.getDate(); + +function buildMonthGrid(year: number, month: number) { + const first = new Date(year, month, 1); + // En France lundi = jour 0 + const startDay = (first.getDay() + 6) % 7; + const daysInMonth = new Date(year, month + 1, 0).getDate(); + const daysInPrev = new Date(year, month, 0).getDate(); + const cells: { date: Date; outside: boolean }[] = []; + + // Préfixe (mois précédent) + for (let i = startDay - 1; i >= 0; i--) { + cells.push({ date: new Date(year, month - 1, daysInPrev - i), outside: true }); + } + for (let d = 1; d <= daysInMonth; d++) { + cells.push({ date: new Date(year, month, d), outside: false }); + } + // Suffixe (mois suivant) + while (cells.length < 42) { + const idx = cells.length - (startDay + daysInMonth); + cells.push({ date: new Date(year, month + 1, idx + 1), outside: true }); + } + return cells; +} + +export type DatePickerProps = { + label?: ReactNode; + hint?: ReactNode; + error?: ReactNode; + value?: Date | null; + onChange?: (date: Date | null) => void; + required?: boolean; + disabled?: boolean; + /** Désactive certaines dates */ + isDisabled?: (date: Date) => boolean; + placeholder?: string; + className?: string; +}; + +export function DatePicker({ + label, + hint, + error, + value, + onChange, + required, + disabled, + isDisabled, + placeholder = "JJ/MM/AAAA", + className, +}: DatePickerProps) { + const id = useId(); + const [open, setOpen] = useState(false); + const [view, setView] = useState(() => value ?? new Date()); + const ref = useRef(null); + + useEffect(() => { + if (value) setView(value); + }, [value]); + + useEffect(() => { + if (!open) return; + const onClick = (e: MouseEvent) => { + if (!ref.current?.contains(e.target as Node)) setOpen(false); + }; + const onKey = (e: KeyboardEvent) => { + if (e.key === "Escape") setOpen(false); + }; + document.addEventListener("mousedown", onClick); + document.addEventListener("keydown", onKey); + return () => { + document.removeEventListener("mousedown", onClick); + document.removeEventListener("keydown", onKey); + }; + }, [open]); + + const cells = useMemo( + () => buildMonthGrid(view.getFullYear(), view.getMonth()), + [view], + ); + const today = new Date(); + + return ( +
+ {label && ( + + )} +
+ !disabled && setOpen((v) => !v)} + onFocus={() => !disabled && setOpen(true)} + aria-haspopup="dialog" + aria-expanded={open} + /> + + + +
+ {error ? ( + {error} + ) : hint ? ( + {hint} + ) : null} + + {open && ( +
+
+ + + {MONTHS[view.getMonth()]} {view.getFullYear()} + + +
+ +
+ {WEEKDAYS.map((w) => ( +
{w}
+ ))} +
+ +
+ {cells.map(({ date, outside }, i) => { + const selected = value && sameDay(date, value); + const todayMatch = sameDay(date, today); + const dis = isDisabled?.(date) ?? false; + return ( + + ); + })} +
+ +
+ + +
+
+ )} +
+ ); +} diff --git a/packages/react/src/DateRangePicker.tsx b/packages/react/src/DateRangePicker.tsx new file mode 100644 index 0000000..602ba0d --- /dev/null +++ b/packages/react/src/DateRangePicker.tsx @@ -0,0 +1,248 @@ +import { useEffect, useId, useMemo, useRef, useState, type ReactNode } from "react"; +import { cx } from "./utils"; +import { Icon } from "./Icon"; +import { Button } from "./Button"; + +const MONTHS = [ + "janvier", "février", "mars", "avril", "mai", "juin", + "juillet", "août", "septembre", "octobre", "novembre", "décembre", +]; +const WEEKDAYS = ["lun", "mar", "mer", "jeu", "ven", "sam", "dim"]; + +const fmt = (d: Date | null) => + d ? d.toLocaleDateString("fr-FR", { day: "2-digit", month: "2-digit", year: "numeric" }) : ""; +const sameDay = (a: Date, b: Date) => + a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate(); +const isBefore = (a: Date, b: Date) => a.getTime() < b.getTime(); +const isBetween = (d: Date, start: Date, end: Date) => + d.getTime() > start.getTime() && d.getTime() < end.getTime(); + +function buildMonthGrid(year: number, month: number) { + const first = new Date(year, month, 1); + const startDay = (first.getDay() + 6) % 7; + const daysInMonth = new Date(year, month + 1, 0).getDate(); + const daysInPrev = new Date(year, month, 0).getDate(); + const cells: { date: Date; outside: boolean }[] = []; + for (let i = startDay - 1; i >= 0; i--) { + cells.push({ date: new Date(year, month - 1, daysInPrev - i), outside: true }); + } + for (let d = 1; d <= daysInMonth; d++) { + cells.push({ date: new Date(year, month, d), outside: false }); + } + while (cells.length < 42) { + const idx = cells.length - (startDay + daysInMonth); + cells.push({ date: new Date(year, month + 1, idx + 1), outside: true }); + } + return cells; +} + +export type DateRange = { start: Date | null; end: Date | null }; + +export type DateRangePickerProps = { + label?: ReactNode; + hint?: ReactNode; + error?: ReactNode; + value?: DateRange; + onChange?: (range: DateRange) => void; + required?: boolean; + disabled?: boolean; + /** Désactive certaines dates (ex. dates passées). */ + isDisabled?: (date: Date) => boolean; + className?: string; +}; + +export function DateRangePicker({ + label, + hint, + error, + value = { start: null, end: null }, + onChange, + required, + disabled, + isDisabled, + className, +}: DateRangePickerProps) { + const id = useId(); + const [open, setOpen] = useState(false); + const [view, setView] = useState(() => value.start ?? new Date()); + const [hover, setHover] = useState(null); + const ref = useRef(null); + + useEffect(() => { + if (!open) return; + const onClick = (e: MouseEvent) => { + if (!ref.current?.contains(e.target as Node)) setOpen(false); + }; + const onKey = (e: KeyboardEvent) => { + if (e.key === "Escape") setOpen(false); + }; + document.addEventListener("mousedown", onClick); + document.addEventListener("keydown", onKey); + return () => { + document.removeEventListener("mousedown", onClick); + document.removeEventListener("keydown", onKey); + }; + }, [open]); + + const cells = useMemo( + () => buildMonthGrid(view.getFullYear(), view.getMonth()), + [view], + ); + const today = new Date(); + + const handleClick = (date: Date) => { + if (!value.start || (value.start && value.end)) { + onChange?.({ start: date, end: null }); + } else if (isBefore(date, value.start)) { + onChange?.({ start: date, end: value.start }); + setOpen(false); + } else { + onChange?.({ start: value.start, end: date }); + setOpen(false); + } + }; + + const inRange = (d: Date) => { + if (!value.start) return false; + const end = value.end ?? hover; + if (!end) return false; + if (isBefore(end, value.start)) return isBetween(d, end, value.start); + return isBetween(d, value.start, end); + }; + + const display = value.start + ? value.end + ? `${fmt(value.start)} → ${fmt(value.end)}` + : `${fmt(value.start)} → …` + : ""; + + return ( +
+ {label && ( + + )} +
+ !disabled && setOpen((v) => !v)} + onFocus={() => !disabled && setOpen(true)} + aria-haspopup="dialog" + aria-expanded={open} + /> + + + +
+ {error ? ( + {error} + ) : hint ? ( + {hint} + ) : null} + + {open && ( +
+
+ + + {MONTHS[view.getMonth()]} {view.getFullYear()} + + +
+ +
+ {WEEKDAYS.map((w) => ( +
{w}
+ ))} +
+ +
+ {cells.map(({ date, outside }, i) => { + const isStart = value.start && sameDay(date, value.start); + const isEnd = value.end && sameDay(date, value.end); + const between = inRange(date); + const todayMatch = sameDay(date, today); + const dis = isDisabled?.(date) ?? false; + return ( + + ); + })} +
+ +
+ + +
+
+ )} +
+ ); +} diff --git a/packages/react/src/Dialog.test.tsx b/packages/react/src/Dialog.test.tsx new file mode 100644 index 0000000..2f3f95b --- /dev/null +++ b/packages/react/src/Dialog.test.tsx @@ -0,0 +1,64 @@ +import { describe, expect, it } from "vitest"; +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { axe } from "vitest-axe"; +import { useState } from "react"; +import { Dialog } from "./Dialog"; + +function Wrapped() { + const [open, setOpen] = useState(false); + return ( + <> + + +

Contenu

+
+ + ); +} + +describe("Dialog", () => { + it("est fermé par défaut", () => { + render(); + expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); + }); + + it("s'ouvre via setState", async () => { + const user = userEvent.setup(); + render(); + await user.click(screen.getByText("Ouvrir")); + expect(await screen.findByRole("dialog")).toBeInTheDocument(); + }); + + it("a un titre lié via aria-labelledby (Radix)", async () => { + const user = userEvent.setup(); + render(); + await user.click(screen.getByText("Ouvrir")); + const dialog = await screen.findByRole("dialog"); + expect(dialog).toHaveAccessibleName("Modifier l'utilisateur"); + }); + + it("se ferme avec Escape", async () => { + const user = userEvent.setup(); + render(); + await user.click(screen.getByText("Ouvrir")); + await screen.findByRole("dialog"); + await user.keyboard("{Escape}"); + // Radix retire le dialog après animation — on attend la disparition + await new Promise((r) => setTimeout(r, 0)); + expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); + }); + + it("a11y axe-core (ouvert)", async () => { + const user = userEvent.setup(); + const { container } = render(); + await user.click(screen.getByText("Ouvrir")); + await screen.findByRole("dialog"); + expect(await axe(container)).toHaveNoViolations(); + }); +}); diff --git a/packages/react/src/Dialog.tsx b/packages/react/src/Dialog.tsx new file mode 100644 index 0000000..b1ab106 --- /dev/null +++ b/packages/react/src/Dialog.tsx @@ -0,0 +1,72 @@ +import { type ReactNode } from "react"; +import * as RadixDialog from "@radix-ui/react-dialog"; +import { cx } from "./utils"; +import { Icon } from "./Icon"; + +export type DialogProps = { + open: boolean; + onOpenChange: (open: boolean) => void; + title?: ReactNode; + description?: ReactNode; + children: ReactNode; + footer?: ReactNode; + /** Largeur max du contenu. */ + size?: "sm" | "md" | "lg" | "xl" | "full"; + /** Cache le bouton de fermeture en haut à droite. */ + hideClose?: boolean; + className?: string; +}; + +/** + * Dialog (modal) — wrapper Radix Dialog. + * + * Focus trap, Escape, scroll lock, restitution du focus à la fermeture, + * tout est géré par Radix. La sémantique est correcte (role="dialog", + * aria-modal, aria-labelledby/-describedby auto via Title/Description). + * + * Pour confirm/destructive, voir ConfirmDialog. + */ +export function Dialog({ + open, + onOpenChange, + title, + description, + children, + footer, + size = "md", + hideClose, + className, +}: DialogProps) { + return ( + + + + + {(title || !hideClose) && ( +
+ {title && {title}} + {!hideClose && ( + + + + )} +
+ )} + {description && ( + + {description} + + )} +
{children}
+ {footer &&
{footer}
} +
+
+
+ ); +} + +export { RadixDialog as DialogPrimitive }; diff --git a/packages/react/src/Drawer.tsx b/packages/react/src/Drawer.tsx new file mode 100644 index 0000000..5fe3dc5 --- /dev/null +++ b/packages/react/src/Drawer.tsx @@ -0,0 +1,71 @@ +import { type ReactNode } from "react"; +import * as RadixDialog from "@radix-ui/react-dialog"; +import { cx } from "./utils"; +import { Icon } from "./Icon"; + +export type DrawerProps = { + open: boolean; + /** Callback de fermeture — déclenché par Esc, click backdrop, click close. */ + onClose: () => void; + /** Côté d'apparition. Défaut "right". */ + side?: "left" | "right"; + /** Largeur. Défaut "md" (480px). */ + size?: "sm" | "md" | "lg" | "xl"; + title?: ReactNode; + children: ReactNode; + footer?: ReactNode; + className?: string; +}; + +/** + * Drawer — panneau latéral (Radix Dialog). + * + * API simplifiée par rapport à Sheet : uniquement left/right, callback + * `onClose` (au lieu de `onOpenChange`). Pour bottom/top sheet ou plus + * de contrôle, utiliser directement Sheet. + * + * Backing Radix : focus trap, scroll lock, restitution focus, Esc — tout + * natif. Anciennement custom (useFocusTrap), maintenant aligné avec Sheet. + */ +export function Drawer({ + open, + onClose, + side = "right", + size = "md", + title, + children, + footer, + className, +}: DrawerProps) { + return ( + !o && onClose()}> + + + + {title && ( +
+
+ {title} +
+ + + +
+ )} +
{children}
+ {footer &&
{footer}
} +
+
+
+ ); +} diff --git a/packages/react/src/EmptyState.tsx b/packages/react/src/EmptyState.tsx new file mode 100644 index 0000000..2e62f26 --- /dev/null +++ b/packages/react/src/EmptyState.tsx @@ -0,0 +1,61 @@ +import type { HTMLAttributes, ReactNode } from "react"; +import { cx } from "./utils"; +import { IconBlock, type IconBlockProps } from "./IconBlock"; +import type { IconName } from "./Icon"; + +export type EmptyStateProps = HTMLAttributes & { + /** Icône Remix à afficher dans un IconBlock. */ + icon?: IconName; + /** Couleur de l'IconBlock. */ + iconColor?: IconBlockProps["color"]; + title: ReactNode; + description?: ReactNode; + /** Action principale (bouton, lien, etc.) */ + action?: ReactNode; + /** Actions secondaires (lien doc, contact support…) */ + secondaryAction?: ReactNode; + /** Variant compacte pour intégration dans un Card */ + compact?: boolean; +}; + +/** + * EmptyState — état vide standardisé. + * + * Cas d'usage : table vide, recherche sans résultat, espace + * non encore configuré, fonctionnalité en cours d'arrivée. + * + * UX : toujours un *next step* clair (action) — jamais juste "rien". + */ +export function EmptyState({ + icon = "search-2-line", + iconColor = "neutral", + title, + description, + action, + secondaryAction, + compact, + className, + ...rest +}: EmptyStateProps) { + return ( +
+ +

{title}

+ {description &&

{description}

} + {(action || secondaryAction) && ( +
+ {action} + {secondaryAction} +
+ )} +
+ ); +} diff --git a/packages/react/src/Extras.tsx b/packages/react/src/Extras.tsx new file mode 100644 index 0000000..19bdd53 --- /dev/null +++ b/packages/react/src/Extras.tsx @@ -0,0 +1,166 @@ +import { useId, type HTMLAttributes, type ReactNode } from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +/* ──────────────────────────────────────────────────────── + SegmentedControl (Apple HIG) + - Choix exclusif court (2-5 options) + - Mieux qu'un Radio quand l'espace horizontal est dispo + - Évite l'overhead cognitif d'un Select pour peu d'options +──────────────────────────────────────────────────────── */ +export type SegmentedItem = { + value: V; + label: ReactNode; + icon?: IconName; + disabled?: boolean; +}; + +export function SegmentedControl({ + items, + value, + onChange, + size = "md", + fullWidth, + ariaLabel, + className, +}: { + items: SegmentedItem[]; + value: V; + onChange: (v: V) => void; + size?: "sm" | "md" | "lg"; + fullWidth?: boolean; + ariaLabel?: string; + className?: string; +}) { + return ( +
+ {items.map((item) => { + const checked = item.value === value; + return ( + + ); + })} +
+ ); +} + +/* ──────────────────────────────────────────────────────── + DescriptionList — pattern clé/valeur structuré (DSFR-like) + Sémantique HTML correcte (
) — meilleur que table + pour des paires non-tabulaires. Lecteurs d'écran nativement + supportés. +──────────────────────────────────────────────────────── */ +export type DListItem = { label: ReactNode; value: ReactNode }; + +export function DescriptionList({ + items, + layout = "horizontal", + className, +}: { + items: DListItem[]; + /** "horizontal" : label à gauche · "vertical" : label au-dessus */ + layout?: "horizontal" | "vertical"; + className?: string; +}) { + return ( +
+ {items.map((item, i) => ( +
+
{item.label}
+
{item.value}
+
+ ))} +
+ ); +} + +/* ──────────────────────────────────────────────────────── + Sparkline — micro graphe pour stat cards / dashboards + Inline SVG, sans dépendance, accessible (table de données + en + role img). +──────────────────────────────────────────────────────── */ +export function Sparkline({ + data, + width = 100, + height = 32, + color = "var(--mmg-color-accent)", + fill = "var(--mmg-color-accent-soft)", + ariaLabel, + className, +}: { + data: number[]; + width?: number; + height?: number; + color?: string; + fill?: string; + ariaLabel?: string; + className?: string; +}) { + if (data.length < 2) return null; + const min = Math.min(...data); + const max = Math.max(...data); + const range = max - min || 1; + const stepX = width / (data.length - 1); + + const points = data.map((v, i) => { + const x = i * stepX; + const y = height - ((v - min) / range) * height; + return `${x.toFixed(1)},${y.toFixed(1)}`; + }); + const linePath = `M ${points.join(" L ")}`; + const areaPath = `${linePath} L ${width},${height} L 0,${height} Z`; + + return ( + <svg + role="img" + aria-label={ariaLabel ?? `Évolution sur ${data.length} points : min ${min}, max ${max}`} + className={cx("mmg-sparkline", className)} + viewBox={`0 0 ${width} ${height}`} + width={width} + height={height} + preserveAspectRatio="none" + > + <path d={areaPath} fill={fill} /> + <path d={linePath} fill="none" stroke={color} strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round" /> + </svg> + ); +} + +/* ──────────────────────────────────────────────────────── + Kbd — wrapping <kbd> stylisé + Pour shortcuts inline ("Appuyez sur ⌘K"). +──────────────────────────────────────────────────────── */ +export function Kbd({ + children, + className, + ...rest +}: HTMLAttributes<HTMLElement>) { + return ( + <kbd className={cx("mmg-kbd", className)} {...rest}> + {children} + </kbd> + ); +} diff --git a/packages/react/src/Fab.tsx b/packages/react/src/Fab.tsx new file mode 100644 index 0000000..9b4efc2 --- /dev/null +++ b/packages/react/src/Fab.tsx @@ -0,0 +1,22 @@ +import type { ButtonHTMLAttributes } from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type FabProps = ButtonHTMLAttributes<HTMLButtonElement> & { + icon: IconName; + label: string; +}; + +export function Fab({ icon, label, className, ...rest }: FabProps) { + return ( + <button + type="button" + className={cx("mmg-fab", className)} + aria-label={label} + title={label} + {...rest} + > + <Icon name={icon} size="lg" /> + </button> + ); +} diff --git a/packages/react/src/FeatureCard.tsx b/packages/react/src/FeatureCard.tsx new file mode 100644 index 0000000..701142c --- /dev/null +++ b/packages/react/src/FeatureCard.tsx @@ -0,0 +1,61 @@ +import { type ReactNode } from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type FeatureCardProps = { + /** Icône principale (Remix). */ + icon?: IconName; + /** Couleur de l'icône (et du glow associé en hover). */ + iconColor?: "brand" | "blue" | "green" | "amber" | "violet" | "neutral"; + title: ReactNode; + description?: ReactNode; + /** Slot pour un lien "En savoir plus". Rendu en bas de la carte. */ + link?: { label: ReactNode; href: string }; + /** Si true, ajoute un effet gradient borde au hover (Vercel-style). */ + glowOnHover?: boolean; + className?: string; +}; + +/** + * FeatureCard — carte de mise en avant (icône + titre + description + lien). + * + * Pattern landing pages Vercel / Linear / Stripe : grille 3 colonnes avec + * un IconBlock coloré, un titre fort, une description et un lien optionnel. + * + * Variante `glowOnHover` : ajoute un effet "border qui s'illumine" au + * hover via un dégradé conique (Vercel signature). Performant (un seul + * background-image animé via mask). + */ +export function FeatureCard({ + icon, + iconColor = "brand", + title, + description, + link, + glowOnHover, + className, +}: FeatureCardProps) { + return ( + <div + className={cx( + "mmg-feature-card", + glowOnHover && "mmg-feature-card--glow", + className, + )} + > + {icon && ( + <span className={cx("mmg-feature-card__icon", `mmg-feature-card__icon--${iconColor}`)} aria-hidden> + <Icon name={icon} size="lg" /> + </span> + )} + <h3 className="mmg-feature-card__title">{title}</h3> + {description && <p className="mmg-feature-card__desc">{description}</p>} + {link && ( + <a className="mmg-feature-card__link" href={link.href}> + {link.label} + <Icon name="arrow-right-line" size="sm" /> + </a> + )} + </div> + ); +} diff --git a/packages/react/src/Feedback.tsx b/packages/react/src/Feedback.tsx new file mode 100644 index 0000000..7add210 --- /dev/null +++ b/packages/react/src/Feedback.tsx @@ -0,0 +1,253 @@ +import { + useEffect, + useRef, + type HTMLAttributes, + type ReactNode, +} from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; +import { useFocusTrap } from "./useFocusTrap"; + +type Severity = "info" | "success" | "warning" | "danger"; + +const SEV_ICON: Record<Severity, IconName> = { + info: "information-fill", + success: "checkbox-circle-fill", + warning: "alert-fill", + danger: "error-warning-fill", +}; + +/* — Alert ————————————————————————————— */ +export function Alert({ + severity = "info", + title, + children, + closable, + onClose, + className, + ...rest +}: HTMLAttributes<HTMLDivElement> & { + severity?: Severity; + title?: ReactNode; + closable?: boolean; + onClose?: () => void; +}) { + return ( + <div + role={severity === "danger" ? "alert" : "status"} + className={cx( + "mmg-alert", + severity !== "info" && `mmg-alert--${severity}`, + className, + )} + {...rest} + > + <Icon name={SEV_ICON[severity]} className="mmg-alert__icon" size="md" /> + <div className="mmg-alert__body"> + {title && <div className="mmg-alert__title">{title}</div>} + {children && <div className="mmg-alert__desc">{children}</div>} + </div> + {closable && ( + <button + type="button" + className="mmg-alert__close" + aria-label="Fermer" + onClick={onClose} + > + <Icon name="close-line" /> + </button> + )} + </div> + ); +} + +/* — Notice ————————————————————————————— */ +export function Notice({ + variant = "brand", + className, + children, + ...rest +}: HTMLAttributes<HTMLDivElement> & { + variant?: "brand" | "info" | "warning" | "danger"; +}) { + return ( + <div + role="status" + className={cx( + "mmg-notice", + variant !== "brand" && `mmg-notice--${variant}`, + className, + )} + {...rest} + > + {children} + </div> + ); +} + +/* — Badge ————————————————————————————— */ +export function Badge({ + variant, + solid, + className, + children, + ...rest +}: HTMLAttributes<HTMLSpanElement> & { + variant?: "brand" | "success" | "warning" | "danger" | "info"; + solid?: boolean; +}) { + return ( + <span + className={cx( + "mmg-badge", + variant && `mmg-badge--${variant}`, + solid && "mmg-badge--solid", + className, + )} + {...rest} + > + {children} + </span> + ); +} + +/* — Modal ————————————————————————————— */ +let modalIdCounter = 0; +export function Modal({ + open, + onClose, + title, + description, + size, + children, + footer, + closable = true, +}: { + open: boolean; + onClose: () => void; + title?: ReactNode; + /** Optionnel — relié via aria-describedby aux lecteurs d'écran. */ + description?: ReactNode; + size?: "sm" | "lg"; + children: ReactNode; + footer?: ReactNode; + closable?: boolean; +}) { + const ref = useFocusTrap<HTMLDivElement>(open); + const titleIdRef = useRef<string>("mmg-modal-title-" + ++modalIdCounter); + const descIdRef = useRef<string>("mmg-modal-desc-" + modalIdCounter); + + useEffect(() => { + if (!open) return; + const onKey = (e: KeyboardEvent) => { + if (e.key === "Escape" && closable) onClose(); + }; + document.addEventListener("keydown", onKey); + const prev = document.body.style.overflow; + document.body.style.overflow = "hidden"; + return () => { + document.removeEventListener("keydown", onKey); + document.body.style.overflow = prev; + }; + }, [open, closable, onClose]); + + if (!open) return null; + return ( + <div + className="mmg-modal-backdrop" + onClick={(e) => { + if (e.target === e.currentTarget && closable) onClose(); + }} + > + <div + ref={ref} + role="dialog" + aria-modal="true" + aria-labelledby={title ? titleIdRef.current : undefined} + aria-describedby={description ? descIdRef.current : undefined} + className={cx("mmg-modal", size && `mmg-modal--${size}`)} + > + {title && ( + <div className="mmg-modal__header"> + <h3 id={titleIdRef.current} className="mmg-modal__title"> + {title} + </h3> + {closable && ( + <button + type="button" + className="mmg-modal__close" + aria-label="Fermer" + onClick={onClose} + > + <Icon name="close-line" size="md" /> + </button> + )} + </div> + )} + <div className="mmg-modal__body"> + {description && ( + <p + id={descIdRef.current} + style={{ marginBottom: "var(--mmg-space-3)", color: "var(--mmg-color-text-tertiary)", fontSize: "var(--mmg-font-size-sm)" }} + > + {description} + </p> + )} + {children} + </div> + {footer && <div className="mmg-modal__footer">{footer}</div>} + </div> + </div> + ); +} + +/* — Toast (basique, contrôlé par parent) ————————————————————————————— */ +export type ToastItem = { + id: string; + severity?: Severity; + title: ReactNode; + desc?: ReactNode; +}; +export function ToastRegion({ + toasts, + onDismiss, +}: { + toasts: ToastItem[]; + onDismiss?: (id: string) => void; +}) { + return ( + <div className="mmg-toast-region" aria-live="polite"> + {toasts.map((t) => ( + <div + key={t.id} + className={cx( + "mmg-toast", + t.severity && t.severity !== "info" && `mmg-toast--${t.severity}`, + )} + onClick={() => onDismiss?.(t.id)} + > + <div> + <div className="mmg-toast__title">{t.title}</div> + {t.desc && <div className="mmg-toast__desc">{t.desc}</div>} + </div> + </div> + ))} + </div> + ); +} + +/* — Spinner ————————————————————————————— */ +export function Spinner({ + size = "md", + className, + ...rest +}: HTMLAttributes<HTMLSpanElement> & { size?: "sm" | "md" | "lg" }) { + return ( + <span + role="status" + aria-label="Chargement" + className={cx("mmg-spinner", size !== "md" && `mmg-spinner--${size}`, className)} + {...rest} + /> + ); +} diff --git a/packages/react/src/FileUpload.tsx b/packages/react/src/FileUpload.tsx new file mode 100644 index 0000000..3ab4030 --- /dev/null +++ b/packages/react/src/FileUpload.tsx @@ -0,0 +1,53 @@ +import { useState, type ReactNode } from "react"; +import { cx } from "./utils"; +import { Icon } from "./Icon"; + +export type FileUploadProps = { + label?: ReactNode; + hint?: ReactNode; + multiple?: boolean; + accept?: string; + onFiles?: (files: FileList) => void; + className?: string; +}; + +export function FileUpload({ + label = "Glissez-déposez vos fichiers ici", + hint = "ou cliquez pour parcourir", + multiple, + accept, + onFiles, + className, +}: FileUploadProps) { + const [dragging, setDragging] = useState(false); + return ( + <label + className={cx("mmg-upload", className)} + data-dragging={dragging || undefined} + onDragEnter={(e) => { + e.preventDefault(); + setDragging(true); + }} + onDragOver={(e) => { + e.preventDefault(); + setDragging(true); + }} + onDragLeave={() => setDragging(false)} + onDrop={(e) => { + e.preventDefault(); + setDragging(false); + if (e.dataTransfer.files.length > 0) onFiles?.(e.dataTransfer.files); + }} + > + <Icon name="upload-line" className="mmg-upload__icon" size="xl" /> + <div className="mmg-upload__text">{label}</div> + <div className="mmg-upload__hint">{hint}</div> + <input + type="file" + multiple={multiple} + accept={accept} + onChange={(e) => e.target.files && onFiles?.(e.target.files)} + /> + </label> + ); +} diff --git a/packages/react/src/Footer.tsx b/packages/react/src/Footer.tsx new file mode 100644 index 0000000..d2cd054 --- /dev/null +++ b/packages/react/src/Footer.tsx @@ -0,0 +1,76 @@ +import type { ReactNode } from "react"; +import { cx } from "./utils"; + +export type FooterColumn = { + title: ReactNode; + links: { label: ReactNode; href: string }[]; +}; + +export type FooterProps = { + brand?: ReactNode; + description?: ReactNode; + columns?: FooterColumn[]; + bottomLinks?: { label: ReactNode; href: string }[]; + copyright?: ReactNode; + className?: string; +}; + +export function Footer({ + brand, + description, + columns, + bottomLinks, + copyright, + className, +}: FooterProps) { + return ( + <footer className={cx("mmg-footer", className)}> + <div className="mmg-container"> + <div className="mmg-footer__top"> + <div> + {brand && <div className="mmg-footer__col-title">{brand}</div>} + {description && ( + <p + style={{ + fontSize: "var(--mmg-font-size-sm)", + color: "var(--mmg-color-text-tertiary)", + marginTop: 8, + }} + > + {description} + </p> + )} + </div> + {columns?.map((col, i) => ( + <div key={i}> + <div className="mmg-footer__col-title">{col.title}</div> + <ul className="mmg-footer__col-list"> + {col.links.map((l, j) => ( + <li key={j}> + <a href={l.href}>{l.label}</a> + </li> + ))} + </ul> + </div> + ))} + </div> + <div className="mmg-footer__bottom"> + <div>{copyright ?? `© ${new Date().getFullYear()} ManageMate Group`}</div> + {bottomLinks && ( + <div className="mmg-inline"> + {bottomLinks.map((l, i) => ( + <a + key={i} + href={l.href} + style={{ fontSize: "var(--mmg-font-size-xs)", color: "var(--mmg-color-text-quaternary)" }} + > + {l.label} + </a> + ))} + </div> + )} + </div> + </div> + </footer> + ); +} diff --git a/packages/react/src/Form.tsx b/packages/react/src/Form.tsx new file mode 100644 index 0000000..b09d65c --- /dev/null +++ b/packages/react/src/Form.tsx @@ -0,0 +1,252 @@ +import { + forwardRef, + useId, + type InputHTMLAttributes, + type SelectHTMLAttributes, + type TextareaHTMLAttributes, + type ReactNode, +} from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +type FieldRenderArg = { + /** id du contrôle (à passer à <input>/<textarea>/<select>) */ + id: string; + /** id du message à passer en aria-describedby (peut être undefined) */ + describedBy: string | undefined; + /** L'état d'invalidité, à passer en aria-invalid */ + invalid: boolean | undefined; +}; + +type FieldProps = { + label?: ReactNode; + hint?: ReactNode; + error?: ReactNode; + success?: ReactNode; + required?: boolean; + className?: string; + id?: string; + children: (arg: FieldRenderArg) => ReactNode; +}; + +export function Field({ + label, + hint, + error, + success, + required, + className, + id: idProp, + children, +}: FieldProps) { + const auto = useId(); + const id = idProp ?? auto; + const messageId = `${id}-message`; + const hasMessage = Boolean(error || success || hint); + const describedBy = hasMessage ? messageId : undefined; + const state = error ? "error" : success ? "success" : undefined; + return ( + <div className={cx("mmg-field", state && `mmg-field--${state}`, className)}> + {label && ( + <label + className={cx( + "mmg-field__label", + required && "mmg-field__label--required", + )} + htmlFor={id} + > + {label} + </label> + )} + {children({ id, describedBy, invalid: error ? true : undefined })} + {error ? ( + <span id={messageId} className="mmg-field__error" role="alert"> + {error} + </span> + ) : success ? ( + <span id={messageId} className="mmg-field__success"> + {success} + </span> + ) : hint ? ( + <span id={messageId} className="mmg-field__hint"> + {hint} + </span> + ) : null} + </div> + ); +} + +/* — Input ————————————————————————————— */ +export type InputProps = Omit<InputHTMLAttributes<HTMLInputElement>, "size"> & { + label?: ReactNode; + hint?: ReactNode; + error?: ReactNode; + success?: ReactNode; + size?: "sm" | "md" | "lg"; + prefixIcon?: IconName; + suffixIcon?: IconName; +}; + +export const Input = forwardRef<HTMLInputElement, InputProps>(function Input( + { label, hint, error, success, size = "md", prefixIcon, suffixIcon, required, className, ...rest }, + ref, +) { + const cls = cx( + "mmg-input", + size !== "md" && `mmg-input--${size}`, + className, + ); + return ( + <Field label={label} hint={hint} error={error} success={success} required={required}> + {({ id, describedBy, invalid }) => + prefixIcon || suffixIcon ? ( + <span className={cx("mmg-input-wrap", suffixIcon && "mmg-input-wrap--with-suffix")}> + {prefixIcon && ( + <span className="mmg-input-wrap__icon"><Icon name={prefixIcon} /></span> + )} + <input + ref={ref} + id={id} + className={cls} + required={required} + aria-describedby={describedBy} + aria-invalid={invalid} + {...rest} + /> + {suffixIcon && ( + <span className="mmg-input-wrap__icon mmg-input-wrap__icon--suffix"> + <Icon name={suffixIcon} /> + </span> + )} + </span> + ) : ( + <input + ref={ref} + id={id} + className={cls} + required={required} + aria-describedby={describedBy} + aria-invalid={invalid} + {...rest} + /> + ) + } + </Field> + ); +}); + +/* — Textarea ————————————————————————————— */ +export type TextareaProps = TextareaHTMLAttributes<HTMLTextAreaElement> & { + label?: ReactNode; + hint?: ReactNode; + error?: ReactNode; + success?: ReactNode; + fieldSize?: "sm" | "md" | "lg"; +}; +export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>( + function Textarea( + { label, hint, error, success, fieldSize = "md", required, className, ...rest }, + ref, + ) { + const cls = cx( + "mmg-textarea", + fieldSize !== "md" && `mmg-textarea--${fieldSize}`, + className, + ); + return ( + <Field label={label} hint={hint} error={error} success={success} required={required}> + {({ id, describedBy, invalid }) => ( + <textarea + ref={ref} + id={id} + className={cls} + required={required} + aria-describedby={describedBy} + aria-invalid={invalid} + {...rest} + /> + )} + </Field> + ); + }, +); + +/* — Select ————————————————————————————— */ +export type SelectOption = { value: string; label: string; disabled?: boolean }; +export type SelectProps = Omit<SelectHTMLAttributes<HTMLSelectElement>, "size"> & { + label?: ReactNode; + hint?: ReactNode; + error?: ReactNode; + success?: ReactNode; + size?: "sm" | "md" | "lg"; + options: SelectOption[]; + placeholder?: string; +}; +export const Select = forwardRef<HTMLSelectElement, SelectProps>(function Select( + { label, hint, error, success, size = "md", options, placeholder, required, className, ...rest }, + ref, +) { + const cls = cx("mmg-select", size !== "md" && `mmg-select--${size}`, className); + return ( + <Field label={label} hint={hint} error={error} success={success} required={required}> + {({ id, describedBy, invalid }) => ( + <select + ref={ref} + id={id} + className={cls} + required={required} + aria-describedby={describedBy} + aria-invalid={invalid} + {...rest} + > + {placeholder && <option value="">{placeholder}</option>} + {options.map((o) => ( + <option key={o.value} value={o.value} disabled={o.disabled}> + {o.label} + </option> + ))} + </select> + )} + </Field> + ); +}); + +/* — Checkbox / Radio ————————————————————————————— */ +type CheckProps = InputHTMLAttributes<HTMLInputElement> & { + label: ReactNode; +}; +export const Checkbox = forwardRef<HTMLInputElement, CheckProps>(function Checkbox( + { label, className, ...rest }, + ref, +) { + return ( + <label className={cx("mmg-check", className)}> + <input ref={ref} type="checkbox" className="mmg-check__input" {...rest} /> + <span className="mmg-check__label">{label}</span> + </label> + ); +}); +export const Radio = forwardRef<HTMLInputElement, CheckProps>(function Radio( + { label, className, ...rest }, + ref, +) { + return ( + <label className={cx("mmg-check", className)}> + <input ref={ref} type="radio" className="mmg-check__input" {...rest} /> + <span className="mmg-check__label">{label}</span> + </label> + ); +}); + +/* — Switch ————————————————————————————— */ +export const Switch = forwardRef<HTMLInputElement, CheckProps>(function Switch( + { label, className, ...rest }, + ref, +) { + return ( + <label className={cx("mmg-switch", className)}> + <input ref={ref} type="checkbox" role="switch" className="mmg-switch__input" {...rest} /> + <span className="mmg-check__label">{label}</span> + </label> + ); +}); diff --git a/packages/react/src/Header.tsx b/packages/react/src/Header.tsx new file mode 100644 index 0000000..96801a2 --- /dev/null +++ b/packages/react/src/Header.tsx @@ -0,0 +1,247 @@ +import { + useEffect, + useRef, + useState, + type ReactNode, +} from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type NavItemSimple = { + label: ReactNode; + href: string; + current?: boolean; +}; + +export type MegaMenuLink = { + label: ReactNode; + href: string; + description?: ReactNode; + icon?: IconName; +}; + +export type MegaMenuColumn = { + title?: ReactNode; + links: MegaMenuLink[]; +}; + +export type MegaMenuFeatured = { + title: ReactNode; + description: ReactNode; + href: string; + cta?: ReactNode; +}; + +export type NavItemMega = { + label: ReactNode; + current?: boolean; + columns: MegaMenuColumn[]; + featured?: MegaMenuFeatured; +}; + +export type HeaderNavItem = NavItemSimple | NavItemMega; + +const isMega = (item: HeaderNavItem): item is NavItemMega => "columns" in item; + +function MegaMenuTrigger({ item, index }: { item: NavItemMega; index: number }) { + const [open, setOpen] = useState(false); + const ref = useRef<HTMLLIElement>(null); + const closeTimer = useRef<number | null>(null); + + useEffect(() => { + if (!open) return; + const onClick = (e: MouseEvent) => { + if (!ref.current?.contains(e.target as Node)) setOpen(false); + }; + const onKey = (e: KeyboardEvent) => { + if (e.key === "Escape") setOpen(false); + }; + document.addEventListener("mousedown", onClick); + document.addEventListener("keydown", onKey); + return () => { + document.removeEventListener("mousedown", onClick); + document.removeEventListener("keydown", onKey); + }; + }, [open]); + + const cancelClose = () => { + if (closeTimer.current) { + window.clearTimeout(closeTimer.current); + closeTimer.current = null; + } + }; + const scheduleClose = () => { + cancelClose(); + closeTimer.current = window.setTimeout(() => setOpen(false), 180); + }; + + return ( + <li + ref={ref} + className="mmg-header__nav-item" + onMouseEnter={() => { + cancelClose(); + setOpen(true); + }} + onMouseLeave={scheduleClose} + > + <button + type="button" + className="mmg-header__nav-trigger" + aria-expanded={open} + aria-haspopup="true" + aria-controls={`mmg-megamenu-${index}`} + onClick={() => setOpen((v) => !v)} + > + {item.label} + <Icon name="arrow-down-line" className="mmg-header__nav-chevron" size="sm" /> + </button> + {open && ( + <div + id={`mmg-megamenu-${index}`} + className="mmg-megamenu" + role="region" + aria-label={typeof item.label === "string" ? item.label : undefined} + > + <div + className="mmg-megamenu__grid" + style={{ + gridTemplateColumns: item.featured + ? `repeat(${item.columns.length}, minmax(180px, 1fr)) 240px` + : `repeat(${item.columns.length}, minmax(180px, 1fr))`, + }} + > + {item.columns.map((col, ci) => ( + <div key={ci}> + {col.title && <div className="mmg-megamenu__col-title">{col.title}</div>} + <ul className="mmg-megamenu__list"> + {col.links.map((l, li) => ( + <li key={li}> + <a href={l.href} className="mmg-megamenu__link"> + {l.icon && ( + <span className="mmg-megamenu__link-icon"> + <Icon name={l.icon} size="md" /> + </span> + )} + <span className="mmg-megamenu__link-content"> + <span className="mmg-megamenu__link-label">{l.label}</span> + {l.description && ( + <span className="mmg-megamenu__link-desc">{l.description}</span> + )} + </span> + </a> + </li> + ))} + </ul> + </div> + ))} + {item.featured && ( + <a + href={item.featured.href} + className="mmg-megamenu__featured" + style={{ textDecoration: "none" }} + > + <div className="mmg-megamenu__featured-title">{item.featured.title}</div> + <div className="mmg-megamenu__featured-desc">{item.featured.description}</div> + {item.featured.cta && ( + <span style={{ color: "var(--mmg-color-accent)", fontWeight: 600, fontSize: "var(--mmg-font-size-sm)" }}> + {item.featured.cta} → + </span> + )} + </a> + )} + </div> + </div> + )} + </li> + ); +} + +export type HeaderProps = { + brand: ReactNode; + brandHref?: string; + /** Si fourni avec serviceTitle, active le mode "institutional". */ + brandTop?: ReactNode; + serviceTitle?: ReactNode; + serviceTagline?: ReactNode; + logoMark?: ReactNode; + nav?: HeaderNavItem[]; + actions?: ReactNode; + className?: string; +}; + +export function Header({ + brand, + brandHref = "/", + brandTop, + serviceTitle, + serviceTagline, + logoMark, + nav, + actions, + className, +}: HeaderProps) { + const initials = typeof brand === "string" ? brand.slice(0, 2).toUpperCase() : null; + const isInstitutional = Boolean(brandTop || serviceTitle); + + return ( + <header + className={cx( + "mmg-header", + isInstitutional && "mmg-header--institutional", + className, + )} + > + <div className="mmg-container"> + <div className="mmg-header__inner"> + <a href={brandHref} className="mmg-header__brand"> + <span className="mmg-header__logo">{logoMark ?? initials}</span> + {isInstitutional ? ( + <span className="mmg-header__brand-text"> + {brandTop && <span className="mmg-header__brand-top">{brandTop}</span>} + {serviceTitle && <span className="mmg-header__service">{serviceTitle}</span>} + {serviceTagline && ( + <span className="mmg-header__service-tagline">{serviceTagline}</span> + )} + </span> + ) : ( + <span className="mmg-header__name">{brand}</span> + )} + </a> + {nav && ( + <nav className="mmg-header__nav" aria-label="Navigation principale"> + <ul + style={{ + display: "flex", + alignItems: "center", + listStyle: "none", + padding: 0, + margin: 0, + gap: "var(--mmg-space-1)", + height: "100%", + }} + > + {nav.map((item, i) => + isMega(item) ? ( + <MegaMenuTrigger key={i} item={item} index={i} /> + ) : ( + <li + key={i} + className="mmg-header__nav-item" + style={{ display: "flex", alignItems: "center" }} + > + <a href={item.href} aria-current={item.current ? "page" : undefined}> + {item.label} + </a> + </li> + ), + )} + </ul> + </nav> + )} + {actions && <div className="mmg-header__actions">{actions}</div>} + </div> + </div> + </header> + ); +} diff --git a/packages/react/src/Highlight.tsx b/packages/react/src/Highlight.tsx new file mode 100644 index 0000000..615363e --- /dev/null +++ b/packages/react/src/Highlight.tsx @@ -0,0 +1,12 @@ +import type { HTMLAttributes } from "react"; +import { cx } from "./utils"; + +export type HighlightProps = HTMLAttributes<HTMLDivElement>; + +export function Highlight({ children, className, ...rest }: HighlightProps) { + return ( + <div className={cx("mmg-highlight", className)} {...rest}> + {children} + </div> + ); +} diff --git a/packages/react/src/HoverCard.tsx b/packages/react/src/HoverCard.tsx new file mode 100644 index 0000000..ed50aca --- /dev/null +++ b/packages/react/src/HoverCard.tsx @@ -0,0 +1,57 @@ +import { type ReactNode } from "react"; +import * as RadixHoverCard from "@radix-ui/react-hover-card"; +import { cx } from "./utils"; + +export type HoverCardProps = { + trigger: ReactNode; + children: ReactNode; + /** Délai d'apparition (ms). Défaut 700. */ + openDelay?: number; + /** Délai avant fermeture (ms). Défaut 300. */ + closeDelay?: number; + side?: "top" | "right" | "bottom" | "left"; + align?: "start" | "center" | "end"; + sideOffset?: number; + className?: string; +}; + +/** + * HoverCard — preview riche au survol (Radix UI HoverCard). + * + * Pour : aperçus de profil utilisateur, métadonnées de lien, fiche produit + * en survol, etc. Pas pour les tooltips courts (utiliser Tooltip). + * + * A11y : Radix gère le hover-bridge (la fenêtre reste ouverte pendant la + * traversée de l'utilisateur entre trigger et content), le focus management + * et l'invocation par focus clavier (le HoverCard ouvre aussi sur :focus). + */ +export function HoverCard({ + trigger, + children, + openDelay = 700, + closeDelay = 300, + side = "bottom", + align = "start", + sideOffset = 8, + className, +}: HoverCardProps) { + return ( + <RadixHoverCard.Root openDelay={openDelay} closeDelay={closeDelay}> + <RadixHoverCard.Trigger asChild>{trigger}</RadixHoverCard.Trigger> + <RadixHoverCard.Portal> + <RadixHoverCard.Content + side={side} + align={align} + sideOffset={sideOffset} + collisionPadding={8} + className={cx("mmg-hover-card", className)} + > + {children} + <RadixHoverCard.Arrow className="mmg-hover-card__arrow" /> + </RadixHoverCard.Content> + </RadixHoverCard.Portal> + </RadixHoverCard.Root> + ); +} + +export { RadixHoverCard as HoverCardPrimitive }; diff --git a/packages/react/src/Icon.tsx b/packages/react/src/Icon.tsx new file mode 100644 index 0000000..0a8cd54 --- /dev/null +++ b/packages/react/src/Icon.tsx @@ -0,0 +1,40 @@ +import type { CSSProperties, HTMLAttributes } from "react"; +import { cx } from "./utils"; + +/** Nom d'une icône DSMMG (préfixe `mmg-icon-`). */ +export type IconName = string; + +export type IconProps = HTMLAttributes<HTMLSpanElement> & { + /** Nom de l'icône (ex. "arrow-right"). Voir packages/icons/dist/icons.json */ + name: IconName; + /** Taille — xs: 12px, sm: 14px, md: 18px, lg: 24px, xl: 32px, 2xl: 48px. + Par défaut hérite de font-size. */ + size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl"; + /** Texte alternatif. Si absent, l'icône est purement décorative (aria-hidden). */ + label?: string; +}; + +export function Icon({ + name, + size, + label, + className, + style, + ...rest +}: IconProps) { + return ( + <span + role={label ? "img" : undefined} + aria-label={label} + aria-hidden={label ? undefined : true} + className={cx( + "mmg-icon", + `mmg-icon-${name}`, + size && `mmg-icon--${size}`, + className, + )} + style={style as CSSProperties} + {...rest} + /> + ); +} diff --git a/packages/react/src/IconBlock.tsx b/packages/react/src/IconBlock.tsx new file mode 100644 index 0000000..4ab4642 --- /dev/null +++ b/packages/react/src/IconBlock.tsx @@ -0,0 +1,54 @@ +import type { HTMLAttributes } from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type IconBlockProps = HTMLAttributes<HTMLSpanElement> & { + /** Icône Remix (préfère les variants -fill pour visibilité). */ + icon: IconName; + /** Taille — xs:32 sm:40 md:56 lg:72 xl:96 px. */ + size?: "xs" | "sm" | "md" | "lg" | "xl"; + /** Variante de couleur sémantique. */ + color?: "brand" | "success" | "warning" | "danger" | "info" | "neutral"; + /** Style visuel — soft (par défaut), filled, outline, gradient. */ + variant?: "soft" | "filled" | "outline" | "gradient"; + /** Texte alternatif. Si absent, IconBlock est décoratif. */ + label?: string; +}; + +/** + * IconBlock — carré coloré avec icône centrée. + * + * Pattern utilisé chez Linear, Vercel, Notion. Plus polyvalent que les + * pictogrammes hand-codés : se compose à partir de n'importe quelle icône + * Remix, scale automatiquement avec les tokens couleur sémantique, et reste + * cohérent en dark mode. + * + * Préférer en Tile pour les pages d'index produits/fonctionnalités. + */ +export function IconBlock({ + icon, + size = "md", + color = "brand", + variant = "soft", + label, + className, + ...rest +}: IconBlockProps) { + return ( + <span + role={label ? "img" : undefined} + aria-label={label} + aria-hidden={label ? undefined : true} + className={cx( + "mmg-iconblock", + `mmg-iconblock--${size}`, + `mmg-iconblock--${color}`, + variant !== "soft" && `mmg-iconblock--${variant}`, + className, + )} + {...rest} + > + <Icon name={icon} /> + </span> + ); +} diff --git a/packages/react/src/Layout.tsx b/packages/react/src/Layout.tsx new file mode 100644 index 0000000..e86c7c8 --- /dev/null +++ b/packages/react/src/Layout.tsx @@ -0,0 +1,225 @@ +import type { HTMLAttributes, ReactNode, AnchorHTMLAttributes, ElementType } from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; +import { IconBlock, type IconBlockProps } from "./IconBlock"; +import { Pictogram, type PictogramName } from "./Pictogram"; + +/* — Container ————————————————————————————— */ +export type ContainerProps = HTMLAttributes<HTMLDivElement> & { + variant?: "default" | "narrow" | "wide" | "fluid"; + as?: ElementType; +}; +export function Container({ + variant = "default", + as: As = "div", + className, + children, + ...rest +}: ContainerProps) { + const Tag = As as ElementType; + return ( + <Tag + className={cx( + "mmg-container", + variant !== "default" && `mmg-container--${variant}`, + className, + )} + {...rest} + > + {children} + </Tag> + ); +} + +/* — Section ————————————————————————————— */ +export type SectionProps = HTMLAttributes<HTMLElement> & { + size?: "sm" | "md" | "lg"; + variant?: "default" | "surface" | "muted" | "brand-soft"; +}; +export function Section({ + size = "md", + variant = "default", + className, + children, + ...rest +}: SectionProps) { + return ( + <section + className={cx( + "mmg-section", + size !== "md" && `mmg-section--${size}`, + variant !== "default" && `mmg-section--${variant}`, + className, + )} + {...rest} + > + {children} + </section> + ); +} + +/* — Stack & Inline ————————————————————————————— */ +export function Stack({ + gap = "md", + className, + children, + ...rest +}: HTMLAttributes<HTMLDivElement> & { gap?: "xs" | "sm" | "md" | "lg" | "xl" }) { + return ( + <div className={cx("mmg-stack", `mmg-stack--${gap}`, className)} {...rest}> + {children} + </div> + ); +} +export function Inline({ + align, + className, + children, + ...rest +}: HTMLAttributes<HTMLDivElement> & { align?: "end" | "between" | "center" }) { + return ( + <div + className={cx("mmg-inline", align && `mmg-inline--${align}`, className)} + {...rest} + > + {children} + </div> + ); +} + +/* — Card ————————————————————————————— */ +export function Card({ + raised, + flat, + noPadding, + className, + children, + ...rest +}: HTMLAttributes<HTMLDivElement> & { + raised?: boolean; + flat?: boolean; + noPadding?: boolean; +}) { + return ( + <div + className={cx( + "mmg-card", + raised && "mmg-card--raised", + flat && "mmg-card--flat", + noPadding && "mmg-card--no-padding", + className, + )} + {...rest} + > + {children} + </div> + ); +} +Card.Header = function CardHeader({ children, className, ...rest }: HTMLAttributes<HTMLDivElement>) { + return <div className={cx("mmg-card__header", className)} {...rest}>{children}</div>; +}; +Card.Title = function CardTitle({ children, className, ...rest }: HTMLAttributes<HTMLHeadingElement>) { + return <h3 className={cx("mmg-card__title", className)} {...rest}>{children}</h3>; +}; +Card.Desc = function CardDesc({ children, className, ...rest }: HTMLAttributes<HTMLParagraphElement>) { + return <p className={cx("mmg-card__desc", className)} {...rest}>{children}</p>; +}; +Card.Footer = function CardFooter({ children, className, ...rest }: HTMLAttributes<HTMLDivElement>) { + return <div className={cx("mmg-card__footer", className)} {...rest}>{children}</div>; +}; + +/* — Tile ————————————————————————————— */ +export type TileProps = AnchorHTMLAttributes<HTMLAnchorElement> & { + title: ReactNode; + desc?: ReactNode; + /** Petite icône carrée (style basique, 48×48). */ + icon?: IconName; + /** IconBlock — pattern recommandé : icône fill colorée sur fond rond. */ + iconBlock?: IconName; + /** Couleur sémantique de l'IconBlock. */ + iconColor?: IconBlockProps["color"]; + /** Variante visuelle de l'IconBlock. */ + iconVariant?: IconBlockProps["variant"]; + /** Pictogramme illustré (legacy v0.2). */ + pictogram?: PictogramName; + /** Disposition horizontale (icône à gauche). */ + horizontal?: boolean; + /** Cache la flèche d'invitation. */ + noArrow?: boolean; + /** Taille — sm (compact), md (défaut), lg (hero). */ + size?: "sm" | "md" | "lg"; +}; + +export function Tile({ + title, + desc, + icon, + iconBlock, + iconColor = "brand", + iconVariant = "soft", + pictogram, + horizontal, + noArrow, + size = "md", + className, + children, + ...rest +}: TileProps) { + const blockSize = size === "sm" ? "sm" : size === "lg" ? "lg" : "md"; + return ( + <a + className={cx( + "mmg-tile", + size !== "md" && `mmg-tile--${size}`, + horizontal && "mmg-tile--horizontal", + className, + )} + {...rest} + > + {iconBlock ? ( + <IconBlock icon={iconBlock} color={iconColor} variant={iconVariant} size={blockSize} /> + ) : pictogram ? ( + <Pictogram name={pictogram} className="mmg-tile__pictogram" /> + ) : icon ? ( + <span className="mmg-tile__icon"> + <Icon name={icon} /> + </span> + ) : null} + <div className="mmg-stack mmg-stack--xs" style={{ flex: 1 }}> + <span className="mmg-tile__title"> + {title} + {!noArrow && ( + <span className="mmg-tile__arrow" aria-hidden> + <Icon name="arrow-right-line" size="md" /> + </span> + )} + </span> + {desc && <span className="mmg-tile__desc">{desc}</span>} + {children} + </div> + </a> + ); +} + +/* — Hero ————————————————————————————— */ +export function Hero({ + title, + lead, + actions, + className, + ...rest +}: HTMLAttributes<HTMLElement> & { + title: ReactNode; + lead?: ReactNode; + actions?: ReactNode; +}) { + return ( + <section className={cx("mmg-hero", className)} {...rest}> + <div className="mmg-container"> + <h1 className="mmg-hero__title">{title}</h1> + {lead && <p className="mmg-hero__lead">{lead}</p>} + {actions && <div className="mmg-inline">{actions}</div>} + </div> + </section> + ); +} diff --git a/packages/react/src/Menu.tsx b/packages/react/src/Menu.tsx new file mode 100644 index 0000000..899650d --- /dev/null +++ b/packages/react/src/Menu.tsx @@ -0,0 +1,99 @@ +import { type ReactNode } from "react"; +import * as RadixMenu from "@radix-ui/react-dropdown-menu"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type MenuItem = + | { + type?: "item"; + label: ReactNode; + icon?: IconName; + onSelect?: () => void; + danger?: boolean; + href?: string; + disabled?: boolean; + shortcut?: string; + } + | { type: "divider" } + | { type: "label"; label: ReactNode }; + +export type MenuProps = { + trigger: ReactNode; + items: MenuItem[]; + align?: "start" | "center" | "end"; + side?: "top" | "right" | "bottom" | "left"; + sideOffset?: number; +}; + +/** + * Menu (dropdown) — wrapper Radix DropdownMenu. + * + * Accessibilité gérée par Radix : navigation flèches, type-ahead, Escape, + * focus management, ARIA roles. Aucun appel a11y custom. + * + * Pour les sous-menus, items radio/checkbox, ouvrir + * MenuPrimitive et composer manuellement. + */ +export function Menu({ + trigger, + items, + align = "start", + side = "bottom", + sideOffset = 6, +}: MenuProps) { + return ( + <RadixMenu.Root> + <RadixMenu.Trigger asChild>{trigger}</RadixMenu.Trigger> + <RadixMenu.Portal> + <RadixMenu.Content + align={align} + side={side} + sideOffset={sideOffset} + collisionPadding={8} + className="mmg-menu" + > + {items.map((item, i) => { + if (item.type === "divider") { + return <RadixMenu.Separator key={i} className="mmg-menu__divider" />; + } + if (item.type === "label") { + return ( + <RadixMenu.Label key={i} className="mmg-menu__label"> + {item.label} + </RadixMenu.Label> + ); + } + const { label, icon, onSelect, danger, href, disabled, shortcut } = item; + const cn = cx("mmg-menu__item", danger && "mmg-menu__item--danger"); + const inner = ( + <> + {icon && <Icon name={icon} />} + <span style={{ flex: 1 }}>{label}</span> + {shortcut && <span className="mmg-menu__shortcut">{shortcut}</span>} + </> + ); + if (href) { + return ( + <RadixMenu.Item key={i} className={cn} disabled={disabled} asChild> + <a href={href}>{inner}</a> + </RadixMenu.Item> + ); + } + return ( + <RadixMenu.Item + key={i} + className={cn} + disabled={disabled} + onSelect={onSelect} + > + {inner} + </RadixMenu.Item> + ); + })} + </RadixMenu.Content> + </RadixMenu.Portal> + </RadixMenu.Root> + ); +} + +export { RadixMenu as MenuPrimitive }; diff --git a/packages/react/src/MetricCard.tsx b/packages/react/src/MetricCard.tsx new file mode 100644 index 0000000..9d8977b --- /dev/null +++ b/packages/react/src/MetricCard.tsx @@ -0,0 +1,114 @@ +import { type ReactNode } from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type MetricTrend = "up" | "down" | "flat"; + +export type MetricCardProps = { + /** Label de la métrique (ex: "MRR", "NPS", "Tickets ouverts"). */ + label: ReactNode; + /** Valeur principale (ex: "12 480 €", "8.2"). */ + value: ReactNode; + /** Variation chiffrée (ex: "+12.4%", "-3"). Affichée sous la valeur. */ + delta?: ReactNode; + /** Sens de la tendance — détermine la couleur (success/danger/neutre). */ + trend?: MetricTrend; + /** Si true, inverse la sémantique : down=success (ex: "tickets en attente"). */ + invertTrend?: boolean; + /** Période / sous-titre (ex: "vs mois dernier"). */ + period?: ReactNode; + /** Icône optionnelle à gauche du label. */ + icon?: IconName; + /** Slot pour un Sparkline ou autre graphique inline. */ + sparkline?: ReactNode; + /** Si fourni, rend la carte cliquable (drill-down). */ + href?: string; + onClick?: () => void; + className?: string; +}; + +const TREND_ICON: Record<MetricTrend, IconName> = { + up: "arrow-right-up-line", + down: "arrow-right-up-line", // rotated via CSS + flat: "subtract-line", +}; + +/** + * MetricCard — carte KPI avec valeur + delta + tendance + sparkline. + * + * Pattern Linear / Vercel / Stripe Dashboard : une grosse valeur, une + * variation colorée (vert si positif, rouge si négatif), période, et + * éventuellement un sparkline en arrière-plan ou inline. + * + * Sémantique : + * - trend "up" : vert par défaut (croissance = bien) + * - trend "down" : rouge par défaut (décroissance = mal) + * - trend "flat" : neutre + * - `invertTrend` inverse pour les KPI où "moins, c'est mieux" + * (tickets ouverts, latence, churn). + */ +export function MetricCard({ + label, + value, + delta, + trend = "flat", + invertTrend, + period, + icon, + sparkline, + href, + onClick, + className, +}: MetricCardProps) { + const Comp: "a" | "button" | "div" = href ? "a" : onClick ? "button" : "div"; + const semantic = + trend === "flat" + ? "neutral" + : (trend === "up" && !invertTrend) || (trend === "down" && invertTrend) + ? "success" + : "danger"; + + return ( + <Comp + className={cx( + "mmg-metric-card", + (href || onClick) && "mmg-metric-card--interactive", + className, + )} + href={href} + type={Comp === "button" ? "button" : undefined} + onClick={onClick} + > + <div className="mmg-metric-card__head"> + {icon && ( + <span className="mmg-metric-card__icon" aria-hidden> + <Icon name={icon} size="sm" /> + </span> + )} + <span className="mmg-metric-card__label">{label}</span> + </div> + + <div className="mmg-metric-card__value">{value}</div> + + {(delta || period) && ( + <div className="mmg-metric-card__footer"> + {delta && ( + <span + className={cx( + "mmg-metric-card__delta", + `mmg-metric-card__delta--${semantic}`, + trend === "down" && "mmg-metric-card__delta--rotated", + )} + > + <Icon name={TREND_ICON[trend]} size="xs" /> + {delta} + </span> + )} + {period && <span className="mmg-metric-card__period">{period}</span>} + </div> + )} + + {sparkline && <div className="mmg-metric-card__sparkline">{sparkline}</div>} + </Comp> + ); +} diff --git a/packages/react/src/Pagination.tsx b/packages/react/src/Pagination.tsx new file mode 100644 index 0000000..9c8f81e --- /dev/null +++ b/packages/react/src/Pagination.tsx @@ -0,0 +1,50 @@ +import { cx } from "./utils"; +import { Icon } from "./Icon"; + +export type PaginationProps = { + page: number; + pageCount: number; + onChange: (p: number) => void; + className?: string; +}; + +export function Pagination({ page, pageCount, onChange, className }: PaginationProps) { + const pages = Array.from({ length: pageCount }, (_, i) => i + 1); + return ( + <nav aria-label="Pagination"> + <ul className={cx("mmg-pagination", className)}> + <li> + <button + type="button" + onClick={() => onChange(Math.max(1, page - 1))} + disabled={page === 1} + aria-label="Page précédente" + > + <Icon name="arrow-left-line" /> + </button> + </li> + {pages.map((p) => ( + <li key={p}> + <button + type="button" + aria-current={p === page ? "page" : undefined} + onClick={() => onChange(p)} + > + {p} + </button> + </li> + ))} + <li> + <button + type="button" + onClick={() => onChange(Math.min(pageCount, page + 1))} + disabled={page === pageCount} + aria-label="Page suivante" + > + <Icon name="arrow-right-line" /> + </button> + </li> + </ul> + </nav> + ); +} diff --git a/packages/react/src/Pictogram.tsx b/packages/react/src/Pictogram.tsx new file mode 100644 index 0000000..78a2959 --- /dev/null +++ b/packages/react/src/Pictogram.tsx @@ -0,0 +1,696 @@ +import type { CSSProperties, JSX } from "react"; +import { cx } from "./utils"; + +/** + * Pictogrammes ManageMate — 80×80, palette artwork stable cross-theme. + * + * Tokens utilisés (définis dans tokens.css) : + * --mmg-color-art-major rose marque + * --mmg-color-art-minor rose foncé + * --mmg-color-art-light fond pâle (rose en light, sombre teinté en dark) + * --mmg-color-art-dark silhouette sombre (clair en dark mode) + * --mmg-color-art-accent bleu pour accent rare + * + * Inspiration : DSFR & defense.gouv.fr — illustrations plates, 2-3 couleurs, + * silhouette claire, pas plus de 4 formes par picto. + */ +export type PictogramName = + // — Démarches / documents —————————————— + | "certificate" + | "transfer" + | "document" + | "duplicate" + | "address" + // — Produits SIRH ————————————————————— + | "people" + | "payroll" + | "calendar" + | "training" + | "shopping" + | "news" + // — Marketing / général —————————————— + | "rocket" + | "shield" + | "settings" + // — Nouveaux v0.2 ———————————————————— + | "success" + | "alert" + | "search" + | "support" + | "growth" + | "target" + | "innovation" + | "savings" + | "handshake" + | "cloud" + | "lock-secure" + | "globe" + | "mobile" + | "analytics" + | "gift" + | "messaging" + // — v0.5 marine ———————————————————— + | "marine-casquette" + | "marine-ancre" + | "marine-porte-avion" + // — v0.6 ManageMate Group products —————————————— + | "synapse" + | "hrtime" + | "forge" + | "orbit" + | "automation" + | "insights" + | "integration" + | "workflow"; + +const MAJOR = "var(--mmg-color-art-major)"; +const MINOR = "var(--mmg-color-art-minor)"; +const LIGHT = "var(--mmg-color-art-light)"; +const DARK = "var(--mmg-color-art-dark)"; +const ACCENT = "var(--mmg-color-art-accent)"; + +const PICTOS: Record<PictogramName, JSX.Element> = { + certificate: ( + <> + <rect x="14" y="10" width="52" height="62" rx="4" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <line x1="22" y1="24" x2="58" y2="24" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="22" y1="32" x2="50" y2="32" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="22" y1="40" x2="46" y2="40" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <circle cx="56" cy="58" r="10" fill={MAJOR} /> + <path d="M52 58 L55 61 L61 55" stroke="white" strokeWidth="2.5" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + </> + ), + + transfer: ( + <> + <rect x="6" y="34" width="32" height="22" rx="3" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <circle cx="14" cy="56" r="4" fill={DARK} /> + <circle cx="30" cy="56" r="4" fill={DARK} /> + <rect x="42" y="40" width="32" height="22" rx="3" fill={MAJOR} /> + <circle cx="50" cy="62" r="4" fill={DARK} /> + <circle cx="66" cy="62" r="4" fill={DARK} /> + <path d="M36 26 L44 26 L44 22 L52 30 L44 38 L44 34 L36 34 Z" fill={MAJOR} /> + </> + ), + + document: ( + <> + <path d="M22 8 L46 8 L58 20 L58 70 Q58 74 54 74 L22 74 Q18 74 18 70 L18 12 Q18 8 22 8 Z" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <path d="M46 8 L46 20 L58 20" fill="none" stroke={MAJOR} strokeWidth="2" strokeLinejoin="round" /> + <line x1="26" y1="34" x2="50" y2="34" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="26" y1="44" x2="50" y2="44" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="26" y1="54" x2="42" y2="54" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + </> + ), + + duplicate: ( + <> + <rect x="10" y="20" width="40" height="50" rx="3" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <rect x="22" y="10" width="40" height="50" rx="3" fill="white" stroke={MAJOR} strokeWidth="2" /> + <line x1="30" y1="26" x2="54" y2="26" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="30" y1="34" x2="50" y2="34" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="30" y1="42" x2="46" y2="42" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + </> + ), + + address: ( + <> + <ellipse cx="40" cy="72" rx="14" ry="3" fill={LIGHT} /> + <path d="M40 8 C28 8 20 16 20 28 C20 44 40 70 40 70 C40 70 60 44 60 28 C60 16 52 8 40 8 Z" fill={MAJOR} /> + <circle cx="40" cy="28" r="8" fill="white" /> + </> + ), + + people: ( + <> + <circle cx="28" cy="26" r="10" fill={MAJOR} /> + <circle cx="52" cy="26" r="10" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <path d="M10 60 Q10 46 28 46 Q46 46 46 60 L46 70 L10 70 Z" fill={MAJOR} /> + <path d="M34 60 Q34 46 52 46 Q70 46 70 60 L70 70 L46 70 L46 60 Z" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + </> + ), + + payroll: ( + <> + <rect x="10" y="18" width="60" height="44" rx="4" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <rect x="10" y="26" width="60" height="6" fill={MAJOR} /> + <circle cx="40" cy="48" r="10" fill="white" stroke={MAJOR} strokeWidth="2" /> + <text x="40" y="52" fontSize="14" fontWeight="700" fill={MAJOR} textAnchor="middle" fontFamily="system-ui, sans-serif">€</text> + <line x1="18" y1="44" x2="26" y2="44" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + <line x1="18" y1="52" x2="26" y2="52" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + <line x1="54" y1="44" x2="62" y2="44" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + <line x1="54" y1="52" x2="62" y2="52" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + </> + ), + + calendar: ( + <> + <rect x="10" y="16" width="60" height="56" rx="4" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <rect x="10" y="16" width="60" height="14" rx="4" fill={MAJOR} /> + <line x1="22" y1="10" x2="22" y2="22" stroke={DARK} strokeWidth="3" strokeLinecap="round" /> + <line x1="58" y1="10" x2="58" y2="22" stroke={DARK} strokeWidth="3" strokeLinecap="round" /> + <rect x="20" y="38" width="8" height="8" fill={MAJOR} /> + <rect x="36" y="38" width="8" height="8" fill={MAJOR} fillOpacity="0.4" /> + <rect x="52" y="38" width="8" height="8" fill={MAJOR} fillOpacity="0.4" /> + <rect x="20" y="52" width="8" height="8" fill={MAJOR} fillOpacity="0.4" /> + <rect x="36" y="52" width="8" height="8" fill={MAJOR} /> + <rect x="52" y="52" width="8" height="8" fill={MAJOR} fillOpacity="0.4" /> + </> + ), + + training: ( + <> + <path d="M10 30 L40 16 L70 30 L40 44 Z" fill={MAJOR} /> + <path d="M22 36 L22 54 Q22 64 40 64 Q58 64 58 54 L58 36" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <line x1="68" y1="32" x2="68" y2="50" stroke={MAJOR} strokeWidth="3" strokeLinecap="round" /> + <circle cx="68" cy="54" r="3" fill={MAJOR} /> + </> + ), + + shopping: ( + <> + <path d="M14 20 L20 20 L26 56 Q26 60 30 60 L60 60 Q64 60 64 56 L68 30 L24 30" fill={LIGHT} stroke={MAJOR} strokeWidth="2" strokeLinejoin="round" /> + <circle cx="32" cy="68" r="4" fill={MAJOR} /> + <circle cx="58" cy="68" r="4" fill={MAJOR} /> + <path d="M30 36 L30 44 M40 36 L40 44 M50 36 L50 44 M60 36 L60 44" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + </> + ), + + news: ( + <> + <rect x="8" y="18" width="56" height="50" rx="3" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <rect x="64" y="30" width="10" height="38" rx="2" fill="white" stroke={MAJOR} strokeWidth="2" /> + <rect x="14" y="24" width="20" height="14" fill={MAJOR} /> + <line x1="38" y1="26" x2="58" y2="26" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + <line x1="38" y1="32" x2="58" y2="32" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + <line x1="38" y1="38" x2="54" y2="38" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + <line x1="14" y1="46" x2="58" y2="46" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + <line x1="14" y1="52" x2="58" y2="52" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + <line x1="14" y1="58" x2="50" y2="58" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + </> + ), + + rocket: ( + <> + <path d="M40 8 Q52 16 52 36 L52 50 L28 50 L28 36 Q28 16 40 8 Z" fill={MAJOR} /> + <circle cx="40" cy="28" r="6" fill="white" /> + <path d="M28 50 L18 60 L18 68 L28 64 Z" fill={LIGHT} stroke={MAJOR} strokeWidth="2" strokeLinejoin="round" /> + <path d="M52 50 L62 60 L62 68 L52 64 Z" fill={LIGHT} stroke={MAJOR} strokeWidth="2" strokeLinejoin="round" /> + <path d="M34 50 L34 64 L40 70 L46 64 L46 50 Z" fill={ACCENT} /> + </> + ), + + shield: ( + <> + <path d="M40 6 L66 16 L66 38 Q66 60 40 74 Q14 60 14 38 L14 16 Z" fill={MAJOR} /> + <path d="M40 14 L60 22 L60 38 Q60 54 40 66 Q20 54 20 38 L20 22 Z" fill={LIGHT} /> + <path d="M30 38 L37 45 L52 30" stroke={MAJOR} strokeWidth="3.5" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + </> + ), + + settings: ( + <> + <circle cx="40" cy="40" r="28" fill={LIGHT} /> + <path d="M40 14 L40 18 M40 62 L40 66 M14 40 L18 40 M62 40 L66 40 M22 22 L25 25 M55 55 L58 58 M22 58 L25 55 M55 25 L58 22" stroke={MAJOR} strokeWidth="3" strokeLinecap="round" /> + <circle cx="40" cy="40" r="14" fill={MAJOR} /> + <circle cx="40" cy="40" r="6" fill="white" /> + </> + ), + + // ─── NOUVEAUX v0.2 ───────────────────────────────── + + success: ( + <> + {/* trophée / médaille */} + <ellipse cx="40" cy="72" rx="22" ry="3" fill={LIGHT} /> + <path d="M28 12 L52 12 L52 28 Q52 44 40 50 Q28 44 28 28 Z" fill={MAJOR} /> + <path d="M28 18 L18 18 L18 28 Q18 38 28 38" fill="none" stroke={MAJOR} strokeWidth="3" strokeLinecap="round" /> + <path d="M52 18 L62 18 L62 28 Q62 38 52 38" fill="none" stroke={MAJOR} strokeWidth="3" strokeLinecap="round" /> + <rect x="34" y="50" width="12" height="14" fill={MINOR} /> + <rect x="26" y="62" width="28" height="6" rx="2" fill={DARK} /> + <path d="M36 24 L40 30 L46 18" stroke="white" strokeWidth="3" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + </> + ), + + alert: ( + <> + <path d="M40 8 L72 64 L8 64 Z" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" strokeLinejoin="round" /> + <rect x="37" y="28" width="6" height="20" rx="2" fill={MAJOR} /> + <circle cx="40" cy="56" r="3" fill={MAJOR} /> + </> + ), + + search: ( + <> + <circle cx="32" cy="32" r="20" fill={LIGHT} stroke={MAJOR} strokeWidth="3" /> + <circle cx="32" cy="32" r="10" fill="white" stroke={MAJOR} strokeWidth="2" /> + <line x1="48" y1="48" x2="68" y2="68" stroke={MAJOR} strokeWidth="6" strokeLinecap="round" /> + </> + ), + + support: ( + <> + {/* casque audio + bulle */} + <path d="M14 44 Q14 18 40 18 Q66 18 66 44 L66 54" fill="none" stroke={MAJOR} strokeWidth="3" strokeLinecap="round" /> + <rect x="10" y="44" width="14" height="22" rx="4" fill={MAJOR} /> + <rect x="56" y="44" width="14" height="22" rx="4" fill={MAJOR} /> + <path d="M58 64 Q58 72 50 72 L42 72" fill="none" stroke={DARK} strokeWidth="2.5" strokeLinecap="round" /> + <circle cx="40" cy="72" r="3" fill={DARK} /> + </> + ), + + growth: ( + <> + {/* graphe en barres + flèche montante */} + <line x1="12" y1="68" x2="68" y2="68" stroke={DARK} strokeWidth="2.5" strokeLinecap="round" /> + <line x1="12" y1="68" x2="12" y2="14" stroke={DARK} strokeWidth="2.5" strokeLinecap="round" /> + <rect x="20" y="48" width="10" height="20" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <rect x="34" y="36" width="10" height="32" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <rect x="48" y="22" width="10" height="46" fill={MAJOR} /> + <path d="M16 56 L30 42 L44 30 L60 16" stroke={MAJOR} strokeWidth="3" fill="none" strokeLinecap="round" /> + <path d="M52 16 L60 16 L60 24" stroke={MAJOR} strokeWidth="3" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + </> + ), + + target: ( + <> + <circle cx="40" cy="40" r="32" fill={LIGHT} /> + <circle cx="40" cy="40" r="22" fill="white" stroke={MAJOR} strokeWidth="2.5" /> + <circle cx="40" cy="40" r="12" fill={MAJOR} /> + <circle cx="40" cy="40" r="4" fill="white" /> + <path d="M58 22 L70 10 M58 22 L65 22 M58 22 L58 15" stroke={DARK} strokeWidth="2.5" fill="none" strokeLinecap="round" /> + </> + ), + + innovation: ( + <> + {/* ampoule */} + <path d="M40 8 Q22 8 22 28 Q22 38 30 46 L30 56 L50 56 L50 46 Q58 38 58 28 Q58 8 40 8 Z" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" /> + <rect x="32" y="58" width="16" height="6" rx="1" fill={DARK} /> + <rect x="34" y="66" width="12" height="4" rx="1" fill={DARK} /> + <path d="M40 22 L40 42 M34 28 L40 22 L46 28" stroke={MAJOR} strokeWidth="2.5" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + <circle cx="14" cy="20" r="2.5" fill={MAJOR} /> + <circle cx="66" cy="20" r="2.5" fill={MAJOR} /> + <circle cx="40" cy="74" r="0" /> + </> + ), + + savings: ( + <> + {/* tirelire */} + <ellipse cx="40" cy="74" rx="20" ry="2" fill={LIGHT} /> + <path d="M16 44 Q16 28 32 24 Q34 18 40 18 Q46 18 48 24 Q64 28 64 44 L64 56 Q64 66 50 66 L30 66 Q16 66 16 56 Z" fill={MAJOR} /> + <circle cx="56" cy="38" r="3" fill="white" /> + <rect x="34" y="20" width="12" height="3" rx="1" fill={DARK} /> + <line x1="32" y1="64" x2="32" y2="72" stroke={DARK} strokeWidth="3" strokeLinecap="round" /> + <line x1="48" y1="64" x2="48" y2="72" stroke={DARK} strokeWidth="3" strokeLinecap="round" /> + </> + ), + + handshake: ( + <> + {/* poignée de main */} + <rect x="6" y="32" width="22" height="14" rx="2" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <rect x="52" y="32" width="22" height="14" rx="2" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <path d="M28 38 L34 38 L40 44 L48 36 L52 36" stroke={MAJOR} strokeWidth="3" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + <path d="M40 44 L46 50 L52 44 L48 40" fill={MAJOR} /> + <path d="M28 32 L48 32" stroke={MAJOR} strokeWidth="2.5" strokeLinecap="round" /> + </> + ), + + cloud: ( + <> + <path d="M22 50 Q12 50 12 40 Q12 30 22 28 Q24 18 36 18 Q48 18 50 26 Q60 24 64 32 Q72 32 72 42 Q72 52 62 52 Z" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" strokeLinejoin="round" /> + <path d="M40 36 L40 56 M32 50 L40 56 L48 50" stroke={MAJOR} strokeWidth="2.5" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + </> + ), + + "lock-secure": ( + <> + <rect x="16" y="34" width="48" height="36" rx="4" fill={MAJOR} /> + <path d="M22 34 L22 24 Q22 8 40 8 Q58 8 58 24 L58 34" fill="none" stroke={MAJOR} strokeWidth="3" strokeLinecap="round" /> + <circle cx="40" cy="48" r="6" fill={LIGHT} /> + <rect x="38" y="50" width="4" height="10" rx="1" fill={LIGHT} /> + </> + ), + + globe: ( + <> + <circle cx="40" cy="40" r="30" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" /> + <ellipse cx="40" cy="40" rx="14" ry="30" fill="none" stroke={MAJOR} strokeWidth="2" /> + <line x1="10" y1="40" x2="70" y2="40" stroke={MAJOR} strokeWidth="2" /> + <path d="M14 28 Q40 22 66 28" fill="none" stroke={MAJOR} strokeWidth="2" /> + <path d="M14 52 Q40 58 66 52" fill="none" stroke={MAJOR} strokeWidth="2" /> + <circle cx="58" cy="22" r="4" fill={ACCENT} /> + </> + ), + + mobile: ( + <> + <rect x="22" y="8" width="36" height="64" rx="6" fill={MAJOR} /> + <rect x="26" y="14" width="28" height="46" rx="2" fill={LIGHT} /> + <circle cx="40" cy="66" r="2.5" fill="white" /> + <line x1="34" y1="11" x2="46" y2="11" stroke="white" strokeWidth="1.5" strokeLinecap="round" /> + <rect x="32" y="22" width="16" height="2.5" rx="1" fill={MAJOR} /> + <rect x="32" y="30" width="12" height="2.5" rx="1" fill={DARK} /> + <rect x="32" y="38" width="14" height="2.5" rx="1" fill={DARK} /> + </> + ), + + analytics: ( + <> + {/* écran avec graphe */} + <rect x="6" y="14" width="68" height="44" rx="3" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <rect x="32" y="60" width="16" height="4" fill={DARK} /> + <rect x="22" y="64" width="36" height="4" rx="1" fill={DARK} /> + <polyline points="14,46 24,38 32,42 42,28 52,32 66,20" fill="none" stroke={MAJOR} strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" /> + <circle cx="14" cy="46" r="2.5" fill={MAJOR} /> + <circle cx="42" cy="28" r="2.5" fill={MAJOR} /> + <circle cx="66" cy="20" r="2.5" fill={MAJOR} /> + </> + ), + + gift: ( + <> + <rect x="10" y="32" width="60" height="38" rx="3" fill={MAJOR} /> + <rect x="10" y="22" width="60" height="14" rx="2" fill={MINOR} /> + <rect x="36" y="22" width="8" height="48" fill={LIGHT} /> + <path d="M28 22 Q24 14 28 10 Q32 6 36 10 Q40 14 40 22" fill="none" stroke={LIGHT} strokeWidth="3" strokeLinecap="round" /> + <path d="M52 22 Q56 14 52 10 Q48 6 44 10 Q40 14 40 22" fill="none" stroke={LIGHT} strokeWidth="3" strokeLinecap="round" /> + </> + ), + + messaging: ( + <> + <path d="M10 18 Q10 14 14 14 L66 14 Q70 14 70 18 L70 50 Q70 54 66 54 L32 54 L20 66 L20 54 L14 54 Q10 54 10 50 Z" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" strokeLinejoin="round" /> + <circle cx="26" cy="34" r="3" fill={MAJOR} /> + <circle cx="40" cy="34" r="3" fill={MAJOR} /> + <circle cx="54" cy="34" r="3" fill={MAJOR} /> + </> + ), + + // ─── Marine v0.5 (defense.gouv-inspired) ───────────────── + "marine-casquette": ( + <> + {/* casquette d'officier de marine — visière arrondie + bande + insigne */} + <ellipse cx="40" cy="68" rx="26" ry="3" fill={LIGHT} /> + {/* visière */} + <path d="M14 56 Q14 52 18 50 L62 50 Q66 52 66 56 Q66 60 62 60 L18 60 Q14 60 14 56 Z" fill={MINOR} /> + {/* bande dorée (band) */} + <rect x="14" y="44" width="52" height="6" fill={DARK} /> + {/* dôme principal */} + <path d="M16 44 Q16 18 40 18 Q64 18 64 44 Z" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" strokeLinejoin="round" /> + {/* insigne ancré */} + <circle cx="40" cy="32" r="6" fill={MAJOR} /> + <line x1="40" y1="28" x2="40" y2="38" stroke="white" strokeWidth="1.5" strokeLinecap="round" /> + <path d="M36 36 Q40 40 44 36" stroke="white" strokeWidth="1.5" fill="none" strokeLinecap="round" /> + {/* feuille d'olivier sur la visière */} + <path d="M22 54 Q26 56 30 54" stroke={DARK} strokeWidth="1" fill="none" strokeLinecap="round" /> + <path d="M50 54 Q54 56 58 54" stroke={DARK} strokeWidth="1" fill="none" strokeLinecap="round" /> + </> + ), + + "marine-ancre": ( + <> + {/* ombre */} + <ellipse cx="40" cy="74" rx="20" ry="2" fill={LIGHT} /> + {/* anneau supérieur */} + <circle cx="40" cy="14" r="6" fill="none" stroke={MAJOR} strokeWidth="3" /> + {/* tige verticale */} + <line x1="40" y1="20" x2="40" y2="60" stroke={MAJOR} strokeWidth="4" strokeLinecap="round" /> + {/* barre horizontale (jas) */} + <line x1="26" y1="28" x2="54" y2="28" stroke={MAJOR} strokeWidth="3.5" strokeLinecap="round" /> + <circle cx="26" cy="28" r="2.5" fill={MAJOR} /> + <circle cx="54" cy="28" r="2.5" fill={MAJOR} /> + {/* bras gauche + patte */} + <path d="M40 56 Q22 56 16 44" fill="none" stroke={MAJOR} strokeWidth="3.5" strokeLinecap="round" /> + <path d="M16 44 L12 50 M16 44 L20 48" stroke={MAJOR} strokeWidth="3" strokeLinecap="round" /> + {/* bras droit + patte */} + <path d="M40 56 Q58 56 64 44" fill="none" stroke={MAJOR} strokeWidth="3.5" strokeLinecap="round" /> + <path d="M64 44 L68 50 M64 44 L60 48" stroke={MAJOR} strokeWidth="3" strokeLinecap="round" /> + {/* corde enroulée — visualisée par 2 ondes */} + <path d="M30 68 Q35 64 40 68 T50 68" fill="none" stroke={DARK} strokeWidth="2" strokeLinecap="round" /> + </> + ), + + // ─── ManageMate Group products v0.6 ─────────────── + + /* Synapse — flux/connexion (réseau de neurones) */ + synapse: ( + <> + <ellipse cx="40" cy="72" rx="20" ry="2" fill={LIGHT} /> + {/* Nœuds (neurones) */} + <circle cx="20" cy="20" r="6" fill={MAJOR} /> + <circle cx="60" cy="20" r="6" fill={MAJOR} /> + <circle cx="14" cy="48" r="6" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <circle cx="40" cy="40" r="9" fill={MAJOR} /> + <circle cx="66" cy="48" r="6" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <circle cx="40" cy="66" r="6" fill={MINOR} /> + {/* Synapses (connexions) */} + <line x1="20" y1="20" x2="40" y2="40" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="60" y1="20" x2="40" y2="40" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="14" y1="48" x2="40" y2="40" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="66" y1="48" x2="40" y2="40" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="40" y1="40" x2="40" y2="66" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + {/* Pulse au centre */} + <circle cx="40" cy="40" r="4" fill="white" /> + </> + ), + + /* HRTime — équipe + horloge (gestion du temps RH) */ + hrtime: ( + <> + <ellipse cx="40" cy="72" rx="22" ry="2" fill={LIGHT} /> + {/* Cadran d'horloge en arrière-plan */} + <circle cx="40" cy="40" r="28" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + {/* Marques d'heures */} + <line x1="40" y1="14" x2="40" y2="18" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="40" y1="62" x2="40" y2="66" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="14" y1="40" x2="18" y2="40" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <line x1="62" y1="40" x2="66" y2="40" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + {/* Aiguilles */} + <line x1="40" y1="40" x2="40" y2="24" stroke={MAJOR} strokeWidth="3" strokeLinecap="round" /> + <line x1="40" y1="40" x2="52" y2="44" stroke={MAJOR} strokeWidth="3" strokeLinecap="round" /> + <circle cx="40" cy="40" r="3" fill={MAJOR} /> + {/* Trois personnes en silhouette devant l'horloge */} + <circle cx="28" cy="50" r="5" fill={MAJOR} /> + <path d="M20 66 Q20 56 28 56 Q36 56 36 66 Z" fill={MAJOR} /> + <circle cx="52" cy="50" r="5" fill={MAJOR} /> + <path d="M44 66 Q44 56 52 56 Q60 56 60 66 Z" fill={MAJOR} /> + </> + ), + + /* Forge — outils (clé + engrenage = construire) */ + forge: ( + <> + <ellipse cx="40" cy="72" rx="20" ry="2" fill={LIGHT} /> + {/* Engrenage central */} + <circle cx="42" cy="38" r="14" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" /> + {/* Dents de l'engrenage */} + <rect x="40" y="18" width="4" height="6" fill={MAJOR} /> + <rect x="40" y="52" width="4" height="6" fill={MAJOR} /> + <rect x="22" y="36" width="6" height="4" fill={MAJOR} /> + <rect x="56" y="36" width="6" height="4" fill={MAJOR} /> + <rect x="27" y="22" width="6" height="4" fill={MAJOR} transform="rotate(-45 30 24)" /> + <rect x="51" y="22" width="6" height="4" fill={MAJOR} transform="rotate(45 54 24)" /> + <rect x="27" y="50" width="6" height="4" fill={MAJOR} transform="rotate(45 30 52)" /> + <rect x="51" y="50" width="6" height="4" fill={MAJOR} transform="rotate(-45 54 52)" /> + <circle cx="42" cy="38" r="5" fill={MAJOR} /> + {/* Clé qui croise l'engrenage */} + <circle cx="14" cy="60" r="6" fill="none" stroke={MAJOR} strokeWidth="3" /> + <line x1="18" y1="56" x2="32" y2="42" stroke={MAJOR} strokeWidth="3.5" strokeLinecap="round" /> + <line x1="28" y1="46" x2="32" y2="50" stroke={MAJOR} strokeWidth="3.5" strokeLinecap="round" /> + <line x1="34" y1="40" x2="36" y2="42" stroke={MAJOR} strokeWidth="3.5" strokeLinecap="round" /> + </> + ), + + /* Orbit — planète + satellites (data orchestration) */ + orbit: ( + <> + <ellipse cx="40" cy="72" rx="22" ry="2" fill={LIGHT} /> + {/* Orbite extérieure (anneau elliptique) */} + <ellipse + cx="40" + cy="40" + rx="32" + ry="14" + fill="none" + stroke={MAJOR} + strokeWidth="2" + strokeDasharray="3 4" + transform="rotate(-25 40 40)" + /> + {/* Planète centrale */} + <circle cx="40" cy="40" r="14" fill={MAJOR} /> + <ellipse cx="40" cy="40" rx="14" ry="5" fill={MINOR} opacity="0.7" /> + <circle cx="36" cy="36" r="3" fill="white" opacity="0.5" /> + {/* Satellites sur l'orbite */} + <circle cx="68" cy="28" r="4" fill={MAJOR} /> + <circle cx="14" cy="56" r="3" fill={MAJOR} /> + <circle cx="62" cy="58" r="3" fill={MINOR} /> + {/* Trail */} + <path d="M68 28 Q66 30 64 30" stroke={MAJOR} strokeWidth="1" strokeLinecap="round" opacity="0.4" /> + </> + ), + + /* Automation — robot/process automatisé */ + automation: ( + <> + <ellipse cx="40" cy="72" rx="20" ry="2" fill={LIGHT} /> + {/* Tête du robot */} + <rect x="20" y="20" width="40" height="32" rx="6" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" /> + {/* Antenne */} + <line x1="40" y1="14" x2="40" y2="20" stroke={MAJOR} strokeWidth="2.5" strokeLinecap="round" /> + <circle cx="40" cy="12" r="3" fill={MAJOR} /> + {/* Yeux */} + <circle cx="30" cy="34" r="4" fill={MAJOR} /> + <circle cx="50" cy="34" r="4" fill={MAJOR} /> + <circle cx="30" cy="34" r="1.5" fill="white" /> + <circle cx="50" cy="34" r="1.5" fill="white" /> + {/* Bouche / interface */} + <rect x="32" y="42" width="16" height="3" rx="1" fill={MAJOR} /> + {/* Corps avec circuits */} + <rect x="26" y="54" width="28" height="14" rx="3" fill={MAJOR} /> + <line x1="32" y1="60" x2="36" y2="60" stroke="white" strokeWidth="1.5" strokeLinecap="round" /> + <line x1="40" y1="60" x2="48" y2="60" stroke="white" strokeWidth="1.5" strokeLinecap="round" /> + </> + ), + + /* Insights — loupe + données (analytique) */ + insights: ( + <> + <ellipse cx="40" cy="72" rx="20" ry="2" fill={LIGHT} /> + {/* Tableau de bord en arrière */} + <rect x="14" y="14" width="44" height="36" rx="3" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + <rect x="20" y="20" width="14" height="3" rx="1" fill={MAJOR} opacity="0.6" /> + {/* Mini barchart */} + <rect x="20" y="38" width="4" height="8" fill={MAJOR} /> + <rect x="26" y="32" width="4" height="14" fill={MAJOR} /> + <rect x="32" y="36" width="4" height="10" fill={MAJOR} opacity="0.7" /> + <rect x="38" y="28" width="4" height="18" fill={MAJOR} /> + <rect x="44" y="34" width="4" height="12" fill={MAJOR} opacity="0.7" /> + {/* Loupe en superposition */} + <circle cx="50" cy="50" r="14" fill="white" stroke={MAJOR} strokeWidth="3" /> + <line x1="60" y1="60" x2="70" y2="70" stroke={MAJOR} strokeWidth="4" strokeLinecap="round" /> + {/* Trend line dans la loupe */} + <polyline points="42,54 46,50 50,52 54,46 58,48" fill="none" stroke={MAJOR} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /> + </> + ), + + /* Integration — modules connectés (puzzle/blocks) */ + integration: ( + <> + <ellipse cx="40" cy="72" rx="20" ry="2" fill={LIGHT} /> + {/* Bloc supérieur gauche */} + <path d="M14 16 L34 16 L34 24 Q34 28 38 28 Q42 28 42 24 L42 16 L42 36 L34 36 Q30 36 30 40 Q30 44 34 44 L42 44 L42 50 L14 50 Z" fill={MAJOR} /> + {/* Bloc inférieur droit complémentaire */} + <path d="M42 30 L62 30 L62 50 L62 60 Q62 64 58 64 Q54 64 54 60 L54 56 L42 56 Z" fill={LIGHT} stroke={MAJOR} strokeWidth="2" /> + {/* Bloc top droit */} + <rect x="48" y="14" width="20" height="14" rx="3" fill={MINOR} /> + {/* Petits accent */} + <circle cx="58" cy="21" r="2" fill="white" /> + </> + ), + + /* Workflow — flèches en boucle (process) */ + workflow: ( + <> + <ellipse cx="40" cy="72" rx="22" ry="2" fill={LIGHT} /> + {/* Étape 1 (cercle haut gauche) */} + <circle cx="22" cy="22" r="10" fill={MAJOR} /> + <text x="22" y="27" fontSize="14" fontWeight="700" fill="white" textAnchor="middle" fontFamily="system-ui, sans-serif">1</text> + {/* Étape 2 (cercle haut droit) */} + <circle cx="58" cy="22" r="10" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" /> + <text x="58" y="27" fontSize="14" fontWeight="700" fill={MAJOR} textAnchor="middle" fontFamily="system-ui, sans-serif">2</text> + {/* Étape 3 (cercle bas droit) */} + <circle cx="58" cy="58" r="10" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" /> + <text x="58" y="63" fontSize="14" fontWeight="700" fill={MAJOR} textAnchor="middle" fontFamily="system-ui, sans-serif">3</text> + {/* Étape 4 (cercle bas gauche) */} + <circle cx="22" cy="58" r="10" fill={LIGHT} stroke={MAJOR} strokeWidth="2.5" /> + <text x="22" y="63" fontSize="14" fontWeight="700" fill={MAJOR} textAnchor="middle" fontFamily="system-ui, sans-serif">4</text> + {/* Flèches entre les étapes */} + <path d="M32 22 L48 22" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <path d="M44 19 L48 22 L44 25" stroke={MAJOR} strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + <path d="M58 32 L58 48" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <path d="M55 44 L58 48 L61 44" stroke={MAJOR} strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + <path d="M48 58 L32 58" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <path d="M36 55 L32 58 L36 61" stroke={MAJOR} strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + <path d="M22 48 L22 32" stroke={MAJOR} strokeWidth="2" strokeLinecap="round" /> + <path d="M19 36 L22 32 L25 36" stroke={MAJOR} strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round" /> + </> + ), + + "marine-porte-avion": ( + <> + {/* mer + reflets */} + <path d="M0 64 Q20 60 40 64 T80 64 L80 80 L0 80 Z" fill={LIGHT} /> + <path d="M4 70 Q14 68 24 70" stroke={ACCENT} strokeWidth="1.5" fill="none" strokeLinecap="round" /> + <path d="M50 72 Q60 70 70 72" stroke={ACCENT} strokeWidth="1.5" fill="none" strokeLinecap="round" /> + {/* coque grise */} + <path d="M4 56 L76 56 L70 64 L10 64 Z" fill={DARK} /> + {/* pont d'envol — plan supérieur avec angle */} + <path d="M2 50 L78 50 L74 56 L6 56 Z" fill="#3D4757" /> + {/* îlot (tour de commandement) */} + <rect x="48" y="32" width="12" height="18" fill={DARK} /> + <rect x="50" y="34" width="3" height="3" fill={LIGHT} /> + <rect x="55" y="34" width="3" height="3" fill={LIGHT} /> + <rect x="50" y="40" width="3" height="3" fill={LIGHT} /> + <rect x="55" y="40" width="3" height="3" fill={LIGHT} /> + {/* radar — mât + plateau */} + <line x1="54" y1="20" x2="54" y2="32" stroke={DARK} strokeWidth="2" /> + <ellipse cx="54" cy="20" rx="6" ry="2" fill={MAJOR} /> + {/* tour antenne secondaire */} + <line x1="60" y1="26" x2="60" y2="32" stroke={DARK} strokeWidth="1.5" /> + <circle cx="60" cy="26" r="1.5" fill={MAJOR} /> + {/* avion sur le pont — silhouette simplifiée */} + <path d="M14 48 L24 44 L28 44 L26 48 L18 50 Z" fill={MAJOR} /> + <path d="M22 44 L22 40 M26 46 L30 44" stroke={MAJOR} strokeWidth="1.5" strokeLinecap="round" /> + {/* marquage centré du pont */} + <line x1="32" y1="53" x2="44" y2="53" stroke="white" strokeWidth="1" strokeDasharray="2 2" /> + </> + ), +}; + +export type PictogramProps = { + name: PictogramName; + size?: number; + className?: string; + style?: CSSProperties; + title?: string; +}; + +export function Pictogram({ + name, + size = 80, + className, + style, + title, +}: PictogramProps) { + return ( + <svg + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 80 80" + width={size} + height={size} + className={cx("mmg-pictogram", className)} + style={style} + role={title ? "img" : "presentation"} + aria-label={title} + > + {title && <title>{title}} + {PICTOS[name]} + + ); +} + +export const PICTOGRAM_NAMES: PictogramName[] = [ + "certificate", "transfer", "document", "duplicate", "address", + "people", "payroll", "calendar", "training", "shopping", "news", + "rocket", "shield", "settings", + "success", "alert", "search", "support", "growth", "target", + "innovation", "savings", "handshake", "cloud", "lock-secure", + "globe", "mobile", "analytics", "gift", "messaging", + "marine-casquette", "marine-ancre", "marine-porte-avion", + "synapse", "hrtime", "forge", "orbit", + "automation", "insights", "integration", "workflow", +]; diff --git a/packages/react/src/Popover.tsx b/packages/react/src/Popover.tsx new file mode 100644 index 0000000..0b6d04b --- /dev/null +++ b/packages/react/src/Popover.tsx @@ -0,0 +1,55 @@ +import { type ReactNode } from "react"; +import * as RadixPopover from "@radix-ui/react-popover"; +import { cx } from "./utils"; + +export type PopoverProps = { + trigger: ReactNode; + children: ReactNode; + open?: boolean; + onOpenChange?: (open: boolean) => void; + defaultOpen?: boolean; + side?: "top" | "right" | "bottom" | "left"; + align?: "start" | "center" | "end"; + sideOffset?: number; + modal?: boolean; + className?: string; +}; + +/** + * Popover — wrapper Radix UI Popover. + * + * Couvre les cas usuels (trigger + contenu). Pour des compositions plus + * fines (close button, anchor séparé, sub-popover) utiliser PopoverPrimitive. + */ +export function Popover({ + trigger, + children, + open, + onOpenChange, + defaultOpen, + side = "bottom", + align = "start", + sideOffset = 8, + modal, + className, +}: PopoverProps) { + return ( + + {trigger} + + + {children} + + + + + ); +} + +export { RadixPopover as PopoverPrimitive }; diff --git a/packages/react/src/PricingCard.tsx b/packages/react/src/PricingCard.tsx new file mode 100644 index 0000000..23357e7 --- /dev/null +++ b/packages/react/src/PricingCard.tsx @@ -0,0 +1,90 @@ +import { type ReactNode } from "react"; +import { cx } from "./utils"; +import { Icon } from "./Icon"; + +export type PricingFeature = { + label: ReactNode; + /** Si false, affiche un icône "x" (feature non incluse dans ce tier). */ + included?: boolean; + /** Texte d'aide en survol. */ + hint?: ReactNode; +}; + +export type PricingCardProps = { + /** Nom du plan (ex: "Starter", "Pro", "Enterprise"). */ + name: ReactNode; + /** Description courte sous le nom. */ + description?: ReactNode; + /** Prix principal (ex: "29 €", "Sur devis"). */ + price: ReactNode; + /** Suffixe du prix (ex: "/ mois / utilisateur"). */ + pricePeriod?: ReactNode; + /** Liste de features. */ + features: PricingFeature[]; + /** CTA principal. */ + cta: ReactNode; + /** Marque ce plan comme "recommandé" (mise en avant visuelle). */ + highlighted?: boolean; + /** Badge en haut à droite (ex: "Populaire", "-20%"). */ + badge?: ReactNode; + className?: string; +}; + +/** + * PricingCard — carte de tarification. + * + * Pattern Stripe / Vercel / Linear : nom + prix + features + CTA. Une + * variante `highlighted` met en avant le plan recommandé via une bordure + * accent et un fond légèrement teinté. + */ +export function PricingCard({ + name, + description, + price, + pricePeriod, + features, + cta, + highlighted, + badge, + className, +}: PricingCardProps) { + return ( +
+ {badge &&
{badge}
} +
+

{name}

+ {description &&

{description}

} +
+
+ {price} + {pricePeriod && {pricePeriod}} +
+
    + {features.map((f, i) => ( +
  • + + {f.label} +
  • + ))} +
+
{cta}
+
+ ); +} diff --git a/packages/react/src/ProfileHeader.tsx b/packages/react/src/ProfileHeader.tsx new file mode 100644 index 0000000..7f9da10 --- /dev/null +++ b/packages/react/src/ProfileHeader.tsx @@ -0,0 +1,92 @@ +import { type ReactNode } from "react"; +import { cx } from "./utils"; +import { Avatar, type AvatarStatus } from "./Avatar"; + +export type ProfileHeaderProps = { + name: ReactNode; + /** Sous-titre (poste, organisation…). */ + subtitle?: ReactNode; + /** Description longue / bio. */ + bio?: ReactNode; + /** URL de la photo de profil. */ + src?: string; + initials?: string; + status?: AvatarStatus; + /** URL de la photo de couverture (cover). Si absente, gradient accent. */ + coverSrc?: string; + /** Stats à droite des actions (commits, reviews, années…). */ + stats?: { label: ReactNode; value: ReactNode }[]; + /** Slot d'actions sous la bio (boutons, menu…). */ + actions?: ReactNode; + /** Slot de badges (sous le nom). */ + badges?: ReactNode; + className?: string; +}; + +/** + * ProfileHeader — en-tête de profil avec photo de couverture + avatar + * en débord (LinkedIn / GitHub / Twitter pattern). + * + * - Cover : image fournie ou gradient accent par défaut. + * - Avatar large (xl) en débord sur la cover. + * - Identité (nom + sous-titre + bio). + * - Stats inline + actions (Suivre, Message…). + */ +export function ProfileHeader({ + name, + subtitle, + bio, + src, + initials, + status, + coverSrc, + stats, + actions, + badges, + className, +}: ProfileHeaderProps) { + return ( +
+
+ {coverSrc ? ( + + ) : ( +
+ )} +
+
+
+ +
+
+
+
+

{name}

+ {subtitle &&
{subtitle}
} + {badges &&
{badges}
} +
+ {actions &&
{actions}
} +
+ {bio &&

{bio}

} + {stats && stats.length > 0 && ( +
+ {stats.map((s, i) => ( +
+
{s.label}
+
{s.value}
+
+ ))} +
+ )} +
+
+
+ ); +} diff --git a/packages/react/src/Progress.tsx b/packages/react/src/Progress.tsx new file mode 100644 index 0000000..9016daf --- /dev/null +++ b/packages/react/src/Progress.tsx @@ -0,0 +1,37 @@ +import type { HTMLAttributes } from "react"; +import { cx } from "./utils"; + +export type ProgressProps = HTMLAttributes & { + value?: number; + max?: number; + variant?: "success" | "warning" | "danger"; + indeterminate?: boolean; +}; + +export function Progress({ + value, + max = 100, + variant, + indeterminate, + className, + ...rest +}: ProgressProps) { + const pct = indeterminate ? 100 : Math.min(100, Math.max(0, ((value ?? 0) / max) * 100)); + return ( +
+
+
+ ); +} diff --git a/packages/react/src/Quote.tsx b/packages/react/src/Quote.tsx new file mode 100644 index 0000000..1f30bc1 --- /dev/null +++ b/packages/react/src/Quote.tsx @@ -0,0 +1,17 @@ +import type { ReactNode } from "react"; +import { cx } from "./utils"; + +export type QuoteProps = { + author?: ReactNode; + children: ReactNode; + className?: string; +}; + +export function Quote({ author, children, className }: QuoteProps) { + return ( +
+

{children}

+ {author && — {author}} +
+ ); +} diff --git a/packages/react/src/SearchBar.tsx b/packages/react/src/SearchBar.tsx new file mode 100644 index 0000000..ec2a525 --- /dev/null +++ b/packages/react/src/SearchBar.tsx @@ -0,0 +1,39 @@ +import { useState, type InputHTMLAttributes } from "react"; +import { cx } from "./utils"; + +export type SearchBarProps = Omit, "onSubmit"> & { + onSearch?: (q: string) => void; + buttonLabel?: string; +}; + +export function SearchBar({ + placeholder = "Rechercher…", + onSearch, + buttonLabel = "Rechercher", + className, + ...rest +}: SearchBarProps) { + const [val, setVal] = useState(""); + return ( +
{ + e.preventDefault(); + onSearch?.(val); + }} + > + setVal(e.target.value)} + {...rest} + /> + +
+ ); +} diff --git a/packages/react/src/Sheet.tsx b/packages/react/src/Sheet.tsx new file mode 100644 index 0000000..f7dd9dc --- /dev/null +++ b/packages/react/src/Sheet.tsx @@ -0,0 +1,90 @@ +import { type ReactNode } from "react"; +import * as RadixDialog from "@radix-ui/react-dialog"; +import { cx } from "./utils"; +import { Icon } from "./Icon"; + +export type SheetSide = "left" | "right" | "top" | "bottom"; +export type SheetSize = "sm" | "md" | "lg" | "xl" | "full"; + +export type SheetProps = { + open: boolean; + onOpenChange: (open: boolean) => void; + /** Côté d'apparition. Défaut "right" (le plus courant pour un sheet desktop). */ + side?: SheetSide; + /** Largeur (left/right) ou hauteur (top/bottom). */ + size?: SheetSize; + title?: ReactNode; + description?: ReactNode; + children: ReactNode; + footer?: ReactNode; + /** Cache le bouton de fermeture en haut à droite. */ + hideClose?: boolean; + className?: string; +}; + +/** + * Sheet — panneau latéral / drawer (Radix Dialog avec position custom). + * + * Différence avec Dialog : Sheet glisse depuis un bord (latéral, top, bottom). + * Différence avec Drawer (legacy) : Sheet utilise Radix → focus trap, scroll + * lock, restitution focus, escape, aria-* tout est natif. Préférer Sheet. + * + * Usage typique : édition rapide d'une ressource, navigation mobile, + * filtres avancés, prévisualisation détaillée. + */ +export function Sheet({ + open, + onOpenChange, + side = "right", + size = "md", + title, + description, + children, + footer, + hideClose, + className, +}: SheetProps) { + return ( + + + + + {(title || !hideClose) && ( +
+
+ {title && ( + + {title} + + )} + {description && ( + + {description} + + )} +
+ {!hideClose && ( + + + + )} +
+ )} +
{children}
+ {footer &&
{footer}
} +
+
+
+ ); +} + +export { RadixDialog as SheetPrimitive }; diff --git a/packages/react/src/Shortcut.tsx b/packages/react/src/Shortcut.tsx new file mode 100644 index 0000000..ad41bac --- /dev/null +++ b/packages/react/src/Shortcut.tsx @@ -0,0 +1,364 @@ +import { + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useRef, + useState, + type ReactNode, +} from "react"; + +/** + * Système global de raccourcis clavier — DSMMG. + * + * Architecture : + * - au sommet de l'app + * - useShortcut(key, handler, options) dans n'importe quel composant + * - ou hook useShortcutList() pour afficher tous + * les raccourcis enregistrés + * + * Conformité a11y : + * - WCAG 2.1.1 (clavier) : tout le système est navigable au clavier + * - WCAG 2.1.4 (raccourcis caractère seul) : on accepte les modifiers + * Ctrl/Cmd/Alt/Shift, ou les chords (g i) — un caractère unique seul + * est désactivé si une saisie est focus (input, textarea, contenteditable) + * + * Format de clé : + * - "cmd+k", "ctrl+/", "shift+?" + * - Chord : "g i", "g h", "y y" + * - Touche simple : "/" , "?" (uniquement si aucun champ focus) + */ + +export type ShortcutOptions = { + /** Catégorie pour le regroupement dans la cheatsheet */ + category?: string; + /** Description affichée dans la cheatsheet */ + description?: string; + /** Désactive le raccourci si vrai */ + disabled?: boolean; + /** Autorise même quand un input/textarea est focusé */ + allowInInput?: boolean; + /** Empêche le default du browser */ + preventDefault?: boolean; +}; + +export type ShortcutEntry = { + id: string; + keys: string; + category: string; + description: string; +}; + +type ShortcutHandler = (event: KeyboardEvent) => void; + +type Registered = { + keys: string; + handler: ShortcutHandler; + options: ShortcutOptions; +}; + +type Ctx = { + register: (id: string, entry: Registered) => () => void; + list: () => ShortcutEntry[]; +}; + +const ShortcutContext = createContext(null); + +const isMac = + typeof navigator !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform); + +function normalizeCombo(combo: string): string { + return combo + .toLowerCase() + .split("+") + .map((p) => p.trim()) + .map((p) => (p === "cmd" || p === "meta" ? (isMac ? "meta" : "ctrl") : p)) + .sort() + .join("+"); +} + +function eventToCombo(e: KeyboardEvent): string { + const parts: string[] = []; + if (e.ctrlKey) parts.push("ctrl"); + if (e.metaKey) parts.push("meta"); + if (e.altKey) parts.push("alt"); + if (e.shiftKey) parts.push("shift"); + // Skip the modifier itself if user is just holding modifiers + const k = e.key.toLowerCase(); + if (!["control", "meta", "alt", "shift"].includes(k)) parts.push(k); + return parts.sort().join("+"); +} + +function isInsideEditableElement(target: EventTarget | null): boolean { + if (!(target instanceof HTMLElement)) return false; + const tag = target.tagName; + if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true; + if (target.isContentEditable) return true; + return false; +} + +export function ShortcutProvider({ children }: { children: ReactNode }) { + const registry = useRef(new Map()); + const chordBuffer = useRef<{ key: string; expires: number } | null>(null); + const CHORD_WINDOW_MS = 800; + + const register = useCallback((id: string, entry: Registered) => { + registry.current.set(id, entry); + return () => { + registry.current.delete(id); + }; + }, []); + + const list = useCallback((): ShortcutEntry[] => { + return Array.from(registry.current.entries()).map(([id, e]) => ({ + id, + keys: e.keys, + category: e.options.category ?? "Général", + description: e.options.description ?? "", + })); + }, []); + + useEffect(() => { + const onKey = (e: KeyboardEvent) => { + const inEditable = isInsideEditableElement(e.target); + + const combo = eventToCombo(e); + const now = Date.now(); + + // Test chord + if (chordBuffer.current && chordBuffer.current.expires > now) { + const chordCombo = `${chordBuffer.current.key} ${combo}`; + for (const [, entry] of registry.current) { + if (entry.options.disabled) continue; + if (inEditable && !entry.options.allowInInput) continue; + const normalized = entry.keys + .split(" ") + .map(normalizeCombo) + .join(" "); + if (normalized === chordCombo) { + if (entry.options.preventDefault !== false) e.preventDefault(); + entry.handler(e); + chordBuffer.current = null; + return; + } + } + } + + // Test single combo + for (const [, entry] of registry.current) { + if (entry.options.disabled) continue; + if (inEditable && !entry.options.allowInInput) continue; + const normalized = normalizeCombo(entry.keys); + if (normalized === combo) { + if (entry.options.preventDefault !== false) e.preventDefault(); + entry.handler(e); + return; + } + } + + // Si la touche n'a pas matché et n'est pas un modifier, mémoriser comme début de chord + if ( + !e.ctrlKey && + !e.metaKey && + !e.altKey && + e.key.length === 1 && + !inEditable + ) { + chordBuffer.current = { + key: combo, + expires: now + CHORD_WINDOW_MS, + }; + } + }; + document.addEventListener("keydown", onKey); + return () => document.removeEventListener("keydown", onKey); + }, []); + + const value = useMemo(() => ({ register, list }), [register, list]); + + return ( + + {children} + + ); +} + +/** + * Hook pour enregistrer un raccourci local au cycle de vie du composant. + * + * useShortcut("cmd+k", () => setOpen(true), { + * description: "Ouvrir la palette", + * category: "Navigation", + * }); + */ +export function useShortcut( + keys: string, + handler: ShortcutHandler, + options: ShortcutOptions = {}, +) { + const ctx = useContext(ShortcutContext); + if (!ctx) + throw new Error("useShortcut requiert un ancêtre."); + + const handlerRef = useRef(handler); + handlerRef.current = handler; + + useEffect(() => { + const id = `${keys}-${Math.random().toString(36).slice(2, 8)}`; + return ctx.register(id, { + keys, + handler: (e) => handlerRef.current(e), + options, + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [keys, options.disabled, options.allowInInput, options.preventDefault]); +} + +/** + * Liste tous les raccourcis enregistrés (pour cheatsheet). + */ +export function useShortcutList(): ShortcutEntry[] { + const ctx = useContext(ShortcutContext); + if (!ctx) return []; + const [, force] = useState(0); + // Re-render léger — la liste peut bouger + useEffect(() => { + const t = setInterval(() => force((n) => n + 1), 1000); + return () => clearInterval(t); + }, []); + return ctx.list(); +} + +/** + * Affichage cheatsheet (ouvert via "?" par défaut). + */ +export function ShortcutCheatsheet({ + open, + onClose, +}: { + open: boolean; + onClose: () => void; +}) { + const list = useShortcutList(); + + useEffect(() => { + if (!open) return; + const onKey = (e: KeyboardEvent) => { + if (e.key === "Escape") onClose(); + }; + document.addEventListener("keydown", onKey); + return () => document.removeEventListener("keydown", onKey); + }, [open, onClose]); + + if (!open) return null; + + // Group by category + const groups = list.reduce>((acc, e) => { + (acc[e.category] ??= []).push(e); + return acc; + }, {}); + + return ( +
{ + if (e.target === e.currentTarget) onClose(); + }} + > +
+
+

Raccourcis clavier

+ +
+
+ {Object.keys(groups).length === 0 ? ( +

+ Aucun raccourci enregistré dans le contexte actuel. +

+ ) : ( + Object.entries(groups).map(([cat, entries]) => ( +
+

+ {cat} +

+
+ {entries.map((e) => ( +
+
+ {e.description || e.id} +
+
+ +
+
+ ))} +
+
+ )) + )} +
+
+
+ ); +} + +/** + * Affichage joli des keys d'un raccourci (chunks ). + */ +export function ShortcutKeys({ keys }: { keys: string }) { + const chords = keys.split(" "); + return ( + + {chords.map((chord, i) => ( + + {chord.split("+").map((k, j) => ( + + {k === "cmd" || k === "meta" ? (isMac ? "⌘" : "Ctrl") : k.toUpperCase()} + + ))} + {i < chords.length - 1 && then} + + ))} + + ); +} diff --git a/packages/react/src/SkipLink.tsx b/packages/react/src/SkipLink.tsx new file mode 100644 index 0000000..4d231bc --- /dev/null +++ b/packages/react/src/SkipLink.tsx @@ -0,0 +1,14 @@ +import type { ReactNode } from "react"; + +export type SkipLinkProps = { + targetId?: string; + children?: ReactNode; +}; + +export function SkipLink({ targetId = "main", children = "Aller au contenu" }: SkipLinkProps) { + return ( + + {children} + + ); +} diff --git a/packages/react/src/Slider.tsx b/packages/react/src/Slider.tsx new file mode 100644 index 0000000..27d1476 --- /dev/null +++ b/packages/react/src/Slider.tsx @@ -0,0 +1,79 @@ +import { type ReactNode } from "react"; +import * as RadixSlider from "@radix-ui/react-slider"; +import { cx } from "./utils"; + +export type SliderProps = { + /** Valeur(s) du slider. Tableau pour permettre les ranges (2 thumbs). */ + value: number[]; + onValueChange: (value: number[]) => void; + /** Valeur min. Défaut 0. */ + min?: number; + /** Valeur max. Défaut 100. */ + max?: number; + /** Pas (granularité). Défaut 1. */ + step?: number; + /** Désactivé. */ + disabled?: boolean; + /** Label accessible (lu par les lecteurs d'écran). */ + label?: string; + /** Si true, affiche la valeur au-dessus du thumb actif. */ + showValue?: boolean; + /** Format de la valeur affichée. Défaut: identité. */ + formatValue?: (v: number) => string; + className?: string; +}; + +/** + * Slider — sélecteur de valeur (single ou range, Radix UI). + * + * - Clavier : flèches (step), Page Up/Down (×10 step), Home/End (min/max). + * - aria-valuenow/min/max/text gérés par Radix. + * - Pour un range, passer un tableau de 2 valeurs. + * + * Style DSMMG : track fin, thumb cerclé pill, accent au remplissage. + * Focus visible : halo accent autour du thumb. + */ +export function Slider({ + value, + onValueChange, + min = 0, + max = 100, + step = 1, + disabled, + label, + showValue, + formatValue = (v) => `${v}`, + className, +}: SliderProps) { + return ( + + + + + {value.map((v, i) => ( + + {showValue && ( + + {formatValue(v)} + + )} + + ))} + + ); +} + +export { RadixSlider as SliderPrimitive }; diff --git a/packages/react/src/Slot.tsx b/packages/react/src/Slot.tsx new file mode 100644 index 0000000..7c375ab --- /dev/null +++ b/packages/react/src/Slot.tsx @@ -0,0 +1,130 @@ +import { + Children, + cloneElement, + forwardRef, + isValidElement, + type CSSProperties, + type HTMLAttributes, + type ReactElement, + type ReactNode, + type Ref, +} from "react"; + +/** + * Slot — pattern Radix UI / shadcn pour le polymorphisme `asChild`. + * + * Permet à un composant DSMMG de "passer" son comportement (props, ref, + * className fusionnée) à son unique enfant React. Cas d'usage typique : + * + * + * Aller à Synapse + * + * + * Ici, le `` reçoit toutes les props du Button (className, onClick, + * aria-*, ref) tout en restant un vrai `` côté DOM. Cela évite de + * dupliquer un Button et un ButtonAsLink, et préserve la sémantique + * native du tag enfant (RGAA 7.1, ARIA rule #1). + */ + +export type SlotProps = HTMLAttributes & { + children?: ReactNode; +}; + +/** + * Fusionne deux className ; conserve l'ordre source → destination. + * Pas de dépendance externe. + */ +function mergeClassNames( + parent?: string, + child?: string, +): string | undefined { + if (!parent && !child) return undefined; + if (!parent) return child; + if (!child) return parent; + return `${parent} ${child}`; +} + +/** + * Fusionne deux styles ; les styles enfants priment (override). + */ +function mergeStyles( + parent?: CSSProperties, + child?: CSSProperties, +): CSSProperties | undefined { + if (!parent && !child) return undefined; + return { ...parent, ...child }; +} + +/** + * Fusionne deux event handlers ; appelle l'enfant en premier — si + * `event.defaultPrevented` est vrai, on n'appelle pas le parent + * (laisse l'enfant override le comportement). + */ +function composeEventHandlers( + parentHandler?: (event: E) => void, + childHandler?: (event: E) => void, +): ((event: E) => void) | undefined { + if (!parentHandler && !childHandler) return undefined; + return (event: E) => { + childHandler?.(event); + if (!event.defaultPrevented) parentHandler?.(event); + }; +} + +/** + * Fusionne refs (callback ou objet). + */ +function composeRefs(...refs: Array | undefined>): Ref { + return (node: T | null) => { + refs.forEach((ref) => { + if (typeof ref === "function") ref(node); + else if (ref != null) (ref as React.MutableRefObject).current = node; + }); + }; +} + +export const Slot = forwardRef(function Slot( + { children, ...slotProps }, + forwardedRef, +) { + if (!isValidElement(children)) { + return null; + } + + const childElement = Children.only(children) as ReactElement< + HTMLAttributes & { ref?: Ref } + >; + const childProps = childElement.props; + + const merged: Record = { ...slotProps }; + + // className : slot puis enfant (l'enfant override visuellement) + merged.className = mergeClassNames(slotProps.className, childProps.className); + merged.style = mergeStyles(slotProps.style, childProps.style); + + // Compose event handlers + for (const key in slotProps) { + if (key.startsWith("on") && typeof (slotProps as any)[key] === "function") { + merged[key] = composeEventHandlers( + (slotProps as any)[key], + (childProps as any)[key], + ); + } + } + + // Ref combinée + merged.ref = composeRefs(forwardedRef, (childElement as any).ref); + + return cloneElement(childElement, merged as never); +}); + +/** + * Helper pour les composants qui acceptent `asChild` : retourne `Slot` si + * `asChild` est vrai, sinon le tag par défaut. + */ +export function getSlotComponent( + asChild: boolean | undefined, + defaultTag: T, +): T | typeof Slot { + return asChild ? Slot : defaultTag; +} diff --git a/packages/react/src/Stat.tsx b/packages/react/src/Stat.tsx new file mode 100644 index 0000000..325bf38 --- /dev/null +++ b/packages/react/src/Stat.tsx @@ -0,0 +1,26 @@ +import type { ReactNode } from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type StatProps = { + icon?: IconName; + value: ReactNode; + label: ReactNode; + className?: string; +}; + +export function Stat({ icon, value, label, className }: StatProps) { + return ( +
+ {icon && ( +
+ +
+ )} +
+
{value}
+
{label}
+
+
+ ); +} diff --git a/packages/react/src/Stepper.tsx b/packages/react/src/Stepper.tsx new file mode 100644 index 0000000..584d21d --- /dev/null +++ b/packages/react/src/Stepper.tsx @@ -0,0 +1,38 @@ +import type { ReactNode } from "react"; +import { cx } from "./utils"; + +export type StepperProps = { + current: number; + total: number; + title: ReactNode; + nextTitle?: ReactNode; + className?: string; +}; + +export function Stepper({ current, total, title, nextTitle, className }: StepperProps) { + return ( +
+
+ Étape {current} sur {total} +
+
+ {Array.from({ length: total }, (_, i) => ( +
+ ))} +
+
{title}
+ {nextTitle && current < total && ( +
+ Étape suivante : {nextTitle} +
+ )} +
+ ); +} diff --git a/packages/react/src/Tabs.tsx b/packages/react/src/Tabs.tsx new file mode 100644 index 0000000..1644122 --- /dev/null +++ b/packages/react/src/Tabs.tsx @@ -0,0 +1,30 @@ +import type { ReactNode } from "react"; +import { cx } from "./utils"; + +export type TabItem = { id: string; label: ReactNode }; + +export type TabsProps = { + items: TabItem[]; + value: string; + onChange: (id: string) => void; + className?: string; +}; + +export function Tabs({ items, value, onChange, className }: TabsProps) { + return ( +
+ {items.map((t) => ( + + ))} +
+ ); +} diff --git a/packages/react/src/Tag.tsx b/packages/react/src/Tag.tsx new file mode 100644 index 0000000..9cf891d --- /dev/null +++ b/packages/react/src/Tag.tsx @@ -0,0 +1,30 @@ +import type { HTMLAttributes } from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type TagProps = HTMLAttributes & { + selected?: boolean; + onSelect?: () => void; + icon?: IconName; +}; + +export function Tag({ selected, onSelect, children, className, icon, ...rest }: TagProps) { + const Comp = onSelect ? "button" : "span"; + return ( + + {icon && } + {children} + + ); +} diff --git a/packages/react/src/Text.tsx b/packages/react/src/Text.tsx new file mode 100644 index 0000000..3bf532e --- /dev/null +++ b/packages/react/src/Text.tsx @@ -0,0 +1,135 @@ +import type { ElementType, HTMLAttributes, ReactNode } from "react"; +import { cx } from "./utils"; + +export type TextVariant = + // Display (landing marketing — Hero produits) + | "display-2xl" + | "display-xl" + | "display-lg" + | "display-md" + // Headlines (apps + pages) + | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" + // Body + | "body-lg" | "body" | "body-sm" | "body-xs" + // Auxiliaires + | "eyebrow" | "lead" | "overline" | "caption"; + +export type TextElement = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span" | "div"; + +export type TextProps = HTMLAttributes & { + /** Variante typographique. Détermine taille/poids/letter-spacing/line-height. */ + variant?: TextVariant; + /** Tag HTML rendu. Choisir selon la sémantique, pas selon la taille. */ + as?: TextElement; + /** Police mono (JetBrains Mono / SF Mono) pour code, IDs, valeurs tabulaires. */ + mono?: boolean; + /** Numérique tabular (alignement vertical des chiffres). Pour stats / tableaux. */ + tabular?: boolean; + /** Gradient accent → accent-strong sur le texte (modern Hero touch). */ + gradient?: boolean; + /** Effet "rainbow" animé. À utiliser une seule fois par page max. */ + rainbow?: boolean; + /** text-wrap: balance — équilibre les retours à la ligne (titres). */ + balance?: boolean; + /** text-wrap: pretty — évite veuves/orphelines (body). */ + pretty?: boolean; + /** Italique — pour titres d'œuvre, citations, mots-clefs sémantiquement à part. */ + italic?: boolean; + /** Italique + couleur d'accent — emphase éditoriale (mot-clef ressortir). */ + emphasis?: boolean; + /** Surligneur teinté accent — highlight ponctuel dans un body. */ + highlight?: boolean; + /** Souligné épais accent — accent fort sur un mot-clef. */ + underline?: boolean; + /** Barré — prix barré, élément déprécié. */ + strike?: boolean; + children?: ReactNode; +}; + +/** + * Text — composant typographique sémantique du DSMMG. + * + * **Choisir le tag (`as`) selon la SÉMANTIQUE, pas selon la taille.** + * Un titre de page reste `

` même si visuellement il s'affiche en + * `display-xl`. Un sous-titre marketing décoratif peut être un `

` + * stylé en `display-lg`. + * + * Usage typique sur une landing produit (HRTime, Synapse…) : + * + * SIRH simple + * + * Le temps de vos équipes, au cordeau. + * + * + * Plannings, congés, paie. Une seule plateforme, sans surprise. + * + * + * Usage app (DataTable, dashboard) : + * + * Effectifs + * 432 collaborateurs actifs. + * Section + */ +export function Text({ + variant = "body", + as, + mono, + tabular, + gradient, + rainbow, + balance, + pretty, + italic, + emphasis, + highlight, + underline, + strike, + className, + children, + ...rest +}: TextProps) { + const Comp: ElementType = + as ?? + (variant.startsWith("display") ? "h1" : + variant === "h1" || variant === "h2" || variant === "h3" || + variant === "h4" || variant === "h5" || variant === "h6" ? variant : + variant === "lead" ? "p" : + "span"); + return ( + + {children} + + ); +} + +/* — Helpers raccourcis pour les variants les plus utilisés ———————————— */ + +export function Display(props: Omit & { size?: "md" | "lg" | "xl" | "2xl" }) { + const { size = "xl", ...rest } = props; + return ; +} + +export function Eyebrow(props: Omit) { + return ; +} + +export function Lead(props: Omit) { + return ; +} diff --git a/packages/react/src/ThemePicker.test.tsx b/packages/react/src/ThemePicker.test.tsx new file mode 100644 index 0000000..f7b4626 --- /dev/null +++ b/packages/react/src/ThemePicker.test.tsx @@ -0,0 +1,76 @@ +import { describe, expect, it, beforeEach } from "vitest"; +import { render, screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { axe } from "vitest-axe"; +import { ThemePicker } from "./ThemePicker"; +import { ACCENT_PRESETS } from "./useAccent"; + +describe("ThemePicker", () => { + beforeEach(() => { + document.documentElement.removeAttribute("data-mmg-accent"); + window.localStorage.clear(); + }); + + it("rend une option par preset", () => { + render(); + const radios = screen.getAllByRole("radio"); + expect(radios).toHaveLength(ACCENT_PRESETS.length); + }); + + it("synapse est sélectionné par défaut", () => { + render(); + const synapse = screen.getByRole("radio", { name: /synapse/i }); + expect(synapse).toHaveAttribute("aria-checked", "true"); + }); + + it("clic sur un preset l'active", async () => { + const user = userEvent.setup(); + render(); + const blue = screen.getByRole("radio", { name: /^Bleu$/i }); + await user.click(blue); + expect(blue).toHaveAttribute("aria-checked", "true"); + expect(document.documentElement.getAttribute("data-mmg-accent")).toBe("blue"); + expect(window.localStorage.getItem("mmg-accent")).toBe("blue"); + }); + + it("navigation flèche droite passe au preset suivant", async () => { + const user = userEvent.setup(); + render(); + const synapse = screen.getByRole("radio", { name: /synapse/i }); + synapse.focus(); + await user.keyboard("{ArrowRight}"); + const rose = screen.getByRole("radio", { name: /^Rose vif$/i }); + expect(rose).toHaveAttribute("aria-checked", "true"); + }); + + it("navigation flèche gauche revient au précédent (avec wrap)", async () => { + const user = userEvent.setup(); + render(); + const synapse = screen.getByRole("radio", { name: /synapse/i }); + synapse.focus(); + await user.keyboard("{ArrowLeft}"); + // Wrap : passe au dernier (slate) + const slate = screen.getByRole("radio", { name: /ardoise/i }); + expect(slate).toHaveAttribute("aria-checked", "true"); + }); + + it("Home / End naviguent aux extrêmes", async () => { + const user = userEvent.setup(); + render(); + screen.getByRole("radio", { name: /synapse/i }).focus(); + await user.keyboard("{End}"); + expect(screen.getByRole("radio", { name: /ardoise/i })).toHaveAttribute("aria-checked", "true"); + await user.keyboard("{Home}"); + expect(screen.getByRole("radio", { name: /synapse/i })).toHaveAttribute("aria-checked", "true"); + }); + + it("expose un radiogroup labelisé", () => { + render(); + expect(screen.getByRole("radiogroup")).toBeInTheDocument(); + }); + + it("n'a pas de violations axe-core", async () => { + const { container } = render(); + expect(await axe(container)).toHaveNoViolations(); + }); +}); diff --git a/packages/react/src/ThemePicker.tsx b/packages/react/src/ThemePicker.tsx new file mode 100644 index 0000000..df8f8c4 --- /dev/null +++ b/packages/react/src/ThemePicker.tsx @@ -0,0 +1,108 @@ +import { useRef, type KeyboardEvent } from "react"; +import { cx } from "./utils"; +import { Icon } from "./Icon"; +import { ACCENT_PRESETS, useAccent, type AccentName } from "./useAccent"; + +export type { AccentName }; + +export type ThemePickerProps = { + /** Légende lue par les lecteurs d'écran. Défaut : "Couleur d'accent". */ + legend?: string; + /** Cache le bouton de réinitialisation au défaut Synapse. */ + hideReset?: boolean; + className?: string; +}; + +/** + * ThemePicker — sélecteur de couleur d'accent utilisateur. + * + * Pattern radiogroup : roving tabindex, navigation flèches gauche/droite, + * sélection à Espace ou Entrée. Persiste l'accent choisi dans localStorage. + * + * Accessibilité : + * - role="radiogroup" + aria-labelledby + * - chaque pastille : role="radio" + aria-checked + * - focus-visible géré, contraste validé sur fonds light & dark + * - le label texte ("Rose Synapse", "Bleu", …) est accessible aux lecteurs + * d'écran via aria-label, pas seulement la couleur (RGAA 9 — couleur seule) + */ +export function ThemePicker({ legend = "Couleur d'accent", hideReset, className }: ThemePickerProps) { + const { accent, setAccent, reset } = useAccent(); + const refs = useRef<(HTMLButtonElement | null)[]>([]); + const headingId = "mmg-theme-picker-heading"; + + const focusIndex = (i: number) => { + const next = (i + ACCENT_PRESETS.length) % ACCENT_PRESETS.length; + refs.current[next]?.focus(); + }; + + const onKey = (e: KeyboardEvent, idx: number) => { + switch (e.key) { + case "ArrowRight": + case "ArrowDown": + e.preventDefault(); + focusIndex(idx + 1); + setAccent(ACCENT_PRESETS[(idx + 1) % ACCENT_PRESETS.length].name); + break; + case "ArrowLeft": + case "ArrowUp": + e.preventDefault(); + focusIndex(idx - 1); + setAccent(ACCENT_PRESETS[(idx - 1 + ACCENT_PRESETS.length) % ACCENT_PRESETS.length].name); + break; + case "Home": + e.preventDefault(); + focusIndex(0); + setAccent(ACCENT_PRESETS[0].name); + break; + case "End": + e.preventDefault(); + focusIndex(ACCENT_PRESETS.length - 1); + setAccent(ACCENT_PRESETS[ACCENT_PRESETS.length - 1].name); + break; + } + }; + + return ( +

+
+ {legend} +
+
+ {ACCENT_PRESETS.map((preset, i) => { + const checked = preset.name === accent; + return ( + + ); + })} +
+ {!hideReset && accent !== "synapse" && ( + + )} +
+ ); +} diff --git a/packages/react/src/Toast.tsx b/packages/react/src/Toast.tsx new file mode 100644 index 0000000..28ad5b1 --- /dev/null +++ b/packages/react/src/Toast.tsx @@ -0,0 +1,392 @@ +import { + createContext, + useCallback, + useContext, + useEffect, + useLayoutEffect, + useMemo, + useRef, + useState, + type ReactNode, +} from "react"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +type Severity = "info" | "success" | "warning" | "danger"; + +export type ToastInput = { + title: ReactNode; + description?: ReactNode; + severity?: Severity; + /** Durée avant auto-dismiss (ms). 0 = persistant. Par défaut 5000. */ + duration?: number; + /** Action optionnelle dans le toast. */ + action?: { label: ReactNode; onClick: () => void }; +}; + +type ToastInternal = ToastInput & { id: string; createdAt: number }; + +type Ctx = { + toast: (t: ToastInput) => string; + dismiss: (id: string) => void; + clear: () => void; +}; + +const ToastContext = createContext(null); + +const SEV_ICON: Record = { + info: "information-fill", + success: "checkbox-circle-fill", + warning: "alert-fill", + danger: "error-warning-fill", +}; + +export type ToastProviderProps = { + children: ReactNode; + position?: "bottom-right" | "bottom-left" | "top-right" | "top-left"; + /** Nombre max conservé en mémoire avant écrêtage du plus ancien. Défaut 5. */ + max?: number; + /** Nombre visible avant collapse en pile (Sonner-style). Défaut 3. */ + visibleCount?: number; + /** Durée par défaut (ms) avant auto-dismiss si non précisé. */ + defaultDuration?: number; + /** Gap entre toasts en mode expanded (px). Défaut 12. */ + gap?: number; + /** Offset entre toasts en pile collapsée (px par cran). Défaut 14. */ + stackOffset?: number; +}; + +const DEFAULT_GAP = 12; +const DEFAULT_STACK_OFFSET = 14; +const SCALE_PER_INDEX = 0.045; + +/** + * ToastProvider — système de notifications empilables (Sonner-style). + * + * Architecture : + * - Chaque toast est en `position: absolute`, ancré bottom: 0 (positions + * bottom-*) ou top: 0 (positions top-*). + * - Les heights sont mesurées via ResizeObserver et exposées en CSS vars. + * - Au repos : translateY = -stackOffset × index (collapsed-y), + * scale = 1 - 0.045 × index. Front-most reste pleine taille. + * - Au hover/focus : translateY = -(somme des heights précédentes + gap × i) + * (expanded-y), scale = 1. + * - La hauteur du region s'ajuste : front-most height (collapsed) ou + * somme totale (expanded), pour ne pas voler de clics au contenu. + * + * A11y : + * - aria-live="polite" — les toasts s'annoncent sans interrompre. + * - Severity "danger" → role="alert" (urgent), sinon role="status". + * - Bouton fermer focusable, label complet ("Fermer la notification"). + * - Pause des timers au hover/focus, reprise au mouseleave/blur. + */ +export function ToastProvider({ + children, + position = "bottom-right", + max = 5, + visibleCount = 3, + defaultDuration = 5000, + gap = DEFAULT_GAP, + stackOffset = DEFAULT_STACK_OFFSET, +}: ToastProviderProps) { + const [toasts, setToasts] = useState([]); + const [expanded, setExpanded] = useState(false); + const [heights, setHeights] = useState>({}); + const timers = useRef(new Map()); + const remainingTimes = useRef(new Map()); + const pausedRef = useRef(false); + const itemRefs = useRef(new Map()); + const observerRef = useRef(null); + + const isTop = position.startsWith("top"); + + // — Lifecycle ———————————————————————————————————————— + const dismiss = useCallback((id: string) => { + setToasts((prev) => prev.filter((t) => t.id !== id)); + const timer = timers.current.get(id); + if (timer) { + window.clearTimeout(timer); + timers.current.delete(id); + } + remainingTimes.current.delete(id); + itemRefs.current.delete(id); + setHeights((h) => { + if (!(id in h)) return h; + const next = { ...h }; + delete next[id]; + return next; + }); + }, []); + + const scheduleDismiss = useCallback( + (id: string, duration: number) => { + if (duration <= 0) return; + const t = window.setTimeout(() => dismiss(id), duration); + timers.current.set(id, t); + remainingTimes.current.set(id, duration); + }, + [dismiss], + ); + + const toast = useCallback( + (input: ToastInput) => { + const id = `t_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`; + const duration = input.duration ?? defaultDuration; + const item: ToastInternal = { ...input, id, createdAt: Date.now() }; + setToasts((prev) => { + const next = [...prev, item]; + return next.length > max ? next.slice(-max) : next; + }); + // Si la pile est déjà hover/focused, on enchaîne en pause aussi. + if (!pausedRef.current) scheduleDismiss(id, duration); + else remainingTimes.current.set(id, duration); + return id; + }, + [defaultDuration, max, scheduleDismiss], + ); + + const clear = useCallback(() => { + timers.current.forEach((t) => window.clearTimeout(t)); + timers.current.clear(); + remainingTimes.current.clear(); + setToasts([]); + }, []); + + const pauseAll = useCallback(() => { + if (pausedRef.current) return; + pausedRef.current = true; + for (const [id, timerId] of timers.current.entries()) { + window.clearTimeout(timerId); + timers.current.delete(id); + } + }, []); + const resumeAll = useCallback(() => { + if (!pausedRef.current) return; + pausedRef.current = false; + for (const [id, remaining] of remainingTimes.current.entries()) { + const t = window.setTimeout(() => dismiss(id), remaining); + timers.current.set(id, t); + } + }, [dismiss]); + + useEffect( + () => () => { + timers.current.forEach((t) => window.clearTimeout(t)); + observerRef.current?.disconnect(); + }, + [], + ); + + // — Mesure des hauteurs via ResizeObserver ———————————— + // Indispensable pour calculer l'expanded-y précisément (somme des heights + // précédentes + gap × index). Évite tout layout shift visible. + useLayoutEffect(() => { + if (typeof ResizeObserver === "undefined") return; + const ro = new ResizeObserver((entries) => { + let mutated = false; + const updates: Record = {}; + for (const entry of entries) { + const el = entry.target as HTMLLIElement; + const id = el.dataset.toastId; + if (!id) continue; + const h = el.offsetHeight; + updates[id] = h; + mutated = true; + } + if (mutated) { + setHeights((prev) => { + let changed = false; + const next = { ...prev }; + for (const [id, h] of Object.entries(updates)) { + if (next[id] !== h) { + next[id] = h; + changed = true; + } + } + return changed ? next : prev; + }); + } + }); + observerRef.current = ro; + for (const el of itemRefs.current.values()) ro.observe(el); + return () => ro.disconnect(); + }, []); + + // Ré-observer lors de l'ajout/retrait + useLayoutEffect(() => { + const ro = observerRef.current; + if (!ro) return; + for (const el of itemRefs.current.values()) ro.observe(el); + }, [toasts.length]); + + // Setter de ref qui (ré-)observe le node + const setItemRef = useCallback( + (id: string) => (el: HTMLLIElement | null) => { + const ro = observerRef.current; + if (el) { + itemRefs.current.set(id, el); + ro?.observe(el); + // Capture immédiate pour éviter un flash au premier render + const h = el.offsetHeight; + if (h > 0) { + setHeights((prev) => (prev[id] === h ? prev : { ...prev, [id]: h })); + } + } else { + const old = itemRefs.current.get(id); + if (old && ro) ro.unobserve(old); + itemRefs.current.delete(id); + } + }, + [], + ); + + // — Ordre + offsets calculés ———————————————————————— + // ordered[i].stackIndex : 0 = front-most (le plus récent). + // Pour bottom-* : DOM order = ancien → récent (column-reverse côté CSS + // n'est plus utilisé maintenant qu'on est en absolute). Le récent est + // au-dessus visuellement → stackIndex 0 = dernier ajouté. + const ordered = useMemo(() => { + const list = toasts.map((t, i) => ({ + ...t, + stackIndex: toasts.length - 1 - i, + })); + // Les offsets dépendent des heights (mesurés) : + // - collapsedOffset = stackOffset × stackIndex (signe selon position) + // - expandedOffset = somme des heights des toasts plus récents (stackIndex < self.stackIndex) + gap × count + return list.map((t) => { + const collapsed = stackOffset * t.stackIndex; + let expanded = 0; + for (let j = 0; j < t.stackIndex; j++) { + const sibling = list.find((o) => o.stackIndex === j); + if (!sibling) continue; + const h = heights[sibling.id] ?? 64; // fallback raisonnable avant mesure + expanded += h + gap; + } + return { ...t, collapsed, expanded }; + }); + }, [toasts, heights, gap, stackOffset]); + + // Hauteur du region : front-most en collapsed, somme en expanded. + const regionHeight = useMemo(() => { + if (toasts.length === 0) return 0; + if (expanded) { + return ordered.reduce((sum, t) => sum + (heights[t.id] ?? 64), 0) + gap * (toasts.length - 1); + } + const front = ordered.find((t) => t.stackIndex === 0); + return heights[front?.id ?? ""] ?? 64; + }, [ordered, heights, gap, expanded, toasts.length]); + + const ctx = useMemo(() => ({ toast, dismiss, clear }), [toast, dismiss, clear]); + + return ( + + {children} +
    { + setExpanded(true); + pauseAll(); + }} + onMouseLeave={() => { + setExpanded(false); + resumeAll(); + }} + onFocus={() => { + setExpanded(true); + pauseAll(); + }} + onBlur={(e) => { + if (!e.currentTarget.contains(e.relatedTarget as Node)) { + setExpanded(false); + resumeAll(); + } + }} + > + {ordered.map((t) => { + const isHidden = !expanded && t.stackIndex >= visibleCount; + // Signes selon position : bottom-* → translateY négatif (vers haut), + // top-* → translateY positif (vers bas). + const sign = isTop ? 1 : -1; + const collapsedY = sign * t.collapsed; + const expandedY = sign * t.expanded; + return ( +
  1. + } + > + +
    +
    {t.title}
    + {t.description &&
    {t.description}
    } + {t.action && ( + + )} +
    + +
  2. + ); + })} +
+
+ ); +} + +/** Hook d'accès au système de toasts. Doit être utilisé sous un ToastProvider. */ +export function useToast() { + const ctx = useContext(ToastContext); + if (!ctx) + throw new Error( + "useToast doit être utilisé dans un . Wrappe ton App.", + ); + return ctx; +} diff --git a/packages/react/src/ToggleGroup.tsx b/packages/react/src/ToggleGroup.tsx new file mode 100644 index 0000000..0bb1ef8 --- /dev/null +++ b/packages/react/src/ToggleGroup.tsx @@ -0,0 +1,81 @@ +import { type ReactNode } from "react"; +import * as RadixToggleGroup from "@radix-ui/react-toggle-group"; +import { cx } from "./utils"; +import { Icon, type IconName } from "./Icon"; + +export type ToggleGroupItem = { + value: string; + label: ReactNode; + icon?: IconName; + /** Affiche uniquement l'icône (label devient aria-label). */ + iconOnly?: boolean; + disabled?: boolean; +}; + +type ToggleGroupCommonProps = { + items: ToggleGroupItem[]; + size?: "sm" | "md" | "lg"; + variant?: "outline" | "solid"; + disabled?: boolean; + /** Label accessible du groupe. */ + ariaLabel?: string; + className?: string; +}; + +export type ToggleGroupSingleProps = ToggleGroupCommonProps & { + type: "single"; + value: string | undefined; + onValueChange: (value: string) => void; +}; + +export type ToggleGroupMultipleProps = ToggleGroupCommonProps & { + type: "multiple"; + value: string[]; + onValueChange: (value: string[]) => void; +}; + +export type ToggleGroupProps = ToggleGroupSingleProps | ToggleGroupMultipleProps; + +/** + * ToggleGroup — groupe de boutons toggle (single ou multiple). + * + * Différence avec SegmentedControl : ToggleGroup peut être en mode multiple + * (plusieurs boutons actifs simultanément) et ne demande pas de label + * obligatoire au-dessus. + * + * Wrapper Radix : roving tabindex, navigation flèches, aria-pressed. + */ +export function ToggleGroup(props: ToggleGroupProps) { + const { items, size = "md", variant = "outline", disabled, ariaLabel, className } = props; + const root = ( + void} + disabled={disabled} + aria-label={ariaLabel} + className={cx( + "mmg-toggle-group", + `mmg-toggle-group--${size}`, + `mmg-toggle-group--${variant}`, + className, + )} + > + {items.map((item) => ( + + {item.icon && } + {!item.iconOnly && {item.label}} + + ))} + + ); + return root; +} + +export { RadixToggleGroup as ToggleGroupPrimitive }; diff --git a/packages/react/src/Tooltip.tsx b/packages/react/src/Tooltip.tsx new file mode 100644 index 0000000..50db15a --- /dev/null +++ b/packages/react/src/Tooltip.tsx @@ -0,0 +1,66 @@ +import { type ReactNode, type ComponentProps } from "react"; +import * as RadixTooltip from "@radix-ui/react-tooltip"; +import { cx } from "./utils"; + +export type TooltipPlacement = "top" | "bottom" | "left" | "right"; + +export type TooltipProps = { + content: ReactNode; + children: ReactNode; + placement?: TooltipPlacement; + /** Délai avant apparition (ms). */ + delay?: number; + /** Décalage par rapport à la cible (px). Défaut 8. */ + sideOffset?: number; + className?: string; +}; + +/** + * Tooltip — wrapper Radix. + * + * - Positionnement intelligent (auto-flip si pas de place) via Floating UI. + * - Focus / hover / Escape gérés par Radix. + * - Respecte prefers-reduced-motion. + * - Pour usage avancé : utiliser TooltipPrimitive.* directement. + * + * Exige un à la racine de l'app (déjà inclus dans + * AppShell). Sinon wrap localement avec . + */ +export function Tooltip({ + content, + children, + placement = "top", + delay = 200, + sideOffset = 8, + className, +}: TooltipProps) { + return ( + + {children} + + + {content} + + + + + ); +} + +export type TooltipProviderProps = ComponentProps; + +/** + * Provider à mettre une fois à la racine de l'app pour partager les délais + * et la file d'attente des tooltips (skipDelayDuration). + */ +export function TooltipProvider(props: TooltipProviderProps) { + return ; +} + +/** Sous-primitives Radix réexportées pour usage avancé (compound). */ +export { RadixTooltip as TooltipPrimitive }; diff --git a/packages/react/src/UserCard.tsx b/packages/react/src/UserCard.tsx new file mode 100644 index 0000000..19f5d5a --- /dev/null +++ b/packages/react/src/UserCard.tsx @@ -0,0 +1,93 @@ +import { type ReactNode } from "react"; +import { cx } from "./utils"; +import { Avatar, type AvatarStatus } from "./Avatar"; + +export type UserCardProps = { + name: ReactNode; + /** Rôle / poste / sous-titre. */ + role?: ReactNode; + /** URL d'image (sinon initiales générées depuis name). */ + src?: string; + initials?: string; + status?: AvatarStatus; + /** Métadonnée optionnelle (e-mail, équipe…). */ + meta?: ReactNode; + /** Slot d'actions à droite (Button, Menu trigger…). */ + actions?: ReactNode; + /** Densité visuelle. */ + size?: "sm" | "md" | "lg"; + /** Si fourni, rend la carte cliquable (entièrement). */ + href?: string; + onClick?: () => void; + className?: string; +}; + +function autoInitials(name: ReactNode) { + if (typeof name !== "string") return undefined; + return name + .split(/\s+/) + .filter(Boolean) + .slice(0, 2) + .map((s) => s[0]) + .join("") + .toUpperCase(); +} + +/** + * UserCard — carte utilisateur compacte (avatar + identité + actions). + * + * Pattern Slack/Linear/Notion : une rangée alignée verticalement avec + * avatar à gauche, identité au milieu, actions à droite. Cliquable en + * entier si href ou onClick. + */ +export function UserCard({ + name, + role, + src, + initials, + status, + meta, + actions, + size = "md", + href, + onClick, + className, +}: UserCardProps) { + const Comp: "a" | "button" | "div" = href ? "a" : onClick ? "button" : "div"; + const interactive = Boolean(href || onClick); + const avatarSize = size === "sm" ? "sm" : size === "lg" ? "lg" : "md"; + + const inner = ( + <> + +
+
{name}
+ {role &&
{role}
} + {meta &&
{meta}
} +
+ {actions &&
{actions}
} + + ); + + return ( + + {inner} + + ); +} diff --git a/packages/react/src/cva.ts b/packages/react/src/cva.ts new file mode 100644 index 0000000..0ee4055 --- /dev/null +++ b/packages/react/src/cva.ts @@ -0,0 +1,116 @@ +/** + * cva — class-variance-authority (implémentation locale légère). + * + * Inspiré de https://cva.style — pas de dépendance externe pour garder + * le bundle DSMMG minimal. Permet de définir des variants typés et + * compositionnés pour un composant. + * + * Usage : + * + * const buttonStyles = cva("mmg-btn", { + * variants: { + * variant: { + * primary: "mmg-btn--primary", + * tonal: "mmg-btn--tonal", + * ghost: "mmg-btn--ghost", + * }, + * size: { + * sm: "mmg-btn--sm", + * md: "mmg-btn--md", + * lg: "mmg-btn--lg", + * }, + * }, + * defaultVariants: { variant: "primary", size: "md" }, + * compoundVariants: [ + * { variant: "ghost", size: "sm", class: "mmg-btn--ghost-sm-tweak" }, + * ], + * }); + * + * buttonStyles({ variant: "tonal", size: "lg" }); + * // → "mmg-btn mmg-btn--tonal mmg-btn--lg" + */ + +type VariantsMap = Record>; + +/** + * Map JS object keys back to their external prop type. Les clés "true"/"false" + * sont des strings côté objet mais on les expose comme `boolean` côté API + * pour que `loading={true}` type-check sans cast. + */ +type ExternalKey = K extends "true" + ? boolean + : K extends "false" + ? boolean + : K; + +type VariantPropsFor = { + [K in keyof V]?: ExternalKey; +}; + +type CompoundVariant = VariantPropsFor & { + class?: string; + className?: string; +}; + +export type CvaConfig = { + variants?: V; + defaultVariants?: VariantPropsFor; + compoundVariants?: CompoundVariant[]; +}; + +export type CvaResult = { + (props?: VariantPropsFor & { className?: string }): string; + /** Pour debug/instrumentation */ + variants: V | undefined; +}; + +export function cva( + base: string, + config: CvaConfig = {}, +): CvaResult { + const { variants, defaultVariants = {}, compoundVariants = [] } = config; + + const fn = (props: (VariantPropsFor & { className?: string }) | undefined = {}) => { + const classes: string[] = [base]; + const merged = { ...defaultVariants, ...props } as VariantPropsFor & { + className?: string; + }; + + if (variants) { + for (const variantKey in variants) { + const value = merged[variantKey] as string | undefined; + if (value != null) { + const variantValueClass = variants[variantKey][value as string]; + if (variantValueClass) classes.push(variantValueClass); + } + } + } + + for (const cv of compoundVariants) { + const matches = Object.entries(cv).every(([k, v]) => { + if (k === "class" || k === "className") return true; + return (merged as any)[k] === v; + }); + if (matches) { + const cn = cv.class ?? cv.className; + if (cn) classes.push(cn); + } + } + + if (props?.className) classes.push(props.className); + return classes.filter(Boolean).join(" "); + }; + + return Object.assign(fn, { variants }); +} + +/** + * Type helper pour extraire les props variants d'un cva ; à utiliser + * dans les composants pour exposer des types stricts : + * + * type ButtonVariants = VariantProps; + */ +export type VariantProps string> = + T extends (props?: infer P & { className?: string }) => string + ? Omit + : never; diff --git a/packages/react/src/index.tsx b/packages/react/src/index.tsx new file mode 100644 index 0000000..01e63cd --- /dev/null +++ b/packages/react/src/index.tsx @@ -0,0 +1,174 @@ +/* ════════════════════════════════════════════════════════════════ + @managemate/react — entry barrel + Exports nommés pour permettre tree-shaking. + Chaque composant vit dans son propre fichier (sideEffects: false). +════════════════════════════════════════════════════════════════ */ + +// — Primitives —————————————————————————————— +export { Slot, type SlotProps } from "./Slot"; +export { cva, type VariantProps, type CvaConfig, type CvaResult } from "./cva"; +export { useFocusTrap } from "./useFocusTrap"; +export { cx } from "./utils"; + +// — Shortcut system ———————————————————————— +export { + ShortcutProvider, + useShortcut, + useShortcutList, + ShortcutCheatsheet, + ShortcutKeys, + type ShortcutEntry, + type ShortcutOptions, +} from "./Shortcut"; + +// — Icon / Pictogram —————————————————————————— +export { Icon, type IconProps, type IconName } from "./Icon"; +export { IconBlock, type IconBlockProps } from "./IconBlock"; +export { + Pictogram, + PICTOGRAM_NAMES, + type PictogramProps, + type PictogramName, +} from "./Pictogram"; + +// — Button —————————————————————————————— +export { Button, type ButtonProps, type ButtonVariants } from "./Button"; + +// — Forms —————————————————————————————— +export { + Field, + Input, + Textarea, + Select, + Checkbox, + Radio, + Switch, + type InputProps, + type TextareaProps, + type SelectProps, + type SelectOption, +} from "./Form"; + +// — Layout —————————————————————————————— +export { + Container, + Section, + Stack, + Inline, + Card, + Tile, + Hero, + type ContainerProps, + type SectionProps, + type TileProps, +} from "./Layout"; + +// — Feedback —————————————————————————————— +export { + Alert, + Notice, + Badge, + Modal, + ToastRegion, + Spinner, + type ToastItem, +} from "./Feedback"; + +// — Chrome (Header / Footer / Nav / Shell) ———————— +export { Header, type HeaderProps, type HeaderNavItem, type NavItemSimple, type NavItemMega, type MegaMenuLink, type MegaMenuColumn, type MegaMenuFeatured } from "./Header"; +export { Footer, type FooterProps, type FooterColumn } from "./Footer"; +export { Breadcrumb, type BreadcrumbProps } from "./Breadcrumb"; +export { Tabs, type TabsProps, type TabItem } from "./Tabs"; +export { Pagination, type PaginationProps } from "./Pagination"; +export { AppShell, Sidebar, AppMain, Topbar, type SidebarProps, type SidebarItem, type SidebarSection, type TopbarProps } from "./AppShell"; +export { Avatar, type AvatarProps, type AvatarSize, type AvatarStatus, type AvatarShape } from "./Avatar"; +export { AvatarGroup, type AvatarGroupProps } from "./AvatarGroup"; +export { UserCard, type UserCardProps } from "./UserCard"; +export { ProfileHeader, type ProfileHeaderProps } from "./ProfileHeader"; +export { MetricCard, type MetricCardProps, type MetricTrend } from "./MetricCard"; +export { PricingCard, type PricingCardProps, type PricingFeature } from "./PricingCard"; +export { FeatureCard, type FeatureCardProps } from "./FeatureCard"; +export { Text, Display, Eyebrow, Lead, type TextProps, type TextVariant, type TextElement } from "./Text"; +export { Stat, type StatProps } from "./Stat"; +export { SkipLink, type SkipLinkProps } from "./SkipLink"; + +// — Advanced (chacun dans son propre fichier) ———————— +export { Stepper, type StepperProps } from "./Stepper"; +export { Accordion, type AccordionProps } from "./Accordion"; +export { Tag, type TagProps } from "./Tag"; +export { Progress, type ProgressProps } from "./Progress"; +export { Drawer, type DrawerProps } from "./Drawer"; +export { Fab, type FabProps } from "./Fab"; +export { Highlight, type HighlightProps } from "./Highlight"; +export { Quote, type QuoteProps } from "./Quote"; +export { Callout, type CalloutProps } from "./Callout"; +export { Banner, type BannerProps } from "./Banner"; +export { FileUpload, type FileUploadProps } from "./FileUpload"; +export { SearchBar, type SearchBarProps } from "./SearchBar"; + +// — Overlays (Radix-backed) —————————————————————— +export { + Tooltip, + TooltipProvider, + TooltipPrimitive, + type TooltipProps, + type TooltipPlacement, + type TooltipProviderProps, +} from "./Tooltip"; +export { Popover, PopoverPrimitive, type PopoverProps } from "./Popover"; +export { Menu, MenuPrimitive, type MenuItem, type MenuProps } from "./Menu"; +export { Dialog, DialogPrimitive, type DialogProps } from "./Dialog"; +export { ConfirmDialog, type ConfirmDialogProps } from "./ConfirmDialog"; +export { Combobox, type ComboboxProps, type ComboboxOption } from "./Combobox"; +export { Sheet, SheetPrimitive, type SheetProps, type SheetSide, type SheetSize } from "./Sheet"; +export { HoverCard, HoverCardPrimitive, type HoverCardProps } from "./HoverCard"; +export { ContextMenu, ContextMenuPrimitive, type ContextMenuProps, type ContextMenuItem } from "./ContextMenu"; +export { Slider, SliderPrimitive, type SliderProps } from "./Slider"; +export { ToggleGroup, ToggleGroupPrimitive, type ToggleGroupProps, type ToggleGroupItem } from "./ToggleGroup"; + +// — DataTable / Tables / Pickers —————————————— +export { + DataTable, + type DataTableProps, + type DataTableColumn, +} from "./DataTable"; +export { + CommandMenu, + useCommandMenu, + type Command, +} from "./CommandMenu"; +export { DatePicker, type DatePickerProps } from "./DatePicker"; +export { + DateRangePicker, + type DateRangePickerProps, + type DateRange, +} from "./DateRangePicker"; + +// — Toast (provider + hook) —————————————————————— +export { ToastProvider, useToast, type ToastInput } from "./Toast"; + +// — EmptyState —————————————————————————————— +export { EmptyState, type EmptyStateProps } from "./EmptyState"; + +// — Extras —————————————————————————————— +export { + SegmentedControl, + DescriptionList, + Sparkline, + Kbd, + type SegmentedItem, + type DListItem, +} from "./Extras"; + +// — Article —————————————————————————————— +export { ArticlePage, type ArticlePageProps } from "./ArticlePage"; +export { ArticleHeader, type ArticleHeaderProps } from "./ArticleHeader"; +export { ArticleAside, type ArticleAsideProps } from "./ArticleAside"; +export { ArticleFooter, type ArticleFooterProps } from "./ArticleFooter"; +export { ArticleCallout, type ArticleCalloutProps } from "./ArticleCallout"; +export { ArticleTOC, type ArticleTOCProps } from "./ArticleTOC"; + +// — Theming (Phase 2) —————————————————————————— +export { ThemePicker, type ThemePickerProps, type AccentName } from "./ThemePicker"; +export { useAccent, applyAccent, ACCENT_PRESETS } from "./useAccent"; +export { useTheme, applyTheme, type ThemeMode } from "./useTheme"; diff --git a/packages/react/src/test-setup.ts b/packages/react/src/test-setup.ts new file mode 100644 index 0000000..59c74e3 --- /dev/null +++ b/packages/react/src/test-setup.ts @@ -0,0 +1,50 @@ +import { afterEach, expect } from "vitest"; +import { cleanup } from "@testing-library/react"; +import * as matchers from "@testing-library/jest-dom/matchers"; +import * as axeMatchers from "vitest-axe/matchers"; + +expect.extend(matchers); +expect.extend(axeMatchers); + +afterEach(() => { + cleanup(); +}); + +// Polyfills attendus par certains composants +if (!("ResizeObserver" in globalThis)) { + // @ts-expect-error — minimal stub for jsdom + globalThis.ResizeObserver = class { + observe() {} + unobserve() {} + disconnect() {} + }; +} + +if (!("IntersectionObserver" in globalThis)) { + // @ts-expect-error — minimal stub for jsdom + globalThis.IntersectionObserver = class { + observe() {} + unobserve() {} + disconnect() {} + takeRecords() { + return []; + } + }; +} + +// matchMedia polyfill (utilisé par Radix UI pour reduced-motion) +if (typeof window !== "undefined" && !window.matchMedia) { + Object.defineProperty(window, "matchMedia", { + writable: true, + value: (query: string) => ({ + matches: false, + media: query, + onchange: null, + addEventListener: () => {}, + removeEventListener: () => {}, + addListener: () => {}, + removeListener: () => {}, + dispatchEvent: () => false, + }), + }); +} diff --git a/packages/react/src/useAccent.ts b/packages/react/src/useAccent.ts new file mode 100644 index 0000000..ef5d06d --- /dev/null +++ b/packages/react/src/useAccent.ts @@ -0,0 +1,95 @@ +import { useCallback, useEffect, useState } from "react"; + +export type AccentName = + | "synapse" + | "rose" + | "blue" + | "violet" + | "green" + | "amber" + | "red" + | "cyan" + | "slate"; + +export const ACCENT_PRESETS: { name: AccentName; label: string; sample: string }[] = [ + { name: "synapse", label: "Rose Synapse", sample: "#D12B6A" }, + { name: "rose", label: "Rose vif", sample: "#E11D48" }, + { name: "blue", label: "Bleu", sample: "#2563EB" }, + { name: "violet", label: "Violet", sample: "#7C3AED" }, + { name: "green", label: "Vert", sample: "#0E9F6E" }, + { name: "amber", label: "Ambre", sample: "#D97706" }, + { name: "red", label: "Rouge", sample: "#DC2626" }, + { name: "cyan", label: "Cyan", sample: "#0891B2" }, + { name: "slate", label: "Ardoise", sample: "#475569" }, +]; + +const STORAGE_KEY = "mmg-accent"; +const DEFAULT_ACCENT: AccentName = "synapse"; + +/** + * Applique un accent au document. Pose [data-mmg-accent="..."] sur . + * Persiste optionnellement dans localStorage. À appeler tôt (avant React) + * pour éviter le flash visuel non désiré. + */ +export function applyAccent(accent: AccentName, persist = true) { + if (typeof document === "undefined") return; + const root = document.documentElement; + if (accent === DEFAULT_ACCENT) { + root.removeAttribute("data-mmg-accent"); + } else { + root.setAttribute("data-mmg-accent", accent); + } + if (persist && typeof window !== "undefined") { + try { + window.localStorage.setItem(STORAGE_KEY, accent); + } catch { + // localStorage may be unavailable (private mode, server) — silently ignore + } + } +} + +/** + * Récupère l'accent stocké côté navigateur, ou le défaut si rien n'est posé. + * Safe SSR : retourne DEFAULT_ACCENT si window n'existe pas. + */ +export function readStoredAccent(): AccentName { + if (typeof window === "undefined") return DEFAULT_ACCENT; + try { + const v = window.localStorage.getItem(STORAGE_KEY); + if (v && ACCENT_PRESETS.some((p) => p.name === v)) return v as AccentName; + } catch { + /* noop */ + } + return DEFAULT_ACCENT; +} + +export type UseAccentReturn = { + accent: AccentName; + setAccent: (a: AccentName) => void; + reset: () => void; +}; + +/** + * Hook pour lire et changer l'accent global. Synchronise localStorage et + * l'attribut [data-mmg-accent] sur . Le composant ThemePicker + * consomme ce hook. + */ +export function useAccent(): UseAccentReturn { + const [accent, setAccentState] = useState(() => readStoredAccent()); + + // Applique au mount pour SSR-safe (l'attribut peut être absent côté serveur). + useEffect(() => { + applyAccent(accent, false); + }, [accent]); + + const setAccent = useCallback((a: AccentName) => { + setAccentState(a); + applyAccent(a, true); + }, []); + + const reset = useCallback(() => { + setAccent(DEFAULT_ACCENT); + }, [setAccent]); + + return { accent, setAccent, reset }; +} diff --git a/packages/react/src/useFocusTrap.ts b/packages/react/src/useFocusTrap.ts new file mode 100644 index 0000000..ee0bf0f --- /dev/null +++ b/packages/react/src/useFocusTrap.ts @@ -0,0 +1,76 @@ +import { useEffect, useRef } from "react"; + +const FOCUSABLE = [ + 'a[href]:not([disabled])', + 'button:not([disabled])', + 'input:not([disabled]):not([type="hidden"])', + 'select:not([disabled])', + 'textarea:not([disabled])', + '[tabindex]:not([tabindex="-1"])', + '[contenteditable="true"]', +].join(","); + +/** + * Piège le focus à l'intérieur du conteneur tant que `active` est vrai. + * - Tab cycle vers le premier élément après le dernier (et inversement). + * - Au montage : focus sur le premier élément focusable. + * - Au démontage : restitution du focus à l'élément précédemment actif. + * + * Conforme WCAG SC 2.4.3 (Focus Order) et WAI-ARIA Authoring Practices + * pour les dialogues modaux. + */ +export function useFocusTrap(active: boolean) { + const ref = useRef(null); + + useEffect(() => { + if (!active) return; + const container = ref.current; + if (!container) return; + + const previouslyFocused = document.activeElement as HTMLElement | null; + + // Focus initial : premier focusable, sinon le conteneur lui-même + const focusables = container.querySelectorAll(FOCUSABLE); + const first = focusables[0] ?? container; + // tabindex sur le conteneur pour qu'il puisse recevoir le focus + if (first === container && !container.hasAttribute("tabindex")) { + container.setAttribute("tabindex", "-1"); + } + // setTimeout pour laisser l'animation d'ouverture se poser + const t = window.setTimeout(() => first.focus({ preventScroll: false }), 30); + + const onKeyDown = (e: KeyboardEvent) => { + if (e.key !== "Tab") return; + const focusables = Array.from( + container.querySelectorAll(FOCUSABLE), + ).filter((el) => el.offsetParent !== null); + if (focusables.length === 0) { + e.preventDefault(); + return; + } + const first = focusables[0]; + const last = focusables[focusables.length - 1]; + + if (e.shiftKey && document.activeElement === first) { + e.preventDefault(); + last.focus(); + } else if (!e.shiftKey && document.activeElement === last) { + e.preventDefault(); + first.focus(); + } + }; + + document.addEventListener("keydown", onKeyDown); + + return () => { + window.clearTimeout(t); + document.removeEventListener("keydown", onKeyDown); + // Restitution du focus + if (previouslyFocused && document.contains(previouslyFocused)) { + previouslyFocused.focus({ preventScroll: true }); + } + }; + }, [active]); + + return ref; +} diff --git a/packages/react/src/useTheme.ts b/packages/react/src/useTheme.ts new file mode 100644 index 0000000..0c9bdcd --- /dev/null +++ b/packages/react/src/useTheme.ts @@ -0,0 +1,56 @@ +import { useCallback, useEffect, useState } from "react"; + +export type ThemeMode = "light" | "dark" | "system"; +const STORAGE_KEY = "mmg-theme"; + +export function applyTheme(mode: ThemeMode, persist = true) { + if (typeof document === "undefined") return; + const root = document.documentElement; + if (mode === "system") { + root.removeAttribute("data-mmg-theme"); + } else { + root.setAttribute("data-mmg-theme", mode); + } + if (persist && typeof window !== "undefined") { + try { + window.localStorage.setItem(STORAGE_KEY, mode); + } catch { + /* noop */ + } + } +} + +function readStoredTheme(): ThemeMode { + if (typeof window === "undefined") return "system"; + try { + const v = window.localStorage.getItem(STORAGE_KEY); + if (v === "light" || v === "dark" || v === "system") return v; + } catch { + /* noop */ + } + return "system"; +} + +export function useTheme() { + const [theme, setThemeState] = useState(() => readStoredTheme()); + + useEffect(() => { + applyTheme(theme, false); + }, [theme]); + + const setTheme = useCallback((t: ThemeMode) => { + setThemeState(t); + applyTheme(t, true); + }, []); + + const toggle = useCallback(() => { + // light → dark → system → light + setThemeState((prev) => { + const next: ThemeMode = prev === "light" ? "dark" : prev === "dark" ? "system" : "light"; + applyTheme(next, true); + return next; + }); + }, []); + + return { theme, setTheme, toggle }; +} diff --git a/packages/react/src/utils.ts b/packages/react/src/utils.ts new file mode 100644 index 0000000..fd49964 --- /dev/null +++ b/packages/react/src/utils.ts @@ -0,0 +1,31 @@ +/** + * Concatène des classNames en filtrant les falsy. + * + * Accepte string, number (0/NaN ignorés), boolean (false ignoré), + * null/undefined, BigInt (0n ignoré, pour les contextes JSX modernes), + * et Record (clés ajoutées si la valeur est truthy). + * + * Pratique avec les patterns `condition && "class"` qui produisent + * facilement des unions type-larges en TS strict. + */ +type ClassValue = + | string + | number + | bigint + | boolean + | null + | undefined + | Record; + +export function cx(...args: ClassValue[]): string { + const out: string[] = []; + for (const a of args) { + if (!a) continue; + if (typeof a === "string") { + out.push(a); + } else if (typeof a === "object") { + for (const k in a) if (a[k]) out.push(k); + } + } + return out.join(" "); +} diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json new file mode 100644 index 0000000..7b3450b --- /dev/null +++ b/packages/react/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "jsx": "react-jsx", + "strict": true, + "noUncheckedIndexedAccess": false, + "noImplicitOverride": true, + "esModuleInterop": true, + "skipLibCheck": true, + "isolatedModules": true, + "verbatimModuleSyntax": false, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist", + "rootDir": "./src", + "noEmit": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "**/*.test.tsx", "**/*.test.ts"] +} diff --git a/packages/react/tsup.config.ts b/packages/react/tsup.config.ts new file mode 100644 index 0000000..eb1ee39 --- /dev/null +++ b/packages/react/tsup.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from "tsup"; + +/** + * @managemate/react — build config + * + * - Output dual (ESM + CJS) avec types .d.ts + * - Tree-shaking : sideEffects: false dans package.json garantit que les + * imports inutilisés sont droppés par les bundlers consommateurs. + * - Ne bundle PAS les peerDependencies (react, react-dom, @managemate/css). + */ +export default defineConfig({ + entry: ["src/index.tsx"], + format: ["esm", "cjs"], + dts: true, + sourcemap: true, + clean: true, + splitting: true, // ESM code-splitting pour permettre le tree-shaking par composant + treeshake: true, + minify: false, + target: "es2022", + external: ["react", "react-dom", "react/jsx-runtime", "@managemate/css", "@managemate/icons"], + // Garantit que les imports d'effet (CSS) ne sont pas tree-shakés par erreur, + // même si on en avait. Cf. https://webpack.js.org/guides/tree-shaking/ +}); diff --git a/packages/react/vitest.config.ts b/packages/react/vitest.config.ts new file mode 100644 index 0000000..51c76ff --- /dev/null +++ b/packages/react/vitest.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from "vitest/config"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [react()], + test: { + environment: "jsdom", + globals: true, + setupFiles: ["./src/test-setup.ts"], + css: false, + coverage: { + provider: "v8", + reporter: ["text", "html", "lcov"], + include: ["src/**/*.{ts,tsx}"], + exclude: ["src/**/*.stories.{ts,tsx}", "src/test-setup.ts"], + thresholds: { + lines: 60, + functions: 60, + branches: 60, + statements: 60, + }, + }, + }, +}); diff --git a/packages/tokens/README.md b/packages/tokens/README.md new file mode 100644 index 0000000..e3f9bc4 --- /dev/null +++ b/packages/tokens/README.md @@ -0,0 +1,55 @@ +# @managemate/tokens + +Source unique des tokens DSMMG au format **W3C Design Tokens Community Group (DTCG)**. + +## Usage + +```sh +pnpm --filter @managemate/tokens build +``` + +Génère dans `dist/` : + +| Fichier | Format | Pour qui | +|---|---|---| +| `tokens.css` | CSS custom properties `--mmg-*` | Le navigateur, importé par `@managemate/css` | +| `tokens.js` | ESM | Code Node/Bundler — JS/TS apps | +| `tokens.cjs` | CommonJS | Code Node legacy | +| `tokens.d.ts` | TypeScript declarations | Auto-complete dans les IDEs | +| `figma-tokens.json` | [Tokens Studio](https://tokens.studio/) | Plugin Figma → sync designer↔code | + +## Workflow Figma + +1. Le designer modifie les variables dans Figma via [Tokens Studio](https://tokens.studio/). +2. Export → push vers `packages/tokens/src/tokens.json` (PR avec changeset minor). +3. CI valide les contrastes et regen les sorties. +4. Ou inversement : modifier `tokens.json` → CI regen Figma JSON → designer pull dans Figma. + +## DTCG schema + +Chaque token a une forme : + +```json +{ + "$value": "#D12B6A", + "$type": "color", + "$description": "(optionnel)" +} +``` + +Types supportés : `color`, `dimension`, `fontWeight`, `duration`. + +## Conventions de naming + +- `color..` : `color.synapse.500` +- `spacing.` : `spacing.4` (= 16px) +- `radius.` : `radius.md` +- `fontSize.` : `fontSize.base` +- `fontWeight.` : `fontWeight.semi` +- `duration.` : `duration.fast` + +Le préfixe CSS `--mmg-` est ajouté automatiquement par Style Dictionary. + +## Présets accent (cross-pkg) + +Les tokens primitifs sont publiés ici. Les presets accent (`[data-mmg-accent="…"]`) restent définis dans `@managemate/css` (`tokens/accent.css`) car ils dépendent du contexte (light/dark, sélection user). diff --git a/packages/tokens/build.mjs b/packages/tokens/build.mjs new file mode 100644 index 0000000..76cc887 --- /dev/null +++ b/packages/tokens/build.mjs @@ -0,0 +1,196 @@ +#!/usr/bin/env node +/** + * @managemate/tokens — build pipeline + * + * Source de vérité unique : src/tokens.json (format W3C DTCG). + * Génère : + * - dist/tokens.css : CSS custom properties --mmg-color-* + * - dist/tokens.js / .d.ts: objet JS/TS pour consommation programmatique + * - dist/tokens.cjs : CommonJS + * - dist/figma-tokens.json: format Tokens Studio pour sync Figma + */ +import StyleDictionary from "style-dictionary"; +import { mkdir, writeFile, readFile } from "node:fs/promises"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; +import { existsSync } from "node:fs"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const ROOT = __dirname; +const DIST = join(ROOT, "dist"); +const SOURCE = join(ROOT, "src", "tokens.json"); + +if (!existsSync(DIST)) await mkdir(DIST, { recursive: true }); + +// — Style Dictionary config ———————————————————————————————————— +const sd = new StyleDictionary({ + source: [SOURCE], + log: { warnings: "warn", verbosity: "default" }, + platforms: { + css: { + transformGroup: "css", + buildPath: "dist/", + files: [ + { + destination: "tokens.css", + format: "css/variables", + options: { + outputReferences: false, + selector: ":root", + }, + }, + ], + prefix: "mmg", + }, + js: { + transformGroup: "js", + buildPath: "dist/", + files: [ + { + destination: "tokens.js", + format: "javascript/esm", + }, + { + destination: "tokens.cjs", + format: "javascript/module", + }, + { + destination: "tokens.d.ts", + format: "typescript/es6-declarations", + }, + ], + prefix: "mmg", + }, + }, +}); + +await sd.cleanAllPlatforms(); +await sd.buildAllPlatforms(); + +// — Figma Tokens Studio export ———————————————————————————————————— +// Plugin Tokens Studio attend un format proche de DTCG mais avec une +// structure aplatie : { "color/neutral/50": { "value": "...", "type": "color" } } +const dtcg = JSON.parse(await readFile(SOURCE, "utf8")); + +function flatten(obj, prefix = "") { + const out = {}; + for (const [k, v] of Object.entries(obj)) { + if (k.startsWith("$")) continue; + const path = prefix ? `${prefix}/${k}` : k; + if (v && typeof v === "object" && "$value" in v) { + out[path] = { value: v.$value, type: v.$type }; + } else if (v && typeof v === "object") { + Object.assign(out, flatten(v, path)); + } + } + return out; +} + +const figmaTokens = { + global: flatten(dtcg), + $themes: [], + $metadata: { + tokenSetOrder: ["global"], + generatedAt: new Date().toISOString(), + generatedBy: "@managemate/tokens build.mjs", + }, +}; + +await writeFile(join(DIST, "figma-tokens.json"), JSON.stringify(figmaTokens, null, 2)); + +// — Tailwind v3 export (theme.extend JSON) ———————————————————————— +function buildTailwindV3() { + const colors = {}; + for (const [name, ramp] of Object.entries(dtcg.color ?? {})) { + if (!ramp || typeof ramp !== "object") continue; + const shades = {}; + for (const [shade, val] of Object.entries(ramp)) { + if (val && typeof val === "object" && "$value" in val) { + shades[shade] = val.$value; + } + } + if (Object.keys(shades).length > 0) colors[name] = shades; + } + const spacing = {}; + for (const [k, v] of Object.entries(dtcg.spacing ?? {})) { + if (v && typeof v === "object" && "$value" in v) { + spacing[`mmg-${k}`] = v.$value; + } + } + const radius = {}; + for (const [k, v] of Object.entries(dtcg.radius ?? {})) { + if (v && typeof v === "object" && "$value" in v) { + radius[`mmg-${k}`] = v.$value; + } + } + const fontSize = {}; + for (const [k, v] of Object.entries(dtcg.fontSize ?? {})) { + if (v && typeof v === "object" && "$value" in v) { + fontSize[`mmg-${k}`] = v.$value; + } + } + return { + theme: { + extend: { + colors: { mmg: colors }, + spacing, + borderRadius: radius, + fontSize, + }, + }, + }; +} + +await writeFile( + join(DIST, "tailwind.config.json"), + JSON.stringify(buildTailwindV3(), null, 2), +); + +// — Tailwind v4 export (@theme CSS block) ———————————————————————— +function buildTailwindV4() { + const lines = ["/* DSMMG tokens — Tailwind v4 @theme block. */", "@theme {"]; + // Colors + for (const [name, ramp] of Object.entries(dtcg.color ?? {})) { + if (!ramp || typeof ramp !== "object") continue; + for (const [shade, val] of Object.entries(ramp)) { + if (val && typeof val === "object" && "$value" in val) { + lines.push(` --color-mmg-${name}-${shade}: ${val.$value};`); + } + } + } + // Spacing + for (const [k, v] of Object.entries(dtcg.spacing ?? {})) { + if (v && typeof v === "object" && "$value" in v) { + lines.push(` --spacing-mmg-${k}: ${v.$value};`); + } + } + // Radius + for (const [k, v] of Object.entries(dtcg.radius ?? {})) { + if (v && typeof v === "object" && "$value" in v) { + lines.push(` --radius-mmg-${k}: ${v.$value};`); + } + } + // Font sizes + for (const [k, v] of Object.entries(dtcg.fontSize ?? {})) { + if (v && typeof v === "object" && "$value" in v) { + lines.push(` --text-mmg-${k}: ${v.$value};`); + } + } + // Durations + for (const [k, v] of Object.entries(dtcg.duration ?? {})) { + if (v && typeof v === "object" && "$value" in v) { + lines.push(` --animate-duration-mmg-${k}: ${v.$value};`); + } + } + lines.push("}"); + return lines.join("\n") + "\n"; +} + +await writeFile(join(DIST, "tailwind.css"), buildTailwindV4()); + +console.log(`✓ Tokens built → ${DIST}`); +console.log(` - tokens.css (CSS custom properties)`); +console.log(` - tokens.{js,cjs,d.ts} (ESM / CJS / TypeScript)`); +console.log(` - figma-tokens.json (Tokens Studio for Figma sync)`); +console.log(` - tailwind.config.json (Tailwind v3 theme.extend)`); +console.log(` - tailwind.css (Tailwind v4 @theme block)`); diff --git a/packages/tokens/package.json b/packages/tokens/package.json new file mode 100644 index 0000000..24506fd --- /dev/null +++ b/packages/tokens/package.json @@ -0,0 +1,36 @@ +{ + "name": "@managemate/tokens", + "version": "0.1.0", + "description": "DSMMG design tokens — DTCG source + Style Dictionary build (CSS, TS, Figma)", + "type": "module", + "license": "UNLICENSED", + "private": true, + "sideEffects": false, + "main": "./dist/tokens.cjs", + "module": "./dist/tokens.js", + "types": "./dist/tokens.d.ts", + "exports": { + ".": { + "types": "./dist/tokens.d.ts", + "import": "./dist/tokens.js", + "require": "./dist/tokens.cjs" + }, + "./css": "./dist/tokens.css", + "./figma": "./dist/figma-tokens.json", + "./tailwind": "./dist/tailwind.config.json", + "./tailwind.css": "./dist/tailwind.css", + "./source": "./src/tokens.json", + "./package.json": "./package.json" + }, + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node build.mjs", + "watch": "node build.mjs --watch" + }, + "devDependencies": { + "style-dictionary": "^4.3.3" + } +} diff --git a/packages/tokens/src/tokens.json b/packages/tokens/src/tokens.json new file mode 100644 index 0000000..7f24600 --- /dev/null +++ b/packages/tokens/src/tokens.json @@ -0,0 +1,173 @@ +{ + "$schema": "https://schemas.tr.designtokens.org/format/", + "color": { + "neutral": { + "0": { "$value": "#FFFFFF", "$type": "color" }, + "50": { "$value": "#F7F6FB", "$type": "color" }, + "100": { "$value": "#F0EFF9", "$type": "color" }, + "150": { "$value": "#EDEDFA", "$type": "color" }, + "200": { "$value": "#E4E3F4", "$type": "color" }, + "300": { "$value": "#C9C7E0", "$type": "color" }, + "400": { "$value": "#AAA8C9", "$type": "color" }, + "500": { "$value": "#7875A1", "$type": "color" }, + "600": { "$value": "#56557A", "$type": "color" }, + "700": { "$value": "#3B3A56", "$type": "color" }, + "800": { "$value": "#1F1E32", "$type": "color" }, + "900": { "$value": "#111120", "$type": "color" } + }, + "synapse": { + "50": { "$value": "#FEF0F4", "$type": "color" }, + "100": { "$value": "#FCE0EA", "$type": "color" }, + "200": { "$value": "#FAD0DF", "$type": "color" }, + "300": { "$value": "#F4A0BD", "$type": "color" }, + "400": { "$value": "#ED608E", "$type": "color" }, + "500": { "$value": "#D12B6A", "$type": "color" }, + "600": { "$value": "#BA245F", "$type": "color" }, + "700": { "$value": "#A82257", "$type": "color" }, + "800": { "$value": "#831B45", "$type": "color" }, + "900": { "$value": "#5A132F", "$type": "color" } + }, + "rose": { + "50": { "$value": "#FFF1F2", "$type": "color" }, + "100": { "$value": "#FFE4E6", "$type": "color" }, + "200": { "$value": "#FECDD3", "$type": "color" }, + "300": { "$value": "#FDA4AF", "$type": "color" }, + "400": { "$value": "#FB7185", "$type": "color" }, + "500": { "$value": "#E11D48", "$type": "color" }, + "600": { "$value": "#BE123C", "$type": "color" }, + "700": { "$value": "#9F1239", "$type": "color" }, + "800": { "$value": "#881337", "$type": "color" }, + "900": { "$value": "#4C0519", "$type": "color" } + }, + "blue": { + "50": { "$value": "#EFF6FF", "$type": "color" }, + "100": { "$value": "#DBEAFE", "$type": "color" }, + "200": { "$value": "#BFDBFE", "$type": "color" }, + "300": { "$value": "#93C5FD", "$type": "color" }, + "400": { "$value": "#60A5FA", "$type": "color" }, + "500": { "$value": "#2563EB", "$type": "color" }, + "600": { "$value": "#1D4ED8", "$type": "color" }, + "700": { "$value": "#1E40AF", "$type": "color" }, + "800": { "$value": "#1E3A8A", "$type": "color" }, + "900": { "$value": "#172554", "$type": "color" } + }, + "violet": { + "50": { "$value": "#F5F3FF", "$type": "color" }, + "100": { "$value": "#EDE9FE", "$type": "color" }, + "200": { "$value": "#DDD6FE", "$type": "color" }, + "300": { "$value": "#C4B5FD", "$type": "color" }, + "400": { "$value": "#A78BFA", "$type": "color" }, + "500": { "$value": "#7C3AED", "$type": "color" }, + "600": { "$value": "#6D28D9", "$type": "color" }, + "700": { "$value": "#5B21B6", "$type": "color" }, + "800": { "$value": "#4C1D95", "$type": "color" }, + "900": { "$value": "#2E1065", "$type": "color" } + }, + "green": { + "50": { "$value": "#ECFDF5", "$type": "color" }, + "100": { "$value": "#D1FAE5", "$type": "color" }, + "200": { "$value": "#BAEFD3", "$type": "color" }, + "300": { "$value": "#6EE7B7", "$type": "color" }, + "400": { "$value": "#34D399", "$type": "color" }, + "500": { "$value": "#0E9F6E", "$type": "color" }, + "600": { "$value": "#0B8861", "$type": "color" }, + "700": { "$value": "#086B4D", "$type": "color" }, + "800": { "$value": "#064E3B", "$type": "color" }, + "900": { "$value": "#022C22", "$type": "color" } + }, + "amber": { + "50": { "$value": "#FFFBEB", "$type": "color" }, + "100": { "$value": "#FEF3C7", "$type": "color" }, + "200": { "$value": "#FDE68A", "$type": "color" }, + "300": { "$value": "#FCD34D", "$type": "color" }, + "400": { "$value": "#FBBF24", "$type": "color" }, + "500": { "$value": "#D97706", "$type": "color" }, + "600": { "$value": "#B45309", "$type": "color" }, + "700": { "$value": "#92400E", "$type": "color" }, + "800": { "$value": "#78350F", "$type": "color" }, + "900": { "$value": "#451A03", "$type": "color" } + }, + "red": { + "50": { "$value": "#FEF2F2", "$type": "color" }, + "100": { "$value": "#FEE2E2", "$type": "color" }, + "200": { "$value": "#FECACA", "$type": "color" }, + "300": { "$value": "#FCA5A5", "$type": "color" }, + "400": { "$value": "#F87171", "$type": "color" }, + "500": { "$value": "#DC2626", "$type": "color" }, + "600": { "$value": "#B91C1C", "$type": "color" }, + "700": { "$value": "#991B1B", "$type": "color" }, + "800": { "$value": "#7F1D1D", "$type": "color" }, + "900": { "$value": "#450A0A", "$type": "color" } + }, + "cyan": { + "50": { "$value": "#ECFEFF", "$type": "color" }, + "100": { "$value": "#CFFAFE", "$type": "color" }, + "200": { "$value": "#A5F3FC", "$type": "color" }, + "300": { "$value": "#67E8F9", "$type": "color" }, + "400": { "$value": "#22D3EE", "$type": "color" }, + "500": { "$value": "#0891B2", "$type": "color" }, + "600": { "$value": "#0E7490", "$type": "color" }, + "700": { "$value": "#155E75", "$type": "color" }, + "800": { "$value": "#164E63", "$type": "color" }, + "900": { "$value": "#083344", "$type": "color" } + }, + "slate": { + "50": { "$value": "#F8FAFC", "$type": "color" }, + "100": { "$value": "#F1F5F9", "$type": "color" }, + "200": { "$value": "#E2E8F0", "$type": "color" }, + "300": { "$value": "#CBD5E1", "$type": "color" }, + "400": { "$value": "#94A3B8", "$type": "color" }, + "500": { "$value": "#475569", "$type": "color" }, + "600": { "$value": "#334155", "$type": "color" }, + "700": { "$value": "#1E293B", "$type": "color" }, + "800": { "$value": "#0F172A", "$type": "color" }, + "900": { "$value": "#020617", "$type": "color" } + } + }, + "spacing": { + "0": { "$value": "0px", "$type": "dimension" }, + "1": { "$value": "4px", "$type": "dimension" }, + "2": { "$value": "8px", "$type": "dimension" }, + "3": { "$value": "12px", "$type": "dimension" }, + "4": { "$value": "16px", "$type": "dimension" }, + "5": { "$value": "20px", "$type": "dimension" }, + "6": { "$value": "24px", "$type": "dimension" }, + "7": { "$value": "32px", "$type": "dimension" }, + "8": { "$value": "40px", "$type": "dimension" }, + "9": { "$value": "48px", "$type": "dimension" }, + "10": { "$value": "64px", "$type": "dimension" }, + "11": { "$value": "80px", "$type": "dimension" }, + "12": { "$value": "120px", "$type": "dimension" } + }, + "radius": { + "sm": { "$value": "8px", "$type": "dimension" }, + "md": { "$value": "12px", "$type": "dimension" }, + "card": { "$value": "20px", "$type": "dimension" }, + "panel": { "$value": "24px", "$type": "dimension" }, + "icon": { "$value": "12px", "$type": "dimension" }, + "pill": { "$value": "9999px", "$type": "dimension" } + }, + "fontSize": { + "xs": { "$value": "11px", "$type": "dimension" }, + "sm": { "$value": "13px", "$type": "dimension" }, + "base": { "$value": "15px", "$type": "dimension" }, + "lg": { "$value": "17px", "$type": "dimension" }, + "xl": { "$value": "20px", "$type": "dimension" }, + "2xl": { "$value": "24px", "$type": "dimension" }, + "3xl": { "$value": "30px", "$type": "dimension" }, + "4xl": { "$value": "36px", "$type": "dimension" }, + "5xl": { "$value": "48px", "$type": "dimension" } + }, + "fontWeight": { + "regular": { "$value": 400, "$type": "fontWeight" }, + "medium": { "$value": 500, "$type": "fontWeight" }, + "semi": { "$value": 600, "$type": "fontWeight" }, + "bold": { "$value": 700, "$type": "fontWeight" }, + "extra": { "$value": 800, "$type": "fontWeight" } + }, + "duration": { + "fast": { "$value": "120ms", "$type": "duration" }, + "base": { "$value": "200ms", "$type": "duration" }, + "slow": { "$value": "320ms", "$type": "duration" } + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..9d5ba35 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,11621 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@changesets/cli': + specifier: ^2.27.11 + version: 2.31.0(@types/node@24.12.2) + '@size-limit/preset-small-lib': + specifier: ^11.1.6 + version: 11.2.0(size-limit@11.2.0) + size-limit: + specifier: ^11.1.6 + version: 11.2.0 + + demo: + dependencies: + '@managemate/css': + specifier: workspace:* + version: link:../packages/css + '@managemate/icons': + specifier: workspace:* + version: link:../packages/icons + '@managemate/react': + specifier: workspace:* + version: link:../packages/react + react: + specifier: ^19.2.5 + version: 19.2.5 + react-dom: + specifier: ^19.2.5 + version: 19.2.5(react@19.2.5) + devDependencies: + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': + specifier: ^6.0.1 + version: 6.0.1(vite@8.0.10(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(yaml@2.8.4)) + typescript: + specifier: ~6.0.2 + version: 6.0.3 + vite: + specifier: ^8.0.10 + version: 8.0.10(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(yaml@2.8.4) + + docs: + dependencies: + '@astrojs/starlight': + specifier: ^0.30.0 + version: 0.30.6(astro@5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4)) + '@managemate/css': + specifier: workspace:* + version: link:../packages/css + '@managemate/icons': + specifier: workspace:* + version: link:../packages/icons + astro: + specifier: ^5.0.0 + version: 5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4) + sharp: + specifier: ^0.33.0 + version: 0.33.5 + + packages/css: + devDependencies: + autoprefixer: + specifier: ^10.4.20 + version: 10.5.0(postcss@8.5.13) + cross-env: + specifier: ^7.0.3 + version: 7.0.3 + cssnano: + specifier: ^7.0.7 + version: 7.1.8(postcss@8.5.13) + postcss: + specifier: ^8.5.0 + version: 8.5.13 + postcss-cli: + specifier: ^11.0.0 + version: 11.0.1(jiti@2.6.1)(postcss@8.5.13) + postcss-import: + specifier: ^16.1.0 + version: 16.1.1(postcss@8.5.13) + + packages/icons: + dependencies: + remixicon: + specifier: ^4.9.1 + version: 4.9.1 + + packages/react: + dependencies: + '@floating-ui/react': + specifier: ^0.27.0 + version: 0.27.19(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@managemate/css': + specifier: workspace:* + version: link:../css + '@managemate/icons': + specifier: workspace:* + version: link:../icons + '@radix-ui/react-context-menu': + specifier: ^2.2.14 + version: 2.2.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-dialog': + specifier: ^1.1.13 + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-dropdown-menu': + specifier: ^2.1.14 + version: 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-hover-card': + specifier: ^1.1.13 + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-popover': + specifier: ^1.1.13 + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slider': + specifier: ^1.3.4 + version: 1.3.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-toggle-group': + specifier: ^1.1.9 + version: 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-tooltip': + specifier: ^1.2.6 + version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: + specifier: '>=18' + version: 19.2.5 + react-dom: + specifier: '>=18' + version: 19.2.5(react@19.2.5) + devDependencies: + '@testing-library/jest-dom': + specifier: ^6.6.3 + version: 6.9.1 + '@testing-library/react': + specifier: ^16.1.0 + version: 16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@testing-library/user-event': + specifier: ^14.5.2 + version: 14.6.1(@testing-library/dom@10.4.0) + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.7.0(vite@8.0.10(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(yaml@2.8.4)) + axe-core: + specifier: ^4.10.2 + version: 4.11.4 + jsdom: + specifier: ^25.0.1 + version: 25.0.1 + tsup: + specifier: ^8.5.0 + version: 8.5.1(jiti@2.6.1)(postcss@8.5.13)(typescript@5.7.3)(yaml@2.8.4) + typescript: + specifier: ~5.7.0 + version: 5.7.3 + vitest: + specifier: ^2.1.9 + version: 2.1.9(@types/node@24.12.2)(jsdom@25.0.1)(lightningcss@1.32.0) + vitest-axe: + specifier: ^0.1.0 + version: 0.1.0(vitest@2.1.9(@types/node@24.12.2)(jsdom@25.0.1)(lightningcss@1.32.0)) + + packages/tokens: + devDependencies: + style-dictionary: + specifier: ^4.3.3 + version: 4.4.0(tslib@2.8.1) + + storybook: + dependencies: + '@managemate/css': + specifier: workspace:* + version: link:../packages/css + '@managemate/icons': + specifier: workspace:* + version: link:../packages/icons + '@managemate/react': + specifier: workspace:* + version: link:../packages/react + react: + specifier: ^19.2.5 + version: 19.2.5 + react-dom: + specifier: ^19.2.5 + version: 19.2.5(react@19.2.5) + devDependencies: + '@storybook/addon-a11y': + specifier: ^8.5.0 + version: 8.6.18(storybook@8.6.18(prettier@3.8.3)) + '@storybook/addon-essentials': + specifier: ^8.5.0 + version: 8.6.14(@types/react@19.2.14)(storybook@8.6.18(prettier@3.8.3)) + '@storybook/addon-interactions': + specifier: ^8.5.0 + version: 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@storybook/blocks': + specifier: ^8.5.0 + version: 8.6.14(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@8.6.18(prettier@3.8.3)) + '@storybook/react': + specifier: ^8.5.0 + version: 8.6.18(@storybook/test@8.6.15(storybook@8.6.18(prettier@3.8.3)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@8.6.18(prettier@3.8.3))(typescript@5.7.3) + '@storybook/react-vite': + specifier: ^8.5.0 + version: 8.6.18(@storybook/test@8.6.15(storybook@8.6.18(prettier@3.8.3)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(rollup@4.60.2)(storybook@8.6.18(prettier@3.8.3))(typescript@5.7.3)(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)) + '@storybook/test': + specifier: ^8.5.0 + version: 8.6.15(storybook@8.6.18(prettier@3.8.3)) + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + '@vitejs/plugin-react': + specifier: ^4.3.4 + version: 4.7.0(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)) + storybook: + specifier: ^8.5.0 + version: 8.6.18(prettier@3.8.3) + typescript: + specifier: ~5.7.0 + version: 5.7.3 + vite: + specifier: ^5.4.11 + version: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0) + +packages: + + '@adobe/css-tools@4.4.4': + resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + + '@asamuzakjp/css-color@3.2.0': + resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} + + '@astrojs/compiler@2.13.1': + resolution: {integrity: sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==} + + '@astrojs/internal-helpers@0.7.6': + resolution: {integrity: sha512-GOle7smBWKfMSP8osUIGOlB5kaHdQLV3foCsf+5Q9Wsuu+C6Fs3Ez/ttXmhjZ1HkSgsogcM1RXSjjOVieHq16Q==} + + '@astrojs/markdown-remark@6.3.11': + resolution: {integrity: sha512-hcaxX/5aC6lQgHeGh1i+aauvSwIT6cfyFjKWvExYSxUhZZBBdvCliOtu06gbQyhbe0pGJNoNmqNlQZ5zYUuIyQ==} + + '@astrojs/mdx@4.3.14': + resolution: {integrity: sha512-FBrqJQORVm+rkRa2TS5CjU9PBA6hkhrwLVBSS9A77gN2+iehvjq1w6yya/d0YKC7osiVorKkr3Qd9wNbl0ZkGA==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + peerDependencies: + astro: ^5.0.0 + + '@astrojs/prism@3.3.0': + resolution: {integrity: sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + + '@astrojs/sitemap@3.7.2': + resolution: {integrity: sha512-PqkzkcZTb5ICiyIR8VoKbIAP/laNRXi5tw616N1Ckk+40oNB8Can1AzVV56lrbC5GKSZFCyJYUVYqVivMisvpA==} + + '@astrojs/starlight@0.30.6': + resolution: {integrity: sha512-/AoLXjPPD1MqixkTd2Lp3qahSzfCejePWHZQ3+fDjj1CuXI7Gjrr5bR3zNV0b9tynloPAIBM0HOyBNEGAo9uAQ==} + peerDependencies: + astro: ^5.0.0 + + '@astrojs/telemetry@3.3.0': + resolution: {integrity: sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.3': + resolution: {integrity: sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.3': + resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@bundled-es-modules/deepmerge@4.3.1': + resolution: {integrity: sha512-Rk453EklPUPC3NRWc3VUNI/SSUjdBaFoaQvFRmNBNtMHVtOFD5AntiWg5kEE1hqcPqedYFDzxE3ZcMYPcA195w==} + + '@bundled-es-modules/glob@10.4.2': + resolution: {integrity: sha512-740y5ofkzydsFao5EXJrGilcIL6EFEw/cmPf2uhTw9J6G1YOhiIFjNFCHdpgEiiH5VlU3G0SARSjlFlimRRSMA==} + + '@bundled-es-modules/memfs@4.17.0': + resolution: {integrity: sha512-ykdrkEmQr9BV804yd37ikXfNnvxrwYfY9Z2/EtMHFEFadEjsQXJ1zL9bVZrKNLDtm91UdUOEHso6Aweg93K6xQ==} + + '@capsizecss/unpack@4.0.0': + resolution: {integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==} + engines: {node: '>=18'} + + '@changesets/apply-release-plan@7.1.1': + resolution: {integrity: sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA==} + + '@changesets/assemble-release-plan@6.0.10': + resolution: {integrity: sha512-rSDcqdJ9KbVyjpBIuCidhvZNIiVt1XaIYp73ycVQRIA5n/j6wQaEk0ChRLMUQ1vkxZe51PTQ9OIhbg6HQMW45A==} + + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + + '@changesets/cli@2.31.0': + resolution: {integrity: sha512-AhI4enNTgHu2IZr6K4WZyf0EPch4XVMn1yOMFmCD9gsfBGqMYaHXls5HyDv6/CL5axVQABz68eG30eCtbr2wFg==} + hasBin: true + + '@changesets/config@3.1.4': + resolution: {integrity: sha512-pf0bvD/v6WI2cRlZ6hzpjtZdSlXDXMAJ+Iz7xfFzV4ZxJ8OGGAON+1qYc99ZPrijnt4xp3VGG7eNvAOGS24V1Q==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.4': + resolution: {integrity: sha512-ZsS00x6WvmHq3sQv8oCMwL0f/z3wbXCVuSVTJwCnnmbC/iBdNJGFx1EcbMG4PC6sXRyH69liM4A2WKXzn/kRPg==} + + '@changesets/get-release-plan@4.0.16': + resolution: {integrity: sha512-2K5Om6CrMPm45rtvckfzWo7e9jOVCKLCnXia5eUPaURH7/LWzri7pK1TycdzAuAtehLkW7VPbWLCSExTHmiI6g==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.4': + resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.3': + resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==} + + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + + '@changesets/read@0.6.7': + resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==} + + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + + '@colordx/core@5.4.3': + resolution: {integrity: sha512-kIxYSfA5T8HXjav55UaaH/o/cKivF6jCCGIb8eqtcsfI46wsvlSiT8jMDyrl779qLec3c2c2oHBZo4oAhvbjrQ==} + + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + + '@ctrl/tinycolor@4.2.0': + resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==} + engines: {node: '>=14'} + + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.27.7': + resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.27.7': + resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.27.7': + resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.27.7': + resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.27.7': + resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.7': + resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.27.7': + resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.7': + resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.27.7': + resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.27.7': + resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.27.7': + resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.27.7': + resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.27.7': + resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.27.7': + resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.7': + resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.27.7': + resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.27.7': + resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.27.7': + resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.7': + resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.27.7': + resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.7': + resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.27.7': + resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.27.7': + resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.27.7': + resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.27.7': + resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.27.7': + resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@expressive-code/core@0.38.3': + resolution: {integrity: sha512-s0/OtdRpBONwcn23O8nVwDNQqpBGKscysejkeBkwlIeHRLZWgiTVrusT5Idrdz1d8cW5wRk9iGsAIQmwDPXgJg==} + + '@expressive-code/plugin-frames@0.38.3': + resolution: {integrity: sha512-qL2oC6FplmHNQfZ8ZkTR64/wKo9x0c8uP2WDftR/ydwN/yhe1ed7ZWYb8r3dezxsls+tDokCnN4zYR594jbpvg==} + + '@expressive-code/plugin-shiki@0.38.3': + resolution: {integrity: sha512-kqHnglZeesqG3UKrb6e9Fq5W36AZ05Y9tCREmSN2lw8LVTqENIeCIkLDdWtQ5VoHlKqwUEQFTVlRehdwoY7Gmw==} + + '@expressive-code/plugin-text-markers@0.38.3': + resolution: {integrity: sha512-dPK3+BVGTbTmGQGU3Fkj3jZ3OltWUAlxetMHI6limUGCWBCucZiwoZeFM/WmqQa71GyKRzhBT+iEov6kkz2xVA==} + + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + + '@floating-ui/react-dom@2.1.8': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/react@0.27.19': + resolution: {integrity: sha512-31B8h5mm8YxotlE7/AU/PhNAl8eWxAmjL/v2QOxroDNkTFLk3Uu82u63N3b6TXa4EGJeeZLVcd/9AlNlVqzeog==} + peerDependencies: + react: '>=17.0.0' + react-dom: '>=17.0.0' + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@joshwooding/vite-plugin-react-docgen-typescript@0.5.0': + resolution: {integrity: sha512-qYDdL7fPwLRI+bJNurVcis+tNgJmvWjH4YTBGXTA8xMuxFrnAz6E5o35iyzyKbq5J5Lr8mJGfrR5GXl+WGwhgQ==} + peerDependencies: + typescript: '>= 4.3.x' + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + typescript: + optional: true + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jsonjoy.com/base64@1.1.2': + resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/base64@17.67.0': + resolution: {integrity: sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@1.2.1': + resolution: {integrity: sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@17.67.0': + resolution: {integrity: sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/codegen@1.0.0': + resolution: {integrity: sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/codegen@17.67.0': + resolution: {integrity: sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-core@4.57.2': + resolution: {integrity: sha512-SVjwklkpIV5wrynpYtuYnfYH1QF4/nDuLBX7VXdb+3miglcAgBVZb/5y0cOsehRV/9Vb+3UqhkMq3/NR3ztdkQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-fsa@4.57.2': + resolution: {integrity: sha512-fhO8+iR2I+OCw668ISDJdn1aArc9zx033sWejIyzQ8RBeXa9bDSaUeA3ix0poYOfrj1KdOzytmYNv2/uLDfV6g==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-builtins@4.57.2': + resolution: {integrity: sha512-xhiegylRmhw43Ki2HO1ZBL7DQ5ja/qpRsL29VtQ2xuUHiuDGbgf2uD4p9Qd8hJI5P6RCtGYD50IXHXVq/Ocjcg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-to-fsa@4.57.2': + resolution: {integrity: sha512-18LmWTSONhoAPW+IWRuf8w/+zRolPFGPeGwMxlAhhfY11EKzX+5XHDBPAw67dBF5dxDErHJbl40U+3IXSDRXSQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-utils@4.57.2': + resolution: {integrity: sha512-rsPSJgekz43IlNbLyAM/Ab+ouYLWGp5DDBfYBNNEqDaSpsbXfthBn29Q4muFA9L0F+Z3mKo+CWlgSCXrf+mOyQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node@4.57.2': + resolution: {integrity: sha512-nX2AdL6cOFwLdju9G4/nbRnYevmCJbh7N7hvR3gGm97Cs60uEjyd0rpR+YBS7cTg175zzl22pGKXR5USaQMvKg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-print@4.57.2': + resolution: {integrity: sha512-wK9NSow48i4DbDl9F1CQE5TqnyZOJ04elU3WFG5aJ76p+YxO/ulyBBQvKsessPxdo381Bc2pcEoyPujMOhcRqQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-snapshot@4.57.2': + resolution: {integrity: sha512-GdduDZuoP5V/QCgJkx9+BZ6SC0EZ/smXAdTS7PfMqgMTGXLlt/bH/FqMYaqB9JmLf05sJPtO0XRbAwwkEEPbVw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@1.21.0': + resolution: {integrity: sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@17.67.0': + resolution: {integrity: sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pointer@1.0.2': + resolution: {integrity: sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pointer@17.67.0': + resolution: {integrity: sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@1.9.0': + resolution: {integrity: sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@17.67.0': + resolution: {integrity: sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} + + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@oslojs/encoding@1.1.0': + resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + + '@oxc-project/types@0.127.0': + resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} + + '@pagefind/darwin-arm64@1.5.2': + resolution: {integrity: sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==} + cpu: [arm64] + os: [darwin] + + '@pagefind/darwin-x64@1.5.2': + resolution: {integrity: sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==} + cpu: [x64] + os: [darwin] + + '@pagefind/default-ui@1.5.2': + resolution: {integrity: sha512-pm1LMnQg8N2B3n2TnjKlhaFihpz6zTiA4HiGQ6/slKO/+8K9CAU5kcjdSSPgpuk1PMuuN4hxLipUIifnrkl3Sg==} + + '@pagefind/freebsd-x64@1.5.2': + resolution: {integrity: sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==} + cpu: [x64] + os: [freebsd] + + '@pagefind/linux-arm64@1.5.2': + resolution: {integrity: sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==} + cpu: [arm64] + os: [linux] + + '@pagefind/linux-x64@1.5.2': + resolution: {integrity: sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==} + cpu: [x64] + os: [linux] + + '@pagefind/windows-arm64@1.5.2': + resolution: {integrity: sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==} + cpu: [arm64] + os: [win32] + + '@pagefind/windows-x64@1.5.2': + resolution: {integrity: sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==} + cpu: [x64] + os: [win32] + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context-menu@2.2.16': + resolution: {integrity: sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dropdown-menu@2.1.16': + resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-hover-card@1.1.15': + resolution: {integrity: sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-menu@2.1.16': + resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popover@1.1.15': + resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slider@1.3.6': + resolution: {integrity: sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-toggle-group@1.1.11': + resolution: {integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-toggle@1.1.10': + resolution: {integrity: sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-tooltip@1.2.8': + resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + + '@rolldown/binding-android-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-rc.17': + resolution: {integrity: sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-rc.17': + resolution: {integrity: sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': + resolution: {integrity: sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': + resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': + resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': + resolution: {integrity: sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': + resolution: {integrity: sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': + resolution: {integrity: sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + + '@rolldown/pluginutils@1.0.0-rc.17': + resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==} + + '@rolldown/pluginutils@1.0.0-rc.7': + resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} + + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.60.2': + resolution: {integrity: sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.2': + resolution: {integrity: sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.2': + resolution: {integrity: sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.2': + resolution: {integrity: sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.2': + resolution: {integrity: sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.2': + resolution: {integrity: sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': + resolution: {integrity: sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.60.2': + resolution: {integrity: sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.60.2': + resolution: {integrity: sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.60.2': + resolution: {integrity: sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.2': + resolution: {integrity: sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.60.2': + resolution: {integrity: sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.2': + resolution: {integrity: sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.60.2': + resolution: {integrity: sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.60.2': + resolution: {integrity: sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.60.2': + resolution: {integrity: sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.60.2': + resolution: {integrity: sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.60.2': + resolution: {integrity: sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.60.2': + resolution: {integrity: sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.60.2': + resolution: {integrity: sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.2': + resolution: {integrity: sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.2': + resolution: {integrity: sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.2': + resolution: {integrity: sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.2': + resolution: {integrity: sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.2': + resolution: {integrity: sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==} + cpu: [x64] + os: [win32] + + '@shikijs/core@1.29.2': + resolution: {integrity: sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ==} + + '@shikijs/core@3.23.0': + resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} + + '@shikijs/engine-javascript@1.29.2': + resolution: {integrity: sha512-iNEZv4IrLYPv64Q6k7EPpOCE/nuvGiKl7zxdq0WFuRPF5PAE9PRo2JGq/d8crLusM59BRemJ4eOqrFrC4wiQ+A==} + + '@shikijs/engine-javascript@3.23.0': + resolution: {integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==} + + '@shikijs/engine-oniguruma@1.29.2': + resolution: {integrity: sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA==} + + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} + + '@shikijs/langs@1.29.2': + resolution: {integrity: sha512-FIBA7N3LZ+223U7cJDUYd5shmciFQlYkFXlkKVaHsCPgfVLiO+e12FmQE6Tf9vuyEsFe3dIl8qGWKXgEHL9wmQ==} + + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} + + '@shikijs/themes@1.29.2': + resolution: {integrity: sha512-i9TNZlsq4uoyqSbluIcZkmPL9Bfi3djVxRnofUHwvx/h6SRW3cwgBC5SML7vsDcWyukY0eCzVN980rqP6qNl9g==} + + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} + + '@shikijs/types@1.29.2': + resolution: {integrity: sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw==} + + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@size-limit/esbuild@11.2.0': + resolution: {integrity: sha512-vSg9H0WxGQPRzDnBzeDyD9XT0Zdq0L+AI3+77/JhxznbSCMJMMr8ndaWVQRhOsixl97N0oD4pRFw2+R1Lcvi6A==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + size-limit: 11.2.0 + + '@size-limit/file@11.2.0': + resolution: {integrity: sha512-OZHE3putEkQ/fgzz3Tp/0hSmfVo3wyTpOJSRNm6AmcwX4Nm9YtTfbQQ/hZRwbBFR23S7x2Sd9EbqYzngKwbRoA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + size-limit: 11.2.0 + + '@size-limit/preset-small-lib@11.2.0': + resolution: {integrity: sha512-RFbbIVfv8/QDgTPyXzjo5NKO6CYyK5Uq5xtNLHLbw5RgSKrgo8WpiB/fNivZuNd/5Wk0s91PtaJ9ThNcnFuI3g==} + peerDependencies: + size-limit: 11.2.0 + + '@storybook/addon-a11y@8.6.18': + resolution: {integrity: sha512-LFvudttdIfDTNWprA8/N1vbiWbJRrNscyt2OP9Qwi85E1d3LKLy+e8AWiqY08gpy2OUYujK7AjxfpKtNeddrxw==} + peerDependencies: + storybook: ^8.6.18 + + '@storybook/addon-actions@8.6.14': + resolution: {integrity: sha512-mDQxylxGGCQSK7tJPkD144J8jWh9IU9ziJMHfB84PKpI/V5ZgqMDnpr2bssTrUaGDqU5e1/z8KcRF+Melhs9pQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-backgrounds@8.6.14': + resolution: {integrity: sha512-l9xS8qWe5n4tvMwth09QxH2PmJbCctEvBAc1tjjRasAfrd69f7/uFK4WhwJAstzBTNgTc8VXI4w8ZR97i1sFbg==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-controls@8.6.14': + resolution: {integrity: sha512-IiQpkNJdiRyA4Mq9mzjZlvQugL/aE7hNgVxBBGPiIZG6wb6Ht9hNnBYpap5ZXXFKV9p2qVI0FZK445ONmAa+Cw==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-docs@8.6.14': + resolution: {integrity: sha512-Obpd0OhAF99JyU5pp5ci17YmpcQtMNgqW2pTXV8jAiiipWpwO++hNDeQmLmlSXB399XjtRDOcDVkoc7rc6JzdQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-essentials@8.6.14': + resolution: {integrity: sha512-5ZZSHNaW9mXMOFkoPyc3QkoNGdJHETZydI62/OASR0lmPlJ1065TNigEo5dJddmZNn0/3bkE8eKMAzLnO5eIdA==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-highlight@8.6.14': + resolution: {integrity: sha512-4H19OJlapkofiE9tM6K/vsepf4ir9jMm9T+zw5L85blJZxhKZIbJ6FO0TCG9PDc4iPt3L6+aq5B0X29s9zicNQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-highlight@8.6.18': + resolution: {integrity: sha512-wTFJ1DPM0C8gK6nGTJxH75byayQj7BPAz02fME4AOmT6clrBpVl1zSTFTkXaSr+k4xOfeMR/xNUfVskaXz6T9w==} + peerDependencies: + storybook: ^8.6.18 + + '@storybook/addon-interactions@8.6.14': + resolution: {integrity: sha512-8VmElhm2XOjh22l/dO4UmXxNOolGhNiSpBcls2pqWSraVh4a670EyYBZsHpkXqfNHo2YgKyZN3C91+9zfH79qQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-measure@8.6.14': + resolution: {integrity: sha512-1Tlyb72NX8aAqm6I6OICsUuGOP6hgnXcuFlXucyhKomPa6j3Eu2vKu561t/f0oGtAK2nO93Z70kVaEh5X+vaGw==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-outline@8.6.14': + resolution: {integrity: sha512-CW857JvN6OxGWElqjlzJO2S69DHf+xO3WsEfT5mT3ZtIjmsvRDukdWfDU9bIYUFyA2lFvYjncBGjbK+I91XR7w==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-toolbars@8.6.14': + resolution: {integrity: sha512-W/wEXT8h3VyZTVfWK/84BAcjAxTdtRiAkT2KAN0nbSHxxB5KEM1MjKpKu2upyzzMa3EywITqbfy4dP6lpkVTwQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/addon-viewport@8.6.14': + resolution: {integrity: sha512-gNzVQbMqRC+/4uQTPI2ZrWuRHGquTMZpdgB9DrD88VTEjNudP+J6r8myLfr2VvGksBbUMHkGHMXHuIhrBEnXYA==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/blocks@8.6.14': + resolution: {integrity: sha512-rBMHAfA39AGHgkrDze4RmsnQTMw1ND5fGWobr9pDcJdnDKWQWNRD7Nrlxj0gFlN3n4D9lEZhWGdFrCbku7FVAQ==} + 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 + storybook: ^8.6.14 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/builder-vite@8.6.18': + resolution: {integrity: sha512-XLqnOv4C36jlTd4uC8xpWBxv+7GV4/05zWJ0wAcU4qflorropUTirt4UQPGkwIzi+BVAhs9pJj+m4k0IWJtpHg==} + peerDependencies: + storybook: ^8.6.18 + vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + + '@storybook/components@8.6.18': + resolution: {integrity: sha512-55yViiZzPS/cPBuOeW4QGxGqrusjXVyxuknmbYCIwDtFyyvI/CgbjXRHdxNBaIjz+IlftxvBmmSaOqFG5+/dkA==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@storybook/core@8.6.18': + resolution: {integrity: sha512-dRBP2TnX6fGdS0T2mXBHjkS/3Nlu1ra1huovZVFuM67CYMzrhM/3hX/zru1vWSC5rqY93ZaAhjMciPW4pK5mMQ==} + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + + '@storybook/csf-plugin@8.6.14': + resolution: {integrity: sha512-dErtc9teAuN+eelN8FojzFE635xlq9cNGGGEu0WEmMUQ4iJ8pingvBO1N8X3scz4Ry7KnxX++NNf3J3gpxS8qQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/csf-plugin@8.6.18': + resolution: {integrity: sha512-x1ioz/L0CwaelCkHci3P31YtvwayN3FBftvwQOPbvRh9qeb4Cpz5IdVDmyvSxxYwXN66uAORNoqgjTi7B4/y5Q==} + peerDependencies: + storybook: ^8.6.18 + + '@storybook/global@5.0.0': + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + + '@storybook/icons@1.6.0': + resolution: {integrity: sha512-hcFZIjW8yQz8O8//2WTIXylm5Xsgc+lW9ISLgUk1xGmptIJQRdlhVIXCpSyLrQaaRiyhQRaVg7l3BD9S216BHw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + + '@storybook/instrumenter@8.6.14': + resolution: {integrity: sha512-iG4MlWCcz1L7Yu8AwgsnfVAmMbvyRSk700Mfy2g4c8y5O+Cv1ejshE1LBBsCwHgkuqU0H4R0qu4g23+6UnUemQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/instrumenter@8.6.15': + resolution: {integrity: sha512-TvHR/+yyIAOp/1bLulFai2kkhIBtAlBw7J6Jd9DKyInoGhTWNE1G1Y61jD5GWXX29AlwaHfzGUaX5NL1K+FJpg==} + peerDependencies: + storybook: ^8.6.15 + + '@storybook/instrumenter@8.6.18': + resolution: {integrity: sha512-viEC1BGlYyjAzi1Tv3LZjByh7Y3Oh04u6QKsujxdeUbr5rUOH4pa/wCKmxXmY6yWrD4WjcNtojmUvQZN/66FXQ==} + peerDependencies: + storybook: ^8.6.18 + + '@storybook/manager-api@8.6.18': + resolution: {integrity: sha512-BjIp12gEMgzFkEsgKpDIbZdnSWTZpm2dlws8WiPJCpgJtG+HWSxZ0/Ms30Au9yfwzQEKRSbV/5zpsKMGc2SIJw==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@storybook/preview-api@8.6.18': + resolution: {integrity: sha512-joXRXh3GdVvzhbfIgmix1xs90p8Q/nja7AhEAC2egn5Pl7SKsIYZUCYI6UdrQANb2myg9P552LKXfPect8llKg==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@storybook/react-dom-shim@8.6.14': + resolution: {integrity: sha512-0hixr3dOy3f3M+HBofp3jtMQMS+sqzjKNgl7Arfuj3fvjmyXOks/yGjDImySR4imPtEllvPZfhiQNlejheaInw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.6.14 + + '@storybook/react-dom-shim@8.6.18': + resolution: {integrity: sha512-N4xULcAWZQTUv4jy1/d346Tyb4gufuC3UaLCuU/iVSZ1brYF4OW3ANr+096btbMxY8pR/65lmtoqr5CTGwnBvA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.6.18 + + '@storybook/react-vite@8.6.18': + resolution: {integrity: sha512-qpSYyH2IizlEsI95MJTdIL6xpLSgiNCMoJpHu+IEqLnyvmecRR/YEZvcHalgdtawuXlimH0bAYuwIu3l8Vo6FQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@storybook/test': 8.6.18 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.6.18 + vite: ^4.0.0 || ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + '@storybook/test': + optional: true + + '@storybook/react@8.6.18': + resolution: {integrity: sha512-BuLpzMkKtF+UCQCbi+lYVX9cdcAMG86Lu2dDn7UFkPi5HRNFq/zHPSvlz1XDgL0OYMtcqB1aoVzFzcyzUBhhjw==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@storybook/test': 8.6.18 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.6.18 + typescript: '>= 4.2.x' + peerDependenciesMeta: + '@storybook/test': + optional: true + typescript: + optional: true + + '@storybook/test@8.6.14': + resolution: {integrity: sha512-GkPNBbbZmz+XRdrhMtkxPotCLOQ1BaGNp/gFZYdGDk2KmUWBKmvc5JxxOhtoXM2703IzNFlQHSSNnhrDZYuLlw==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/test@8.6.15': + resolution: {integrity: sha512-EwquDRUDVvWcZds3T2abmB5wSN/Vattal4YtZ6fpBlIUqONV4o/cOBX39cFfQSUCBrIXIjQ6RmapQCHK/PvBYw==} + peerDependencies: + storybook: ^8.6.15 + + '@storybook/test@8.6.18': + resolution: {integrity: sha512-u/RwfWMyHcH0N2hqfMTw2CoZ58IXdeED3b8NmcHc8bmERB3byI5vVAkwYbcD7+WeRHIiym38ZHi0SRn+IpkO3Q==} + peerDependencies: + storybook: ^8.6.18 + + '@storybook/theming@8.6.18': + resolution: {integrity: sha512-n6OEjEtHupa2PdTwWzRepr7cO8NkDd4rgF6BKLitRbujOspLxzMBEqdphs+QLcuiCIgf33SqmEA64QWnbSMhPw==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.5.0': + resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react@16.3.2': + resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@testing-library/user-event@14.5.2': + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/doctrine@0.0.9': + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/nlcst@2.0.3': + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@24.12.2': + resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@types/resolve@1.20.6': + resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} + + '@types/sax@1.2.7': + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/uuid@9.0.8': + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@vitejs/plugin-react@4.7.0': + resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + + '@vitejs/plugin-react@6.0.1': + resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + + '@vitest/expect@2.0.5': + resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} + + '@vitest/expect@2.1.9': + resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + + '@vitest/mocker@2.1.9': + resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.0.5': + resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/runner@2.1.9': + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + + '@vitest/snapshot@2.1.9': + resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + + '@vitest/spy@2.0.5': + resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} + + '@vitest/spy@2.1.9': + resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + + '@vitest/utils@2.0.5': + resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} + + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + + '@zip.js/zip.js@2.8.26': + resolution: {integrity: sha512-RQ4h9F6DOiHxpdocUDrOl6xBM+yOtz+LkUol47AVWcfebGBDpZ7w7Xvz9PS24JgXvLGiXXzSAfdCdVy1tPlaFA==} + engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=18.0.0'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-iterate@2.0.1: + resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + assert@2.1.0: + resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + astro-expressive-code@0.38.3: + resolution: {integrity: sha512-Tvdc7RV0G92BbtyEOsfJtXU35w41CkM94fOAzxbQP67Wj5jArfserJ321FO4XA7WG9QMV0GIBmQq77NBIRDzpQ==} + peerDependencies: + astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 + + astro@5.18.1: + resolution: {integrity: sha512-m4VWilWZ+Xt6NPoYzC4CgGZim/zQUO7WFL0RHCH0AiEavF1153iC3+me2atDvXpf/yX4PyGUeD8wZLq1cirT3g==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + autoprefixer@10.5.0: + resolution: {integrity: sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.11.4: + resolution: {integrity: sha512-KunSNx+TVpkAw/6ULfhnx+HWRecjqZGTOyquAoWHYLRSdK1tB5Ihce1ZW+UY3fj33bYAFWPu7W/GRSmmrCGuxA==} + engines: {node: '>=4'} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base-64@1.0.0: + resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.10.27: + resolution: {integrity: sha512-zEs/ufmZoUd7WftKpKyXaT6RFxpQ5Qm9xytKRHvJfxFV9DFJkZph9RvJ1LcOUi0Z1ZVijMte65JbILeV+8QQEA==} + engines: {node: '>=6.0.0'} + hasBin: true + + bcp-47-match@2.0.3: + resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} + + bcp-47@2.1.0: + resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==} + + better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boxen@8.0.1: + resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} + engines: {node: '>=18'} + + brace-expansion@2.1.0: + resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browser-assert@1.2.1: + resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + bytes-iec@3.1.1: + resolution: {integrity: sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA==} + engines: {node: '>= 0.8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} + + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + + caniuse-lite@1.0.30001791: + resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} + + chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} + engines: {node: '>= 16'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + common-ancestor-path@1.0.1: + resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} + + component-emitter@2.0.0: + resolution: {integrity: sha512-4m5s3Me2xxlVKG9PkZpQqHQR7bgpnN7joDMJ4yvVkVXngjoITG76IaZmzmywSeRTeTpc6N6r3H3+KyUurV8OYw==} + engines: {node: '>=18'} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + css-declaration-sorter@7.4.0: + resolution: {integrity: sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-selector-parser@3.3.0: + resolution: {integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-default@7.0.16: + resolution: {integrity: sha512-W0hiFi/ca/u2OTptL11OdApaz1vh9jyfd2ku9dMjou6KdpdgbMTagaXHKNl5kaEyRSCu9GIIaPRp5YLdqRAZMw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + cssnano-utils@5.0.3: + resolution: {integrity: sha512-ynIREMICLxkxm7e9bCR9sh75s4Q5drICi0ua1yxo5jH2XPBqSKkl4dOh4EbFqtUmnTMhRffHgYL0EKKkMjtJTg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + cssnano@7.1.8: + resolution: {integrity: sha512-OGXtXqXmwEoIGfXM2QoD35vweUAtx+J8ZvLSZHOEV0Jv9Hs9ScTdGGjRzZXun5J4PEZhEoytKig2O2NR8NXxKw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + cssstyle@4.6.0: + resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} + engines: {node: '>=18'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dependency-graph@1.0.0: + resolution: {integrity: sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==} + engines: {node: '>=4'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + deterministic-object-hash@2.0.2: + resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} + engines: {node: '>=18'} + + devalue@5.8.0: + resolution: {integrity: sha512-2zA9pFEsnp7vWBZbXF5JAgAq0fsUIt/1XPbRiAmRV3lp/2C3upzH+sADiyy66aFCihoLEsrQHxNM5w1gIDfsBg==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + direction@2.0.1: + resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} + hasBin: true + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dset@3.1.4: + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} + engines: {node: '>=4'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + electron-to-chromium@1.5.349: + resolution: {integrity: sha512-QsWVGyRuY07Aqb234QytTfwd5d9AJlfNIQ5wIOl1L+PZDzI9d9+Fn0FRale/QYlFxt/bUnB0/nLd1jFPGxGK1A==} + + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + esbuild-register@3.6.0: + resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} + peerDependencies: + esbuild: '>=0.12 <1' + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.27.7: + resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + expressive-code@0.38.3: + resolution: {integrity: sha512-COM04AiUotHCKJgWdn7NtW2lqu8OW8owAidMpkXt1qxrZ9Q2iC7+tok/1qIn2ocGnczvr9paIySgGnEwFeEQ8Q==} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-yarn-workspace-root@2.0.0: + resolution: {integrity: sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==} + + fix-dts-default-cjs-exports@1.0.1: + resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + + flattie@1.1.1: + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} + engines: {node: '>=8'} + + fontace@0.4.1: + resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==} + + fontkitten@1.0.3: + resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} + engines: {node: '>=20'} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@11.3.4: + resolution: {integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==} + engines: {node: '>=14.14'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-to-regex.js@1.2.0: + resolution: {integrity: sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + engines: {node: '>= 0.4'} + + hast-util-embedded@3.0.0: + resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} + + hast-util-format@1.1.0: + resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} + + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + + hast-util-is-body-ok-link@3.0.1: + resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-minify-whitespace@1.0.1: + resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-phrasing@3.0.1: + resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-select@6.0.4: + resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + html-whitespace-sensitive-tag-names@3.0.1: + resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + human-id@4.1.3: + resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} + hasBin: true + + hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} + + i18next@23.16.8: + resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsdoc-type-pratt-parser@4.8.0: + resolution: {integrity: sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==} + engines: {node: '>=12.0.0'} + + jsdom@25.0.1: + resolution: {integrity: sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==} + engines: {node: '>=18'} + peerDependencies: + canvas: ^2.11.2 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-stable-stringify@1.3.0: + resolution: {integrity: sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==} + engines: {node: '>= 0.4'} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.2.1: + resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} + + jsonify@0.0.1: + resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} + + klaw-sync@6.0.0: + resolution: {integrity: sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@11.3.5: + resolution: {integrity: sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==} + engines: {node: 20 || >=22} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + magicast@0.5.2: + resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} + + map-or-similar@1.5.0: + resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-definitions@6.0.0: + resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} + + mdast-util-directive@3.1.0: + resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + memfs@4.57.2: + resolution: {integrity: sha512-2nWzSsJzrukurSDna4Z0WywuScK4Id3tSKejgu74u8KCdW4uNrseKRSIDg75C6Yw5ZRqBe0F0EtMNlTbUq8bAQ==} + peerDependencies: + tslib: '2' + + memoizerific@1.11.3: + resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@3.0.2: + resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.1.11: + resolution: {integrity: sha512-v+KEsUv2ps74PaSKv0gHTxTCgMXOIfBEbaqa6w6ISIGC7ZsvHN4N9oJ8d4cmf0n5oTzQz2SLmThbQWhjd/8eKg==} + engines: {node: ^18 || >=20} + hasBin: true + + nanospinner@1.2.2: + resolution: {integrity: sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==} + + neotraverse@0.6.18: + resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} + engines: {node: '>= 10'} + + nlcst-to-string@4.0.0: + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + + node-releases@2.0.38: + resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nwsapi@2.2.23: + resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + oniguruma-parser@0.12.2: + resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} + + oniguruma-to-es@2.3.0: + resolution: {integrity: sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g==} + + oniguruma-to-es@4.3.6: + resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + + open@7.4.2: + resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} + engines: {node: '>=8'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@6.2.0: + resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} + engines: {node: '>=18'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-queue@8.1.1: + resolution: {integrity: sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==} + engines: {node: '>=18'} + + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + package-manager-detector@0.2.11: + resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} + + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + + pagefind@1.5.2: + resolution: {integrity: sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==} + hasBin: true + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-latin@7.0.0: + resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + patch-package@8.0.1: + resolution: {integrity: sha512-VsKRIA8f5uqHQ7NGhwIna6Bx6D9s/1iXlA1hthBVBEbkq+t4kXD0HHt+rJhf/Z+Ci0F/HCB2hvn0qLdLG+Qxlw==} + engines: {node: '>=14', npm: '>5'} + hasBin: true + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + path-unified@0.2.0: + resolution: {integrity: sha512-MNKqvrKbbbb5p7XHXV6ZAsf/1f/yJQa13S/fcX0uua8ew58Tgc6jXV+16JyAbnR/clgCH+euKDxrF2STxMHdrg==} + + path@0.12.7: + resolution: {integrity: sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + + piccolore@0.1.3: + resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + polished@4.3.1: + resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} + engines: {node: '>=10'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-calc@10.1.1: + resolution: {integrity: sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==} + engines: {node: ^18.12 || ^20.9 || >=22.0} + peerDependencies: + postcss: ^8.4.38 + + postcss-cli@11.0.1: + resolution: {integrity: sha512-0UnkNPSayHKRe/tc2YGW6XnSqqOA9eqpiRMgRlV1S6HdGi16vwJBx7lviARzbV1HpQHqLLRH3o8vTcB0cLc+5g==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + postcss: ^8.0.0 + + postcss-colormin@7.0.10: + resolution: {integrity: sha512-yFr6JezOolHLta/buLE71VKPh2mXursp4saVe98/ol8ZnEWhL+racShqPKlvd/DKWLre/39B6HhcMXf7RZ3hxg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-convert-values@7.0.12: + resolution: {integrity: sha512-xurKu5qqk4viR3Cp3p4xBR4KfnZm4w4ys6+UBwBmeuBSNkH7+DtLnYOYnOffgtE4yx8sH9S1VZ6RAAvROXzP2Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-discard-comments@7.0.8: + resolution: {integrity: sha512-CvvS5S9WrXblFXCEJ9nVo+4z+eA7zSC7Z88V1HEJuwlQhlFnYTIjg1xJY+BCUiG2bvICap2tXii4mP22BD108Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-discard-duplicates@7.0.4: + resolution: {integrity: sha512-VBNn1+EuMZkeGVVtz0gRfbNGtx9IFgAsAV+E2pHtXPrp4qfGBkhTIiAuE/wrb+Y6Pakg9NewAlfTpYIFAWODtw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-discard-empty@7.0.3: + resolution: {integrity: sha512-M2pyjQCU+/7cMHVtL6bKTHjv0lZnPLMpicgr67Dlth7AbuV9gjVTtUqaRwn6Pp6BwSDspUzhz8SaUrRykJU5Dw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-discard-overridden@7.0.3: + resolution: {integrity: sha512-aNovXo9UsZuRNLzHJtp13lHIvinDPfiXBPePpXkSjCbgp++iU2FqE+YxvjIsg6EdyPZsASFbfu+JcBFVsErXIQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-import@16.1.1: + resolution: {integrity: sha512-2xVS1NCZAfjtVdvXiyegxzJ447GyqCeEI5V7ApgQVOWnros1p5lGNovJNapwPpMombyFBfqDwt7AD3n2l0KOfQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-load-config@5.1.0: + resolution: {integrity: sha512-G5AJ+IX0aD0dygOE0yFZQ/huFFMSNneyfp0e3/bT05a8OfPC5FUoZRPfGijUdGOJNMewJiwzcHJXFafFzeKFVA==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-merge-longhand@7.0.7: + resolution: {integrity: sha512-b3mfYUxR388u5Pt0HPcVIUtUDn/k15UfTY9M+ORW+meCR6JLNxoZffiYvXyOYQoRYQNZyX/UFkMCM/mNHxe1qA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-merge-rules@7.0.11: + resolution: {integrity: sha512-SJUPM18g2BmPhf8BVlbwqWz4aK3pLu6u6xjfwEzra7xL6IBR10sUaiB++EzqcVfadPHrKBSMlNdP+XieykhI+Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-minify-font-values@7.0.3: + resolution: {integrity: sha512-yilG/VOaNI74IylQvAQQxm3/wZVBkXyYUqNUAdxqwtbWUXPsbK1q8Ms0mL83v+f8YicgcyfYCRZtWACUdYajpA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-minify-gradients@7.0.5: + resolution: {integrity: sha512-YraROyQRg3BI1+Hg8E05B/JPdnTm8EDSVu4P2BxdM+CRiOyfmou809+chGIqo6fQqwjPGQ947nbGncSjmTU1WQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-minify-params@7.0.9: + resolution: {integrity: sha512-R8itbB8BhlpoYyBm1ou0dD+vJnQ3F6adQipR4UnkCHUwlo+S9WXJaDRg1RHjC8YVAtIdrQzSWvJl40HnGDTKjA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-minify-selectors@7.1.1: + resolution: {integrity: sha512-MZWXwSTfcpmNVJIs7tddar/275a4/zT5nG9/gEndHPRZGTAQNpiSkk8s/dq+yZVX2jKfvVn1d5X8Z5SJHWnDoQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-normalize-charset@7.0.3: + resolution: {integrity: sha512-NoBfZu8PR4c2NlmjvrqQTzCzLY79hwcSRgNQ3ZiNK0ABzf9kYKloE/jNj+/8GQY1wsm8pRRgANk6ydLH8cwo0Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-normalize-display-values@7.0.3: + resolution: {integrity: sha512-ldsCX0QIt05pKIOobZtVQ48wXJecr+czw4+e1/YjVhLMqslShgpVxgPtI2CefURR8oyVoYaU/l829MMwExDMLw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-normalize-positions@7.0.4: + resolution: {integrity: sha512-VEvlpeGd3Ju1Hqa/oN4jaP3+ms4laYwkEL9N9u+B6k54PZjXbW1n6wI+aVprf1BQXlCYpS5+1pl/7/vHiKgARg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-normalize-repeat-style@7.0.4: + resolution: {integrity: sha512-6mPKlY/8cSaDHxX502wERADarJsccwlky6yIrOapHH2ZgfoKAV94SbiTKfKEs4EEpdazuc3J72WsqeYk7hp9+Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-normalize-string@7.0.3: + resolution: {integrity: sha512-HnEQPUchi1eznmDKEYrKUTqrprEq97SrpUYClgUkv7V2zRODD9DFoUsYU+m9ZOetmD5ku7fEMZB/lwy8IT6xVQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-normalize-timing-functions@7.0.3: + resolution: {integrity: sha512-zmEzHdvpZBZu0OKlbJSfgASQvaayyAoVuWtvyr34IJ/LyS+DaOKvvR3EvFJ9RWWtNIx+CMvO125OVophaxNYew==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-normalize-unicode@7.0.9: + resolution: {integrity: sha512-DRAdWfeh/TjmhLJsw91vdiWCnUod9iwvM7xyS02/nF/sLsCR3A8l3pztrSUrWG8DSBqfX7yEk9FM0USaVJ2mSg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-normalize-url@7.0.3: + resolution: {integrity: sha512-CL93wmloq5qsffmFv+bw24MIRbmhHrp53qoh1LDAb/5TtjWEXI/np4xcP/Gw9oWCb2XyWnqHYLDUwiKRoJBA1Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-normalize-whitespace@7.0.3: + resolution: {integrity: sha512-FdHjjn+Ht5Z2ZRjNOmeCbNq6lq09sUYKpmlF/Aq0XjVNSLTL6fmHlA/3swN2wP2caY9GV/tjSDcIIyS7aN7W0A==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-ordered-values@7.0.4: + resolution: {integrity: sha512-nubSi49hDHQk4E8KIj+IbLY8Bg+8OcSUEhgyolgM+atnOvXjV7EjaR6bac4YGZoFyPa9mWoAF3EaYbWdFkKqVg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-reduce-initial@7.0.9: + resolution: {integrity: sha512-ztTNPdIxXTxtBcG03E9u8v44M4ElXbMIRT7pf2onlquGula0Y83nKKxqM22FA/hMgkfCjN7ohevkVlaNwI8iOQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-reduce-transforms@7.0.3: + resolution: {integrity: sha512-FXsnN9ZwcZTT8Yf8cAHA8qIGUXcX6WfLd9JoYhrdDfmvsVhhfqkkv7m4AC3rwFOfz+GzkUa87OCKF9dUcicd+g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-reporter@7.1.0: + resolution: {integrity: sha512-/eoEylGWyy6/DOiMP5lmFRdmDKThqgn7D6hP2dXKJI/0rJSO1ADFNngZfDzxL0YAxFvws+Rtpuji1YIHj4mySA==} + engines: {node: '>=10'} + peerDependencies: + postcss: ^8.1.0 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss-svgo@7.1.3: + resolution: {integrity: sha512-2QfoFOYMcj8lwcVEf9WeTlkVIAm7u2QvOEhMzkQU3KUhhGX/l8hVV9EtjMv4iq3E9iI3OeeMN0YoMLbGusuigw==} + engines: {node: ^18.12.0 || ^20.9.0 || >= 18} + peerDependencies: + postcss: ^8.5.13 + + postcss-unique-selectors@7.0.7: + resolution: {integrity: sha512-d+sCkaRnSefghOUdH8CMJZV9yUQhj2ojpe8Nw/lA+LV1UOfeleGkLTl6XdCFFSai9UJ+DJPb69FFuqthXYsY8w==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.13: + resolution: {integrity: sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==} + engines: {node: ^10 || ^12 || >=14} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@3.8.3: + resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + pretty-hrtime@1.0.3: + resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} + engines: {node: '>= 0.8'} + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} + engines: {node: '>=0.6'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + react-docgen-typescript@2.4.0: + resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} + peerDependencies: + typescript: '>= 4.3.x' + + react-docgen@7.1.1: + resolution: {integrity: sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg==} + engines: {node: '>=16.14.0'} + + react-dom@19.2.5: + resolution: {integrity: sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==} + peerDependencies: + react: ^19.2.5 + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} + engines: {node: '>=0.10.0'} + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react@19.2.5: + resolution: {integrity: sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==} + engines: {node: '>=0.10.0'} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + regex-recursion@5.1.1: + resolution: {integrity: sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@5.1.1: + resolution: {integrity: sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + rehype-expressive-code@0.38.3: + resolution: {integrity: sha512-RYSSDkMBikoTbycZPkcWp6ELneANT4eTpND1DSRJ6nI2eVFUwTBDCvE2vO6jOOTaavwnPiydi4i/87NRyjpdOA==} + + rehype-format@5.0.1: + resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} + + rehype-parse@9.0.1: + resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + rehype-stringify@10.0.1: + resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} + + rehype@13.0.2: + resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} + + remark-directive@3.0.1: + resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-smartypants@3.0.2: + resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} + engines: {node: '>=16.0.0'} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remixicon@4.9.1: + resolution: {integrity: sha512-36gLSoujkabnCFZFDyP17VNh9piuBA/rsXUb4auSJWLGsHVXtmxLj/EM5FjaEAGnk8oIAj1Azob/DZ2N+90lAQ==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + + retext-latin@4.0.0: + resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + + retext-smartypants@6.2.0: + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + + retext-stringify@4.0.0: + resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + + retext@9.0.0: + resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rolldown@1.0.0-rc.17: + resolution: {integrity: sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rollup@4.60.2: + resolution: {integrity: sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rrweb-cssom@0.7.1: + resolution: {integrity: sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==} + + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shiki@1.29.2: + resolution: {integrity: sha512-njXuliz/cP+67jU2hukkxCNuH1yUi4QfdZZY+sMr5PPrIyXSu5iTb/qYC4BiWWB0vZ+7TbdvYUCeL23zpwCfbg==} + + shiki@3.23.0: + resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + sitemap@9.0.1: + resolution: {integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==} + engines: {node: '>=20.19.5', npm: '>=10.8.2'} + hasBin: true + + size-limit@11.2.0: + resolution: {integrity: sha512-2kpQq2DD/pRpx3Tal/qRW1SYwcIeQ0iq8li5CJHQgOC+FtPn2BVmuDtzUCgNnpCrbgtfEHqh+iWzxK+Tq6C+RQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + slash@2.0.0: + resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} + engines: {node: '>=6'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + smol-toml@1.6.1: + resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} + engines: {node: '>= 18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + storybook@8.6.18: + resolution: {integrity: sha512-p8seiSI6FiVY6P3V0pG+5v7c8pDMehMAFRWEhG5XqIBSQszzOjDnW2rNvm3odoLKfo3V3P6Cs6Hv9ILzymULyQ==} + hasBin: true + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + + stream-replace-string@2.0.0: + resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} + + stream@0.0.3: + resolution: {integrity: sha512-aMsbn7VKrl4A2T7QAQQbzgN7NVc70vgF5INQrBXqn4dCXN1zy3L9HGgLO5s7PExmdrzTJ8uR/27aviW8or8/+A==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-indent@4.1.1: + resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} + engines: {node: '>=12'} + + style-dictionary@4.4.0: + resolution: {integrity: sha512-+xU0IA1StzqAqFs/QtXkK+XJa7wpS4X5H+JQccRKsRCElgeLGocFU1U/UMvMUylKFw6vwGV+Y/a2wb2pm5rFFQ==} + engines: {node: '>=18.0.0'} + hasBin: true + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + stylehacks@7.0.11: + resolution: {integrity: sha512-iODNfhXVLqc5LADs+Y6Oh5wJuK5ZcHbVng8aiK3y9pjMQdc5hLrBW0eFU6FtnpNrE6PoEg/MmFTU4waotj5WNg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.5.13 + + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svgo@4.0.1: + resolution: {integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==} + engines: {node: '>=16'} + hasBin: true + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + tabbable@6.4.0: + resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + thenby@1.4.1: + resolution: {integrity: sha512-D5a/bO0KdalOE3q8MlrRmSxjbKZHT3MQmXkJP+r97Vw8MMwOZKOwUSEyTtK7eSMj2y0kyAjpYMRMZmmLw1FtNQ==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + thingies@2.6.0: + resolution: {integrity: sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinycolor2@1.6.0: + resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyexec@1.1.2: + resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} + engines: {node: '>=18'} + + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + + tldts@6.1.86: + resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + hasBin: true + + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} + engines: {node: '>=16'} + + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + engines: {node: '>=18'} + + tree-dump@1.1.0: + resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsup@8.5.1: + resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + ultrahtml@1.6.0: + resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unifont@0.7.4: + resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-modify-children@4.0.0: + resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-children@3.0.0: + resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unplugin@1.16.1: + resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} + engines: {node: '>=14.0.0'} + + unstorage@1.17.5: + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + url@0.11.4: + resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} + engines: {node: '>= 0.4'} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.10.4: + resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). + hasBin: true + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite-node@2.1.9: + resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vite@6.4.2: + resolution: {integrity: sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vite@8.0.10: + resolution: {integrity: sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitefu@1.1.3: + resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + vite: + optional: true + + vitest-axe@0.1.0: + resolution: {integrity: sha512-jvtXxeQPg8R/2ANTY8QicA5pvvdRP4F0FsVUAHANJ46YCDASie/cuhlSzu0DGcLmZvGBSBNsNuK3HqfaeknyvA==} + peerDependencies: + vitest: '>=0.16.0' + + vitest@2.1.9: + resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.9 + '@vitest/ui': 2.1.9 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} + engines: {node: '>=18'} + + which-pm-runs@1.1.0: + resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} + engines: {node: '>=4'} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + widest-line@5.0.0: + resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} + engines: {node: '>=18'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + xxhash-wasm@1.1.0: + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yaml@2.8.4: + resolution: {integrity: sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + yocto-spinner@0.2.3: + resolution: {integrity: sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==} + engines: {node: '>=18.19'} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + + zod-to-ts@1.2.0: + resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==} + peerDependencies: + typescript: ^4.9.4 || ^5.0.2 + zod: ^3 + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@adobe/css-tools@4.4.4': {} + + '@asamuzakjp/css-color@3.2.0': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 10.4.3 + + '@astrojs/compiler@2.13.1': {} + + '@astrojs/internal-helpers@0.7.6': {} + + '@astrojs/markdown-remark@6.3.11': + dependencies: + '@astrojs/internal-helpers': 0.7.6 + '@astrojs/prism': 3.3.0 + github-slugger: 2.0.0 + hast-util-from-html: 2.0.3 + hast-util-to-text: 4.0.2 + import-meta-resolve: 4.2.0 + js-yaml: 4.1.1 + mdast-util-definitions: 6.0.0 + rehype-raw: 7.0.0 + rehype-stringify: 10.0.1 + remark-gfm: 4.0.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remark-smartypants: 3.0.2 + shiki: 3.23.0 + smol-toml: 1.6.1 + unified: 11.0.5 + unist-util-remove-position: 5.0.0 + unist-util-visit: 5.1.0 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/mdx@4.3.14(astro@5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4))': + dependencies: + '@astrojs/markdown-remark': 6.3.11 + '@mdx-js/mdx': 3.1.1 + acorn: 8.16.0 + astro: 5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4) + es-module-lexer: 1.7.0 + estree-util-visit: 2.0.0 + hast-util-to-html: 9.0.5 + piccolore: 0.1.3 + rehype-raw: 7.0.0 + remark-gfm: 4.0.1 + remark-smartypants: 3.0.2 + source-map: 0.7.6 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/prism@3.3.0': + dependencies: + prismjs: 1.30.0 + + '@astrojs/sitemap@3.7.2': + dependencies: + sitemap: 9.0.1 + stream-replace-string: 2.0.0 + zod: 4.4.3 + + '@astrojs/starlight@0.30.6(astro@5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4))': + dependencies: + '@astrojs/mdx': 4.3.14(astro@5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4)) + '@astrojs/sitemap': 3.7.2 + '@pagefind/default-ui': 1.5.2 + '@types/hast': 3.0.4 + '@types/js-yaml': 4.0.9 + '@types/mdast': 4.0.4 + astro: 5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4) + astro-expressive-code: 0.38.3(astro@5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4)) + bcp-47: 2.1.0 + hast-util-from-html: 2.0.3 + hast-util-select: 6.0.4 + hast-util-to-string: 3.0.1 + hastscript: 9.0.1 + i18next: 23.16.8 + js-yaml: 4.1.1 + mdast-util-directive: 3.1.0 + mdast-util-to-markdown: 2.1.2 + mdast-util-to-string: 4.0.0 + pagefind: 1.5.2 + rehype: 13.0.2 + rehype-format: 5.0.1 + remark-directive: 3.0.1 + unified: 11.0.5 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@astrojs/telemetry@3.3.0': + dependencies: + ci-info: 4.4.0 + debug: 4.4.3 + dlv: 1.1.3 + dset: 3.1.4 + is-docker: 3.0.0 + is-wsl: 3.1.1 + which-pm-runs: 1.1.0 + transitivePeerDependencies: + - supports-color + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.3': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.3 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.3 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/runtime@7.29.2': {} + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.3 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@bundled-es-modules/deepmerge@4.3.1': + dependencies: + deepmerge: 4.3.1 + + '@bundled-es-modules/glob@10.4.2': + dependencies: + buffer: 6.0.3 + events: 3.3.0 + glob: 10.5.0 + patch-package: 8.0.1 + path: 0.12.7 + stream: 0.0.3 + string_decoder: 1.3.0 + url: 0.11.4 + + '@bundled-es-modules/memfs@4.17.0(tslib@2.8.1)': + dependencies: + assert: 2.1.0 + buffer: 6.0.3 + events: 3.3.0 + memfs: 4.57.2(tslib@2.8.1) + path: 0.12.7 + stream: 0.0.3 + util: 0.12.5 + transitivePeerDependencies: + - tslib + + '@capsizecss/unpack@4.0.0': + dependencies: + fontkitten: 1.0.3 + + '@changesets/apply-release-plan@7.1.1': + dependencies: + '@changesets/config': 3.1.4 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.4 + + '@changesets/assemble-release-plan@6.0.10': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.4 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/cli@2.31.0(@types/node@24.12.2)': + dependencies: + '@changesets/apply-release-plan': 7.1.1 + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.4 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/get-release-plan': 4.0.16 + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@inquirer/external-editor': 1.0.3(@types/node@24.12.2) + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + enquirer: 2.4.1 + fs-extra: 7.0.1 + mri: 1.2.0 + package-manager-detector: 0.2.11 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.7.4 + spawndamnit: 3.0.1 + term-size: 2.2.1 + transitivePeerDependencies: + - '@types/node' + + '@changesets/config@3.1.4': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.4 + '@changesets/logger': 0.1.1 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.4': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.7.4 + + '@changesets/get-release-plan@4.0.16': + dependencies: + '@changesets/assemble-release-plan': 6.0.10 + '@changesets/config': 3.1.4 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.7 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.3': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 4.1.1 + + '@changesets/pre@2.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.7': + dependencies: + '@changesets/git': 3.0.4 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.3 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.1.0': {} + + '@changesets/write@0.4.0': + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.1.3 + prettier: 2.8.8 + + '@colordx/core@5.4.3': {} + + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + + '@ctrl/tinycolor@4.2.0': {} + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/aix-ppc64@0.27.7': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.27.7': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-arm@0.27.7': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/android-x64@0.27.7': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.27.7': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.27.7': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.27.7': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.27.7': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.27.7': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-arm@0.27.7': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.27.7': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.27.7': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.27.7': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.27.7': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.27.7': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.27.7': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/linux-x64@0.27.7': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.27.7': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.27.7': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.27.7': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.27.7': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.27.7': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.27.7': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.27.7': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.27.7': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@esbuild/win32-x64@0.27.7': + optional: true + + '@expressive-code/core@0.38.3': + dependencies: + '@ctrl/tinycolor': 4.2.0 + hast-util-select: 6.0.4 + hast-util-to-html: 9.0.5 + hast-util-to-text: 4.0.2 + hastscript: 9.0.1 + postcss: 8.5.13 + postcss-nested: 6.2.0(postcss@8.5.13) + unist-util-visit: 5.1.0 + unist-util-visit-parents: 6.0.2 + + '@expressive-code/plugin-frames@0.38.3': + dependencies: + '@expressive-code/core': 0.38.3 + + '@expressive-code/plugin-shiki@0.38.3': + dependencies: + '@expressive-code/core': 0.38.3 + shiki: 1.29.2 + + '@expressive-code/plugin-text-markers@0.38.3': + dependencies: + '@expressive-code/core': 0.38.3 + + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 + + '@floating-ui/dom@1.7.6': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + + '@floating-ui/react-dom@2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@floating-ui/dom': 1.7.6 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + + '@floating-ui/react@0.27.19(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@floating-ui/utils': 0.2.11 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + tabbable: 6.4.0 + + '@floating-ui/utils@0.2.11': {} + + '@img/colour@1.1.0': + optional: true + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.10.0 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.10.0 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@inquirer/external-editor@1.0.3(@types/node@24.12.2)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 24.12.2 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@joshwooding/vite-plugin-react-docgen-typescript@0.5.0(typescript@5.7.3)(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0))': + dependencies: + glob: 10.5.0 + magic-string: 0.27.0 + react-docgen-typescript: 2.4.0(typescript@5.7.3) + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0) + optionalDependencies: + typescript: 5.7.3 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/base64@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@1.2.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@1.0.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-core@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-fsa@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-builtins@4.57.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-to-fsa@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-fsa': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-utils@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-print@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-snapshot@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@1.21.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@1.0.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@1.9.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.29.2 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.29.2 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@mdx-js/mdx@3.1.1': + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.16.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.16.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 19.2.14 + react: 19.2.5 + + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@oslojs/encoding@1.1.0': {} + + '@oxc-project/types@0.127.0': {} + + '@pagefind/darwin-arm64@1.5.2': + optional: true + + '@pagefind/darwin-x64@1.5.2': + optional: true + + '@pagefind/default-ui@1.5.2': {} + + '@pagefind/freebsd-x64@1.5.2': + optional: true + + '@pagefind/linux-arm64@1.5.2': + optional: true + + '@pagefind/linux-x64@1.5.2': + optional: true + + '@pagefind/windows-arm64@1.5.2': + optional: true + + '@pagefind/windows-x64@1.5.2': + optional: true + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@radix-ui/number@1.1.1': {} + + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-context-menu@2.2.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + aria-hidden: 1.2.6 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-direction@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + aria-hidden: 1.2.6 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + aria-hidden: 1.2.6 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/rect': 1.1.1 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-slider@1.3.6(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-toggle@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.5) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/rect': 1.1.1 + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-use-size@1.1.1(@types/react@19.2.14)(react@19.2.5)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.5) + react: 19.2.5 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@radix-ui/rect@1.1.1': {} + + '@rolldown/binding-android-arm64@1.0.0-rc.17': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.17': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.17': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.27': {} + + '@rolldown/pluginutils@1.0.0-rc.17': {} + + '@rolldown/pluginutils@1.0.0-rc.7': {} + + '@rollup/pluginutils@5.3.0(rollup@4.60.2)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.4 + optionalDependencies: + rollup: 4.60.2 + + '@rollup/rollup-android-arm-eabi@4.60.2': + optional: true + + '@rollup/rollup-android-arm64@4.60.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.2': + optional: true + + '@rollup/rollup-darwin-x64@4.60.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.2': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.2': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.2': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.2': + optional: true + + '@shikijs/core@1.29.2': + dependencies: + '@shikijs/engine-javascript': 1.29.2 + '@shikijs/engine-oniguruma': 1.29.2 + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/core@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 2.3.0 + + '@shikijs/engine-javascript@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.6 + + '@shikijs/engine-oniguruma@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/engine-oniguruma@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + + '@shikijs/langs@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/themes@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + + '@shikijs/themes@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/types@1.29.2': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/types@3.23.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@size-limit/esbuild@11.2.0(size-limit@11.2.0)': + dependencies: + esbuild: 0.25.12 + nanoid: 5.1.11 + size-limit: 11.2.0 + + '@size-limit/file@11.2.0(size-limit@11.2.0)': + dependencies: + size-limit: 11.2.0 + + '@size-limit/preset-small-lib@11.2.0(size-limit@11.2.0)': + dependencies: + '@size-limit/esbuild': 11.2.0(size-limit@11.2.0) + '@size-limit/file': 11.2.0(size-limit@11.2.0) + size-limit: 11.2.0 + + '@storybook/addon-a11y@8.6.18(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/addon-highlight': 8.6.18(storybook@8.6.18(prettier@3.8.3)) + '@storybook/global': 5.0.0 + '@storybook/test': 8.6.18(storybook@8.6.18(prettier@3.8.3)) + axe-core: 4.11.4 + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/addon-actions@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + '@types/uuid': 9.0.8 + dequal: 2.0.3 + polished: 4.3.1 + storybook: 8.6.18(prettier@3.8.3) + uuid: 9.0.1 + + '@storybook/addon-backgrounds@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + storybook: 8.6.18(prettier@3.8.3) + ts-dedent: 2.2.0 + + '@storybook/addon-controls@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + dequal: 2.0.3 + storybook: 8.6.18(prettier@3.8.3) + ts-dedent: 2.2.0 + + '@storybook/addon-docs@8.6.14(@types/react@19.2.14)(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.5) + '@storybook/blocks': 8.6.14(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@8.6.18(prettier@3.8.3)) + '@storybook/csf-plugin': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@storybook/react-dom-shim': 8.6.14(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@8.6.18(prettier@3.8.3)) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + storybook: 8.6.18(prettier@3.8.3) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + + '@storybook/addon-essentials@8.6.14(@types/react@19.2.14)(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/addon-actions': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@storybook/addon-backgrounds': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@storybook/addon-controls': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@storybook/addon-docs': 8.6.14(@types/react@19.2.14)(storybook@8.6.18(prettier@3.8.3)) + '@storybook/addon-highlight': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@storybook/addon-measure': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@storybook/addon-outline': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@storybook/addon-toolbars': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@storybook/addon-viewport': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + storybook: 8.6.18(prettier@3.8.3) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + + '@storybook/addon-highlight@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/addon-highlight@8.6.18(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/addon-interactions@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@storybook/test': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + polished: 4.3.1 + storybook: 8.6.18(prettier@3.8.3) + ts-dedent: 2.2.0 + + '@storybook/addon-measure@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.6.18(prettier@3.8.3) + tiny-invariant: 1.3.3 + + '@storybook/addon-outline@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.6.18(prettier@3.8.3) + ts-dedent: 2.2.0 + + '@storybook/addon-toolbars@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/addon-viewport@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + memoizerific: 1.11.3 + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/blocks@8.6.14(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/icons': 1.6.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + storybook: 8.6.18(prettier@3.8.3) + ts-dedent: 2.2.0 + optionalDependencies: + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + + '@storybook/builder-vite@8.6.18(storybook@8.6.18(prettier@3.8.3))(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0))': + dependencies: + '@storybook/csf-plugin': 8.6.18(storybook@8.6.18(prettier@3.8.3)) + browser-assert: 1.2.1 + storybook: 8.6.18(prettier@3.8.3) + ts-dedent: 2.2.0 + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0) + + '@storybook/components@8.6.18(storybook@8.6.18(prettier@3.8.3))': + dependencies: + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/core@8.6.18(prettier@3.8.3)(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/theming': 8.6.18(storybook@8.6.18(prettier@3.8.3)) + better-opn: 3.0.2 + browser-assert: 1.2.1 + esbuild: 0.25.12 + esbuild-register: 3.6.0(esbuild@0.25.12) + jsdoc-type-pratt-parser: 4.8.0 + process: 0.11.10 + recast: 0.23.11 + semver: 7.7.4 + util: 0.12.5 + ws: 8.20.0 + optionalDependencies: + prettier: 3.8.3 + transitivePeerDependencies: + - bufferutil + - storybook + - supports-color + - utf-8-validate + + '@storybook/csf-plugin@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + storybook: 8.6.18(prettier@3.8.3) + unplugin: 1.16.1 + + '@storybook/csf-plugin@8.6.18(storybook@8.6.18(prettier@3.8.3))': + dependencies: + storybook: 8.6.18(prettier@3.8.3) + unplugin: 1.16.1 + + '@storybook/global@5.0.0': {} + + '@storybook/icons@1.6.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + + '@storybook/instrumenter@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + '@vitest/utils': 2.1.9 + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/instrumenter@8.6.15(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + '@vitest/utils': 2.1.9 + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/instrumenter@8.6.18(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + '@vitest/utils': 2.1.9 + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/manager-api@8.6.18(storybook@8.6.18(prettier@3.8.3))': + dependencies: + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/preview-api@8.6.18(storybook@8.6.18(prettier@3.8.3))': + dependencies: + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/react-dom-shim@8.6.14(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@8.6.18(prettier@3.8.3))': + dependencies: + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/react-dom-shim@8.6.18(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@8.6.18(prettier@3.8.3))': + dependencies: + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/react-vite@8.6.18(@storybook/test@8.6.15(storybook@8.6.18(prettier@3.8.3)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(rollup@4.60.2)(storybook@8.6.18(prettier@3.8.3))(typescript@5.7.3)(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0))': + dependencies: + '@joshwooding/vite-plugin-react-docgen-typescript': 0.5.0(typescript@5.7.3)(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)) + '@rollup/pluginutils': 5.3.0(rollup@4.60.2) + '@storybook/builder-vite': 8.6.18(storybook@8.6.18(prettier@3.8.3))(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)) + '@storybook/react': 8.6.18(@storybook/test@8.6.15(storybook@8.6.18(prettier@3.8.3)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@8.6.18(prettier@3.8.3))(typescript@5.7.3) + find-up: 5.0.0 + magic-string: 0.30.21 + react: 19.2.5 + react-docgen: 7.1.1 + react-dom: 19.2.5(react@19.2.5) + resolve: 1.22.12 + storybook: 8.6.18(prettier@3.8.3) + tsconfig-paths: 4.2.0 + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0) + optionalDependencies: + '@storybook/test': 8.6.15(storybook@8.6.18(prettier@3.8.3)) + transitivePeerDependencies: + - rollup + - supports-color + - typescript + + '@storybook/react@8.6.18(@storybook/test@8.6.15(storybook@8.6.18(prettier@3.8.3)))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@8.6.18(prettier@3.8.3))(typescript@5.7.3)': + dependencies: + '@storybook/components': 8.6.18(storybook@8.6.18(prettier@3.8.3)) + '@storybook/global': 5.0.0 + '@storybook/manager-api': 8.6.18(storybook@8.6.18(prettier@3.8.3)) + '@storybook/preview-api': 8.6.18(storybook@8.6.18(prettier@3.8.3)) + '@storybook/react-dom-shim': 8.6.18(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@8.6.18(prettier@3.8.3)) + '@storybook/theming': 8.6.18(storybook@8.6.18(prettier@3.8.3)) + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + storybook: 8.6.18(prettier@3.8.3) + optionalDependencies: + '@storybook/test': 8.6.15(storybook@8.6.18(prettier@3.8.3)) + typescript: 5.7.3 + + '@storybook/test@8.6.14(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.6.14(storybook@8.6.18(prettier@3.8.3)) + '@testing-library/dom': 10.4.0 + '@testing-library/jest-dom': 6.5.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) + '@vitest/expect': 2.0.5 + '@vitest/spy': 2.0.5 + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/test@8.6.15(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.6.15(storybook@8.6.18(prettier@3.8.3)) + '@testing-library/dom': 10.4.0 + '@testing-library/jest-dom': 6.5.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) + '@vitest/expect': 2.0.5 + '@vitest/spy': 2.0.5 + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/test@8.6.18(storybook@8.6.18(prettier@3.8.3))': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.6.18(storybook@8.6.18(prettier@3.8.3)) + '@testing-library/dom': 10.4.0 + '@testing-library/jest-dom': 6.5.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) + '@vitest/expect': 2.0.5 + '@vitest/spy': 2.0.5 + storybook: 8.6.18(prettier@3.8.3) + + '@storybook/theming@8.6.18(storybook@8.6.18(prettier@3.8.3))': + dependencies: + storybook: 8.6.18(prettier@3.8.3) + + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/runtime': 7.29.2 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.5.0': + dependencies: + '@adobe/css-tools': 4.4.4 + aria-query: 5.3.2 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.18.1 + redent: 3.0.0 + + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.4.4 + aria-query: 5.3.2 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 + + '@testing-library/react@16.3.2(@testing-library/dom@10.4.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + dependencies: + '@babel/runtime': 7.29.2 + '@testing-library/dom': 10.4.0 + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)': + dependencies: + '@testing-library/dom': 10.4.0 + + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.0)': + dependencies: + '@testing-library/dom': 10.4.0 + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/aria-query@5.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/doctrine@0.0.9': {} + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/js-yaml@4.0.9': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/ms@2.1.0': {} + + '@types/nlcst@2.0.3': + dependencies: + '@types/unist': 3.0.3 + + '@types/node@12.20.55': {} + + '@types/node@24.12.2': + dependencies: + undici-types: 7.16.0 + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@types/resolve@1.20.6': {} + + '@types/sax@1.2.7': + dependencies: + '@types/node': 24.12.2 + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@types/uuid@9.0.8': {} + + '@ungap/structured-clone@1.3.0': {} + + '@vitejs/plugin-react@4.7.0(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-beta.27 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-react@4.7.0(vite@8.0.10(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(yaml@2.8.4))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-beta.27 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: 8.0.10(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(yaml@2.8.4) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-react@6.0.1(vite@8.0.10(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(yaml@2.8.4))': + dependencies: + '@rolldown/pluginutils': 1.0.0-rc.7 + vite: 8.0.10(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(yaml@2.8.4) + + '@vitest/expect@2.0.5': + dependencies: + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.3.3 + tinyrainbow: 1.2.0 + + '@vitest/expect@2.1.9': + dependencies: + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.9(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0))': + dependencies: + '@vitest/spy': 2.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0) + + '@vitest/pretty-format@2.0.5': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.9': + dependencies: + '@vitest/utils': 2.1.9 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + magic-string: 0.30.21 + pathe: 1.1.2 + + '@vitest/spy@2.0.5': + dependencies: + tinyspy: 3.0.2 + + '@vitest/spy@2.1.9': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.0.5': + dependencies: + '@vitest/pretty-format': 2.0.5 + estree-walker: 3.0.3 + loupe: 3.2.1 + tinyrainbow: 1.2.0 + + '@vitest/utils@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.2.1 + tinyrainbow: 1.2.0 + + '@yarnpkg/lockfile@1.1.0': {} + + '@zip.js/zip.js@2.8.26': {} + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + agent-base@7.1.4: {} + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-colors@4.1.3: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.3: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + + array-iterate@2.0.1: {} + + array-union@2.1.0: {} + + assert@2.1.0: + dependencies: + call-bind: 1.0.9 + is-nan: 1.3.2 + object-is: 1.1.6 + object.assign: 4.1.7 + util: 0.12.5 + + assertion-error@2.0.1: {} + + ast-types@0.16.1: + dependencies: + tslib: 2.8.1 + + astring@1.9.0: {} + + astro-expressive-code@0.38.3(astro@5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4)): + dependencies: + astro: 5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4) + rehype-expressive-code: 0.38.3 + + astro@5.18.1(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.2)(typescript@6.0.3)(yaml@2.8.4): + dependencies: + '@astrojs/compiler': 2.13.1 + '@astrojs/internal-helpers': 0.7.6 + '@astrojs/markdown-remark': 6.3.11 + '@astrojs/telemetry': 3.3.0 + '@capsizecss/unpack': 4.0.0 + '@oslojs/encoding': 1.1.0 + '@rollup/pluginutils': 5.3.0(rollup@4.60.2) + acorn: 8.16.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + boxen: 8.0.1 + ci-info: 4.4.0 + clsx: 2.1.1 + common-ancestor-path: 1.0.1 + cookie: 1.1.1 + cssesc: 3.0.0 + debug: 4.4.3 + deterministic-object-hash: 2.0.2 + devalue: 5.8.0 + diff: 8.0.4 + dlv: 1.1.3 + dset: 3.1.4 + es-module-lexer: 1.7.0 + esbuild: 0.27.7 + estree-walker: 3.0.3 + flattie: 1.1.1 + fontace: 0.4.1 + github-slugger: 2.0.0 + html-escaper: 3.0.3 + http-cache-semantics: 4.2.0 + import-meta-resolve: 4.2.0 + js-yaml: 4.1.1 + magic-string: 0.30.21 + magicast: 0.5.2 + mrmime: 2.0.1 + neotraverse: 0.6.18 + p-limit: 6.2.0 + p-queue: 8.1.1 + package-manager-detector: 1.6.0 + piccolore: 0.1.3 + picomatch: 4.0.4 + prompts: 2.4.2 + rehype: 13.0.2 + semver: 7.7.4 + shiki: 3.23.0 + smol-toml: 1.6.1 + svgo: 4.0.1 + tinyexec: 1.1.2 + tinyglobby: 0.2.16 + tsconfck: 3.1.6(typescript@6.0.3) + ultrahtml: 1.6.0 + unifont: 0.7.4 + unist-util-visit: 5.1.0 + unstorage: 1.17.5 + vfile: 6.0.3 + vite: 6.4.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.4) + vitefu: 1.1.3(vite@6.4.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.4)) + xxhash-wasm: 1.1.0 + yargs-parser: 21.1.1 + yocto-spinner: 0.2.3 + zod: 3.25.76 + zod-to-json-schema: 3.25.2(zod@3.25.76) + zod-to-ts: 1.2.0(typescript@6.0.3)(zod@3.25.76) + optionalDependencies: + sharp: 0.34.5 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@types/node' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - idb-keyval + - ioredis + - jiti + - less + - lightningcss + - rollup + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - uploadthing + - yaml + + asynckit@0.4.0: {} + + autoprefixer@10.5.0(postcss@8.5.13): + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001791 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axe-core@4.11.4: {} + + axobject-query@4.1.0: {} + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + base-64@1.0.0: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.10.27: {} + + bcp-47-match@2.0.3: {} + + bcp-47@2.1.0: + dependencies: + is-alphabetical: 2.0.1 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + + better-opn@3.0.2: + dependencies: + open: 8.4.2 + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + binary-extensions@2.3.0: {} + + boolbase@1.0.0: {} + + boxen@8.0.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 8.0.0 + chalk: 5.6.2 + cli-boxes: 3.0.0 + string-width: 7.2.0 + type-fest: 4.41.0 + widest-line: 5.0.0 + wrap-ansi: 9.0.2 + + brace-expansion@2.1.0: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browser-assert@1.2.1: {} + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.27 + caniuse-lite: 1.0.30001791 + electron-to-chromium: 1.5.349 + node-releases: 2.0.38 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bundle-require@5.1.0(esbuild@0.27.7): + dependencies: + esbuild: 0.27.7 + load-tsconfig: 0.2.5 + + bytes-iec@3.1.1: {} + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + camelcase@8.0.0: {} + + caniuse-api@3.0.0: + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001791 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + + caniuse-lite@1.0.30001791: {} + + ccount@2.0.1: {} + + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.3 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + + chalk@3.0.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + change-case@5.4.4: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + chardet@2.1.1: {} + + check-error@2.1.3: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + + ci-info@3.9.0: {} + + ci-info@4.4.0: {} + + cli-boxes@3.0.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clsx@2.1.1: {} + + collapse-white-space@2.1.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + comma-separated-tokens@2.0.3: {} + + commander@11.1.0: {} + + commander@12.1.0: {} + + commander@4.1.1: {} + + common-ancestor-path@1.0.1: {} + + component-emitter@2.0.0: {} + + confbox@0.1.8: {} + + consola@3.4.2: {} + + convert-source-map@2.0.0: {} + + cookie-es@1.2.3: {} + + cookie@1.1.1: {} + + cross-env@7.0.3: + dependencies: + cross-spawn: 7.0.6 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + css-declaration-sorter@7.4.0(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-selector-parser@3.3.0: {} + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.1 + + css-what@6.2.2: {} + + css.escape@1.5.1: {} + + cssesc@3.0.0: {} + + cssnano-preset-default@7.0.16(postcss@8.5.13): + dependencies: + browserslist: 4.28.2 + css-declaration-sorter: 7.4.0(postcss@8.5.13) + cssnano-utils: 5.0.3(postcss@8.5.13) + postcss: 8.5.13 + postcss-calc: 10.1.1(postcss@8.5.13) + postcss-colormin: 7.0.10(postcss@8.5.13) + postcss-convert-values: 7.0.12(postcss@8.5.13) + postcss-discard-comments: 7.0.8(postcss@8.5.13) + postcss-discard-duplicates: 7.0.4(postcss@8.5.13) + postcss-discard-empty: 7.0.3(postcss@8.5.13) + postcss-discard-overridden: 7.0.3(postcss@8.5.13) + postcss-merge-longhand: 7.0.7(postcss@8.5.13) + postcss-merge-rules: 7.0.11(postcss@8.5.13) + postcss-minify-font-values: 7.0.3(postcss@8.5.13) + postcss-minify-gradients: 7.0.5(postcss@8.5.13) + postcss-minify-params: 7.0.9(postcss@8.5.13) + postcss-minify-selectors: 7.1.1(postcss@8.5.13) + postcss-normalize-charset: 7.0.3(postcss@8.5.13) + postcss-normalize-display-values: 7.0.3(postcss@8.5.13) + postcss-normalize-positions: 7.0.4(postcss@8.5.13) + postcss-normalize-repeat-style: 7.0.4(postcss@8.5.13) + postcss-normalize-string: 7.0.3(postcss@8.5.13) + postcss-normalize-timing-functions: 7.0.3(postcss@8.5.13) + postcss-normalize-unicode: 7.0.9(postcss@8.5.13) + postcss-normalize-url: 7.0.3(postcss@8.5.13) + postcss-normalize-whitespace: 7.0.3(postcss@8.5.13) + postcss-ordered-values: 7.0.4(postcss@8.5.13) + postcss-reduce-initial: 7.0.9(postcss@8.5.13) + postcss-reduce-transforms: 7.0.3(postcss@8.5.13) + postcss-svgo: 7.1.3(postcss@8.5.13) + postcss-unique-selectors: 7.0.7(postcss@8.5.13) + + cssnano-utils@5.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + + cssnano@7.1.8(postcss@8.5.13): + dependencies: + cssnano-preset-default: 7.0.16(postcss@8.5.13) + lilconfig: 3.1.3 + postcss: 8.5.13 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + cssstyle@4.6.0: + dependencies: + '@asamuzakjp/css-color': 3.2.0 + rrweb-cssom: 0.8.0 + + csstype@3.2.3: {} + + data-urls@5.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decimal.js@10.6.0: {} + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + deep-eql@5.0.2: {} + + deepmerge@4.3.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + defu@6.1.7: {} + + delayed-stream@1.0.0: {} + + dependency-graph@1.0.0: {} + + dequal@2.0.3: {} + + destr@2.0.5: {} + + detect-indent@6.1.0: {} + + detect-libc@2.1.2: {} + + detect-node-es@1.1.0: {} + + deterministic-object-hash@2.0.2: + dependencies: + base-64: 1.0.0 + + devalue@5.8.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@8.0.4: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + direction@2.0.1: {} + + dlv@1.1.3: {} + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dset@3.1.4: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eastasianwidth@0.2.0: {} + + electron-to-chromium@1.5.349: {} + + emoji-regex-xs@1.0.0: {} + + emoji-regex@10.6.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + entities@4.5.0: {} + + entities@6.0.1: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.16.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + esbuild-register@3.6.0(esbuild@0.25.12): + dependencies: + debug: 4.4.3 + esbuild: 0.25.12 + transitivePeerDependencies: + - supports-color + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + esbuild@0.27.7: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.7 + '@esbuild/android-arm': 0.27.7 + '@esbuild/android-arm64': 0.27.7 + '@esbuild/android-x64': 0.27.7 + '@esbuild/darwin-arm64': 0.27.7 + '@esbuild/darwin-x64': 0.27.7 + '@esbuild/freebsd-arm64': 0.27.7 + '@esbuild/freebsd-x64': 0.27.7 + '@esbuild/linux-arm': 0.27.7 + '@esbuild/linux-arm64': 0.27.7 + '@esbuild/linux-ia32': 0.27.7 + '@esbuild/linux-loong64': 0.27.7 + '@esbuild/linux-mips64el': 0.27.7 + '@esbuild/linux-ppc64': 0.27.7 + '@esbuild/linux-riscv64': 0.27.7 + '@esbuild/linux-s390x': 0.27.7 + '@esbuild/linux-x64': 0.27.7 + '@esbuild/netbsd-arm64': 0.27.7 + '@esbuild/netbsd-x64': 0.27.7 + '@esbuild/openbsd-arm64': 0.27.7 + '@esbuild/openbsd-x64': 0.27.7 + '@esbuild/openharmony-arm64': 0.27.7 + '@esbuild/sunos-x64': 0.27.7 + '@esbuild/win32-arm64': 0.27.7 + '@esbuild/win32-ia32': 0.27.7 + '@esbuild/win32-x64': 0.27.7 + + escalade@3.2.0: {} + + escape-string-regexp@5.0.0: {} + + esprima@4.0.1: {} + + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + eventemitter3@5.0.4: {} + + events@3.3.0: {} + + expect-type@1.3.0: {} + + expressive-code@0.38.3: + dependencies: + '@expressive-code/core': 0.38.3 + '@expressive-code/plugin-frames': 0.38.3 + '@expressive-code/plugin-shiki': 0.38.3 + '@expressive-code/plugin-text-markers': 0.38.3 + + extend@3.0.2: {} + + extendable-error@0.1.7: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-yarn-workspace-root@2.0.0: + dependencies: + micromatch: 4.0.8 + + fix-dts-default-cjs-exports@1.0.1: + dependencies: + magic-string: 0.30.21 + mlly: 1.8.2 + rollup: 4.60.2 + + flattie@1.1.1: {} + + fontace@0.4.1: + dependencies: + fontkitten: 1.0.3 + + fontkitten@1.0.3: + dependencies: + tiny-inflate: 1.0.3 + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.3 + mime-types: 2.1.35 + + fraction.js@5.3.4: {} + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs-extra@11.3.4: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + generator-function@2.0.1: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.5.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + + get-nonce@1.0.1: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + github-slugger@2.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regex.js@1.2.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.4 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.3: + dependencies: + function-bind: 1.1.2 + + hast-util-embedded@3.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-is-element: 3.0.0 + + hast-util-format@1.1.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-minify-whitespace: 1.0.1 + hast-util-phrasing: 3.0.1 + hast-util-whitespace: 3.0.0 + html-whitespace-sensitive-tag-names: 3.0.1 + unist-util-visit-parents: 6.0.2 + + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.3 + parse5: 7.3.0 + vfile: 6.0.3 + vfile-message: 4.0.3 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-has-property@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-body-ok-link@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-minify-whitespace@1.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-is-element: 3.0.0 + hast-util-whitespace: 3.0.0 + unist-util-is: 6.0.1 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-phrasing@3.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-embedded: 3.0.0 + hast-util-has-property: 3.0.0 + hast-util-is-body-ok-link: 3.0.1 + hast-util-is-element: 3.0.0 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-select@6.0.4: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + bcp-47-match: 2.0.3 + comma-separated-tokens: 2.0.3 + css-selector-parser: 3.3.0 + devlop: 1.1.0 + direction: 2.0.1 + hast-util-has-property: 3.0.0 + hast-util-to-string: 3.0.1 + hast-util-whitespace: 3.0.0 + nth-check: 2.1.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + + html-escaper@3.0.3: {} + + html-void-elements@3.0.0: {} + + html-whitespace-sensitive-tag-names@3.0.1: {} + + http-cache-semantics@4.2.0: {} + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + human-id@4.1.3: {} + + hyperdyperid@1.2.0: {} + + i18next@23.16.8: + dependencies: + '@babel/runtime': 7.29.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + import-meta-resolve@4.2.0: {} + + indent-string@4.0.0: {} + + inherits@2.0.3: {} + + inherits@2.0.4: {} + + inline-style-parser@0.2.7: {} + + iron-webcrypto@1.2.1: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-arrayish@0.3.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.3 + + is-decimal@2.0.1: {} + + is-docker@2.2.1: {} + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-nan@1.3.2: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + + is-number@7.0.0: {} + + is-plain-obj@4.1.0: {} + + is-potential-custom-element-name@1.0.1: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + is-windows@1.0.2: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@2.6.1: {} + + joycon@3.1.1: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsdoc-type-pratt-parser@4.8.0: {} + + jsdom@25.0.1: + dependencies: + cssstyle: 4.6.0 + data-urls: 5.0.0 + decimal.js: 10.6.0 + form-data: 4.0.5 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.23 + parse5: 7.3.0 + rrweb-cssom: 0.7.1 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.1.2 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + ws: 8.20.0 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jsesc@3.1.0: {} + + json-stable-stringify@1.3.0: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + isarray: 2.0.5 + jsonify: 0.0.1 + object-keys: 1.1.1 + + json5@2.2.3: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@6.2.1: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonify@0.0.1: {} + + klaw-sync@6.0.0: + dependencies: + graceful-fs: 4.2.11 + + kleur@3.0.3: {} + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.18.1: {} + + lodash.memoize@4.1.2: {} + + lodash.startcase@4.4.0: {} + + lodash.uniq@4.5.0: {} + + lodash@4.18.1: {} + + longest-streak@3.1.0: {} + + loupe@3.2.1: {} + + lru-cache@10.4.3: {} + + lru-cache@11.3.5: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lz-string@1.5.0: {} + + magic-string@0.27.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magicast@0.5.2: + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + source-map-js: 1.2.1 + + map-or-similar@1.5.0: {} + + markdown-extensions@2.0.0: {} + + markdown-table@3.0.4: {} + + math-intrinsics@1.1.0: {} + + mdast-util-definitions@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + unist-util-visit: 5.1.0 + + mdast-util-directive@3.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-visit-parents: 6.0.2 + transitivePeerDependencies: + - supports-color + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.28: {} + + mdn-data@2.27.1: {} + + memfs@4.57.2(tslib@2.8.1): + dependencies: + '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + memoizerific@1.11.3: + dependencies: + map-or-similar: 1.5.0 + + merge2@1.4.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@3.0.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + min-indent@1.0.1: {} + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.1.0 + + minimist@1.2.8: {} + + minipass@7.1.3: {} + + mlly@1.8.2: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.4 + + mri@1.2.0: {} + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.12: {} + + nanoid@5.1.11: {} + + nanospinner@1.2.2: + dependencies: + picocolors: 1.1.1 + + neotraverse@0.6.18: {} + + nlcst-to-string@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + + node-fetch-native@1.6.7: {} + + node-mock-http@1.0.4: {} + + node-releases@2.0.38: {} + + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nwsapi@2.2.23: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + ohash@2.0.11: {} + + oniguruma-parser@0.12.2: {} + + oniguruma-to-es@2.3.0: + dependencies: + emoji-regex-xs: 1.0.0 + regex: 5.1.1 + regex-recursion: 5.1.1 + + oniguruma-to-es@4.3.6: + dependencies: + oniguruma-parser: 0.12.2 + regex: 6.1.0 + regex-recursion: 6.0.2 + + open@7.4.2: + dependencies: + is-docker: 2.2.1 + is-wsl: 2.2.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + outdent@0.5.0: {} + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-limit@6.2.0: + dependencies: + yocto-queue: 1.2.2 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@2.1.0: {} + + p-queue@8.1.1: + dependencies: + eventemitter3: 5.0.4 + p-timeout: 6.1.4 + + p-timeout@6.1.4: {} + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + package-manager-detector@0.2.11: + dependencies: + quansync: 0.2.11 + + package-manager-detector@1.6.0: {} + + pagefind@1.5.2: + optionalDependencies: + '@pagefind/darwin-arm64': 1.5.2 + '@pagefind/darwin-x64': 1.5.2 + '@pagefind/freebsd-x64': 1.5.2 + '@pagefind/linux-arm64': 1.5.2 + '@pagefind/linux-x64': 1.5.2 + '@pagefind/windows-arm64': 1.5.2 + '@pagefind/windows-x64': 1.5.2 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-latin@7.0.0: + dependencies: + '@types/nlcst': 2.0.3 + '@types/unist': 3.0.3 + nlcst-to-string: 4.0.0 + unist-util-modify-children: 4.0.0 + unist-util-visit-children: 3.0.0 + vfile: 6.0.3 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + patch-package@8.0.1: + dependencies: + '@yarnpkg/lockfile': 1.1.0 + chalk: 4.1.2 + ci-info: 3.9.0 + cross-spawn: 7.0.6 + find-yarn-workspace-root: 2.0.0 + fs-extra: 10.1.0 + json-stable-stringify: 1.3.0 + klaw-sync: 6.0.0 + minimist: 1.2.8 + open: 7.4.2 + semver: 7.7.4 + slash: 2.0.0 + tmp: 0.2.5 + yaml: 2.8.4 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + + path-type@4.0.0: {} + + path-unified@0.2.0: {} + + path@0.12.7: + dependencies: + process: 0.11.10 + util: 0.10.4 + + pathe@1.1.2: {} + + pathe@2.0.3: {} + + pathval@2.0.1: {} + + piccolore@0.1.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.4: {} + + pify@2.3.0: {} + + pify@4.0.1: {} + + pirates@4.0.7: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + polished@4.3.1: + dependencies: + '@babel/runtime': 7.29.2 + + possible-typed-array-names@1.1.0: {} + + postcss-calc@10.1.1(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + postcss-cli@11.0.1(jiti@2.6.1)(postcss@8.5.13): + dependencies: + chokidar: 3.6.0 + dependency-graph: 1.0.0 + fs-extra: 11.3.4 + picocolors: 1.1.1 + postcss: 8.5.13 + postcss-load-config: 5.1.0(jiti@2.6.1)(postcss@8.5.13) + postcss-reporter: 7.1.0(postcss@8.5.13) + pretty-hrtime: 1.0.3 + read-cache: 1.0.0 + slash: 5.1.0 + tinyglobby: 0.2.16 + yargs: 17.7.2 + transitivePeerDependencies: + - jiti + - tsx + + postcss-colormin@7.0.10(postcss@8.5.13): + dependencies: + '@colordx/core': 5.4.3 + browserslist: 4.28.2 + caniuse-api: 3.0.0 + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-convert-values@7.0.12(postcss@8.5.13): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@7.0.8(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-selector-parser: 7.1.1 + + postcss-discard-duplicates@7.0.4(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + + postcss-discard-empty@7.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + + postcss-discard-overridden@7.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + + postcss-import@16.1.1(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.12 + + postcss-load-config@5.1.0(jiti@2.6.1)(postcss@8.5.13): + dependencies: + lilconfig: 3.1.3 + yaml: 2.8.4 + optionalDependencies: + jiti: 2.6.1 + postcss: 8.5.13 + + postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.13)(yaml@2.8.4): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 2.6.1 + postcss: 8.5.13 + yaml: 2.8.4 + + postcss-merge-longhand@7.0.7(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + stylehacks: 7.0.11(postcss@8.5.13) + + postcss-merge-rules@7.0.11(postcss@8.5.13): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + cssnano-utils: 5.0.3(postcss@8.5.13) + postcss: 8.5.13 + postcss-selector-parser: 7.1.1 + + postcss-minify-font-values@7.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@7.0.5(postcss@8.5.13): + dependencies: + '@colordx/core': 5.4.3 + cssnano-utils: 5.0.3(postcss@8.5.13) + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-minify-params@7.0.9(postcss@8.5.13): + dependencies: + browserslist: 4.28.2 + cssnano-utils: 5.0.3(postcss@8.5.13) + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@7.1.1(postcss@8.5.13): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + cssesc: 3.0.0 + postcss: 8.5.13 + postcss-selector-parser: 7.1.1 + + postcss-nested@6.2.0(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-selector-parser: 6.1.2 + + postcss-normalize-charset@7.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + + postcss-normalize-display-values@7.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@7.0.4(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@7.0.4(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@7.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@7.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@7.0.9(postcss@8.5.13): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@7.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@7.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@7.0.4(postcss@8.5.13): + dependencies: + cssnano-utils: 5.0.3(postcss@8.5.13) + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@7.0.9(postcss@8.5.13): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + postcss: 8.5.13 + + postcss-reduce-transforms@7.0.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + + postcss-reporter@7.1.0(postcss@8.5.13): + dependencies: + picocolors: 1.1.1 + postcss: 8.5.13 + thenby: 1.4.1 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@7.1.3(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-value-parser: 4.2.0 + svgo: 4.0.1 + + postcss-unique-selectors@7.0.7(postcss@8.5.13): + dependencies: + postcss: 8.5.13 + postcss-selector-parser: 7.1.1 + + postcss-value-parser@4.2.0: {} + + postcss@8.5.13: + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@2.8.8: {} + + prettier@3.8.3: {} + + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + pretty-hrtime@1.0.3: {} + + prismjs@1.30.0: {} + + process@0.11.10: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + property-information@7.1.0: {} + + punycode@1.4.1: {} + + punycode@2.3.1: {} + + qs@6.15.1: + dependencies: + side-channel: 1.1.0 + + quansync@0.2.11: {} + + queue-microtask@1.2.3: {} + + radix3@1.1.2: {} + + react-docgen-typescript@2.4.0(typescript@5.7.3): + dependencies: + typescript: 5.7.3 + + react-docgen@7.1.1: + dependencies: + '@babel/core': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + '@types/doctrine': 0.0.9 + '@types/resolve': 1.20.6 + doctrine: 3.0.0 + resolve: 1.22.12 + strip-indent: 4.1.1 + transitivePeerDependencies: + - supports-color + + react-dom@19.2.5(react@19.2.5): + dependencies: + react: 19.2.5 + scheduler: 0.27.0 + + react-is@17.0.2: {} + + react-refresh@0.17.0: {} + + react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.5): + dependencies: + react: 19.2.5 + react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.5) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + react-remove-scroll@2.7.2(@types/react@19.2.14)(react@19.2.5): + dependencies: + react: 19.2.5 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.14)(react@19.2.5) + react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.5) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.2.14)(react@19.2.5) + use-sidecar: 1.1.3(@types/react@19.2.14)(react@19.2.5) + optionalDependencies: + '@types/react': 19.2.14 + + react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.5): + dependencies: + get-nonce: 1.0.1 + react: 19.2.5 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + react@19.2.5: {} + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.2 + pify: 4.0.1 + strip-bom: 3.0.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + + readdirp@4.1.2: {} + + readdirp@5.0.0: {} + + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + + regex-recursion@5.1.1: + dependencies: + regex: 5.1.1 + regex-utilities: 2.3.0 + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@5.1.1: + dependencies: + regex-utilities: 2.3.0 + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + rehype-expressive-code@0.38.3: + dependencies: + expressive-code: 0.38.3 + + rehype-format@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-format: 1.1.0 + + rehype-parse@9.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-html: 2.0.3 + unified: 11.0.5 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + rehype-stringify@10.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + unified: 11.0.5 + + rehype@13.0.2: + dependencies: + '@types/hast': 3.0.4 + rehype-parse: 9.0.1 + rehype-stringify: 10.0.1 + unified: 11.0.5 + + remark-directive@3.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-directive: 3.1.0 + micromark-extension-directive: 3.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-smartypants@3.0.2: + dependencies: + retext: 9.0.0 + retext-smartypants: 6.2.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + remixicon@4.9.1: {} + + require-directory@2.1.1: {} + + resolve-from@5.0.0: {} + + resolve@1.22.12: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + retext-latin@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + parse-latin: 7.0.0 + unified: 11.0.5 + + retext-smartypants@6.2.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unist-util-visit: 5.1.0 + + retext-stringify@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unified: 11.0.5 + + retext@9.0.0: + dependencies: + '@types/nlcst': 2.0.3 + retext-latin: 4.0.0 + retext-stringify: 4.0.0 + unified: 11.0.5 + + reusify@1.1.0: {} + + rolldown@1.0.0-rc.17: + dependencies: + '@oxc-project/types': 0.127.0 + '@rolldown/pluginutils': 1.0.0-rc.17 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-x64': 1.0.0-rc.17 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.17 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.17 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.17 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.17 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.17 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 + + rollup@4.60.2: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.2 + '@rollup/rollup-android-arm64': 4.60.2 + '@rollup/rollup-darwin-arm64': 4.60.2 + '@rollup/rollup-darwin-x64': 4.60.2 + '@rollup/rollup-freebsd-arm64': 4.60.2 + '@rollup/rollup-freebsd-x64': 4.60.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.2 + '@rollup/rollup-linux-arm-musleabihf': 4.60.2 + '@rollup/rollup-linux-arm64-gnu': 4.60.2 + '@rollup/rollup-linux-arm64-musl': 4.60.2 + '@rollup/rollup-linux-loong64-gnu': 4.60.2 + '@rollup/rollup-linux-loong64-musl': 4.60.2 + '@rollup/rollup-linux-ppc64-gnu': 4.60.2 + '@rollup/rollup-linux-ppc64-musl': 4.60.2 + '@rollup/rollup-linux-riscv64-gnu': 4.60.2 + '@rollup/rollup-linux-riscv64-musl': 4.60.2 + '@rollup/rollup-linux-s390x-gnu': 4.60.2 + '@rollup/rollup-linux-x64-gnu': 4.60.2 + '@rollup/rollup-linux-x64-musl': 4.60.2 + '@rollup/rollup-openbsd-x64': 4.60.2 + '@rollup/rollup-openharmony-arm64': 4.60.2 + '@rollup/rollup-win32-arm64-msvc': 4.60.2 + '@rollup/rollup-win32-ia32-msvc': 4.60.2 + '@rollup/rollup-win32-x64-gnu': 4.60.2 + '@rollup/rollup-win32-x64-msvc': 4.60.2 + fsevents: 2.3.3 + + rrweb-cssom@0.7.1: {} + + rrweb-cssom@0.8.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.2.1: {} + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safer-buffer@2.1.2: {} + + sax@1.6.0: {} + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.27.0: {} + + semver@6.3.1: {} + + semver@7.7.4: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + optional: true + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shiki@1.29.2: + dependencies: + '@shikijs/core': 1.29.2 + '@shikijs/engine-javascript': 1.29.2 + '@shikijs/engine-oniguruma': 1.29.2 + '@shikijs/langs': 1.29.2 + '@shikijs/themes': 1.29.2 + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + shiki@3.23.0: + dependencies: + '@shikijs/core': 3.23.0 + '@shikijs/engine-javascript': 3.23.0 + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + + sisteransi@1.0.5: {} + + sitemap@9.0.1: + dependencies: + '@types/node': 24.12.2 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.6.0 + + size-limit@11.2.0: + dependencies: + bytes-iec: 3.1.1 + chokidar: 4.0.3 + jiti: 2.6.1 + lilconfig: 3.1.3 + nanospinner: 1.2.2 + picocolors: 1.1.1 + tinyglobby: 0.2.16 + + slash@2.0.0: {} + + slash@3.0.0: {} + + slash@5.1.0: {} + + smol-toml@1.6.1: {} + + source-map-js@1.2.1: {} + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + space-separated-tokens@2.0.2: {} + + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + sprintf-js@1.0.3: {} + + stackback@0.0.2: {} + + std-env@3.10.0: {} + + storybook@8.6.18(prettier@3.8.3): + dependencies: + '@storybook/core': 8.6.18(prettier@3.8.3)(storybook@8.6.18(prettier@3.8.3)) + optionalDependencies: + prettier: 3.8.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + stream-replace-string@2.0.0: {} + + stream@0.0.3: + dependencies: + component-emitter: 2.0.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@3.0.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-indent@4.1.1: {} + + style-dictionary@4.4.0(tslib@2.8.1): + dependencies: + '@bundled-es-modules/deepmerge': 4.3.1 + '@bundled-es-modules/glob': 10.4.2 + '@bundled-es-modules/memfs': 4.17.0(tslib@2.8.1) + '@zip.js/zip.js': 2.8.26 + chalk: 5.6.2 + change-case: 5.4.4 + commander: 12.1.0 + is-plain-obj: 4.1.0 + json5: 2.2.3 + patch-package: 8.0.1 + path-unified: 0.2.0 + prettier: 3.8.3 + tinycolor2: 1.6.0 + transitivePeerDependencies: + - tslib + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + stylehacks@7.0.11(postcss@8.5.13): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.13 + postcss-selector-parser: 7.1.1 + + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.16 + ts-interface-checker: 0.1.13 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svgo@4.0.1: + dependencies: + commander: 11.1.0 + css-select: 5.2.2 + css-tree: 3.2.1 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.6.0 + + symbol-tree@3.2.4: {} + + tabbable@6.4.0: {} + + term-size@2.2.1: {} + + thenby@1.4.1: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + thingies@2.6.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + tiny-inflate@1.0.3: {} + + tiny-invariant@1.3.3: {} + + tinybench@2.9.0: {} + + tinycolor2@1.6.0: {} + + tinyexec@0.3.2: {} + + tinyexec@1.1.2: {} + + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tinypool@1.1.1: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + + tldts-core@6.1.86: {} + + tldts@6.1.86: + dependencies: + tldts-core: 6.1.86 + + tmp@0.2.5: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tough-cookie@5.1.2: + dependencies: + tldts: 6.1.86 + + tr46@5.1.1: + dependencies: + punycode: 2.3.1 + + tree-dump@1.1.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + tree-kill@1.2.2: {} + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-dedent@2.2.0: {} + + ts-interface-checker@0.1.13: {} + + tsconfck@3.1.6(typescript@6.0.3): + optionalDependencies: + typescript: 6.0.3 + + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} + + tsup@8.5.1(jiti@2.6.1)(postcss@8.5.13)(typescript@5.7.3)(yaml@2.8.4): + dependencies: + bundle-require: 5.1.0(esbuild@0.27.7) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3 + esbuild: 0.27.7 + fix-dts-default-cjs-exports: 1.0.1 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.13)(yaml@2.8.4) + resolve-from: 5.0.0 + rollup: 4.60.2 + source-map: 0.7.6 + sucrase: 3.35.1 + tinyexec: 0.3.2 + tinyglobby: 0.2.16 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.5.13 + typescript: 5.7.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + type-fest@4.41.0: {} + + typescript@5.7.3: {} + + typescript@6.0.3: {} + + ufo@1.6.4: {} + + ultrahtml@1.6.0: {} + + uncrypto@0.1.3: {} + + undici-types@7.16.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unifont@0.7.4: + dependencies: + css-tree: 3.2.1 + ofetch: 1.5.1 + ohash: 2.0.11 + + unist-util-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-modify-children@4.0.0: + dependencies: + '@types/unist': 3.0.3 + array-iterate: 2.0.1 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit: 5.1.0 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-children@3.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + universalify@0.1.2: {} + + universalify@2.0.1: {} + + unplugin@1.16.1: + dependencies: + acorn: 8.16.0 + webpack-virtual-modules: 0.6.2 + + unstorage@1.17.5: + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.3.5 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + url@0.11.4: + dependencies: + punycode: 1.4.1 + qs: 6.15.1 + + use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.5): + dependencies: + react: 19.2.5 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.5): + dependencies: + detect-node-es: 1.1.0 + react: 19.2.5 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.14 + + util-deprecate@1.0.2: {} + + util@0.10.4: + dependencies: + inherits: 2.0.3 + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.2 + is-typed-array: 1.1.15 + which-typed-array: 1.1.20 + + uuid@9.0.1: {} + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite-node@2.1.9(@types/node@24.12.2)(lightningcss@1.32.0): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 1.1.2 + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.13 + rollup: 4.60.2 + optionalDependencies: + '@types/node': 24.12.2 + fsevents: 2.3.3 + lightningcss: 1.32.0 + + vite@6.4.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.4): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.13 + rollup: 4.60.2 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 24.12.2 + fsevents: 2.3.3 + jiti: 2.6.1 + lightningcss: 1.32.0 + yaml: 2.8.4 + + vite@8.0.10(@types/node@24.12.2)(esbuild@0.27.7)(jiti@2.6.1)(yaml@2.8.4): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.13 + rolldown: 1.0.0-rc.17 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 24.12.2 + esbuild: 0.27.7 + fsevents: 2.3.3 + jiti: 2.6.1 + yaml: 2.8.4 + + vitefu@1.1.3(vite@6.4.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.4)): + optionalDependencies: + vite: 6.4.2(@types/node@24.12.2)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.4) + + vitest-axe@0.1.0(vitest@2.1.9(@types/node@24.12.2)(jsdom@25.0.1)(lightningcss@1.32.0)): + dependencies: + aria-query: 5.3.2 + axe-core: 4.11.4 + chalk: 5.6.2 + dom-accessibility-api: 0.5.16 + lodash-es: 4.18.1 + redent: 3.0.0 + vitest: 2.1.9(@types/node@24.12.2)(jsdom@25.0.1)(lightningcss@1.32.0) + + vitest@2.1.9(@types/node@24.12.2)(jsdom@25.0.1)(lightningcss@1.32.0): + dependencies: + '@vitest/expect': 2.1.9 + '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@24.12.2)(lightningcss@1.32.0)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.9 + '@vitest/snapshot': 2.1.9 + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.3.0 + magic-string: 0.30.21 + pathe: 1.1.2 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.1.1 + tinyrainbow: 1.2.0 + vite: 5.4.21(@types/node@24.12.2)(lightningcss@1.32.0) + vite-node: 2.1.9(@types/node@24.12.2)(lightningcss@1.32.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.12.2 + jsdom: 25.0.1 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + web-namespaces@2.0.1: {} + + webidl-conversions@7.0.0: {} + + webpack-virtual-modules@0.6.2: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + whatwg-url@14.2.0: + dependencies: + tr46: 5.1.1 + webidl-conversions: 7.0.0 + + which-pm-runs@1.1.0: {} + + which-typed-array@1.1.20: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + widest-line@5.0.0: + dependencies: + string-width: 7.2.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + ws@8.20.0: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + + xxhash-wasm@1.1.0: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yaml@2.8.4: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} + + yocto-queue@1.2.2: {} + + yocto-spinner@0.2.3: + dependencies: + yoctocolors: 2.1.2 + + yoctocolors@2.1.2: {} + + zod-to-json-schema@3.25.2(zod@3.25.76): + dependencies: + zod: 3.25.76 + + zod-to-ts@1.2.0(typescript@6.0.3)(zod@3.25.76): + dependencies: + typescript: 6.0.3 + zod: 3.25.76 + + zod@3.25.76: {} + + zod@4.4.3: {} + + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..62386d6 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +packages: + - "packages/*" + - "demo" + - "storybook" + - "docs" diff --git a/scripts/lint-contrast.mjs b/scripts/lint-contrast.mjs new file mode 100644 index 0000000..871d3a6 --- /dev/null +++ b/scripts/lint-contrast.mjs @@ -0,0 +1,180 @@ +#!/usr/bin/env node +/** + * lint-contrast.mjs — vérifie WCAG AA sur les paires texte/fond du DSMMG + * + * Pour chaque preset accent (light + dark), valide : + * - text-primary / text-secondary / text-tertiary sur bg-page, bg-surface, bg-muted + * - accent-on sur accent (le bouton primary doit avoir 4.5:1) + * - accent sur bg-page (composant non-texte ≥ 3:1) + * + * Critères WCAG : + * - Texte normal ≥ 4.5:1 (AA) + * - Texte gros (18pt+/14pt+ bold) ≥ 3:1 (AA-large) + * - Composants non-texte ≥ 3:1 (AA, SC 1.4.11) + * + * Sortie : + * - Console + fichier dist/contrast-report.json + * - Exit code 1 si violation détectée → fail CI + */ +import { readFile, writeFile, mkdir } from "node:fs/promises"; +import { dirname, join } from "node:path"; +import { existsSync } from "node:fs"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const ROOT = join(__dirname, ".."); +const REPORT_DIR = join(ROOT, "dist"); +const REPORT_PATH = join(REPORT_DIR, "contrast-report.json"); + +// — Lecture des tokens depuis le DTCG —————————————————————— +const tokensJson = JSON.parse( + await readFile(join(ROOT, "packages/tokens/src/tokens.json"), "utf8"), +); + +function flatten(obj, prefix = "") { + const out = {}; + for (const [k, v] of Object.entries(obj)) { + if (k.startsWith("$")) continue; + const path = prefix ? `${prefix}.${k}` : k; + if (v && typeof v === "object" && "$value" in v) { + out[path] = v.$value; + } else if (v && typeof v === "object") { + Object.assign(out, flatten(v, path)); + } + } + return out; +} + +const flat = flatten(tokensJson); + +// — Conversion hex → RGB → luminance relative ——————————————— +function hexToRgb(hex) { + const m = hex.replace("#", "").match(/.{2}/g); + if (!m || m.length !== 3) throw new Error(`Invalid hex: ${hex}`); + return m.map((h) => parseInt(h, 16)); +} + +/** WCAG relative luminance (sRGB). */ +function relLuminance([r, g, b]) { + const norm = [r, g, b].map((c) => { + const s = c / 255; + return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4); + }); + return 0.2126 * norm[0] + 0.7152 * norm[1] + 0.0722 * norm[2]; +} + +/** WCAG contrast ratio. */ +function ratio(c1, c2) { + const l1 = relLuminance(hexToRgb(c1)); + const l2 = relLuminance(hexToRgb(c2)); + const [a, b] = l1 > l2 ? [l1, l2] : [l2, l1]; + return (a + 0.05) / (b + 0.05); +} + +// — Définition des presets light —————————————————————————— +const PRESETS = ["synapse", "rose", "blue", "violet", "green", "amber", "red", "cyan", "slate"]; + +// Couleurs sémantiques light (résolues en hard-coded car semantic.css fait +// les indirections via var(--mmg-color-neutral-*) — équivalent ici). +// Reflète semantic.css (text-tertiary bumpé à neutral-600 pour AA). +const LIGHT = { + bgPage: flat["color.neutral.50"], + bgSurface: flat["color.neutral.0"], + bgMuted: flat["color.neutral.150"], + textPrimary: flat["color.neutral.900"], + textSecondary: flat["color.neutral.700"], + textTertiary: flat["color.neutral.600"], +}; + +// — Tests par preset ———————————————————————————————————————— +const results = []; +let failures = 0; + +function check(label, fg, bg, threshold = 4.5) { + const r = ratio(fg, bg); + const pass = r >= threshold; + if (!pass) failures++; + return { label, fg, bg, ratio: +r.toFixed(2), threshold, pass }; +} + +// 1. Texte sur bg-page / bg-surface / bg-muted (sémantique fixe) +results.push({ + group: "Sémantique fixe — light", + tests: [ + check("text-primary on bg-page", LIGHT.textPrimary, LIGHT.bgPage, 4.5), + check("text-secondary on bg-page", LIGHT.textSecondary, LIGHT.bgPage, 4.5), + check("text-tertiary on bg-page", LIGHT.textTertiary, LIGHT.bgPage, 4.5), + check("text-primary on bg-surface", LIGHT.textPrimary, LIGHT.bgSurface, 4.5), + check("text-secondary on bg-surface", LIGHT.textSecondary, LIGHT.bgSurface, 4.5), + check("text-primary on bg-muted", LIGHT.textPrimary, LIGHT.bgMuted, 4.5), + ], +}); + +// 2. Pour chaque preset accent (light) — accent-on sur accent (CTA primary) +// Reflète accent.css : green/cyan utilisent -700 (au lieu de -500), +// slate utilise -700, amber utilise -500 avec accent-on=text-primary. +const ACCENT_SHADE = { + synapse: 500, rose: 500, blue: 500, violet: 500, red: 500, + amber: 600, green: 700, cyan: 700, slate: 700, +}; +const ACCENT_ON = (_preset) => "#FFFFFF"; + +for (const preset of PRESETS) { + const shade = ACCENT_SHADE[preset]; + const accent = flat[`color.${preset}.${shade}`]; + const accentOn = ACCENT_ON(preset); + results.push({ + group: `Accent: ${preset} (${shade}) — light`, + tests: [ + check(`accent-on on ${preset}-${shade}`, accentOn, accent, 4.5), + check(`${preset}-${shade} on bg-page`, accent, LIGHT.bgPage, 3.0), + check(`${preset}-${shade} on bg-surface`, accent, LIGHT.bgSurface, 3.0), + ], + }); +} + +// 3. Sémantique fixe sur bg-page light +// Reflète semantic.css : warning bumpé à amber-600 pour passer AA. +const SEM = { + success: flat["color.green.500"], + warning: flat["color.amber.600"], + danger: flat["color.red.500"], + info: flat["color.blue.500"], +}; +results.push({ + group: "Sémantique success/warning/danger/info — light", + tests: [ + // success (vert): #0E9F6E sur fond clair → contraste sera < 4.5 mais ≥ 3 (composant) + check("success on bg-page", SEM.success, LIGHT.bgPage, 3.0), + check("warning on bg-page", SEM.warning, LIGHT.bgPage, 3.0), + check("danger on bg-page", SEM.danger, LIGHT.bgPage, 3.0), + check("info on bg-page", SEM.info, LIGHT.bgPage, 3.0), + ], +}); + +// — Sortie —————————————————————————————————————————————————— +const total = results.reduce((s, g) => s + g.tests.length, 0); +const passed = total - failures; + +console.log(`\n━━━ DSMMG contrast lint ━━━`); +for (const group of results) { + console.log(`\n${group.group}`); + for (const t of group.tests) { + const icon = t.pass ? "✓" : "✗"; + const color = t.pass ? "\x1b[32m" : "\x1b[31m"; + console.log(` ${color}${icon}\x1b[0m ${t.label.padEnd(40)} ${t.ratio.toFixed(2)}:1 (≥ ${t.threshold}:1)`); + } +} +console.log(`\n${passed}/${total} passed.`); + +if (!existsSync(REPORT_DIR)) await mkdir(REPORT_DIR, { recursive: true }); +await writeFile( + REPORT_PATH, + JSON.stringify({ passed, failed: failures, total, results }, null, 2), +); + +if (failures > 0) { + console.error(`\n✗ ${failures} contrast violation(s).`); + process.exit(1); +} +console.log(`\n✓ All contrast checks pass WCAG AA.`); diff --git a/scripts/migrate-tokens.mjs b/scripts/migrate-tokens.mjs new file mode 100644 index 0000000..0b5755e --- /dev/null +++ b/scripts/migrate-tokens.mjs @@ -0,0 +1,191 @@ +#!/usr/bin/env node +// DSMMG token migration codemod +// Renomme les références --mmg-* legacy vers la nomenclature --mmg-color-*. +// Sûr et idempotent : applique les mappings dans l'ordre du plus spécifique +// au plus générique (longest-match-first). +import { readFile, writeFile, readdir, stat } from "node:fs/promises"; +import { join, extname } from "node:path"; +import { fileURLToPath } from "node:url"; +import { dirname } from "node:path"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const ROOT = join(__dirname, ".."); + +// IMPORTANT : ordre du plus long au plus court pour éviter les collisions +// (ex: --mmg-text-1 doit matcher AVANT --mmg-text-). +const MAPPINGS = [ + // — Texte (couleur) — longest first —————————— + ["--mmg-text-inverse", "--mmg-color-text-inverse"], + ["--mmg-text-1", "--mmg-color-text-primary"], + ["--mmg-text-2", "--mmg-color-text-secondary"], + ["--mmg-text-3", "--mmg-color-text-tertiary"], + ["--mmg-text-4", "--mmg-color-text-quaternary"], + + // — Texte (font-size) — distincts —————————— + ["--mmg-text-xs", "--mmg-font-size-xs"], + ["--mmg-text-sm", "--mmg-font-size-sm"], + ["--mmg-text-base", "--mmg-font-size-base"], + ["--mmg-text-lg", "--mmg-font-size-lg"], + ["--mmg-text-xl", "--mmg-font-size-xl"], + ["--mmg-text-2xl", "--mmg-font-size-2xl"], + ["--mmg-text-3xl", "--mmg-font-size-3xl"], + ["--mmg-text-4xl", "--mmg-font-size-4xl"], + ["--mmg-text-5xl", "--mmg-font-size-5xl"], + + // — Background —————————— + ["--mmg-bg-page", "--mmg-color-bg-page"], + ["--mmg-bg-surface", "--mmg-color-bg-surface"], + ["--mmg-bg-raised", "--mmg-color-bg-raised"], + ["--mmg-bg-muted", "--mmg-color-bg-muted"], + ["--mmg-bg-subtle", "--mmg-color-bg-subtle"], + ["--mmg-bg-overlay", "--mmg-color-bg-overlay"], + + // — Border —————————— + ["--mmg-border-soft", "--mmg-color-border-soft"], + ["--mmg-border-strong", "--mmg-color-border-strong"], + ["--mmg-border", "--mmg-color-border"], + + // — Brand → Accent —————————— + ["--mmg-brand-hover", "--mmg-color-accent-hover"], + ["--mmg-brand-active", "--mmg-color-accent-active"], + ["--mmg-brand-soft", "--mmg-color-accent-soft"], + ["--mmg-brand-border", "--mmg-color-accent-border"], + ["--mmg-brand-strong", "--mmg-color-accent-strong"], + ["--mmg-brand-on", "--mmg-color-accent-on"], + ["--mmg-brand", "--mmg-color-accent"], + + // — Semantic colors —————————— + ["--mmg-success-soft", "--mmg-color-success-soft"], + ["--mmg-success-border", "--mmg-color-success-border"], + ["--mmg-success-strong", "--mmg-color-success-strong"], + ["--mmg-success-on", "--mmg-color-success-on"], + ["--mmg-success", "--mmg-color-success"], + ["--mmg-warning-soft", "--mmg-color-warning-soft"], + ["--mmg-warning-border", "--mmg-color-warning-border"], + ["--mmg-warning-strong", "--mmg-color-warning-strong"], + ["--mmg-warning-on", "--mmg-color-warning-on"], + ["--mmg-warning", "--mmg-color-warning"], + ["--mmg-danger-soft", "--mmg-color-danger-soft"], + ["--mmg-danger-border", "--mmg-color-danger-border"], + ["--mmg-danger-strong", "--mmg-color-danger-strong"], + ["--mmg-danger-on", "--mmg-color-danger-on"], + ["--mmg-danger", "--mmg-color-danger"], + ["--mmg-info-soft", "--mmg-color-info-soft"], + ["--mmg-info-border", "--mmg-color-info-border"], + ["--mmg-info-strong", "--mmg-color-info-strong"], + ["--mmg-info-on", "--mmg-color-info-on"], + ["--mmg-info", "--mmg-color-info"], + + // — Artwork —————————— + ["--mmg-art-major", "--mmg-color-art-major"], + ["--mmg-art-minor", "--mmg-color-art-minor"], + ["--mmg-art-light", "--mmg-color-art-light"], + ["--mmg-art-dark", "--mmg-color-art-dark"], + ["--mmg-art-accent", "--mmg-color-art-accent"], + + // — État système —————————— + ["--mmg-state-disabled-bg", "--mmg-color-state-disabled-bg"], + ["--mmg-state-disabled-text", "--mmg-color-state-disabled-text"], + ["--mmg-state-disabled-border", "--mmg-color-state-disabled-border"], + ["--mmg-state-selection-bg", "--mmg-color-state-selection-bg"], + ["--mmg-state-selection-text", "--mmg-color-state-selection-text"], + + // — Line height —————————— + ["--mmg-leading-tight", "--mmg-line-height-tight"], + ["--mmg-leading-snug", "--mmg-line-height-snug"], + ["--mmg-leading-normal", "--mmg-line-height-normal"], + + // — Font weight —————————— + ["--mmg-weight-regular", "--mmg-font-weight-regular"], + ["--mmg-weight-medium", "--mmg-font-weight-medium"], + ["--mmg-weight-semi", "--mmg-font-weight-semi"], + ["--mmg-weight-bold", "--mmg-font-weight-bold"], + ["--mmg-weight-extra", "--mmg-font-weight-extra"], + + // — Shadow accent —————————— + ["--mmg-shadow-brand-hover", "--mmg-shadow-accent-hover"], + ["--mmg-shadow-brand-soft", "--mmg-shadow-accent-soft"], + ["--mmg-shadow-brand", "--mmg-shadow-accent"], +]; + +// Cibles : tous les .css et .tsx hors node_modules / dist / tokens (déjà OK) +const TARGET_DIRS = [ + "packages/css/src/components", + "packages/css/src", // pour base.css uniquement, on filtre tokens via skip + "packages/react/src", + "demo/src", +]; +const SKIP_FILES = new Set([ + // Les nouveaux tokens sont déjà à la nouvelle nomenclature. + "tokens.css", + "primitives.css", + "semantic.css", + "accent.css", + "system.css", +]); +const EXTS = new Set([".css", ".tsx", ".ts"]); + +async function* walk(dir) { + const entries = await readdir(dir, { withFileTypes: true }); + for (const e of entries) { + if (e.name === "node_modules" || e.name === "dist") continue; + const full = join(dir, e.name); + if (e.isDirectory()) yield* walk(full); + else yield full; + } +} + +function migrate(content) { + let out = content; + let count = 0; + for (const [from, to] of MAPPINGS) { + // Word-boundary safe : --mmg-brand ne doit PAS matcher dans --mmg-brand-soft. + // Comme MAPPINGS est trié longest-first, lorsque --mmg-brand est traité, + // les longs ont déjà été remplacés. Mais on ajoute un lookahead négatif + // pour les caractères pouvant prolonger un identifiant CSS (-, lettre, chiffre). + const re = new RegExp(escape(from) + "(?![\\w-])", "g"); + const matches = out.match(re); + if (matches) { + count += matches.length; + out = out.replace(re, to); + } + } + return { out, count }; +} + +function escape(s) { + return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + +async function main() { + let totalReplacements = 0; + let touched = 0; + for (const rel of TARGET_DIRS) { + const dir = join(ROOT, rel); + try { + await stat(dir); + } catch { + continue; + } + for await (const file of walk(dir)) { + const ext = extname(file); + if (!EXTS.has(ext)) continue; + const base = file.split(/[\\/]/).pop(); + if (SKIP_FILES.has(base)) continue; + const content = await readFile(file, "utf8"); + const { out, count } = migrate(content); + if (count > 0) { + await writeFile(file, out, "utf8"); + touched += 1; + totalReplacements += count; + console.log(` ${count.toString().padStart(4)} ${file.replace(ROOT, "")}`); + } + } + } + console.log(`\n✓ ${totalReplacements} replacements across ${touched} files`); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/storybook/.storybook/main.ts b/storybook/.storybook/main.ts new file mode 100644 index 0000000..2c36fa6 --- /dev/null +++ b/storybook/.storybook/main.ts @@ -0,0 +1,27 @@ +import type { StorybookConfig } from "@storybook/react-vite"; + +const config: StorybookConfig = { + stories: ["../stories/**/*.mdx", "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + addons: [ + "@storybook/addon-essentials", + "@storybook/addon-interactions", + "@storybook/addon-a11y", + ], + framework: { + name: "@storybook/react-vite", + options: {}, + }, + docs: { + autodocs: "tag", + }, + typescript: { + reactDocgen: "react-docgen-typescript", + reactDocgenTypescriptOptions: { + shouldExtractLiteralValuesFromEnum: true, + propFilter: (prop) => + prop.parent ? !/node_modules/.test(prop.parent.fileName) : true, + }, + }, + staticDirs: ["../public"], +}; +export default config; diff --git a/storybook/.storybook/preview.css b/storybook/.storybook/preview.css new file mode 100644 index 0000000..9d8c3a4 --- /dev/null +++ b/storybook/.storybook/preview.css @@ -0,0 +1,3 @@ +/* Override le fond Storybook pour utiliser nos tokens */ +body { font-family: var(--mmg-font-sans); } +.docs-story { background: var(--mmg-color-bg-page); } diff --git a/storybook/.storybook/preview.ts b/storybook/.storybook/preview.ts new file mode 100644 index 0000000..fb3f3cd --- /dev/null +++ b/storybook/.storybook/preview.ts @@ -0,0 +1,126 @@ +import type { Preview } from "@storybook/react"; +import "@managemate/css"; +import "@managemate/icons"; +import "./preview.css"; + +const preview: Preview = { + parameters: { + layout: "padded", + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + backgrounds: { + default: "page", + values: [ + { name: "page", value: "var(--mmg-color-bg-page)" }, + { name: "surface", value: "var(--mmg-color-bg-surface)" }, + { name: "white", value: "#FFFFFF" }, + { name: "dark", value: "#0B0D14" }, + ], + }, + a11y: { + // axe-core configuration. WCAG 2.1 AA + RGAA tags. + config: { + rules: [ + { id: "color-contrast", enabled: true }, + { id: "label", enabled: true }, + { id: "button-name", enabled: true }, + ], + }, + options: { + runOnly: { + type: "tag", + values: ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "best-practice"], + }, + }, + }, + options: { + storySort: { + order: [ + "Intro", + "Tokens", + ["Colors", "Spacing", "Typography", "Shadows", "Motion"], + "Layout", + "Forms", + ["Button", "Input", "Select", "Checkbox", "Radio", "Switch"], + "Feedback", + "Overlays", + "Navigation", + "Data display", + "Advanced", + "Theming", + ], + }, + }, + }, + globalTypes: { + theme: { + description: "Thème global", + defaultValue: "light", + toolbar: { + title: "Thème", + icon: "circlehollow", + items: [ + { value: "light", title: "Light" }, + { value: "dark", title: "Dark" }, + { value: "system", title: "Système" }, + ], + dynamicTitle: true, + }, + }, + accent: { + description: "Couleur d'accent (preset DSMMG)", + defaultValue: "synapse", + toolbar: { + title: "Accent", + icon: "paintbrush", + items: [ + { value: "synapse", title: "Synapse (rose)" }, + { value: "rose", title: "Rose vif" }, + { value: "blue", title: "Bleu" }, + { value: "violet", title: "Violet" }, + { value: "green", title: "Vert" }, + { value: "amber", title: "Ambre" }, + { value: "red", title: "Rouge" }, + { value: "cyan", title: "Cyan" }, + { value: "slate", title: "Ardoise" }, + ], + dynamicTitle: true, + }, + }, + density: { + description: "Densité", + defaultValue: "comfortable", + toolbar: { + title: "Densité", + icon: "component", + items: [ + { value: "comfortable", title: "Comfortable" }, + { value: "cozy", title: "Cozy" }, + { value: "compact", title: "Compact" }, + ], + dynamicTitle: true, + }, + }, + }, + decorators: [ + (Story, ctx) => { + const root = document.documentElement; + // Theme + if (ctx.globals.theme === "system") root.removeAttribute("data-mmg-theme"); + else root.setAttribute("data-mmg-theme", ctx.globals.theme); + // Accent + if (ctx.globals.accent === "synapse") root.removeAttribute("data-mmg-accent"); + else root.setAttribute("data-mmg-accent", ctx.globals.accent); + // Density + if (ctx.globals.density === "comfortable") root.removeAttribute("data-mmg-density"); + else root.setAttribute("data-mmg-density", ctx.globals.density); + return Story(); + }, + ], +}; + +export default preview; diff --git a/storybook/package.json b/storybook/package.json new file mode 100644 index 0000000..7e66bcb --- /dev/null +++ b/storybook/package.json @@ -0,0 +1,33 @@ +{ + "name": "storybook", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "storybook dev -p 6006", + "build": "storybook build", + "preview": "vite preview --outDir storybook-static" + }, + "dependencies": { + "@managemate/css": "workspace:*", + "@managemate/icons": "workspace:*", + "@managemate/react": "workspace:*", + "react": "^19.2.5", + "react-dom": "^19.2.5" + }, + "devDependencies": { + "@storybook/addon-a11y": "^8.5.0", + "@storybook/addon-essentials": "^8.5.0", + "@storybook/addon-interactions": "^8.5.0", + "@storybook/blocks": "^8.5.0", + "@storybook/react": "^8.5.0", + "@storybook/react-vite": "^8.5.0", + "@storybook/test": "^8.5.0", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^4.3.4", + "storybook": "^8.5.0", + "typescript": "~5.7.0", + "vite": "^5.4.11" + } +} diff --git a/storybook/stories/Button.stories.tsx b/storybook/stories/Button.stories.tsx new file mode 100644 index 0000000..c3bd02c --- /dev/null +++ b/storybook/stories/Button.stories.tsx @@ -0,0 +1,79 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { Button } from "@managemate/react"; + +const meta = { + title: "Forms/Button", + component: Button, + tags: ["autodocs"], + parameters: { + docs: { + description: { + component: + "Bouton DSMMG avec variants Material 3 / Fluent. Pill par défaut. Tous les états (default, hover, active, focus-visible, disabled, loading) sont stylés. Touch target 44×44 garanti pour `icon-only`.", + }, + }, + }, + argTypes: { + variant: { + control: "select", + options: ["primary", "tonal", "secondary", "tertiary", "ghost", "elevated", "danger", "success"], + }, + size: { control: "select", options: ["xs", "sm", "md", "lg", "xl"] }, + loading: { control: "boolean" }, + disabled: { control: "boolean" }, + block: { control: "boolean" }, + }, + args: { children: "Continuer", variant: "primary", size: "md" }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Primary: Story = {}; + +export const Tonal: Story = { args: { variant: "tonal" } }; +export const Secondary: Story = { args: { variant: "secondary" } }; +export const Tertiary: Story = { args: { variant: "tertiary" } }; +export const Ghost: Story = { args: { variant: "ghost" } }; +export const Elevated: Story = { args: { variant: "elevated" } }; +export const Danger: Story = { args: { variant: "danger", children: "Supprimer" } }; +export const Success: Story = { args: { variant: "success", children: "Valider" } }; + +export const Loading: Story = { args: { loading: true } }; +export const Disabled: Story = { args: { disabled: true } }; +export const Block: Story = { args: { block: true } }; + +export const WithIcon: Story = { + args: { icon: "arrow-right-line", iconPosition: "right" }, +}; + +export const IconOnly: Story = { + args: { icon: "settings-3-line", "aria-label": "Paramètres", children: undefined }, +}; + +export const AllSizes: Story = { + render: (args) => ( +
+ + + + + +
+ ), +}; + +export const AllVariants: Story = { + render: () => ( +
+ + + + + + + + +
+ ), +}; diff --git a/storybook/stories/Combobox.stories.tsx b/storybook/stories/Combobox.stories.tsx new file mode 100644 index 0000000..4be393a --- /dev/null +++ b/storybook/stories/Combobox.stories.tsx @@ -0,0 +1,46 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { Combobox } from "@managemate/react"; + +const meta = { + title: "Forms/Combobox", + component: Combobox, + tags: ["autodocs"], + parameters: { + docs: { + description: { + component: + "Combobox WAI-ARIA 1.2 (combobox + listbox). Floating UI pour positionnement, aria-activedescendant pour le focus virtuel sur l'option courante.", + }, + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const COUNTRIES = [ + { value: "fr", label: "France" }, + { value: "be", label: "Belgique" }, + { value: "ch", label: "Suisse" }, + { value: "ca", label: "Canada" }, + { value: "lu", label: "Luxembourg" }, + { value: "ma", label: "Maroc" }, + { value: "tn", label: "Tunisie" }, + { value: "sn", label: "Sénégal" }, + { value: "ci", label: "Côte d'Ivoire" }, +]; + +export const Default: Story = { + render: () => { + const [val, setVal] = useState(); + return ( +
+ +

+ Sélectionné : {val ?? "—"} +

+
+ ); + }, +}; diff --git a/storybook/stories/Dialog.stories.tsx b/storybook/stories/Dialog.stories.tsx new file mode 100644 index 0000000..c1eb232 --- /dev/null +++ b/storybook/stories/Dialog.stories.tsx @@ -0,0 +1,64 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import { Dialog, ConfirmDialog, Button } from "@managemate/react"; + +const meta = { + title: "Overlays/Dialog", + component: Dialog, + tags: ["autodocs"], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: () => { + const [open, setOpen] = useState(false); + return ( + <> + + + + +

+ } + > +

Contenu du dialog…

+ + + ); + }, +}; + +export const Confirm: Story = { + name: "ConfirmDialog (destructive)", + render: () => { + const [open, setOpen] = useState(false); + return ( + <> + + alert("Confirmé")} + /> + + ); + }, +}; diff --git a/storybook/stories/Intro.mdx b/storybook/stories/Intro.mdx new file mode 100644 index 0000000..f1885ae --- /dev/null +++ b/storybook/stories/Intro.mdx @@ -0,0 +1,58 @@ +import { Meta } from "@storybook/blocks"; + + + +# DSMMG — Design System ManageMate Group + +Référence pour designers et développeurs des produits ManageMate (Synapse, HRTime, Forge, Orbit, MSLM, Espace-Client, sites publics). + +## Principes + +1. **Accessibilité non-négociable** — RGAA 4.1 / WCAG 2.2 AA, validé via axe-core en CI sur chaque composant. +2. **Headless-first** — comportement (focus, keyboard, ARIA) découplé du style. Primitives Radix UI / Floating UI dessous. +3. **Tokens partout** — aucun hex en dur, aucun `--mmg-color-synapse` direct. Tout passe par les sémantiques (`--mmg-color-text-primary`, `--mmg-color-bg-surface`) et l'accent (`--mmg-color-accent`). +4. **Tree-shakable** — un composant = un fichier. `sideEffects: false`. Les imports inutilisés sont droppés par les bundlers consommateurs. + +## Theming utilisateur + +Chaque utilisateur peut choisir son accent (rose Synapse par défaut). 9 presets validés AA : +- `synapse` (rose corporate, défaut) +- `rose`, `blue`, `violet`, `green`, `amber`, `red`, `cyan`, `slate` + +Le picker change en live ici (toolbar Storybook → "Accent"). Voir aussi le composant **``** dans `Theming`. + +## Density + +3 modes adaptables via `[data-mmg-density]` : +- `comfortable` (défaut, public) +- `cozy` (apps métier) +- `compact` (power users) + +## Standards + +- shadcn/ui + Radix UI (architecture, primitives a11y) +- Linear, Notion, Vercel, Stripe (références SaaS dense) +- DSFR (méthodologie a11y) +- Atlassian DS, IBM Carbon (apps enterprise) + +## Conventions de naming + +| Catégorie | Préfixe | +|---|---| +| Tokens couleur | `--mmg-color-*` | +| Tokens taille | `--mmg-space-*`, `--mmg-radius-*`, `--mmg-font-size-*` | +| Tokens motion | `--mmg-duration-*`, `--mmg-ease-*` | +| Classes CSS | `mmg-` | +| Classes utilitaires | `mmg-u-*` | +| Variantes BEM | `mmg---` | +| Sous-éléments BEM | `mmg-__` | + +## Navigation + +- **Tokens** — primitives, sémantiques, accent, motion +- **Forms** — Button, Input, Select, Checkbox, Radio, Switch, Combobox +- **Layout** — Container, Stack, Grid, Card, Tile +- **Overlays** — Tooltip, Popover, Menu, Dialog (tous Radix-backed) +- **Navigation** — Header, Footer, Breadcrumb, Tabs, Pagination, AppShell +- **Data display** — DataTable, Stat, Avatar, Tag, Badge, Progress +- **Theming** — ThemePicker, dark mode toggle diff --git a/storybook/stories/ThemePicker.stories.tsx b/storybook/stories/ThemePicker.stories.tsx new file mode 100644 index 0000000..38ea605 --- /dev/null +++ b/storybook/stories/ThemePicker.stories.tsx @@ -0,0 +1,43 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { ThemePicker, Button, Card } from "@managemate/react"; + +const meta = { + title: "Theming/ThemePicker", + component: ThemePicker, + tags: ["autodocs"], + parameters: { + docs: { + description: { + component: + "Sélecteur de couleur d'accent utilisateur. Pattern radiogroup avec navigation flèches, persistance localStorage. 9 presets validés AA.", + }, + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + render: () => , +}; + +export const InCard: Story = { + render: () => ( + +

Préférences d'apparence

+

+ Choisissez la couleur d'accent qui vous convient. Cette préférence est sauvegardée localement. +

+ +
+ + +
+
+ ), +}; + +export const HiddenReset: Story = { + render: () => , +}; diff --git a/storybook/stories/Tokens.stories.tsx b/storybook/stories/Tokens.stories.tsx new file mode 100644 index 0000000..706db3c --- /dev/null +++ b/storybook/stories/Tokens.stories.tsx @@ -0,0 +1,160 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +const meta = { + title: "Tokens/Colors", + parameters: { + layout: "padded", + docs: { + description: { + component: + "Tokens couleur DSMMG. Les sémantiques se réfèrent aux primitives — c'est ce que les composants consomment. L'accent est user-themable via `[data-mmg-accent]`.", + }, + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const Swatch = ({ name, css }: { name: string; css: string }) => ( +
+
+
+ {css} +
+
{name}
+
+); + +const Grid = ({ children }: { children: React.ReactNode }) => ( +
+ {children} +
+); + +export const Surfaces: Story = { + render: () => ( + + + + + + + + ), +}; + +export const Borders: Story = { + render: () => ( + + + + + + ), +}; + +export const Text: Story = { + render: () => ( + + + + + + + ), +}; + +export const Accent: Story = { + render: () => ( + + + + + + + + + + ), +}; + +export const Semantic: Story = { + render: () => ( + <> +

Success

+ + + + + + +

Warning

+ + + + + + +

Danger

+ + + + + + +

Info

+ + + + + + + + ), +}; + +const palette = (name: string, label: string) => { + const shades = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900]; + return ( + <> +

{label}

+ + {shades.map((s) => ( + + ))} + + + ); +}; + +export const Palettes: Story = { + render: () => ( + <> + {palette("synapse", "Synapse (default)")} + {palette("rose", "Rose")} + {palette("blue", "Blue")} + {palette("violet", "Violet")} + {palette("green", "Green")} + {palette("amber", "Amber")} + {palette("red", "Red")} + {palette("cyan", "Cyan")} + {palette("slate", "Slate")} + + ), +}; diff --git a/storybook/stories/Tooltip.stories.tsx b/storybook/stories/Tooltip.stories.tsx new file mode 100644 index 0000000..e6be430 --- /dev/null +++ b/storybook/stories/Tooltip.stories.tsx @@ -0,0 +1,47 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { Tooltip, TooltipProvider, Button } from "@managemate/react"; + +const meta = { + title: "Overlays/Tooltip", + component: Tooltip, + tags: ["autodocs"], + decorators: [ + (Story) => ( + + + + ), + ], + parameters: { + docs: { + description: { + component: + "Tooltip basé sur Radix UI. Auto-flip, focus management, Escape, prefers-reduced-motion. Exige `` à la racine.", + }, + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { content: "Action sécurisée" }, + render: (args) => ( + + + + ), +}; + +export const Placements: Story = { + render: () => ( +
+ {(["top", "right", "bottom", "left"] as const).map((p) => ( + + + + ))} +
+ ), +};