diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml new file mode 100644 index 0000000..4a9c614 --- /dev/null +++ b/.github/workflows/deploy-pages.yml @@ -0,0 +1,90 @@ +name: Deploy site to GitHub Pages + +# Builds the Next.js static export from `site/` and publishes it to the +# `gh-pages` branch (project root). PR previews live under `pr//` on +# the same branch — see `preview-pr.yml`. `keep_files: true` preserves +# those subdirectories when main republishes. +# +# Both workflows share the `gh-pages-write` concurrency group so they +# can't push to `gh-pages` at the same time and clobber each other. +# +# `SITE_ORIGIN` and `SITE_BASE_PATH` default to the project-Pages URL +# derived from repo metadata. Override via repo variables +# (Settings → Secrets and variables → Actions → Variables) when cutting +# over to a custom domain — both workflows read the same vars, so a +# single edit keeps main and previews in lockstep. + +on: + push: + branches: [main] + paths: + - "skills/**" + - "site/**" + - ".github/workflows/deploy-pages.yml" + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: gh-pages-write + cancel-in-progress: false + +defaults: + run: + working-directory: site + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + SITE_ORIGIN: ${{ vars.SITE_ORIGIN || format('https://{0}.github.io/{1}', github.repository_owner, github.event.repository.name) }} + NEXT_BASE_PATH: ${{ vars.SITE_BASE_PATH || format('/{0}', github.event.repository.name) }} + steps: + - uses: actions/checkout@v4 + + - uses: pnpm/action-setup@v4 + with: + version: 10.15.1 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + cache-dependency-path: site/pnpm-lock.yaml + + - run: pnpm install --frozen-lockfile + + - run: pnpm lint + + - run: pnpm lint:ts + + - run: pnpm build + + - name: Verify hero text matches SITE_ORIGIN (no subpath leak) + run: | + HOST="${SITE_ORIGIN#https://}" + HOST="${HOST#http://}" + # Single exact-match check: the hero pill text is wrapped by + # tag boundaries, so requiring `>...<` rejects both a missing + # match AND any subpath leak (`/pr/N`, etc.) that would change + # the content between the tags. + if ! grep -qF ">Read ${HOST} before you start building on Stellar.<" out/index.html; then + echo "::error::Hero pill text in out/index.html doesn't exactly match SITE_ORIGIN=${SITE_ORIGIN}" + exit 1 + fi + + # peaceiris/actions-gh-pages@v4.1.0 pinned to commit SHA for + # supply-chain safety. Bump intentionally when reviewing release + # notes. Dependabot can automate this once `github-actions` + # updates are enabled. + - name: Publish to gh-pages + uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: site/out + publish_branch: gh-pages + # Don't wipe pr// subdirectories owned by preview-pr.yml. + keep_files: true + commit_message: "deploy: main @ ${{ github.sha }}" diff --git a/.github/workflows/preview-pr.yml b/.github/workflows/preview-pr.yml new file mode 100644 index 0000000..b5c3408 --- /dev/null +++ b/.github/workflows/preview-pr.yml @@ -0,0 +1,120 @@ +name: Deploy PR preview + +# Internal-PR-only preview deployments. Each PR gets its own +# subdirectory on the `gh-pages` branch (`pr//`) and a comment with +# the URL. The same workflow tears the subdirectory down when the PR +# closes, so previews don't accumulate. +# +# `SITE_ORIGIN` deliberately matches main (production), NOT the preview +# URL. The hero pill, copy-pastable card URLs, and `llms.txt` show what +# users will see after merge — preview URLs would die when the PR +# closes and poison anything that copied them. Only `NEXT_BASE_PATH` +# varies, so Next.js routes assets to the preview subpath while the +# displayed content stays canonical. `IS_PREVIEW` renders a banner so +# reviewers know what they're looking at. +# +# Fork PRs are intentionally skipped (see the `if:` guard below): they +# can't safely receive the repo's GITHUB_TOKEN, and our `peaceiris` + +# `rossjrw` steps need write access to push to `gh-pages` and comment. +# +# Concurrency: both this workflow and `deploy-pages.yml` use the shared +# `gh-pages-write` group so two simultaneous pushes to `gh-pages` can't +# collide. `cancel-in-progress: false` keeps each preview build to +# completion; PRs in rapid succession queue rather than thrash. + +on: + pull_request: + types: [opened, reopened, synchronize, closed] + branches: [main] + +permissions: + contents: write + pull-requests: write + +concurrency: + group: gh-pages-write + cancel-in-progress: false + +defaults: + run: + working-directory: site + +jobs: + preview: + # Skip PRs opened from forks (no write token, can't deploy). + if: github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + # Production origin (same as main) — see header comment. + SITE_ORIGIN: ${{ vars.SITE_ORIGIN || format('https://{0}.github.io/{1}', github.repository_owner, github.event.repository.name) }} + # Preview-scoped path so assets resolve under pr//. + NEXT_BASE_PATH: ${{ vars.SITE_BASE_PATH || format('/{0}', github.event.repository.name) }}/pr/${{ github.event.number }} + IS_PREVIEW: "true" + # PR head SHA so card "view source" links resolve for newly-added + # files that aren't on main yet. + GITHUB_SOURCE_REF: ${{ github.event.pull_request.head.sha }} + GITHUB_PR_NUMBER: ${{ github.event.number }} + steps: + # Explicitly check out the PR head, not the auto-generated merge + # commit. The merge commit can drift from the PR's actual state + # (e.g., when base advances), so building head.sha makes the + # preview match exactly what was pushed to the PR. + - if: github.event.action != 'closed' + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + # On `closed` events we don't build. We just need a checkout for + # the cleanup step to run from. + - if: github.event.action == 'closed' + uses: actions/checkout@v4 + + - if: github.event.action != 'closed' + uses: pnpm/action-setup@v4 + with: + version: 10.15.1 + + - if: github.event.action != 'closed' + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + cache-dependency-path: site/pnpm-lock.yaml + + - if: github.event.action != 'closed' + run: pnpm install --frozen-lockfile + + - if: github.event.action != 'closed' + run: pnpm lint + + - if: github.event.action != 'closed' + run: pnpm lint:ts + + - if: github.event.action != 'closed' + run: pnpm build + + - name: Verify hero text matches production SITE_ORIGIN (no PR path leak) + if: github.event.action != 'closed' + run: | + HOST="${SITE_ORIGIN#https://}" + HOST="${HOST#http://}" + # Single exact-match check: requiring tag boundaries on either + # side rejects subpath leaks (`pr//`, asset prefixes, etc.) + # that would otherwise pass a loose `grep -qF`. + if ! grep -qF ">Read ${HOST} before you start building on Stellar.<" out/index.html; then + echo "::error::Hero pill text in out/index.html doesn't exactly match SITE_ORIGIN=${SITE_ORIGIN}" + exit 1 + fi + + # rossjrw/pr-preview-action@v1.8.1 pinned to commit SHA for + # supply-chain safety. Bump intentionally when reviewing release + # notes. Dependabot can automate this once `github-actions` + # updates are enabled. + - name: Deploy / remove preview + uses: rossjrw/pr-preview-action@ffa7509e91a3ec8dfc2e5536c4d5c1acdf7a6de9 + with: + source-dir: site/out + preview-branch: gh-pages + umbrella-dir: pr + action: auto diff --git a/site/.env.example b/site/.env.example new file mode 100644 index 0000000..9ac3540 --- /dev/null +++ b/site/.env.example @@ -0,0 +1,56 @@ +# Site env variables. +# +# Local dev needs none of these — `pnpm dev` works with all defaults. +# To override locally, copy this file to `.env.local` (gitignored) and +# uncomment the values you want to set. +# +# README.md → "Build-time env vars" is the canonical reference; mirror +# changes there when you edit this file. + +# ----------------------------------------------------------------------------- +# Site origin and base path +# ----------------------------------------------------------------------------- + +# Canonical public origin used in displayed/copied URLs, sitemap, and +# llms.txt. Default: http://localhost:3000. +# +# SITE_ORIGIN=https://skills.stellar.org + +# Next.js asset path prefix. Set automatically by the deploy workflows to +# match the GitHub Pages project subpath; unset for custom-domain +# deployments. Unset locally. +# +# NEXT_BASE_PATH=/stellar-dev-skill + +# ----------------------------------------------------------------------------- +# Preview build flags (set by preview-pr.yml, not for local use) +# ----------------------------------------------------------------------------- + +# Renders the "PR preview" banner and forces noindex/nofollow when "true". +# +# IS_PREVIEW=true + +# PR number for the banner link. +# +# GITHUB_PR_NUMBER=42 + +# Git ref used in card "view source" links. Default: "main". +# +# GITHUB_SOURCE_REF=feature-branch + +# owner/repo for "view source" links and the preview banner. The GitHub +# Actions runner sets this automatically; the upstream repo is the default +# locally. +# +# GITHUB_REPOSITORY=stellar/stellar-dev-skill + +# ----------------------------------------------------------------------------- +# Analytics +# ----------------------------------------------------------------------------- + +# Set to "true" to disable Google Tag Manager in production builds. GTM +# is loaded via @next/third-parties in src/app/layout.tsx. In development +# (NODE_ENV !== "production") and in PR previews (IS_PREVIEW=true) GTM is +# always disabled regardless of this flag. +# +# NEXT_PUBLIC_DISABLE_GOOGLE_ANALYTICS=true diff --git a/site/.eslintrc.json b/site/.eslintrc.json new file mode 100644 index 0000000..8877bea --- /dev/null +++ b/site/.eslintrc.json @@ -0,0 +1,13 @@ +{ + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "next/core-web-vitals", + "prettier" + ], + "rules": { + "@typescript-eslint/no-explicit-any": "warn", + "import/first": "error", + "import/named": "off" + } +} diff --git a/site/.gitignore b/site/.gitignore new file mode 100644 index 0000000..dfba631 --- /dev/null +++ b/site/.gitignore @@ -0,0 +1,53 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +package-lock.json + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# typescript +*.tsbuildinfo +next-env.d.ts + +# test files +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ + +# ide settings +/.idea/ +/.vscode/ +/.kiro/ + +# versions +mise.toml + +# copied at build time from ../skills/ +/public/skills/ + +# generated at build time from src/data/skills.ts +/public/llms.txt diff --git a/site/.prettierrc.json b/site/.prettierrc.json new file mode 100644 index 0000000..05d2e77 --- /dev/null +++ b/site/.prettierrc.json @@ -0,0 +1,11 @@ +{ + "bracketSpacing": true, + "bracketSameLine": false, + "printWidth": 80, + "proseWrap": "always", + "semi": true, + "singleQuote": false, + "tabWidth": 2, + "trailingComma": "all", + "useTabs": false +} diff --git a/site/CLAUDE.md b/site/CLAUDE.md new file mode 100644 index 0000000..aa7665f --- /dev/null +++ b/site/CLAUDE.md @@ -0,0 +1,130 @@ +# Claude Code Instructions for `site/` + +The landing page that ships with this repo, served at +[skills.stellar.org](https://skills.stellar.org). See +[README.md](README.md) for the public-facing overview. + +The skill markdown lives at `../skills/` (the repo root). This site +mirrors those files into `public/skills/` at build time and exposes +them as copy-pastable URLs plus an `/llms.txt` index. + +## SSR is the point + +The page is a server component, statically generated at build time and +exported (`next build` with `output: 'export'` produces `out/`). The +full HTML returned by `GET /` already contains every card's title, +description, URL, and `data-category`. AI agents and crawlers do not +need to run JavaScript. The same data builds `public/llms.txt`. Both +the UI and llms.txt read from `src/data/skills.ts`. + +When making changes: anything that should be visible to agents must +render on the server in `src/app/page.tsx` or +`src/app/_components/SkillCard.tsx`. Don't move card data into a +client component. + +## Where things live + +- `src/data/skills.ts`: single source of truth. + `SKILL_CARD_SOURCES` (main list), `ECOSYSTEM_CARDS` (community + section), `FilterType` / `FILTERS` (category tabs). +- `src/lib/skill-meta.mjs`: parses each upstream SKILL.md's + frontmatter `description` and first `# heading` so cards default to + upstream metadata when `title` / `description` aren't overridden in + skills.ts. Shared by `src/app/page.tsx` and + `scripts/generate-llms-txt.mjs`. +- `src/app/page.tsx`: server-rendered landing page. +- `src/app/_components/`: `SkillCard` (server), `icons` (server, inline + SVGs), `CopyButton` / `SkillsFilter` / `ThemeSwitchIsland` (client + islands). `SkillsFilter` is used twice — once for the skills grid + (`All` + categories) and once for the Installing section's tabs + (Claude Code / Cursor / npx skills / Clone repo). +- `scripts/copy-skills.mjs`: mirrors `../skills/` into + `public/` on `predev` / `prebuild`. No network; just `cp`. +- `scripts/generate-llms-txt.mjs`: writes `public/llms.txt` from + `src/data/skills.ts`. Imports the frontmatter parser from + `src/lib/skill-meta.mjs` so the index and the page agree. +- `next.config.js`: `output: 'export'` and a tree-shake hint for + `@stellar/design-system`. No headers function (GitHub Pages doesn't + set response headers), no middleware. + +There is no routing beyond `/`, no API routes, no backend, no test +runner. + +## Quick reference + +```bash +pnpm dev # predev: cached copy + regen llms.txt +pnpm build # prebuild: strict copy + regen llms.txt; static export +pnpm lint # eslint +pnpm lint:ts # tsc --noEmit +pnpm sync:skills # refresh public/skills/ from ../skills/ +pnpm generate:llms-txt # regenerate public/llms.txt +``` + +## Adding a skill + +**Main list:** add `skills//SKILL.md` at the repo root, +then append to `SKILL_CARD_SOURCES`: + +```ts +{ + source: "skills//SKILL.md", + category: "Soroban", // any FilterType value + // Optional overrides — both default to the upstream SKILL.md's + // first H1 (title) and frontmatter `description`. + title: "Your Skill Title", + description: "Verb-led summary of what this skill teaches.", +} +``` + +`pnpm sync:skills && pnpm dev` to verify. New category? Add it to the +`FilterType` union and the `FILTERS` array. + +**Ecosystem:** external link, no upstream copy. + +```ts +{ + title: "Project Name", + description: "Verb-led summary of what the skill does.", + pathLabel: "owner/repo", + copyValue: "https://github.com/owner/repo/blob/main/path/to/SKILL.md", + category: "Ecosystem", +} +``` + +## Conventions + +- Use `@stellar/design-system` components; don't hand-roll UI primitives. +- SCSS files only; no inline `style={}`. +- `@/` path alias for imports from `src/`. +- `"use client"` only for components using hooks, `window`, or + `useSearchParams`. +- PascalCase components, camelCase helpers, `use` prefix for hooks. +- Skill descriptions: lead with a verb, list concrete topics, no em-dashes. + +## Don't add + +- No state libraries (Zustand, React Query). Plain `useState` is enough. +- No `@stellar/stellar-sdk`, no XDR, no transaction logic. The app + makes no network requests at runtime. +- No Jest, Playwright, Sentry, or pre-commit hooks unless asked. +- No middleware. (Static export wouldn't run it anyway.) + +## Before merging + +- `pnpm lint:ts` passes +- `pnpm lint` passes +- `pnpm build` succeeds (produces `out/`) +- Card data still rendered server-side (visible in + `curl out/index.html`) +- No em-dashes in descriptions or docs + +## Deploy + +`.github/workflows/deploy-pages.yml` at the repo root. Triggered on +push to `main` when `skills/**` or `site/**` changes. Builds the +static export and publishes to GitHub Pages. + +Deploy URL and basePath are controlled by `NEXT_BASE_PATH` and +`SITE_ORIGIN` env vars in that workflow — see `README.md` → Deploying +for the cutover from project Pages URL to custom domain. diff --git a/site/README.md b/site/README.md new file mode 100644 index 0000000..23e2873 --- /dev/null +++ b/site/README.md @@ -0,0 +1,184 @@ +# skills.stellar.org + +The landing page that ships with [stellar/stellar-dev-skill](../README.md). A +static Next.js site that mirrors every `SKILL.md` under `../skills/` and +exposes them as a copy-pastable directory at +[skills.stellar.org](https://skills.stellar.org), plus an `/llms.txt` +index for AI agents. + +The same data drives both surfaces, so `curl /` returns the full +catalog inline. + +## Local development + +Prerequisites: Node.js >= 22.22.0, pnpm >= 10.15.1. + +```sh +pnpm install +pnpm dev +``` + +Scripts: + +```sh +pnpm dev # next dev (cached sibling-skill copy) +pnpm build # static export to out/ (fresh copy + llms.txt) +pnpm lint # eslint +pnpm lint:ts # tsc --noEmit +pnpm sync:skills # refresh public/skills/ from ../skills/ +pnpm generate:llms-txt # regenerate public/llms.txt +``` + +## How content stays in sync + +The site lives in `site/` alongside `skills/` at the repo root. Each +entry in `src/data/skills.ts` has a `source` field pointing at an +upstream path (e.g. `skills/soroban/SKILL.md`). +`scripts/copy-skills.mjs` mirrors that path verbatim into `public/` +on `predev` / `prebuild`. There's no network fetch and no upstream ref +to pin: the site always reflects whatever's on disk in `../skills/`, +so a PR touching a skill and the site stays internally consistent. + +Both `public/skills/` and `public/llms.txt` are generated and +gitignored. + +Card titles and descriptions default to the upstream SKILL.md's first +H1 and frontmatter `description`. Override them per card in +`src/data/skills.ts` when you want a shorter title or a different +summary for the landing card. (llms.txt always prefers the upstream +frontmatter so AI agents still see the longer, agent-tuned summary.) + +## Deploying + +GitHub Pages, branch-based, via two workflows at the repo root: + +- `.github/workflows/deploy-pages.yml` — runs on push to `main` when + `skills/**` or `site/**` changes. Publishes `site/out/` to the root + of the `gh-pages` branch with `keep_files: true` so it doesn't + trample PR preview subdirectories. +- `.github/workflows/preview-pr.yml` — runs on every internal-branch + PR targeting `main`. Publishes to `gh-pages:/pr//` and comments + the preview URL on the PR. Cleans up the subdirectory when the PR + closes. PRs from forks are skipped (no write token). + +PR authors and branch creators do nothing: open a PR, wait ~1–2 +minutes, click the bot comment. + +**Why `SITE_ORIGIN` is pinned to production in both workflows.** The +hero pill, copy-pastable card URLs, and `llms.txt` are the *product* — +reviewers must see the URLs the merged build will publish, not +ephemeral preview URLs that 404 on PR close. Previews vary only +`NEXT_BASE_PATH` so Next.js routes assets to the preview subpath; a +small banner identifies preview builds. + +### One-time repo setup + +After merging the workflow files, do this once in repo settings: + +1. **Settings → Pages → Build and deployment → Source:** choose + **Deploy from a branch**, branch `gh-pages`, folder `/ (root)`. The + `gh-pages` branch is created automatically the first time + `deploy-pages.yml` runs. +2. **Settings → Actions → General → Workflow permissions:** confirm + **Read and write permissions** (the workflows also declare + `contents: write` per-job, so this is belt-and-braces). + +URLs once Pages is live: + +- Main: `https://.github.io//` +- PR-N: `https://.github.io//pr//` + +### Switching to a custom domain later + +Both workflows derive `SITE_ORIGIN` and the base path from repo +metadata by default. To cut over to a custom apex domain, set repo +variables in **Settings → Secrets and variables → Actions → +Variables**: + +- `SITE_ORIGIN` = `https://` +- `SITE_BASE_PATH` = (empty) + +Then: + +1. Add `public/CNAME` with one line: your apex domain. +2. In repo Settings → Pages, set the custom domain. +3. Point DNS at GitHub Pages (`A` records for the apex or a `CNAME` + for a subdomain). + +No workflow edits needed; both workflows read the same variables, so +main and previews stay in lockstep. + +### Build-time env vars + +All have local-dev-safe defaults — `pnpm dev` needs no env setup. + +| Env var | Set by | Purpose | +|---|---|---| +| `SITE_ORIGIN` | both workflows | Canonical public origin in displayed/copied URLs and `llms.txt`. Default: `http://localhost:3000` | +| `NEXT_BASE_PATH` | both workflows | Next.js asset path prefix | +| `IS_PREVIEW` | preview-pr.yml | Renders the preview banner when `"true"` | +| `GITHUB_SOURCE_REF` | preview-pr.yml | Git ref for card "view source" links. Default: `main` | +| `GITHUB_PR_NUMBER` | preview-pr.yml | PR number for the banner link | +| `GITHUB_REPOSITORY` | runner default | `owner/repo` for "view source" links. Default: `stellar/stellar-dev-skill` | + +## Adding a skill + +### Main list (`SKILL_CARD_SOURCES`) + +For skills hosted in this repo. Add `skills//SKILL.md` at +the repo root, then append to `SKILL_CARD_SOURCES` in +`src/data/skills.ts`: + +```ts +{ + source: "skills//SKILL.md", + category: "Soroban", // any FilterType value + // Optional overrides — default to the upstream SKILL.md's first H1 + // (title) and frontmatter `description`. + title: "Your Skill Title", + description: "What this skill teaches.", +} +``` + +Run `pnpm sync:skills && pnpm dev` to verify. `pnpm build` fails if +the upstream file is missing. New category? Add it to the `FilterType` +union and the `FILTERS` array. + +### Community section (`ECOSYSTEM_CARDS`) + +For skills hosted elsewhere (typically a third-party GitHub repo). +These render in the "Community skills" section at the bottom of the +page. There's no upstream copy — the card just links out to the +external SKILL.md, and the user copies that URL to install it with +their agent. + +Append to `ECOSYSTEM_CARDS` in `src/data/skills.ts`: + +```ts +{ + title: "Project Name", + description: "Verb-led summary of what the skill does.", + pathLabel: "owner/repo", + copyValue: "https://github.com/owner/repo/blob/main/path/to/SKILL.md", + category: "Ecosystem", +} +``` + +- `pathLabel` is the short label shown on the card (typically + `owner/repo`). +- `copyValue` is the full URL written to the clipboard when the user + clicks the pill — point it directly at the raw SKILL.md so an agent + can fetch it. +- `category` is always `"Ecosystem"` for this section. + +Run `pnpm dev` to verify the card renders. No `sync:skills` step +needed since ecosystem entries aren't mirrored locally. + +## Tech stack + +Next.js 15 (App Router) with static export, React 19, TypeScript 5, +Stellar Design System, Sass. See `package.json` for exact versions. + +## License + +Apache 2.0. See [`LICENSE`](../LICENSE). diff --git a/site/next.config.js b/site/next.config.js new file mode 100644 index 0000000..1f3bdd6 --- /dev/null +++ b/site/next.config.js @@ -0,0 +1,24 @@ +/** @type {import('next').NextConfig} */ + +// When deploying to a project-level GitHub Pages URL +// (https://.github.io//), every asset and route has to be +// prefixed with `/`. The deploy workflow sets NEXT_BASE_PATH for +// that case. Once a custom domain is in place (CNAME serves the site +// at the apex), drop the env var and the basePath block goes with it. +const basePath = process.env.NEXT_BASE_PATH; + +const nextConfig = { + // Emit a static export to `out/` for GitHub Pages. The site has no API + // routes, no middleware, no ISR, and no runtime image optimization, so + // there's nothing the static export can't handle. + output: "export", + // Tree-shake `@stellar/design-system` — without this, the barrel ships + // every component (Modal, Tooltip, the full icon set, etc.) even though + // we only render Card, Badge, Logo, ThemeSwitch, and a few icons. + experimental: { + optimizePackageImports: ["@stellar/design-system"], + }, + ...(basePath ? { basePath, assetPrefix: basePath } : {}), +}; + +module.exports = nextConfig; diff --git a/site/package.json b/site/package.json new file mode 100644 index 0000000..032516f --- /dev/null +++ b/site/package.json @@ -0,0 +1,41 @@ +{ + "name": "stellar-skills-site", + "version": "0.1.0", + "license": "Apache-2.0", + "private": true, + "engines": { + "node": ">=22.22.0" + }, + "scripts": { + "sync:skills": "node scripts/copy-skills.mjs", + "generate:llms-txt": "node --experimental-strip-types --disable-warning=ExperimentalWarning --disable-warning=MODULE_TYPELESS_PACKAGE_JSON scripts/generate-llms-txt.mjs", + "predev": "node scripts/copy-skills.mjs --cached --lenient && pnpm generate:llms-txt", + "dev": "next dev", + "prebuild": "node scripts/copy-skills.mjs && pnpm generate:llms-txt", + "build": "next build", + "lint": "next lint", + "lint:ts": "tsc --noEmit" + }, + "dependencies": { + "@next/third-parties": "^15.5.7", + "@stellar/design-system": "^3.2.7", + "next": "15.5.9", + "react": "^19.2.2", + "react-dom": "^19.2.2" + }, + "devDependencies": { + "@next/eslint-plugin-next": "^15.4.4", + "@types/node": "^24.1.0", + "@types/react": "^19.1.9", + "@types/react-dom": "^19.1.7", + "@typescript-eslint/eslint-plugin": "^8.30.1", + "eslint": "^9.32.0", + "eslint-config-next": "15.4.4", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-react-hooks": "^5.2.0", + "prettier": "^3.5.3", + "sass": "^1.86.3", + "typescript": "^5.8.3" + }, + "packageManager": "pnpm@10.15.1" +} diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml new file mode 100644 index 0000000..5bf833b --- /dev/null +++ b/site/pnpm-lock.yaml @@ -0,0 +1,3671 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@next/third-parties': + specifier: ^15.5.7 + version: 15.5.18(next@15.5.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.99.0))(react@19.2.6) + '@stellar/design-system': + specifier: ^3.2.7 + version: 3.2.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + next: + specifier: 15.5.9 + version: 15.5.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.99.0) + react: + specifier: ^19.2.2 + version: 19.2.6 + react-dom: + specifier: ^19.2.2 + version: 19.2.6(react@19.2.6) + devDependencies: + '@next/eslint-plugin-next': + specifier: ^15.4.4 + version: 15.5.18 + '@types/node': + specifier: ^24.1.0 + version: 24.12.4 + '@types/react': + specifier: ^19.1.9 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.1.7 + version: 19.2.3(@types/react@19.2.14) + '@typescript-eslint/eslint-plugin': + specifier: ^8.30.1 + version: 8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + eslint: + specifier: ^9.32.0 + version: 9.39.4 + eslint-config-next: + specifier: 15.4.4 + version: 15.4.4(eslint@9.39.4)(typescript@5.9.3) + eslint-config-prettier: + specifier: ^10.1.8 + version: 10.1.8(eslint@9.39.4) + eslint-plugin-react-hooks: + specifier: ^5.2.0 + version: 5.2.0(eslint@9.39.4) + prettier: + specifier: ^3.5.3 + version: 3.8.3 + sass: + specifier: ^1.86.3 + version: 1.99.0 + typescript: + specifier: ^5.8.3 + version: 5.9.3 + +packages: + + '@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==} + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@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/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@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.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.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + 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.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + + '@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] + + '@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] + + '@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] + + '@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] + + '@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] + + '@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] + + '@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] + + '@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] + + '@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.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.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@next/env@15.5.9': + resolution: {integrity: sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==} + + '@next/eslint-plugin-next@15.4.4': + resolution: {integrity: sha512-1FDsyN//ai3Jd97SEd7scw5h1yLdzDACGOPRofr2GD3sEFsBylEEoL0MHSerd4n2dq9Zm/mFMqi4+NRMOreOKA==} + + '@next/eslint-plugin-next@15.5.18': + resolution: {integrity: sha512-w4MYq8M26a8PNrfto0JosLf5/3ssln1rsyP96g2DkC8uFVymStM5DLSz5ElxxrPRg2XnTMnFo3kREFlhYvxhWw==} + + '@next/swc-darwin-arm64@15.5.7': + resolution: {integrity: sha512-IZwtxCEpI91HVU/rAUOOobWSZv4P2DeTtNaCdHqLcTJU4wdNXgAySvKa/qJCgR5m6KI8UsKDXtO2B31jcaw1Yw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@15.5.7': + resolution: {integrity: sha512-UP6CaDBcqaCBuiq/gfCEJw7sPEoX1aIjZHnBWN9v9qYHQdMKvCKcAVs4OX1vIjeE+tC5EIuwDTVIoXpUes29lg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@15.5.7': + resolution: {integrity: sha512-NCslw3GrNIw7OgmRBxHtdWFQYhexoUCq+0oS2ccjyYLtcn1SzGzeM54jpTFonIMUjNbHmpKpziXnpxhSWLcmBA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@15.5.7': + resolution: {integrity: sha512-nfymt+SE5cvtTrG9u1wdoxBr9bVB7mtKTcj0ltRn6gkP/2Nu1zM5ei8rwP9qKQP0Y//umK+TtkKgNtfboBxRrw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.5.7': + resolution: {integrity: sha512-hvXcZvCaaEbCZcVzcY7E1uXN9xWZfFvkNHwbe/n4OkRhFWrs1J1QV+4U1BN06tXLdaS4DazEGXwgqnu/VMcmqw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@15.5.7': + resolution: {integrity: sha512-4IUO539b8FmF0odY6/SqANJdgwn1xs1GkPO5doZugwZ3ETF6JUdckk7RGmsfSf7ws8Qb2YB5It33mvNL/0acqA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.5.7': + resolution: {integrity: sha512-CpJVTkYI3ZajQkC5vajM7/ApKJUOlm6uP4BknM3XKvJ7VXAvCqSjSLmM0LKdYzn6nBJVSjdclx8nYJSa3xlTgQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.5.7': + resolution: {integrity: sha512-gMzgBX164I6DN+9/PGA+9dQiwmTkE4TloBNx8Kv9UiGARsr9Nba7IpcBRA1iTV9vwlYnrE3Uy6I7Aj6qLjQuqw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@next/third-parties@15.5.18': + resolution: {integrity: sha512-Kp51CbeHgYelpkasFI1gAeAeMPfMTctLcmVIfE2MiRRfC6oYbR3+lO4S0NbNRppOZ7RkbB5P6uW/qOewxth6iA==} + peerDependencies: + next: ^13.0.0 || ^14.0.0 || ^15.0.0 + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + + '@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'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} + engines: {node: '>= 10.0.0'} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@rushstack/eslint-patch@1.16.1': + resolution: {integrity: sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==} + + '@stellar/design-system@3.2.8': + resolution: {integrity: sha512-h2AaxQNjUl3DaaydJAYHKfqIuojBEjHNuxzSiQdCZXz9FEp2Ohm0evsgS4GsPu0wxqAFKzDFbqGM2AOJxkXyMw==} + engines: {node: '>=22.0.0'} + peerDependencies: + react: '>=18.x' + react-dom: '>=18.x' + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/node@24.12.4': + resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} + + '@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==} + + '@typescript-eslint/eslint-plugin@8.59.3': + resolution: {integrity: sha512-PwFvSKsXGShKGW6n5bZOhGHEcCZXM8HofLK9fNsEwZXzFRjoY+XT1Vsf1zgyXdwTr0ZYz1/2tkZ0DBTT9jZjhw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.59.3 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.59.3': + resolution: {integrity: sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.59.3': + resolution: {integrity: sha512-ECiUWa/KYRGDFUqTNehaRgzDshnJfkTABJxVemHk4ko22gcr0ukloKjWvyQ64g8YCV/UI47kN1dbmjf/GaQYng==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.59.3': + resolution: {integrity: sha512-t2LvZnoEfzKtnPjgeEu41xw5gxq9mQVfYy4OoZ4Vlt0sk3JwxmhCca/AR7DwOiHrjWgjAj6as4AhRLKSDfvZIA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.59.3': + resolution: {integrity: sha512-PcIJHjmaREXLgIAIzLnSY9VucEzz8FKXsRgFa1DmdGCK/5tJpW03TKJF01Q6VZd1lLdz2sIKPWaDUZN9dp//dw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.59.3': + resolution: {integrity: sha512-g71d8QD8UaiHGvrJwyIS1hCX5r63w6Jll+4VEYhEAHXTDIqX1JgxhTAbEHtKntL9kuc4jRo7/GWw5xfCepSccQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.59.3': + resolution: {integrity: sha512-ePFoH0g4ludssdRFqqDxQePCxU4WQyRa9+XVwjm7yLn0FKhMeoetC+qBEEI1Eyb1pGSDveTIT09Bvw2WhlGayg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.59.3': + resolution: {integrity: sha512-CbRjVRAf7Lr9Kr8RopKcbY45p2VfmmHrm0ygOCYFi7oU8q19m0Fs/6iHS7kNOmwpp+ob07ZVcAqlxUod9lYdmg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.59.3': + resolution: {integrity: sha512-JAvT14goBzRzzzZyqq3P9BLArIxTtQURUtFgQ/V7FO+eU+Gg6ES+5ymOPP1wRxXcxAYeivCk4uS3jCKWI1K8Zg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.59.3': + resolution: {integrity: sha512-f1UQF7ggd42YiwI5wGrRaPsa+P0CINBlrkLPmGfpq/u/I/oVtecoEIfFR9ag/oa1sLOsRNZ6xehf6qMZhQGBDg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + + 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 + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + 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'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + 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'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001792: + resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + 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==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + copy-to-clipboard@3.3.3: + resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} + engines: {node: '>= 0.4'} + + 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-iterator-helpers@1.3.2: + resolution: {integrity: sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==} + engines: {node: '>= 0.4'} + + 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'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-next@15.4.4: + resolution: {integrity: sha512-sK/lWLUVF5om18O5w76Jt3F8uzu/LP5mVa6TprCMWkjWHUmByq80iHGHcdH7k1dLiJlj+DRIWf98d5piwRsSuA==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.10: + resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} + + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + 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 + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + 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-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + 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'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + immutable@5.1.5: + resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + 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-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + next@15.5.9: + resolution: {integrity: sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-exports-info@1.6.0: + resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} + engines: {node: '>= 0.4'} + + 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-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'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + 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==} + + 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'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.8.3: + resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} + engines: {node: '>=14'} + hasBin: true + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-copy-to-clipboard-ts@1.3.1: + resolution: {integrity: sha512-qA4J3vHAdkdrqmaYvFCt5dbATtG8mQPl4Ar8HNrfrPvdaUqAQiwyQSg8fqSw8QYkH5KVUspNyvP6o/7kwZLw8Q==} + peerDependencies: + react: '>=18.0.0' + + react-dom@19.2.6: + resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} + peerDependencies: + react: ^19.2.6 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react@19.2.6: + resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} + engines: {node: '>=0.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@2.0.0-next.6: + resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.4: + resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + sass@1.99.0: + resolution: {integrity: sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==} + engines: {node: '>=14.0.0'} + hasBin: true + + 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.8.0: + resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + 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'} + + 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'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: 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'} + + third-party-capital@1.0.20: + resolution: {integrity: sha512-oB7yIimd8SuGptespDAZnNkzIz+NWaJCu2RMsbs4Wmp9zSDUM8Nhi3s2OOcqYuv3mN4hitXc8DVx+LyUmbUDiA==} + + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toggle-selection@1.0.6: + resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.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 + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@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 + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + dependencies: + eslint: 9.39.4 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@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/utils@0.2.11': {} + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@img/colour@1.1.0': + 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.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + 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.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.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.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.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.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.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.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.34.5': + dependencies: + '@emnapi/runtime': 1.10.0 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 + optional: true + + '@next/env@15.5.9': {} + + '@next/eslint-plugin-next@15.4.4': + dependencies: + fast-glob: 3.3.1 + + '@next/eslint-plugin-next@15.5.18': + dependencies: + fast-glob: 3.3.1 + + '@next/swc-darwin-arm64@15.5.7': + optional: true + + '@next/swc-darwin-x64@15.5.7': + optional: true + + '@next/swc-linux-arm64-gnu@15.5.7': + optional: true + + '@next/swc-linux-arm64-musl@15.5.7': + optional: true + + '@next/swc-linux-x64-gnu@15.5.7': + optional: true + + '@next/swc-linux-x64-musl@15.5.7': + optional: true + + '@next/swc-win32-arm64-msvc@15.5.7': + optional: true + + '@next/swc-win32-x64-msvc@15.5.7': + optional: true + + '@next/third-parties@15.5.18(next@15.5.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.99.0))(react@19.2.6)': + dependencies: + next: 15.5.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.99.0) + react: 19.2.6 + third-party-capital: 1.0.20 + + '@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 + + '@nolyfill/is-core-module@1.0.39': {} + + '@parcel/watcher-android-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': + optional: true + + '@parcel/watcher-win32-arm64@2.5.6': + optional: true + + '@parcel/watcher-win32-ia32@2.5.6': + optional: true + + '@parcel/watcher-win32-x64@2.5.6': + optional: true + + '@parcel/watcher@2.5.6': + dependencies: + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.4 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + optional: true + + '@rtsao/scc@1.1.0': {} + + '@rushstack/eslint-patch@1.16.1': {} + + '@stellar/design-system@3.2.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@floating-ui/dom': 1.7.6 + bignumber.js: 9.3.1 + lodash: 4.18.1 + react: 19.2.6 + react-copy-to-clipboard-ts: 1.3.1(react@19.2.6) + react-dom: 19.2.6(react@19.2.6) + tslib: 2.8.1 + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@tybys/wasm-util@0.10.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/estree@1.0.9': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/node@24.12.4': + 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 + + '@typescript-eslint/eslint-plugin@8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.59.3(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/type-utils': 8.59.3(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.3(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.3 + eslint: 9.39.4 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.59.3(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.3 + debug: 4.4.3 + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.59.3(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3) + '@typescript-eslint/types': 8.59.3 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.59.3': + dependencies: + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/visitor-keys': 8.59.3 + + '@typescript-eslint/tsconfig-utils@8.59.3(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.59.3(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.3(eslint@9.39.4)(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.59.3': {} + + '@typescript-eslint/typescript-estree@8.59.3(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.59.3(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.3(typescript@5.9.3) + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/visitor-keys': 8.59.3 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.8.0 + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.59.3(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@typescript-eslint/scope-manager': 8.59.3 + '@typescript-eslint/types': 8.59.3 + '@typescript-eslint/typescript-estree': 8.59.3(typescript@5.9.3) + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.59.3': + dependencies: + '@typescript-eslint/types': 8.59.3 + eslint-visitor-keys: 5.0.1 + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + ast-types-flow@0.0.8: {} + + async-function@1.0.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: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + bignumber.js@9.3.1: {} + + brace-expansion@1.1.14: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + 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 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001792: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + client-only@0.0.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + copy-to-clipboard@3.3.3: + dependencies: + toggle-selection: 1.0.6 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.2.3: {} + + damerau-levenshtein@1.0.8: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + detect-libc@2.1.2: + optional: true + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + emoji-regex@9.2.2: {} + + es-abstract@1.24.2: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.4 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.20 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.3.2: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + math-intrinsics: 1.1.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 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.3 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + escape-string-regexp@4.0.0: {} + + eslint-config-next@15.4.4(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@next/eslint-plugin-next': 15.4.4 + '@rushstack/eslint-patch': 1.16.1 + '@typescript-eslint/eslint-plugin': 8.59.3(@typescript-eslint/parser@8.59.3(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.3(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.3(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4) + eslint-plugin-react: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: 5.2.0(eslint@9.39.4) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + + eslint-config-prettier@10.1.8(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + + eslint-import-resolver-node@0.3.10: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.2 + resolve: 2.0.0-next.6 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3 + eslint: 9.39.4 + get-tsconfig: 4.14.0 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.16 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.3(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.59.3(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.3(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.59.3(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + hasown: 2.0.3 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.59.3(eslint@9.39.4)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.11.4 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.39.4 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-react-hooks@5.2.0(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + + eslint-plugin-react@7.37.5(eslint@9.39.4): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.3.2 + eslint: 9.39.4 + estraverse: 5.3.0 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.6 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.1: + 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 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.3 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + generator-function@2.0.1: {} + + 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-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.14.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 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 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + immutable@5.1.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.3 + side-channel: 1.1.0 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-bun-module@2.0.0: + dependencies: + semver: 7.8.0 + + is-callable@1.2.7: {} + + is-core-module@2.16.2: + dependencies: + hasown: 2.0.3 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + 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-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + 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-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + js-tokens@4.0.0: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash@4.18.1: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + math-intrinsics@1.1.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.6 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.14 + + minimist@1.2.8: {} + + ms@2.1.3: {} + + nanoid@3.3.12: {} + + napi-postinstall@0.3.4: {} + + natural-compare@1.4.0: {} + + next@15.5.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.99.0): + dependencies: + '@next/env': 15.5.9 + '@swc/helpers': 0.5.15 + caniuse-lite: 1.0.30001792 + postcss: 8.4.31 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + styled-jsx: 5.1.6(react@19.2.6) + optionalDependencies: + '@next/swc-darwin-arm64': 15.5.7 + '@next/swc-darwin-x64': 15.5.7 + '@next/swc-linux-arm64-gnu': 15.5.7 + '@next/swc-linux-arm64-musl': 15.5.7 + '@next/swc-linux-x64-gnu': 15.5.7 + '@next/swc-linux-x64-musl': 15.5.7 + '@next/swc-win32-arm64-msvc': 15.5.7 + '@next/swc-win32-x64-msvc': 15.5.7 + sass: 1.99.0 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + node-addon-api@7.1.1: + optional: true + + node-exports-info@1.6.0: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + 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 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.4: {} + + possible-typed-array-names@1.1.0: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier@3.8.3: {} + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + react-copy-to-clipboard-ts@1.3.1(react@19.2.6): + dependencies: + copy-to-clipboard: 3.3.3 + react: 19.2.6 + + react-dom@19.2.6(react@19.2.6): + dependencies: + react: 19.2.6 + scheduler: 0.27.0 + + react-is@16.13.1: {} + + react@19.2.6: {} + + readdirp@4.1.2: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@2.0.0-next.6: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.2 + node-exports-info: 1.6.0 + object-keys: 1.1.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.4: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + sass@1.99.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.5 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 + + scheduler@0.27.0: {} + + semver@6.3.1: {} + + semver@7.8.0: {} + + 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 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.0 + 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: {} + + 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 + + source-map-js@1.2.1: {} + + stable-hash@0.0.5: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + styled-jsx@5.1.6(react@19.2.6): + dependencies: + client-only: 0.0.1 + react: 19.2.6 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + third-party-capital@1.0.20: {} + + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toggle-selection@1.0.6: {} + + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript@5.9.3: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@7.16.0: {} + + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + 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 + + word-wrap@1.2.5: {} + + yocto-queue@0.1.0: {} diff --git a/site/scripts/copy-skills.mjs b/site/scripts/copy-skills.mjs new file mode 100644 index 0000000..947d5a7 --- /dev/null +++ b/site/scripts/copy-skills.mjs @@ -0,0 +1,116 @@ +#!/usr/bin/env node +/** + * Mirrors `/skills/` into `/public/skills/` so each + * upstream SKILL.md is served at the same path on the deployed site. + * + * The site lives at `/site/` alongside `/skills/`. + * Each card in src/data/skills.ts has a `source` field — an + * upstream-relative path like "skills/soroban/SKILL.md" — that we copy + * verbatim into public/, so the upstream layout drives the site URL. + * + * Flags: + * --cached skip the copy if every advertised source already exists. + * Used by `predev` so subsequent dev starts work offline. + * --lenient warn instead of failing when an advertised source has no + * corresponding upstream file. Used by `predev` for DX. + */ +import { + cpSync, + existsSync, + mkdirSync, + readFileSync, + rmSync, + statSync, +} from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const args = new Set(process.argv.slice(2)); +const cached = args.has("--cached"); +const strict = !args.has("--lenient"); + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const SITE_ROOT = dirname(__dirname); +const REPO_ROOT = dirname(SITE_ROOT); +const PUBLIC_DIR = join(SITE_ROOT, "public"); +const PUBLIC_SKILLS_DIR = join(PUBLIC_DIR, "skills"); +const UPSTREAM_SKILLS_DIR = join(REPO_ROOT, "skills"); +const SKILLS_DATA_FILE = join(SITE_ROOT, "src/data/skills.ts"); + +if (!existsSync(UPSTREAM_SKILLS_DIR)) { + console.error( + `[copy-skills] expected sibling skills/ at ${UPSTREAM_SKILLS_DIR}`, + ); + process.exit(1); +} + +// `source:` only appears in SKILL_CARD_SOURCES — ECOSYSTEM_CARDS uses +// `pathLabel:` / `copyValue:`, which the word boundary excludes. +const skillsSource = readFileSync(SKILLS_DATA_FILE, "utf8"); +const sources = [ + ...skillsSource.matchAll(/\bsource:\s*"([^"]+)"/g), +].map((m) => m[1]); +if (sources.length === 0) { + console.error(`[copy-skills] no sources found in ${SKILLS_DATA_FILE}`); + process.exit(1); +} + +// `--cached` skips the copy when every dest exists AND every dest is at +// least as fresh as its upstream source. Without the mtime check, editing +// a SKILL.md during `pnpm dev` wouldn't show up until the next manual +// `pnpm sync:skills`. +const isFresh = (source) => { + const dest = join(PUBLIC_DIR, source); + if (!existsSync(dest)) return false; + const src = join(REPO_ROOT, source); + if (!existsSync(src)) { + // Upstream missing; --lenient will warn later. Treat as fresh so we + // don't trigger a full re-copy just to discover the same missing file. + return true; + } + return statSync(dest).mtimeMs >= statSync(src).mtimeMs; +}; + +if (cached && sources.every(isFresh)) { + console.log( + `[copy-skills] cached (${sources.length} files) — run \`pnpm sync:skills\` to refresh`, + ); + process.exit(0); +} + +// Clean stale files before copying so removed skills don't linger. +rmSync(PUBLIC_SKILLS_DIR, { recursive: true, force: true }); + +const missing = []; +for (const source of sources) { + const src = join(REPO_ROOT, source); + const dest = join(PUBLIC_DIR, source); + if (!existsSync(src)) { + missing.push(source); + continue; + } + mkdirSync(dirname(dest), { recursive: true }); + cpSync(src, dest, { dereference: false }); +} + +// Apache-2.0 attribution alongside the content. +const upstreamLicense = join(REPO_ROOT, "LICENSE"); +if (existsSync(upstreamLicense)) { + mkdirSync(PUBLIC_SKILLS_DIR, { recursive: true }); + cpSync(upstreamLicense, join(PUBLIC_SKILLS_DIR, "LICENSE"), { + dereference: false, + }); +} + +if (missing.length > 0) { + const lines = missing.map((s) => ` ${s}`).join("\n"); + const msg = `[copy-skills] ${missing.length} advertised source(s) missing under ${UPSTREAM_SKILLS_DIR}:\n${lines}`; + if (strict) { + console.error(msg); + process.exit(1); + } + console.warn(msg); +} + +const ok = sources.length - missing.length; +console.log(`[copy-skills] copied ${ok}/${sources.length} files`); diff --git a/site/scripts/generate-llms-txt.mjs b/site/scripts/generate-llms-txt.mjs new file mode 100644 index 0000000..bd7afd0 --- /dev/null +++ b/site/scripts/generate-llms-txt.mjs @@ -0,0 +1,152 @@ +#!/usr/bin/env node +/** + * Generates public/llms.txt from src/data/skills.ts at build time. + * + * Follows the llms.txt convention (https://llmstxt.org): a flat markdown + * file at the site root listing every agent-fetchable resource, grouped + * by category, so AI tools that look for /llms.txt get a clean index + * even if they can't run JS to read the landing page. + * + * Title and description default to upstream frontmatter / first H1 of + * each SKILL.md (parsed via src/lib/skill-meta.mjs, shared with + * src/app/page.tsx); overrides in skills.ts take precedence. Runs + * after the skill markdown has been written to public/skills/ by the + * `copy-skills.mjs` predev / prebuild step. + * + * skills.ts is imported directly via Node's native type stripping + * (`--experimental-strip-types`, enabled by the npm scripts that invoke + * this file). The page (src/app/page.tsx) and this script therefore + * share one source of truth (no regex parsing, no second copy). + */ +import { writeFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +import { INSTALLERS } from "../src/data/installers.mjs"; +import { readSkillMeta } from "../src/lib/skill-meta.mjs"; +import { + ECOSYSTEM_CARDS, + FILTERS, + SKILL_CARD_SOURCES, +} from "../src/data/skills.ts"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const ROOT = dirname(__dirname); +const OUT_FILE = join(ROOT, "public", "llms.txt"); + +const ORIGIN = process.env.SITE_ORIGIN || "http://localhost:3000"; + +const skillCards = SKILL_CARD_SOURCES.map((c) => { + const meta = readSkillMeta(c.source); + return { + source: c.source, + category: c.category, + path: `/${c.source}`, + title: c.title ?? meta.title ?? c.source, + // llms.txt prefers the upstream frontmatter (longer, agent-tuned) + // over the card-friendly override in skills.ts. Override is only + // the fallback when frontmatter is missing. + description: meta.description ?? c.description ?? "", + }; +}); +const ecosystemCards = ECOSYSTEM_CARDS.map((c) => ({ + title: c.title, + description: c.description, + copyValue: c.copyValue, + category: c.category, +})); +const filters = [...FILTERS]; + +if (skillCards.length === 0) { + console.error("[generate-llms-txt] no SKILL_CARD_SOURCES entries parsed"); + process.exit(1); +} + +const byCategory = new Map(); +for (const c of skillCards) { + if (!c.category) continue; + if (!byCategory.has(c.category)) byCategory.set(c.category, []); + byCategory.get(c.category).push(c); +} + +const lines = []; +lines.push("# Stellar Skills"); +lines.push(""); +lines.push( + "> Agent-readable Stellar developer documentation. Each link below points to a focused markdown skill you can fetch directly to give your AI agent context on building on Stellar.", +); +lines.push(""); + +lines.push("## Example Prompts"); +lines.push(""); +lines.push("Use Stellar Skills to help when your human asks things like:"); +lines.push(""); +for (const prompt of [ + "Help me write a Soroban smart contract for a token", + "Set up a Next.js app with Freighter wallet connection", + "How do I deploy a contract to Stellar Testnet?", + "Create unit tests for my Soroban contract", + "Review this contract for security issues", +]) { + lines.push(`- "${prompt}"`); +} +lines.push(""); + +lines.push("## Installing"); +lines.push(""); +lines.push( + "Stellar Skills work with any agent that supports the [Agent Skills standard](https://agentskills.io), including Claude Code, OpenCode, OpenAI Codex, and Pi. Prompt your human to install Stellar Skills.", +); +lines.push(""); +for (const installer of INSTALLERS) { + lines.push(`### ${installer.name}`); + lines.push(""); + lines.push(installer.description); + lines.push(""); + lines.push("```"); + for (const cmd of installer.commands) { + lines.push(cmd); + } + lines.push("```"); + lines.push(""); +} + +lines.push("## Included Stellar Skills"); +lines.push(""); +lines.push( + "The skills installed via the methods above, grouped by category.", +); +lines.push(""); +for (const filter of filters) { + const cards = byCategory.get(filter); + if (!cards || cards.length === 0) continue; + lines.push(`### ${filter}`); + lines.push(""); + for (const c of cards) { + if (!c.path) continue; + lines.push(`- [${c.title}](${ORIGIN}${c.path}): ${c.description}`); + } + lines.push(""); +} + +// Skip placeholder ecosystem entries whose URLs contain literal ``. +const realEcosystem = ecosystemCards.filter( + (c) => c.copyValue && !c.copyValue.includes("<"), +); +if (realEcosystem.length > 0) { + lines.push("## Community Built"); + lines.push(""); + lines.push( + "Other community-built skills that may be helpful for your build. These aren't installed via the methods above; each project has its own setup, so follow the link on each entry. Not endorsed by the Stellar Foundation; do your own research.", + ); + lines.push(""); + for (const c of realEcosystem) { + lines.push(`- [${c.title}](${c.copyValue}): ${c.description}`); + } + lines.push(""); +} + +writeFileSync(OUT_FILE, lines.join("\n")); +console.log( + `[generate-llms-txt] wrote ${OUT_FILE} (${skillCards.length} skills, ${realEcosystem.length} ecosystem)`, +); diff --git a/site/src/app/_components/CopyButton.tsx b/site/src/app/_components/CopyButton.tsx new file mode 100644 index 0000000..9bda2bf --- /dev/null +++ b/site/src/app/_components/CopyButton.tsx @@ -0,0 +1,140 @@ +"use client"; + +import { useEffect, useRef, useState } from "react"; + +import { CheckCircleIcon, Copy01Icon } from "./icons"; + +type CopyButtonVariant = "pill" | "path"; + +export type CopyButtonProps = { + /** The string written to the clipboard. */ + value: string; + /** Optional label shown to the user; defaults to `value`. */ + displayValue?: string; + /** + * Visual variant. + * - `pill`: prominent hero-style copy chip. + * - `path`: smaller path-style chip used inside skill cards. + */ + variant?: CopyButtonVariant; +}; + +const COPIED_RESET_MS = 1000; + +// Fallback for browsers / contexts where `navigator.clipboard` is +// unavailable (insecure HTTP origins, sandboxed iframes, permission +// denied). Returns true on success. +const legacyCopy = (text: string): boolean => { + if (typeof document === "undefined") return false; + const textarea = document.createElement("textarea"); + textarea.value = text; + textarea.setAttribute("readonly", ""); + textarea.style.position = "fixed"; + textarea.style.opacity = "0"; + document.body.appendChild(textarea); + textarea.select(); + let ok = false; + try { + ok = document.execCommand("copy"); + } catch { + ok = false; + } + document.body.removeChild(textarea); + return ok; +}; + +/** + * Button that copies a string to the clipboard and shows a transient + * "copied" affordance. Used for both the hero pill and per-card path + * pills. + */ +export const CopyButton = ({ + value, + displayValue, + variant = "pill", +}: CopyButtonProps) => { + const [copied, setCopied] = useState(false); + const [failed, setFailed] = useState(false); + const resetTimer = useRef | null>(null); + + useEffect( + () => () => { + if (resetTimer.current !== null) { + clearTimeout(resetTimer.current); + } + }, + [], + ); + + const handleCopy = async () => { + let ok = false; + try { + if (navigator.clipboard?.writeText) { + await navigator.clipboard.writeText(value); + ok = true; + } else { + ok = legacyCopy(value); + } + } catch { + // Clipboard API can reject (denied permission, non-secure + // context). Fall through to the legacy path before giving up. + ok = legacyCopy(value); + } + + setCopied(ok); + setFailed(!ok); + + if (resetTimer.current !== null) clearTimeout(resetTimer.current); + resetTimer.current = setTimeout(() => { + setCopied(false); + setFailed(false); + resetTimer.current = null; + }, COPIED_RESET_MS); + }; + + const wrapperClass = + variant === "pill" ? "SkillsCopyPill__wrapper" : "SkillsCard__pathWrapper"; + const buttonClass = + variant === "pill" ? "SkillsCopyPill" : "SkillsCard__pathButton"; + const textClass = + variant === "pill" ? "SkillsCopyPill__text" : "SkillsCard__pathText"; + + const liveMessage = copied + ? `Copied ${displayValue ?? value}` + : failed + ? "Copy failed" + : ""; + + return ( +
+ + + {liveMessage} + +
+ ); +}; diff --git a/site/src/app/_components/SkillCard.tsx b/site/src/app/_components/SkillCard.tsx new file mode 100644 index 0000000..5c66101 --- /dev/null +++ b/site/src/app/_components/SkillCard.tsx @@ -0,0 +1,57 @@ +import { Card } from "@stellar/design-system"; + +import { CopyButton } from "./CopyButton"; +import { LinkExternal01Icon } from "./icons"; + +export type SkillCardProps = { + title: string; + description: string; + pathLabel: string; + copyValue: string; + /** External link rendered as a real anchor so crawlers see the URL. */ + sourceUrl: string; + /** h2 in the main grid, h3 in the ecosystem section. */ + headingLevel?: 2 | 3; +}; + +/** + * Server component. Emits the full card markup as static HTML. The only + * client-side bit is ``, which hydrates over the rendered + * button. + */ +export const SkillCard = ({ + title, + description, + pathLabel, + copyValue, + sourceUrl, + headingLevel = 2, +}: SkillCardProps) => { + const Heading = headingLevel === 3 ? "h3" : "h2"; + return ( + +
+
+ {title} + + + +
+ +

{description}

+ + +
+
+ ); +}; diff --git a/site/src/app/_components/SkillsFilter.tsx b/site/src/app/_components/SkillsFilter.tsx new file mode 100644 index 0000000..93cf375 --- /dev/null +++ b/site/src/app/_components/SkillsFilter.tsx @@ -0,0 +1,120 @@ +"use client"; + +import { KeyboardEvent, ReactNode, useId, useRef, useState } from "react"; + +type Props = { + filters: readonly string[]; + /** Optional starting tab. Defaults to the first item in `filters`. */ + defaultFilter?: string; + /** Class applied to the tabpanel. Lets each independent use of this + * component target its own CSS-driven show/hide rules. */ + panelClassName?: string; + /** aria-label for the tablist. */ + ariaLabel?: string; + /** Pre-rendered card markup (server). Each child should carry a + * `data-category` attribute matching one of `filters` so CSS can hide + * non-matching cards based on the panel's `data-active-filter`. */ + children: ReactNode; +}; + +/** + * Client island that owns the active-filter state and the ARIA tablist + * keyboard handling. The cards themselves render server-side and are + * passed in as `children`; this component just toggles a `data-active- + * filter` attribute on the wrapping panel so CSS can hide non-matching + * entries. + * + * Each instance scopes its tab/panel ARIA wiring with `useId()` so + * multiple independent tablists can coexist on the same page (skills + * filter + installer filter). + * + * @see https://www.w3.org/WAI/ARIA/apg/patterns/tabs/ + */ +export const SkillsFilter = ({ + filters, + defaultFilter, + panelClassName = "SkillsLanding__filterPanel", + ariaLabel = "Filter skills", + children, +}: Props) => { + const baseId = useId(); + const panelId = `${baseId}-panel`; + const tabId = (filter: string) => `${baseId}-tab-${filter}`; + + // Callers always pass at least one filter; the `?? ""` is a type-level + // guard against `noUncheckedIndexedAccess` and never hits at runtime. + const [activeFilter, setActiveFilter] = useState( + defaultFilter ?? filters[0] ?? "", + ); + const tabRefs = useRef>({}); + + const handleTabKeyDown = ( + event: KeyboardEvent, + index: number, + ) => { + let nextIndex: number | null = null; + if (event.key === "ArrowRight") { + nextIndex = (index + 1) % filters.length; + } else if (event.key === "ArrowLeft") { + nextIndex = (index - 1 + filters.length) % filters.length; + } else if (event.key === "Home") { + nextIndex = 0; + } else if (event.key === "End") { + nextIndex = filters.length - 1; + } + + if (nextIndex !== null) { + event.preventDefault(); + const nextFilter = filters[nextIndex]; + // `% filters.length` guarantees in-bounds; guard satisfies + // `noUncheckedIndexedAccess` without changing runtime behavior. + if (nextFilter === undefined) return; + setActiveFilter(nextFilter); + tabRefs.current[nextFilter]?.focus(); + } + }; + + return ( + <> +
+ {filters.map((filter, index) => { + const isActive = activeFilter === filter; + return ( + + ); + })} +
+ +
+ {children} +
+ + ); +}; diff --git a/site/src/app/_components/ThemeSwitchIsland.tsx b/site/src/app/_components/ThemeSwitchIsland.tsx new file mode 100644 index 0000000..048013a --- /dev/null +++ b/site/src/app/_components/ThemeSwitchIsland.tsx @@ -0,0 +1,20 @@ +"use client"; + +import { ThemeSwitch } from "@stellar/design-system"; + +const LOCAL_STORAGE_SAVED_THEME = "stellarTheme:Laboratory"; + +/** + * Client island for the design system's ThemeSwitch. The wrapping div has + * `suppressHydrationWarning` because ThemeSwitch reads localStorage on + * first render — its post-hydration UI legitimately differs from the SSR + * placeholder when a saved theme exists. The wrapper reserves a slot in + * the static HTML so there's no header CLS bump. + */ +export const ThemeSwitchIsland = () => { + return ( +
+ +
+ ); +}; diff --git a/site/src/app/_components/icons.tsx b/site/src/app/_components/icons.tsx new file mode 100644 index 0000000..db98a96 --- /dev/null +++ b/site/src/app/_components/icons.tsx @@ -0,0 +1,71 @@ +/** + * Inline SVG icons. We render only 4 icons site-wide; importing + * `Icon` from `@stellar/design-system` ships its full ~1,177-icon + * runtime barrel (~150 kB gzipped) because property access on the + * `Icon` object can't be tree-shaken. These components match the SDS + * SVG sources verbatim. + */ + +type IconProps = React.SVGProps; + +const baseProps = { + width: 24, + height: 24, + viewBox: "0 0 24 24", + fill: "none", + xmlns: "http://www.w3.org/2000/svg", + stroke: "currentColor", + "aria-hidden": true, +} as const; + +export const LinkExternal01Icon = (props: IconProps) => ( + + + +); + +export const Copy01Icon = (props: IconProps) => ( + + + +); + +export const CheckCircleIcon = (props: IconProps) => ( + + + +); + +export const ArrowLeftIcon = (props: IconProps) => ( + + + +); + +// GitHub mark is a filled glyph, so it overrides the stroke-based defaults +// from baseProps and paints with `currentColor` fill instead. +export const GitHubIcon = (props: IconProps) => ( + + + +); diff --git a/site/src/app/apple-icon.png b/site/src/app/apple-icon.png new file mode 100644 index 0000000..1b2d022 Binary files /dev/null and b/site/src/app/apple-icon.png differ diff --git a/site/src/app/error.tsx b/site/src/app/error.tsx new file mode 100644 index 0000000..8d1e408 --- /dev/null +++ b/site/src/app/error.tsx @@ -0,0 +1,51 @@ +"use client"; + +import { useEffect } from "react"; + +import { ArrowLeftIcon } from "./_components/icons"; + +type ErrorProps = { + error: Error & { digest?: string }; + reset: () => void; +}; + +export default function Error({ error, reset }: ErrorProps) { + useEffect(() => { + console.error(error); + }, [error]); + + return ( +
+
+

Unhandled Error

+ +

+ Uh-oh, we didn’t handle this error. We would appreciate it if you + opened an issue on GitHub, providing as many details as possible to + help us fix this bug. + {error.digest ? ` (digest: ${error.digest})` : null} +

+
+ +
+ + + + Open Issue + +
+
+ ); +} diff --git a/site/src/app/favicon.ico b/site/src/app/favicon.ico new file mode 100644 index 0000000..90c5012 Binary files /dev/null and b/site/src/app/favicon.ico differ diff --git a/site/src/app/global-error.tsx b/site/src/app/global-error.tsx new file mode 100644 index 0000000..09a0b1e --- /dev/null +++ b/site/src/app/global-error.tsx @@ -0,0 +1,13 @@ +"use client"; + +import NextError from "next/error"; + +export default function GlobalError() { + return ( + + + + + + ); +} diff --git a/site/src/app/icon.svg b/site/src/app/icon.svg new file mode 100644 index 0000000..e85f97c --- /dev/null +++ b/site/src/app/icon.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/site/src/app/icon1.png b/site/src/app/icon1.png new file mode 100644 index 0000000..5b96327 Binary files /dev/null and b/site/src/app/icon1.png differ diff --git a/site/src/app/icon2.png b/site/src/app/icon2.png new file mode 100644 index 0000000..897f472 Binary files /dev/null and b/site/src/app/icon2.png differ diff --git a/site/src/app/layout.tsx b/site/src/app/layout.tsx new file mode 100644 index 0000000..a1e3e52 --- /dev/null +++ b/site/src/app/layout.tsx @@ -0,0 +1,79 @@ +import type { Metadata, Viewport } from "next"; +import { GoogleTagManager } from "@next/third-parties/google"; + +import "@stellar/design-system/build/styles.min.css"; +import "@/styles/globals.scss"; + +const SITE_ORIGIN = process.env.SITE_ORIGIN || "http://localhost:3000"; +const IS_PREVIEW = process.env.IS_PREVIEW === "true"; + +const GA_TRACKING_ENABLED = + process.env.NEXT_PUBLIC_DISABLE_GOOGLE_ANALYTICS !== "true" && + process.env.NODE_ENV === "production" && + !IS_PREVIEW; + +// SITE_ORIGIN can carry a project-Pages path prefix (e.g. +// `https://owner.github.io/repo`). For metadataBase we need a pure +// origin; the canonical path picks up whatever prefix was in SITE_ORIGIN +// (with a trailing slash so URL resolution stays deterministic). +const siteOriginUrl = new URL(SITE_ORIGIN); +const canonicalPath = siteOriginUrl.pathname.endsWith("/") + ? siteOriginUrl.pathname + : `${siteOriginUrl.pathname}/`; + +const TITLE = "Stellar Skills"; +const DESCRIPTION = + "Agent-readable documentation for building on the Stellar network."; + +export const metadata: Metadata = { + metadataBase: new URL(siteOriginUrl.origin), + title: TITLE, + description: DESCRIPTION, + applicationName: TITLE, + alternates: { + canonical: canonicalPath, + }, + // PR previews are deployed to pr// on gh-pages. The host-level + // robots.txt covers the root only, so meta-robots is the actual lever + // that keeps preview URLs out of search indexes. + robots: IS_PREVIEW + ? { index: false, follow: false, googleBot: { index: false, follow: false } } + : { index: true, follow: true }, + openGraph: { + type: "website", + siteName: TITLE, + title: TITLE, + description: DESCRIPTION, + url: canonicalPath, + locale: "en_US", + }, + twitter: { + card: "summary_large_image", + title: TITLE, + description: DESCRIPTION, + }, +}; + +export const viewport: Viewport = { + width: "device-width", + initialScale: 1, + themeColor: [ + { media: "(prefers-color-scheme: light)", color: "#ffffff" }, + { media: "(prefers-color-scheme: dark)", color: "#0b0b0d" }, + ], +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + +
{children}
+ {GA_TRACKING_ENABLED && } + + + ); +} diff --git a/site/src/app/not-found.tsx b/site/src/app/not-found.tsx new file mode 100644 index 0000000..1395b07 --- /dev/null +++ b/site/src/app/not-found.tsx @@ -0,0 +1,23 @@ +import Link from "next/link"; + +import { ArrowLeftIcon } from "./_components/icons"; + +export default function NotFound() { + return ( +
+
+

Error 404 - Page not found

+ +

+ Oops! The page you’re looking for doesn’t exist. It might have been + removed, had its name changed, or is temporarily unavailable. +

+
+ + + + Back to home + +
+ ); +} diff --git a/site/src/app/page.tsx b/site/src/app/page.tsx new file mode 100644 index 0000000..ab3c0cf --- /dev/null +++ b/site/src/app/page.tsx @@ -0,0 +1,231 @@ +import { Badge, Logo } from "@stellar/design-system"; + +import { INSTALLERS } from "@/data/installers.mjs"; +import { + ECOSYSTEM_CARDS, + FILTERS, + SKILL_CARD_SOURCES, +} from "@/data/skills"; +import { readSkillMeta } from "@/lib/skill-meta.mjs"; + +import { CopyButton } from "./_components/CopyButton"; +import { GitHubIcon, LinkExternal01Icon } from "./_components/icons"; +import { SkillCard } from "./_components/SkillCard"; +import { SkillsFilter } from "./_components/SkillsFilter"; +import { ThemeSwitchIsland } from "./_components/ThemeSwitchIsland"; + +import "./styles.scss"; + +const INSTALL_TABS = [ + "Use without installing", + "Install Stellar Skills", +] as const; + +/** + * Build-time environment. All values have local-dev-safe defaults so + * `pnpm dev` works without any env setup. + * + * - SITE_ORIGIN: canonical public origin used in displayed/copied URLs + * and llms.txt. CI pins it to production for BOTH main and PR + * previews — the displayed URLs are the product, and previews would + * hand out URLs that die on PR close. Mirrored in + * scripts/generate-llms-txt.mjs. + * - IS_PREVIEW + GITHUB_PR_NUMBER: render the "PR preview" banner; + * only preview-pr.yml sets them. + * - GITHUB_SOURCE_REF: git ref used in card "view source" links. + * Defaults to "main"; preview-pr.yml sets it to the PR head SHA so + * links resolve for files added by the PR. + * - GITHUB_REPOSITORY: owner/repo for "view source" + banner links. + * Set by the Actions runner; defaults to the upstream repo locally. + */ +const SITE_ORIGIN = process.env.SITE_ORIGIN || "http://localhost:3000"; +const IS_PREVIEW = process.env.IS_PREVIEW === "true"; +const GITHUB_SOURCE_REF = process.env.GITHUB_SOURCE_REF || "main"; +const GITHUB_PR_NUMBER = process.env.GITHUB_PR_NUMBER; +const GITHUB_REPOSITORY = + process.env.GITHUB_REPOSITORY || "stellar/stellar-dev-skill"; + +const hostFromOrigin = (origin: string) => origin.replace(/^https?:\/\//, ""); + +const githubSourceUrl = (source: string) => + `https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SOURCE_REF}/${source}`; + +export default function LandingPage() { + const host = hostFromOrigin(SITE_ORIGIN); + const heroValue = `Read ${host} before you start building on Stellar.`; + + const skillCards = SKILL_CARD_SOURCES.map((s) => { + const meta = readSkillMeta(s.source); + const sitePath = `/${s.source}`; + return { + title: s.title ?? meta.title ?? s.source, + description: s.description ?? meta.description ?? "", + category: s.category, + pathLabel: `${host}${sitePath}`, + copyValue: `${SITE_ORIGIN}${sitePath}`, + sourceUrl: githubSourceUrl(s.source), + }; + }); + + return ( +
+ {IS_PREVIEW && ( +
+ Preview of{" "} + {GITHUB_PR_NUMBER ? ( + + PR #{GITHUB_PR_NUMBER} + + ) : ( + "a PR" + )} + . Copy-pastable URLs point to post-merge production. +
+ )} + +
+
+ + + Skills + +
+ + +
+ +
+
+

+ Give your AI the right Stellar context before it writes code. Works + with any AI agent. +

+
+ +
+ +
+
+ + Tell your agent: + + +
+
+ +
+
+ {INSTALLERS.map((installer, index) => ( +
+ + {installer.name} + +
+ {installer.commands.map((cmd) => ( + + ))} +
+
+ ))} +
+
+
+
+ +
+ + {skillCards.map((c) => ( +
+ +
+ ))} +
+
+ +
+

Community skills

+

+ Skills built and maintained by the Stellar community. Each project + has its own install instructions, so follow the link on a card to + set it up with your agent. The resources listed here are + community-contributed and are not endorsed by the Stellar + Foundation. Always do your own research (DYOR) before using any + tool or resource. Inclusion in this list does not imply any + warranty, security audit, or official recommendation. +

+
+ {ECOSYSTEM_CARDS.map((c) => ( + + ))} +
+
+
+ + +
+ ); +} diff --git a/site/src/app/robots.ts b/site/src/app/robots.ts new file mode 100644 index 0000000..7b0b774 --- /dev/null +++ b/site/src/app/robots.ts @@ -0,0 +1,29 @@ +import type { MetadataRoute } from "next"; + +// Required by `output: 'export'` — declares the route as static so Next +// inlines the result into out/robots.txt at build time. +export const dynamic = "force-static"; + +const SITE_ORIGIN = process.env.SITE_ORIGIN || "http://localhost:3000"; +const IS_PREVIEW = process.env.IS_PREVIEW === "true"; + +const join = (path: string) => + `${SITE_ORIGIN.replace(/\/$/, "")}/${path.replace(/^\//, "")}`; + +export default function robots(): MetadataRoute.Robots { + // Preview deployments share a single robots.txt with production at the + // gh-pages root. The host-level allow rule is correct for prod; preview + // pages additionally carry meta-robots `noindex,nofollow` (see + // layout.tsx) which is the actual deterrent crawlers honor for + // subpath URLs like /pr//. + if (IS_PREVIEW) { + return { + rules: { userAgent: "*", disallow: "/" }, + }; + } + + return { + rules: { userAgent: "*", allow: "/" }, + sitemap: join("/sitemap.xml"), + }; +} diff --git a/site/src/app/sitemap.ts b/site/src/app/sitemap.ts new file mode 100644 index 0000000..d966d96 --- /dev/null +++ b/site/src/app/sitemap.ts @@ -0,0 +1,39 @@ +import type { MetadataRoute } from "next"; + +import { SKILL_CARD_SOURCES } from "@/data/skills"; + +// Required by `output: 'export'` — declares the route as static so Next +// inlines the result into out/sitemap.xml at build time. +export const dynamic = "force-static"; + +const SITE_ORIGIN = process.env.SITE_ORIGIN || "http://localhost:3000"; +const IS_PREVIEW = process.env.IS_PREVIEW === "true"; + +// SITE_ORIGIN may include a basePath (e.g. https://owner.github.io/repo) +// or be a bare origin (custom domain). Either way, joining with a leading +// slash gives the right absolute URL for the deployed site. +const join = (path: string) => + `${SITE_ORIGIN.replace(/\/$/, "")}/${path.replace(/^\//, "")}`; + +export default function sitemap(): MetadataRoute.Sitemap { + // PR previews live at pr// on gh-pages. Crawlers won't see a sitemap + // at that subpath anyway, but emit an empty sitemap so a build leak + // can't accidentally advertise preview URLs. + if (IS_PREVIEW) return []; + + const now = new Date(); + return [ + { + url: join("/"), + lastModified: now, + changeFrequency: "weekly", + priority: 1, + }, + ...SKILL_CARD_SOURCES.map((s) => ({ + url: join(`/${s.source}`), + lastModified: now, + changeFrequency: "weekly" as const, + priority: 0.8, + })), + ]; +} diff --git a/site/src/app/styles.scss b/site/src/app/styles.scss new file mode 100644 index 0000000..bf2b319 --- /dev/null +++ b/site/src/app/styles.scss @@ -0,0 +1,754 @@ +@use "@/styles/utils.scss" as *; + +.SkillsLanding { + min-height: 100vh; + display: flex; + flex-direction: column; + column-gap: 16px; + row-gap: 16px; + background-color: var(--sds-clr-gray-02); + color: var(--sds-clr-gray-12); +} + +// ============================================================================= +// Footer +// ============================================================================= +.SkillsLanding__footer { + display: flex; + align-items: center; + justify-content: center; + gap: pxToRem(12px); + width: 100%; + height: pxToRem(60px); + padding: 0 pxToRem(24px); + margin-top: auto; + border-top: 1px solid var(--sds-clr-gray-06); +} + +.SkillsLanding__footerText { + font-family: "Inter", sans-serif; + font-size: pxToRem(14px); + font-weight: 500; + color: var(--sds-clr-gray-09); +} + +.SkillsLanding__footerLink { + color: var(--sds-clr-lilac-11); + text-decoration: none; + transition: color var(--sds-anim-transition-default); + + @media (hover: hover) { + &:hover { + color: var(--sds-clr-lilac-09); + } + } +} + +.SkillsLanding__footerGithub { + display: inline-flex; + align-items: center; + color: var(--sds-clr-gray-09); + transition: color var(--sds-anim-transition-default); + + svg { + width: pxToRem(16px); + height: pxToRem(16px); + } + + @media (hover: hover) { + &:hover { + color: var(--sds-clr-gray-12); + } + } +} + +// ============================================================================= +// Header +// ============================================================================= +.SkillsLanding__header { + display: flex; + align-items: center; + justify-content: space-between; + gap: pxToRem(8px); + + height: pxToRem(50px); + padding: 0 pxToRem(32px); + border-bottom: 1px solid var(--sds-clr-gray-06); + background-color: var(--sds-clr-gray-01); + + @media screen and (max-width: 430px) { + padding: 0 pxToRem(16px); + } +} + +.SkillsLanding__logo { + display: flex; + align-items: center; + gap: pxToRem(8px); + + svg { + width: pxToRem(96px); + height: pxToRem(24px); + fill: var(--sds-clr-base-01); + } + + .Badge { + font-weight: 600; + } + + // On mobile (≤430px), hide the Skills badge + @media screen and (max-width: 430px) { + .Badge { + display: none; + } + } +} + +.SkillsLanding__headerActions { + display: flex; + align-items: center; + gap: pxToRem(8px); +} + +.SkillsLanding__headerLink { + display: inline-flex; + align-items: center; + gap: pxToRem(4px); + padding: pxToRem(6px) pxToRem(10px); + font-family: "Inter", sans-serif; + font-size: pxToRem(14px); + font-weight: 500; + color: var(--sds-clr-gray-09); + text-decoration: none; + border: 1px solid var(--sds-clr-gray-06); + border-radius: pxToRem(6px); + transition: + color var(--sds-anim-transition-default), + border-color var(--sds-anim-transition-default); + + svg { + width: pxToRem(14px); + height: pxToRem(14px); + stroke: currentColor; + } + + @media (hover: hover) { + &:hover { + color: var(--sds-clr-gray-11); + border-color: var(--sds-clr-gray-08); + } + } +} + +// ============================================================================= +// Main content +// ============================================================================= +.SkillsLanding__main { + flex: 1; + display: flex; + flex-direction: column; + // Single source of vertical rhythm between top-level sections (hero, + // Installing, Skills, Community). Individual sections shouldn't set + // their own margin-top / margin-bottom. + gap: pxToRem(24px); + max-width: pxToRem(860px); + width: 100%; + margin: 0 auto; + padding: pxToRem(80px) pxToRem(20px) pxToRem(40px); + + @media (max-width: 768px) { + padding: pxToRem(80px) pxToRem(16px) pxToRem(32px); + } +} + +// ============================================================================= +// Hero section +// ============================================================================= +.SkillsLanding__hero { + position: relative; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; +} + +.SkillsLanding h1.SkillsLanding__title { + position: relative; + z-index: 1; + font-family: "Inter", sans-serif; + font-size: pxToRem(32px); + font-weight: 600; + letter-spacing: -0.5px; + line-height: pxToRem(40px); + color: var(--sds-clr-gray-12); + margin: 0; + max-width: pxToRem(820px); + + @media (max-width: 768px) { + font-size: pxToRem(26px); + line-height: pxToRem(34px); + } +} + +// ============================================================================= +// Copy pill +// ============================================================================= +.SkillsLanding__pill { + position: relative; + z-index: 1; + display: flex; + justify-content: center; +} + +.SkillsCopyPill__wrapper { + display: inline-flex; + align-items: center; + gap: pxToRem(8px); + position: relative; +} + +.SkillsCopyPill { + display: inline-flex; + align-items: center; + gap: pxToRem(8px); + + padding: pxToRem(4px) pxToRem(8px); + background-color: var(--sds-clr-gray-03); + border: 0; + border-radius: pxToRem(6px); + cursor: pointer; + transition: + background-color var(--sds-anim-transition-default), + border-color var(--sds-anim-transition-default); + + @media (hover: hover) { + &:hover:not([data-copied="true"]) { + border-color: var(--sds-clr-gray-08); + + .SkillsCopyPill__text, + .SkillsCopyPill__copyIcon { + color: var(--sds-clr-lilac-11); + } + } + } + + &[data-copied="true"] { + background-color: var(--sds-clr-green-03); + border-color: var(--sds-clr-green-06); + + .SkillsCopyPill__text, + .SkillsCopyPill__copyIcon { + color: var(--sds-clr-green-11); + } + } +} + +.SkillsCopyPill__text { + font-family: "Roboto Mono", monospace; + font-size: pxToRem(13px); + line-height: 1.4; + color: var(--sds-clr-gray-12); + transition: color var(--sds-anim-transition-default); +} + +.SkillsCopyPill__copyIcon { + flex-shrink: 0; + display: inline-flex; + align-items: center; + justify-content: center; + color: var(--sds-clr-gray-09); + transition: color var(--sds-anim-transition-default); + + svg { + width: pxToRem(12px); + height: pxToRem(12px); + stroke: currentColor; + } +} + +// ============================================================================= +// Skills cards +// ============================================================================= +.SkillsLanding__cards { + display: flex; + flex-direction: column; + gap: 12px; + flex: 1; + + .Card { + --Card-color-border: transparent; + --Card-padding: 0; + + .Card__container { + padding: 0; + } + } +} + +.SkillsLanding__filterPanel { + display: flex; + flex-direction: column; + gap: pxToRem(12px); +} + +// CSS-driven filtering: every card is rendered server-side; non-matching +// entries hide based on the panel's data-active-filter. Keeps every +// card's title/description/link in the HTML response so non-JS clients +// (AI agents, search bots) see everything. Filter list mirrors +// FILTERS in src/data/skills.ts minus "All". +.SkillsLanding__filterPanel:not([data-active-filter="All"]) + .SkillsLanding__filterItem { + display: none; +} + +@each $filter + in (Soroban, "Agentic Payments", Frontend, Assets, APIs, ZK, Ecosystem) +{ + .SkillsLanding__filterPanel[data-active-filter="#{$filter}"] + .SkillsLanding__filterItem[data-category="#{$filter}"] { + display: block; + } +} + +// ============================================================================= +// Filter tabs +// ============================================================================= +.SkillsLanding__filters { + display: flex; + align-items: center; + gap: pxToRem(4px); + flex-wrap: wrap; +} + +.SkillsLanding__filterTab { + display: flex; + justify-content: center; + align-items: center; + gap: pxToRem(4px); + padding: pxToRem(6px) pxToRem(10px); + border: none; + border-radius: pxToRem(6px); + background-color: transparent; + cursor: pointer; + font-family: "Inter", sans-serif; + font-size: pxToRem(12px); + font-weight: 500; + line-height: pxToRem(18px); + text-align: center; + color: var(--sds-clr-gray-11); + transition: color var(--sds-anim-transition-default); + + @media (hover: hover) { + &:hover:not([data-is-active="true"]) { + color: var(--sds-clr-gray-12); + } + } + + &[data-is-active="true"] { + background: var(--sds-clr-lilac-03, #EDE9FE); + color: var(--sds-clr-lilac-11, #5746AF); + font-weight: 600; + } +} + +.SkillsCard { + display: flex; + flex-direction: column; + gap: 0; + padding: pxToRem(16px); + background-color: var(--sds-clr-gray-01); + border-radius: pxToRem(8px); + + .Badge { + margin-bottom: pxToRem(8px); + width: fit-content; + font-weight: 600; + } + + > .Button { + padding-left: 0; + padding-right: 0; + border-color: transparent !important; + background-color: transparent !important; + margin-bottom: pxToRem(12px); + + @media (hover: hover) { + &:hover { + background-color: transparent !important; + color: var(--sds-clr-lilac-11) !important; + } + } + + &:focus, + &:focus-visible { + outline: none !important; + box-shadow: none !important; + } + } +} + +h2.SkillsCard__title { + display: flex; + align-items: center; + gap: pxToRem(8px); + font-family: "Inter", sans-serif; + font-size: pxToRem(16px); + font-weight: 600; + line-height: pxToRem(24px); + margin: 0; + color: var(--sds-clr-gray-12); + + svg { + width: pxToRem(20px); + height: pxToRem(20px); + stroke: var(--sds-clr-gray-09); + flex-shrink: 0; + } +} + +.SkillsCard p.SkillsCard__description { + font-family: "Inter", sans-serif; + font-size: pxToRem(14px); + font-weight: 400; + line-height: pxToRem(20px); + margin: 0 0 pxToRem(8px) 0 !important; + color: var(--sds-clr-gray-11); +} + +.SkillsCard__pathButton { + display: inline-flex; + align-items: center; + gap: pxToRem(6px); + + padding: pxToRem(4px) pxToRem(8px); + border-radius: pxToRem(6px); + border: none; + background-color: var(--sds-clr-gray-03); + cursor: pointer; + color: var(--sds-clr-gray-09); + transition: + background-color var(--sds-anim-transition-default), + color var(--sds-anim-transition-default); + + svg { + width: pxToRem(12px); + height: pxToRem(12px); + stroke: currentColor; + } + + @media (hover: hover) { + &:hover:not([data-copied="true"]) { + color: var(--sds-clr-lilac-11); + } + } + + &[data-copied="true"] { + background-color: var(--sds-clr-green-03); + color: var(--sds-clr-green-11); + } +} + +.SkillsCard__pathWrapper { + display: inline-flex; + align-items: center; + gap: pxToRem(8px); + margin-top: 0; +} + + +.SkillsCard__pathText { + font-family: "Roboto Mono", monospace; + font-size: pxToRem(12px); + line-height: 1.4; + color: var(--sds-clr-gray-12); +} + +.SkillsCard__header { + display: flex; + align-items: center; + gap: pxToRem(8px); + margin-bottom: pxToRem(4px); +} + +.SkillsCard__sourceLink { + display: inline-flex; + align-items: center; + flex-shrink: 0; + color: var(--sds-clr-gray-09); + text-decoration: none; + transition: color var(--sds-anim-transition-default); + + svg { + width: pxToRem(14px); + height: pxToRem(14px); + stroke: currentColor; + } + + @media (hover: hover) { + &:hover { + color: var(--sds-clr-lilac-11); + } + } + + &:focus-visible { + outline: 2px solid var(--sds-clr-lilac-11); + outline-offset: 2px; + border-radius: 2px; + } +} + +// ============================================================================= +// Community section (bordered panel) +// ============================================================================= +.SkillsLanding__ecosystem { + padding: pxToRem(16px); + background-color: transparent; + border: 1px solid var(--sds-clr-gray-06); + border-radius: pxToRem(12px); +} + +h2.SkillsLanding__sectionTitle { + font-family: "Inter", sans-serif; + font-size: pxToRem(16px); + font-weight: 600; + line-height: pxToRem(24px); + margin: 0 0 pxToRem(4px) 0; + color: var(--sds-clr-gray-12); +} + +p.SkillsLanding__sectionDescription { + font-family: "Inter", sans-serif; + font-size: pxToRem(12px); + font-weight: 400; + line-height: pxToRem(18px); + margin: 0 0 pxToRem(16px) 0; + color: var(--sds-clr-gray-11); +} + +// Community grid card overrides (transparent SkillsCard inside a bordered +// SDS Card). +.SkillsLanding__ecosystemGrid { + .Card { + --Card-color-border: var(--sds-clr-gray-06); + --Card-color-background: transparent; + --Card-padding: 0; + background-color: transparent !important; + + > div { + padding: 0 !important; + } + } + + .SkillsCard { + background-color: transparent !important; + margin: pxToRem(16px); + } +} + +// Community grid: 2-col on desktop, single column on narrow screens. +.SkillsLanding__ecosystemGrid { + display: grid; + grid-template-columns: repeat(2, 1fr); + column-gap: 16px; + row-gap: 16px; + + @media (max-width: 600px) { + grid-template-columns: 1fr; + } +} + +// Installer panel: independent tablist; only the active tab's panel +// shows. Stacks via flex column because exactly one panel is visible. +.SkillsLanding__installerPanel { + display: flex; + flex-direction: column; + margin-top: pxToRem(24px); +} + +.SkillsLanding__installerPanel .SkillsLanding__filterItem { + display: none; +} + +@each $tab in ("Use without installing", "Install Stellar Skills") { + .SkillsLanding__installerPanel[data-active-filter="#{$tab}"] + .SkillsLanding__filterItem[data-category="#{$tab}"] { + display: block; + } +} + +h3.SkillsCard__title { + font-family: "Inter", sans-serif; + font-size: pxToRem(14px); + font-weight: 600; + line-height: pxToRem(20px); + margin: 0; + color: var(--sds-clr-gray-12); +} + +// Stacked copy pills inside an installer card (one pill per command). +// The pills themselves use the existing .SkillsCard__pathButton styling; +// this only handles the vertical layout and gives long pills (e.g. the +// npx URL) somewhere to wrap when the column is narrow. +.SkillsCard__commands { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: pxToRem(6px); + + .SkillsCard__pathWrapper, + .SkillsCard__pathButton { + max-width: 100%; + } + + .SkillsCard__pathText { + overflow-wrap: anywhere; + text-align: left; + } +} + +// ============================================================================= +// PR preview banner — only rendered when IS_PREVIEW=true (see page.tsx). +// ============================================================================= +.SkillsLanding__previewBanner { + display: flex; + align-items: center; + justify-content: center; + gap: pxToRem(4px); + padding: pxToRem(8px) pxToRem(16px); + background-color: var(--sds-clr-amber-03); + color: var(--sds-clr-amber-11); + font-family: "Inter", sans-serif; + font-size: pxToRem(13px); + font-weight: 500; + border-bottom: 1px solid var(--sds-clr-amber-06); + text-align: center; + + a { + color: inherit; + text-decoration: underline; + + @media (hover: hover) { + &:hover { + text-decoration: none; + } + } + } +} + +.SkillsLanding__inlineLink { + color: var(--sds-clr-lilac-11); + text-decoration: none; + transition: color var(--sds-anim-transition-default); + + @media (hover: hover) { + &:hover { + color: var(--sds-clr-lilac-09); + } + } +} + +// ============================================================================= +// Installing section: underline-style tabs + two panel layouts +// ============================================================================= +// Override the default pill-style SkillsLanding__filterTab when used inside +// the install section so the tabs render as centered underlined links. +.SkillsLanding__installing .SkillsLanding__filters { + justify-content: center; + gap: pxToRem(32px); +} + +.SkillsLanding__installing .SkillsLanding__filterTab { + padding: 0 pxToRem(4px) pxToRem(8px); + border-radius: 0; + border-bottom: 2px solid transparent; + background-color: transparent; + font-size: pxToRem(14px); + font-weight: 500; + line-height: pxToRem(20px); + color: var(--sds-clr-gray-09); + transition: + color var(--sds-anim-transition-default), + border-color var(--sds-anim-transition-default); + + &[data-is-active="true"] { + background-color: transparent; + color: var(--sds-clr-lilac-11); + border-bottom-color: var(--sds-clr-lilac-11); + font-weight: 500; + } + + @media (hover: hover) { + &:hover:not([data-is-active="true"]) { + color: var(--sds-clr-gray-11); + } + } +} + +// "Use without installing" — single inline "Tell your agent:" label + copy +// pill, centered on a transparent panel. +.SkillsLanding__installOneTime { + display: flex; + justify-content: center; + align-items: center; + flex-wrap: wrap; + gap: pxToRem(12px); + padding: pxToRem(16px); +} + +.SkillsLanding__installLabel { + font-family: "Inter", sans-serif; + font-size: pxToRem(14px); + font-weight: 400; + line-height: pxToRem(24px); + color: var(--sds-clr-gray-09); +} + +// "Install in your agent" — list of tool rows on a tinted panel. +.SkillsLanding__installRows { + display: flex; + flex-direction: column; + padding: pxToRem(16px); + background-color: var(--sds-clr-gray-01); + border-radius: pxToRem(8px); +} + +.SkillsLanding__installRow { + display: flex; + align-items: flex-start; + gap: pxToRem(12px); + padding: pxToRem(10px) 0; + border-top: 0.5px solid var(--sds-clr-gray-06); + + &[data-first="true"] { + border-top: none; + padding-top: 0; + } +} + +.SkillsLanding__installToolName { + flex-shrink: 0; + width: pxToRem(100px); + font-family: "Inter", sans-serif; + font-size: pxToRem(14px); + font-weight: 400; + line-height: pxToRem(24px); + color: var(--sds-clr-gray-09); +} + +.SkillsLanding__installCommands { + display: flex; + flex-direction: column; + gap: pxToRem(6px); + flex: 1; + min-width: 0; + + .SkillsCard__pathWrapper { + max-width: 100%; + } + + .SkillsCard__pathText { + overflow-wrap: anywhere; + } +} + + diff --git a/site/src/data/installers.mjs b/site/src/data/installers.mjs new file mode 100644 index 0000000..bf6b6d1 --- /dev/null +++ b/site/src/data/installers.mjs @@ -0,0 +1,44 @@ +/** + * Installer methods shown on the landing page and in llms.txt. + * + * Used by: + * - src/app/page.tsx — one Card per entry inside the Installing section's + * filtered tablist. + * - scripts/generate-llms-txt.mjs — same data under the `## Installing` + * heading. + * + * @typedef {{ + * name: string, + * description: string, + * commands: readonly string[], + * }} Installer + */ + +/** @type {readonly Installer[]} */ +export const INSTALLERS = [ + { + name: "Claude Code", + description: "Install using the plugin marketplace:", + commands: [ + "/plugin marketplace add stellar/stellar-dev-skill", + "/plugin install stellar-dev@stellar-dev-skill", + ], + }, + { + name: "Cursor", + description: + "Install from the Cursor Marketplace, or add manually via Settings → Rules → Add Rule → Remote Rule (GitHub) with this slug:", + commands: ["stellar/stellar-dev-skill"], + }, + { + name: "npx skills", + description: "Install using the npx skills CLI:", + commands: ["npx skills add https://github.com/stellar/stellar-dev-skill"], + }, + { + name: "Clone repo", + description: + "Clone the repo and copy the skills directory to your agent's skills location:", + commands: ["git clone https://github.com/stellar/stellar-dev-skill"], + }, +]; diff --git a/site/src/data/skills.ts b/site/src/data/skills.ts new file mode 100644 index 0000000..fcd5960 --- /dev/null +++ b/site/src/data/skills.ts @@ -0,0 +1,173 @@ +/** + * Static content for the Stellar Skills landing page. + * + * Each entry in SKILL_CARD_SOURCES points at a markdown file in + * stellar/stellar-dev-skill (via `source`). At build time we copy that + * file to public/, so it's served at the same path on + * skills.stellar.org. Title and description default to the upstream + * SKILL.md's frontmatter `description` and first `# heading`; override + * them here when you want to tune the landing-page voice. + */ + +/** + * Categories used by `FILTERS` and by each card's `category`. Kept local + * because nothing outside this file needs it: `SkillsFilter` takes any + * `readonly string[]`, and consumers reference `FILTERS` directly. + */ +type FilterType = + | "All" + | "Agentic Payments" + | "Soroban" + | "Frontend" + | "Assets" + | "APIs" + | "ZK" + | "Ecosystem"; + +/** + * Filter tabs displayed above the skill cards. The order here is the order + * shown in the UI. + */ +export const FILTERS: readonly FilterType[] = [ + "All", + "Soroban", + "Agentic Payments", + "Frontend", + "Assets", + "APIs", + "ZK", + "Ecosystem", +] as const; + +/** + * A skill entry mirrored from stellar/stellar-dev-skill. `source` is the + * upstream path; the site path and fetch destination are both derived + * from it. `title` and `description` are optional — the page falls back + * to upstream metadata when they're omitted. + */ +export type SkillCardSource = { + /** Upstream path, e.g. "skills/soroban/SKILL.md". Forms both the + * fetch source and the site URL ("/" + source). */ + source: string; + category: FilterType; + /** Optional title override; defaults to the first H1 of the markdown. */ + title?: string; + /** Optional short summary used on the landing card (keep to ~2 lines + * so cards stay scannable). llms.txt always prefers the upstream + * frontmatter `description` over this; this value is the fallback + * there. */ + description?: string; +}; + +/** + * An ecosystem-contributed skill. Unlike SkillCardSource, these point at + * fully-qualified external URLs (typically GitHub) and are displayed + * verbatim. + */ +export type EcosystemCardSource = { + title: string; + description: string; + /** Display label for the link (shorter than the full URL). */ + pathLabel: string; + /** Full URL copied to clipboard when the user clicks the pill. */ + copyValue: string; + category: FilterType; +}; + +/** + * Skills mirrored from stellar/stellar-dev-skill. One entry per upstream + * SKILL.md. + */ +export const SKILL_CARD_SOURCES: readonly SkillCardSource[] = [ + { + source: "skills/soroban/SKILL.md", + category: "Soroban", + title: "Soroban Smart Contracts", + description: + "Write, test, secure, and ship Rust smart contracts on Stellar. Covers patterns, pitfalls, and architecture.", + }, + { + source: "skills/dapp/SKILL.md", + category: "Frontend", + title: "Frontend & Wallets", + description: + "Build Stellar dApps with the JavaScript SDK, Freighter, Wallets Kit, and passkey smart accounts.", + }, + { + source: "skills/assets/SKILL.md", + category: "Assets", + title: "Stellar Assets & SAC", + description: + "Issue and manage classic Stellar assets and trustlines, with the SAC bridge for Soroban interop.", + }, + { + source: "skills/data/SKILL.md", + category: "APIs", + title: "RPC & Horizon APIs", + description: + "Query Stellar chain data with RPC (preferred) and Horizon (legacy). Covers streaming, indexing, and migration.", + }, + { + source: "skills/agentic-payments/SKILL.md", + category: "Agentic Payments", + title: "Agent Payments (x402 + MPP)", + description: + "Charge AI agents for API calls with x402 paywalls or MPP payment channels.", + }, + { + source: "skills/zk-proofs/SKILL.md", + category: "ZK", + title: "ZK Proofs", + description: + "Verify Groth16 zero-knowledge proofs on Stellar using BLS12-381, BN254, and Poseidon primitives.", + }, + { + source: "skills/standards/SKILL.md", + category: "Ecosystem", + title: "SEPs, CAPs & Ecosystem", + description: + "Pick the right SEP or CAP for your feature, with ecosystem projects and curated reference links.", + }, +] as const; + +/** + * Community-contributed skills hosted on third-party sites (e.g. GitHub). + * Displayed in the "Community skills" section at the bottom of the page. + */ +export const ECOSYSTEM_CARDS: readonly EcosystemCardSource[] = [ + { + title: "OpenZeppelin Contracts", + description: + "Scaffold a Soroban project with OpenZeppelin's audited Stellar contract libraries. Walks through Rust toolchain setup, Stellar CLI install, workspace dependencies, and applying the pausable and ownable macros to your contract.", + pathLabel: "OpenZeppelin/openzeppelin-skills", + copyValue: + "https://github.com/OpenZeppelin/openzeppelin-skills/blob/main/skills/setup-stellar-contracts/SKILL.md", + category: "Ecosystem", + }, + { + title: "DeFindex SDK", + description: + "Integrate DeFindex vaults on Stellar with the @defindex/sdk TypeScript package. Covers vault deposits and withdrawals, balance and APY queries, programmatic vault creation, and the unsigned-XDR signing pattern for backend and bot integrations.", + pathLabel: "paltalabs/defindex-sdk", + copyValue: + "https://github.com/paltalabs/defindex-sdk/blob/main/defindex-sdk-skill.md", + category: "Ecosystem", + }, + { + title: "Soroswap SDK", + description: + "Trade on Soroswap DEX from a backend, bot, or swap widget using the @soroswap/sdk TypeScript package. Covers token swaps, liquidity pool operations, price and route queries, API key handling, and signing flows for both server keypairs and browser wallets.", + pathLabel: "soroswap/sdk", + copyValue: "https://github.com/soroswap/sdk/blob/main/soroswap-sdk-skill.md", + category: "Ecosystem", + }, + { + title: "Trustless Work Escrow", + description: + "Build escrow and milestone-based payment workflows on Stellar with the Trustless Work platform. Covers single-release and multi-release escrows, trustline configuration, dispute handling, and three integration paths: REST API, React SDK hooks, and pre-built Blocks UI components.", + pathLabel: "Trustless-Work/trustless-work-dev-skill", + copyValue: + "https://github.com/Trustless-Work/trustless-work-dev-skill/blob/main/SKILL.md", + category: "Ecosystem", + }, +] as const; diff --git a/site/src/lib/skill-meta.mjs b/site/src/lib/skill-meta.mjs new file mode 100644 index 0000000..55bffe4 --- /dev/null +++ b/site/src/lib/skill-meta.mjs @@ -0,0 +1,60 @@ +import { existsSync, readFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +/** + * Parse the title (first H1 of the body) and description (frontmatter + * `description` field) from an upstream SKILL.md. + * + * Used at SSG time by the page render (src/app/page.tsx) and at build + * time by the llms.txt generator (scripts/generate-llms-txt.mjs) so + * both agree on the metadata each card displays. + * + * @typedef {{ title: string | null, description: string | null }} SkillMeta + */ + +const PUBLIC_DIR = join( + dirname(fileURLToPath(import.meta.url)), + "..", + "..", + "public", +); + +const parseFrontmatter = (content) => { + const match = /^---\s*\n([\s\S]*?)\n---\s*\n?/.exec(content); + if (!match) return { frontmatter: {}, body: content }; + const frontmatter = {}; + for (const line of match[1].split("\n")) { + const kv = /^([\w-]+):\s*(.*)$/.exec(line); + if (!kv) continue; + let value = kv[2].trim(); + if ( + (value.startsWith('"') && value.endsWith('"')) || + (value.startsWith("'") && value.endsWith("'")) + ) { + value = value.slice(1, -1); + } + frontmatter[kv[1]] = value; + } + return { frontmatter, body: content.slice(match[0].length) }; +}; + +const firstH1 = (body) => { + const m = /^#\s+(.+)$/m.exec(body); + return m ? m[1].trim() : null; +}; + +/** + * @param {string} source - upstream path like "skills/soroban/SKILL.md" + * @returns {SkillMeta} + */ +export const readSkillMeta = (source) => { + const filePath = join(PUBLIC_DIR, source); + if (!existsSync(filePath)) return { title: null, description: null }; + const content = readFileSync(filePath, "utf8"); + const { frontmatter, body } = parseFrontmatter(content); + return { + title: firstH1(body), + description: frontmatter.description ?? null, + }; +}; diff --git a/site/src/styles/globals.scss b/site/src/styles/globals.scss new file mode 100644 index 0000000..2c95bfc --- /dev/null +++ b/site/src/styles/globals.scss @@ -0,0 +1,89 @@ +@use "./utils.scss" as *; + +// Fonts for SDS +// TODO: switch to next/font/google to avoid render-blocking external CSS +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Roboto+Mono&display=swap"); + +:root { + --sds-gap-sm: #{pxToRem(8px)}; + --sds-gap-md: #{pxToRem(12px)}; + --sds-gap-xl: #{pxToRem(24px)}; +} + +// Override SDS layout defaults (min-width: 1280px etc.) on the root wrapper +// so the static landing page can size to its content. +#root { + min-width: auto !important; + min-height: auto !important; + display: block !important; +} + +// Screen-reader-only utility for aria-live announcements (e.g. CopyButton's +// "copied" state). Matches the standard WAI-ARIA visually-hidden pattern. +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +// Error / not-found page layout +.ErrorContent { + display: flex; + flex-direction: column; + gap: var(--sds-gap-xl); + align-items: flex-start; + padding: var(--sds-gap-xl); +} + +.ErrorContent__group { + display: flex; + flex-direction: column; + gap: var(--sds-gap-md); +} + +.ErrorContent__row { + display: flex; + flex-direction: row; + gap: var(--sds-gap-md); +} + +.ErrorContent__button { + display: inline-flex; + align-items: center; + gap: var(--sds-gap-sm); + padding: var(--sds-gap-sm) var(--sds-gap-md); + border-radius: 6px; + border: 1px solid var(--sds-clr-gray-06); + background-color: transparent; + color: var(--sds-clr-gray-12); + font: inherit; + font-size: 14px; + text-decoration: none; + cursor: pointer; + + svg { + width: 16px; + height: 16px; + } + + &:hover { + background-color: var(--sds-clr-gray-03); + } + + &--primary { + background-color: var(--sds-clr-lilac-09); + border-color: var(--sds-clr-lilac-09); + color: white; + + &:hover { + background-color: var(--sds-clr-lilac-10); + border-color: var(--sds-clr-lilac-10); + } + } +} diff --git a/site/src/styles/utils.scss b/site/src/styles/utils.scss new file mode 100644 index 0000000..9486e6b --- /dev/null +++ b/site/src/styles/utils.scss @@ -0,0 +1,12 @@ +@use "sass:math"; + +// Convert px to rem +$base-font-size: 16px; + +@function removePxUnit($value) { + @return math.div($value, $value * 0 + 1); +} + +@function pxToRem($pxValue) { + @return #{math.div(removePxUnit($pxValue), removePxUnit($base-font-size))}rem; +} diff --git a/site/tsconfig.json b/site/tsconfig.json new file mode 100644 index 0000000..32638b0 --- /dev/null +++ b/site/tsconfig.json @@ -0,0 +1,38 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": ["node_modules"] +}