diff --git a/.env.dist b/.env.dist new file mode 100644 index 0000000..9f49bb2 --- /dev/null +++ b/.env.dist @@ -0,0 +1,2 @@ +# Site URL - must match SITE_URL in wrangler.jsonc for the target environment +SITE_URL=https://johnhooks.io diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 7417183..0000000 --- a/.eslintignore +++ /dev/null @@ -1,18 +0,0 @@ -.DS_Store -node_modules - -/apps - -dist -lib -!apps/website/src/lib -temp - -.env -.env.* -!.env.example - -# Ignore files for PNPM, NPM and YARN -pnpm-lock.yaml -package-lock.json -yarn.lock diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 706b3e9..0000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,53 +0,0 @@ -module.exports = { - root: true, - parser: "@typescript-eslint/parser", - extends: [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:import/recommended", - "plugin:import/typescript", - "prettier", - ], - plugins: ["@typescript-eslint"], - ignorePatterns: ["*.cjs"], - overrides: [ - { - files: ["**/?(*.)+(spec|test).ts"], - extends: ["plugin:testing-library/dom", "plugin:jest-dom/recommended"], - }, - ], - rules: { - "import/order": [ - "error", - { - alphabetize: { - order: "asc", - caseInsensitive: true, - }, - "newlines-between": "always", - groups: ["builtin", "external", "parent", "sibling", "index"], - pathGroupsExcludedImportTypes: ["builtin"], - }, - ], - }, - settings: { - "import/parsers": { - "@typescript-eslint/parser": [".ts"], - }, - "import/resolver": { - typescript: { - alwaysTryTypes: true, - projects: ["./"], - }, - }, - }, - parserOptions: { - sourceType: "module", - ecmaVersion: 2020, - }, - env: { - browser: true, - es2017: true, - node: true, - }, -}; diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml deleted file mode 100644 index 6ec588a..0000000 --- a/.github/actions/build/action.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Build application - -inputs: - repo-token: - description: "Token to access the repo" - required: true - -runs: - using: "composite" - steps: - - name: Setup Node - uses: actions/setup-node@v3 - with: - node-version: "16" - - - name: Turborepo local server - uses: felixmosh/turborepo-gh-artifacts@v2.1.0 - with: - repo-token: ${{ inputs.repo-token }} - - - name: Install specific Yarn version - shell: bash - run: | - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.22.19 - echo 'export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH"' >> $GITHUB_PATH - - - name: Get yarn cache directory path - id: yarn-cache-dir-path - shell: bash - run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - - - name: Cache node_modules - uses: actions/cache@v3 - id: yarn-cache - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - - name: Install Packages - shell: bash - run: yarn install --frozen-lockfile - - - name: Build application - shell: bash - run: yarn build - - - name: Test application - shell: bash - run: yarn test - - - name: Lint application - shell: bash - run: yarn lint - - - name: Type check application - shell: bash - run: yarn run check - - diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 0000000..79d134e --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,18 @@ +name: Setup +description: Setup Node.js, pnpm, and install dependencies + +runs: + using: composite + steps: + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "22" + cache: "pnpm" + + - name: Install Dependencies + shell: bash + run: pnpm install --frozen-lockfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d4b88e5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,71 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Setup Environment + run: cp .env.dist .env + + - name: Build + run: pnpm build + + - name: Upload Build Artifacts + uses: actions/upload-artifact@v4 + with: + name: build-output + path: | + .svelte-kit + node_modules + retention-days: 1 + + lint: + needs: build + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Download Build Artifacts + uses: actions/download-artifact@v4 + with: + name: build-output + + - name: Run Lint + run: pnpm lint + + check: + needs: build + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Download Build Artifacts + uses: actions/download-artifact@v4 + with: + name: build-output + + - name: Run Type Check + run: pnpm check diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml new file mode 100644 index 0000000..8554ab8 --- /dev/null +++ b/.github/workflows/deploy-production.yml @@ -0,0 +1,21 @@ +name: Deploy Production + +on: + workflow_dispatch: + inputs: + ref: + description: "Branch or tag to deploy (leave empty for default branch)" + required: false + type: string + default: "" + +jobs: + deploy: + uses: ./.github/workflows/wrangler-deploy.yml + with: + environment: production + site_url: https://johnhooks.io + ref: ${{ inputs.ref }} + secrets: + cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml new file mode 100644 index 0000000..979aaf7 --- /dev/null +++ b/.github/workflows/deploy-staging.yml @@ -0,0 +1,21 @@ +name: Deploy Staging + +on: + workflow_dispatch: + inputs: + ref: + description: "Branch or tag to deploy (leave empty for default branch)" + required: false + type: string + default: "" + +jobs: + deploy: + uses: ./.github/workflows/wrangler-deploy.yml + with: + environment: staging + site_url: https://website-staging.johnhooks.workers.dev + ref: ${{ inputs.ref }} + secrets: + cloudflare_api_token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + cloudflare_account_id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml deleted file mode 100644 index e0af56d..0000000 --- a/.github/workflows/deploy.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Deploy SvelteKit static site to Pages - -on: - # Runs on pushes targeting the default branch - push: - branches: ["main"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow one concurrent deployment -concurrency: - group: "pages" - cancel-in-progress: true - -jobs: - # Build Job - build: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Build packages - uses: ./.github/actions/build - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Build website - shell: bash - run: yarn website:build - - # This action uploads an artifact named `github-pages` which will be used by actions/deploy-pages - - name: Upload artifact - uses: actions/upload-pages-artifact@v1 - with: - path: ./apps/website/build - - # Deploy job - deploy: - # Only deploy if the string '(website)' is in the commit message. NOTE not a RegExp - if: "contains(github.event.head_commit.message, '(website)')" - - # Add a dependency to the build job - needs: build - - # Grant GITHUB_TOKEN the permissions required to make a Pages deployment - permissions: - pages: write # to deploy to Pages - id-token: write # to verify the deployment originates from an appropriate source - - # Deploy to the github-pages environment - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - - # Specify runner + deployment step - runs-on: ubuntu-latest - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v1 diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml deleted file mode 100644 index cc230ea..0000000 --- a/.github/workflows/pipeline.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Run build pipeline - -on: - pull_request: - workflow_dispatch: - -env: - # environment variables to config `turbo` to use the local cache server - TURBO_API: "http://127.0.0.1:9080" - TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} - TURBO_TEAM: "dinero" - TURBO_REMOTE_ONLY: true - # Used by scripts/build/types.js - CI: true - -jobs: - pipeline: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Build application - uses: ./.github/actions/build - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/wrangler-deploy.yml b/.github/workflows/wrangler-deploy.yml new file mode 100644 index 0000000..c48e9a8 --- /dev/null +++ b/.github/workflows/wrangler-deploy.yml @@ -0,0 +1,48 @@ +name: Reusable Workflow - Wrangler Deploy + +on: + workflow_call: + inputs: + environment: + required: true + type: string + description: Environment to deploy (production or staging) + site_url: + required: true + type: string + description: Site URL for build + ref: + required: false + type: string + description: Git ref to deploy + default: "" + secrets: + cloudflare_api_token: + required: true + cloudflare_account_id: + required: true + +jobs: + deploy: + runs-on: ubuntu-latest + environment: ${{ inputs.environment }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref || github.ref }} + + - name: Setup + uses: ./.github/actions/setup + + - name: Build + run: pnpm build + env: + SITE_URL: ${{ inputs.site_url }} + + - name: Deploy to Cloudflare + run: pnpm wrangler deploy --env ${{ inputs.environment }} + env: + CLOUDFLARE_API_TOKEN: ${{ secrets.cloudflare_api_token }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.cloudflare_account_id }} diff --git a/.gitignore b/.gitignore index dcb996d..f9703fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,10 @@ .DS_Store node_modules -.turbo .svelte-kit -package - - -dist -lib -temp - -apps/website/static/worklets -apps/website/build/ -!apps/*/src/lib +.wrangler +build .env .env.* -!.env.example +!.env.dist diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index d24fdfc..0000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - -npx lint-staged diff --git a/.prettierignore b/.prettierignore index ffbf774..bd5535a 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,22 +1 @@ -.DS_Store -node_modules -build -.svelte-kit -package - -dist -lib -temp - -!apps/*/src/lib - -**/*.md - -.env -.env.* -!.env.example - -# Ignore files for PNPM, NPM and YARN pnpm-lock.yaml -package-lock.json -yarn.lock diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index c2f7493..0000000 --- a/.prettierrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "useTabs": false, - "singleQuote": false, - "semi": true, - "trailingComma": "es5", - "printWidth": 100, - "proseWrap": "never", - "pluginSearchDirs": ["."], - "overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index d6bd910..fb2a417 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -35,7 +35,7 @@ "html.autoClosingTags": true, "typescript.suggest.completeJSDocs": false, "typescript.disableAutomaticTypeAcquisition": true, - "eslint.workingDirectories": ["./apps/website", "./"], + "eslint.workingDirectories": ["./"], "cSpell.words": [ "compile", "csrf", diff --git a/README.md b/README.md index bbf4739..6829bbb 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,32 @@ -# My Website +# johnhooks.io [johnhooks.io](https://johnhooks.io) -This is the repo for my personal website. Using [SvelteKit](https://kit.svelte.dev), it is statically built though a GitHub Action and deployed to GitHub Pages. - -I use this site as a place to learn new things and also make notes that as much for my own retention of information as for sharing with others. +Personal website built with [SvelteKit](https://kit.svelte.dev) and deployed to Cloudflare Workers. ## Developing -Once you've downloaded the project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: - ```bash -npm run dev - -# or start the server and open the app in a new browser tab -npm run dev -- --open +pnpm install +pnpm dev ``` ## Building -To create a production version of the app: +```bash +pnpm build +pnpm preview +``` + +## Deployment ```bash -npm run build +pnpm deploy ``` -You can preview the production build with `npm run preview`. +Or test locally with wrangler: + +```bash +pnpm build +wrangler dev .svelte-kit/cloudflare +``` diff --git a/api-extractor.json b/api-extractor.json deleted file mode 100644 index a2a468a..0000000 --- a/api-extractor.json +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Config file for API Extractor. For more info, please visit: https://api-extractor.com - */ -{ - "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "/lib/index.d.ts", - "bundledPackages": [], - "compiler": { - "overrideTsconfig": { - "$schema": "http://json.schemastore.org/tsconfig", - "extends": "./tsconfig", - "compilerOptions": { - "paths": {} - } - } - }, - "apiReport": { - "enabled": true - }, - "docModel": { - "enabled": false - }, - "dtsRollup": { - "enabled": true, - "untrimmedFilePath": "", - "publicTrimmedFilePath": "/dist/index.d.ts" - }, - "tsdocMetadata": { - "tsdocMetadataFilePath": "/dist/tsdoc-metadata.json" - }, - "newlineKind": "lf", - "messages": { - "compilerMessageReporting": { - "default": { - "logLevel": "warning" - } - }, - "extractorMessageReporting": { - "default": { - "logLevel": "warning" - } - }, - "tsdocMessageReporting": { - "default": { - "logLevel": "warning" - } - } - } -} diff --git a/apps/tsconfig.json b/apps/tsconfig.json deleted file mode 100644 index b5cc680..0000000 --- a/apps/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "../tsconfig.base.json", - "files": [], - "include": [], - "references": [{ "path": "./website" }] -} diff --git a/apps/website/.eslintignore b/apps/website/.eslintignore deleted file mode 100644 index eef1b50..0000000 --- a/apps/website/.eslintignore +++ /dev/null @@ -1,14 +0,0 @@ -.DS_Store -node_modules -/build -/.svelte-kit -/package -/static/worklets -.env -.env.* -!.env.example - -# Ignore files for PNPM, NPM and YARN -pnpm-lock.yaml -package-lock.json -yarn.lock diff --git a/apps/website/.eslintrc.cjs b/apps/website/.eslintrc.cjs deleted file mode 100644 index 795310e..0000000 --- a/apps/website/.eslintrc.cjs +++ /dev/null @@ -1,99 +0,0 @@ -const path = require("node:path"); - -module.exports = { - root: true, - parser: "@typescript-eslint/parser", - extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], - plugins: ["svelte3", "@typescript-eslint", "import"], - ignorePatterns: ["*.cjs"], - rules: { - "import/no-extraneous-dependencies": [ - "error", - { packageDir: [__dirname, path.resolve(__dirname, "../../")] }, - ], - "import/order": [ - "error", - { - alphabetize: { - order: "asc", - caseInsensitive: true, - }, - "newlines-between": "always", - groups: ["builtin", "external", "parent", "sibling", "index"], - pathGroups: [ - { - pattern: "$app/**/*", - group: "parent", - position: "before", - }, - { - pattern: "$lib/**/*", - group: "parent", - position: "before", - }, - ], - pathGroupsExcludedImportTypes: ["builtin"], - }, - ], - }, - overrides: [ - { - files: ["**/*.(js|ts)"], - plugins: ["import"], - extends: ["prettier", "plugin:import/recommended", "plugin:import/typescript"], - rules: { - "import/order": [ - "error", - { - alphabetize: { - order: "asc", - caseInsensitive: true, - }, - "newlines-between": "always", - groups: ["builtin", "external", "parent", "sibling", "index"], - pathGroups: [ - { - pattern: "$lib/**/*", - group: "parent", - position: "before", - }, - ], - pathGroupsExcludedImportTypes: ["builtin"], - }, - ], - }, - }, - { - files: ["*.svelte"], - processor: "svelte3/svelte3", - rules: { - "import/no-unresolved": "off", - }, - }, - { - files: ["**/?(*.)+(spec|test).ts"], - extends: ["plugin:testing-library/dom", "plugin:jest-dom/recommended"], - }, - ], - settings: { - "svelte3/typescript": () => require("typescript"), - "import/parsers": { - "@typescript-eslint/parser": [".ts"], - }, - "import/resolver": { - typescript: { - alwaysTryTypes: true, - projects: ["./"], - }, - }, - }, - parserOptions: { - sourceType: "module", - ecmaVersion: 2020, - }, - env: { - browser: true, - es2017: true, - node: true, - }, -}; diff --git a/apps/website/.npmrc b/apps/website/.npmrc deleted file mode 100644 index b6f27f1..0000000 --- a/apps/website/.npmrc +++ /dev/null @@ -1 +0,0 @@ -engine-strict=true diff --git a/apps/website/.prettierignore b/apps/website/.prettierignore deleted file mode 100644 index de5b084..0000000 --- a/apps/website/.prettierignore +++ /dev/null @@ -1,17 +0,0 @@ -.DS_Store -node_modules -build -.svelte-kit -package - -static/worklets -**/*.md - -.env -.env.* -!.env.example - -# Ignore files for PNPM, NPM and YARN -pnpm-lock.yaml -package-lock.json -yarn.lock diff --git a/apps/website/NOTES.md b/apps/website/NOTES.md deleted file mode 100644 index f9e11a7..0000000 --- a/apps/website/NOTES.md +++ /dev/null @@ -1,7 +0,0 @@ -## Todo - -- [x] create a markdown metadata type - -## Reminders - -- The concepts from big companies tend to filter down to smaller organizations. Though keep in mind the difference in scale. Systems that are well designed and functional at a large scale may not be right for a smaller team. diff --git a/apps/website/mdsvex/highligher.js b/apps/website/mdsvex/highligher.js deleted file mode 100644 index 121ee34..0000000 --- a/apps/website/mdsvex/highligher.js +++ /dev/null @@ -1,110 +0,0 @@ -import { toHtml } from "hast-util-to-html"; -import { h } from "hastscript"; -import rangeParser from "parse-numeric-range"; -import rehypeParse from "rehype-parse"; -import shiki from "shiki"; -import { unified } from "unified"; -import { visit } from "unist-util-visit"; - -// -/** - * Escape curlies, backtick, \t, \r, \n to avoid breaking output of {@html `here`} in .svelte - * - * [reference](https://github.com/pngwn/MDsveX/blob/6c60fe68c335fce559db9690fbf5e69ef539d37d/packages/mdsvex/src/transformers/index.ts#L571) - * @param {string} str - * @returns {string} - */ -const escape_svelty = (str) => - str - .replace(/[{}`]/g, (c) => ({ "{": "{", "}": "}", "`": "`" }[c])) - .replace(/\\([trn])/g, "\$1"); - -export const reverseString = (s) => s?.split("").reverse().join(""); - -const hastParser = unified().use(rehypeParse, { fragment: true }); - -const shikiHighlighter = await shiki.getHighlighter({ theme: "css-variables" }); - -/** - * Highlighter function for Mdsvex codeblocks. - * - * [reference](https://github.com/atomiks/rehype-pretty-code/blob/e24f8415c8264dc868006ced839d3cb7445e716a/src/index.js#L50) - * @param {string} raw - Source code to highlight - * @param {string} lang - Source language - * @param {string} meta - Source metadata - * @returns - */ -export async function highlighter(raw, lang, meta) { - const titleMatch = meta?.match(/title="(.+)"/); - const title = titleMatch?.[1] ?? null; - const titleString = titleMatch?.[0] ?? ""; - const metaWithoutTitle = meta?.replace(titleString, ""); - - const tree = hastParser.parse(shikiHighlighter.codeToHtml(raw, { lang: lang || "txt" })); - - const lineNumbers = meta ? rangeParser(metaWithoutTitle.match(/{(.*)}/)?.[1] ?? "") : []; - let lineCounter = 0; - - // inspiration: https://github.com/atomiks/rehype-pretty-code/blob/e24f8415c8264dc868006ced839d3cb7445e716a/src/index.js#L89 - visit(tree, "element", (node) => { - if (node.tagName === "code" && /srebmuNeniLwohs(?!(.*)(\/))/.test(reverseString(meta))) { - node.properties["data-line-numbers"] = ""; - - const lineNumbersStartAtMatch = reverseString(meta).match( - /(?:\}(\d+){)?srebmuNeniLwohs(?!(.*)(\/))/ - ); - if (lineNumbersStartAtMatch[1]) - node.properties["style"] = `counter-set: line ${ - reverseString(lineNumbersStartAtMatch[1]) - 1 - };`; - } - - if (node.properties.className?.[0] === "line") { - if (lineNumbers.length !== 0 && lineNumbers.includes(++lineCounter)) { - node.properties["data-highlight"] = ""; - } - } - }); - - toFragment({ node: tree, lang, title }); - - return escape_svelty(toHtml(tree)); -} - -/** - * - * [reference](https://github.com/atomiks/rehype-pretty-code/blob/e24f8415c8264dc868006ced839d3cb7445e716a/src/index.js#L9) - * @param {{node: , lang: string, title?: string, inline: boolean}} params - Params object - * @returns - */ -function toFragment({ node, lang, title, inline = false }) { - node.tagName = inline ? "span" : "div"; - // User can replace this with a real Fragment at runtime - node.properties = { "data-code-fragment": "" }; - - const pre = node.children[0]; - // Remove class="shiki" and the background-color - pre.properties = {}; - pre.properties["data-language"] = lang; - pre.properties["data-code-title"] = title; - - const code = pre.children[0]; - code.properties["data-language"] = lang; - - if (inline) { - node.children = [code]; - return; - } - - if (title) { - node.children = [ - h("div", { className: ["codeblock"] }, [ - h("p", { className: ["text-gray-500"], "data-language": lang }, title), - pre, - ]), - ]; - return; - } - - node.children = [pre]; -} diff --git a/apps/website/package.json b/apps/website/package.json deleted file mode 100644 index c7de17e..0000000 --- a/apps/website/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "website", - "version": "0.1.0", - "type": "module", - "private": true, - "homepage": "https://github.com/johnhooks/johnhooks.github.io#readme", - "bugs": "https://github.com/johnhooks/johnhooks.github.io/issues", - "repository": { - "type": "git", - "url": "https://github.com/johnhooks/johnhooks.github.io.git" - }, - "author": { - "name": "John Hooks", - "url": "https://johnhooks.io" - }, - "license": "MIT", - "scripts": { - "dev": "vite dev", - "build": "vite build", - "build:worklets": "scripts/build/worklets.sh", - "prepare": "svelte-kit sync", - "preview": "vite preview", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "lint": "prettier --check . && eslint .", - "format": "prettier --write .", - "test": "vitest run" - }, - "devDependencies": { - "@bitmachina/highlighter": "1.0.0-alpha.6", - "@sveltejs/adapter-static": "1.0.0", - "@sveltejs/kit": "1.0.0", - "@sveltejs/vite-plugin-svelte": "2.0.2", - "@tailwindcss/typography": "0.5.8", - "@types/lodash-es": "4.17.6", - "autoprefixer": "10.4.13", - "hast-util-select": "5.0.2", - "hast-util-to-html": "8.0.3", - "hast-util-to-string": "2.0.0", - "hastscript": "7.1.0", - "mdsvex": "0.10.6", - "parse-numeric-range": "^1.3.0", - "postcss": "8.4.20", - "rehype-autolink-headings": "6.1.1", - "rehype-parse": "8.0.4", - "rehype-slug": "5.1.0", - "remark-gfm": "3.0.1", - "shiki": "0.10.1", - "svelte-check": "2.10.2", - "svelte-preprocess": "5.0.0", - "tailwindcss": "3.2.4", - "unified": "^10.1.2", - "unist-util-visit": "4.1.1" - }, - "dependencies": { - "@bitmachina/midi": "1.0.0-alpha.1", - "@bitmachina/reactive": "1.0.0-alpha.1", - "@xstate/svelte": "2.0.1", - "date-fns": "2.29.3", - "lodash-es": "4.17.21", - "rxjs": "7.8.0", - "xstate": "4.35.1", - "zod": "3.20.2" - } -} diff --git a/apps/website/setupTests.js b/apps/website/setupTests.js deleted file mode 100644 index 0fd55cd..0000000 --- a/apps/website/setupTests.js +++ /dev/null @@ -1,49 +0,0 @@ -import matchers from "@testing-library/jest-dom/matchers"; -import { expect, vi } from "vitest"; - -expect.extend(matchers); - -// https://github.com/sveltejs/kit/issues/5525#issuecomment-1186390654 -vi.mock("$app/stores", async () => { - const { readable, writable } = await import("svelte/store"); - /** - * @type {import('$app/stores').getStores} - */ - const getStores = () => ({ - navigating: readable(null), - page: readable({ url: new URL("http://localhost"), params: {} }), - session: writable(null), - updated: readable(false), - }); - /** @type {typeof import('$app/stores').page} */ - const page = { - subscribe(fn) { - return getStores().page.subscribe(fn); - }, - }; - /** @type {typeof import('$app/stores').navigating} */ - const navigating = { - subscribe(fn) { - return getStores().navigating.subscribe(fn); - }, - }; - /** @type {typeof import('$app/stores').session} */ - const session = { - subscribe(fn) { - return getStores().session.subscribe(fn); - }, - }; - /** @type {typeof import('$app/stores').updated} */ - const updated = { - subscribe(fn) { - return getStores().updated.subscribe(fn); - }, - }; - return { - getStores, - navigating, - page, - session, - updated, - }; -}); diff --git a/apps/website/src/app.d.ts b/apps/website/src/app.d.ts deleted file mode 100644 index 3e4ed20..0000000 --- a/apps/website/src/app.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -// See https://kit.svelte.dev/docs/types#app -// for information about these interfaces -// and what to do when importing types -declare namespace App { - // interface Locals {} - // interface PageData {} - // interface Error {} - // interface Platform {} -} diff --git a/apps/website/src/app.html b/apps/website/src/app.html deleted file mode 100644 index 468e072..0000000 --- a/apps/website/src/app.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - %sveltekit.head% - - -
%sveltekit.body%
- - diff --git a/apps/website/src/globals.d.ts b/apps/website/src/globals.d.ts deleted file mode 100644 index 1a27bc9..0000000 --- a/apps/website/src/globals.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -/// - -// https://github.com/pngwn/MDsveX/blob/6c60fe68c335fce559db9690fbf5e69ef539d37d/packages/mdsvex/globals.d.ts -declare module "*.md" { - import type { SvelteComponentDev } from "svelte/internal"; - - export default class Comp extends SvelteComponentDev { - // eslint-disable-next-line @typescript-eslint/ban-types - $$prop_def: {}; - } - export const metadata: Record; -} - -declare module "*.svelte" { - export { SvelteComponentDev as default } from "svelte/internal"; -} diff --git a/apps/website/src/lib/components/midi.svelte b/apps/website/src/lib/components/midi.svelte deleted file mode 100644 index e69de29..0000000 diff --git a/apps/website/src/lib/components/navigation.test.ts b/apps/website/src/lib/components/navigation.test.ts deleted file mode 100644 index 3c8ebf4..0000000 --- a/apps/website/src/lib/components/navigation.test.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { render, screen } from "@testing-library/svelte"; - -import Navigation from "./navigation.svelte"; - -describe("test navigation.svelte", async () => { - describe("home page navigation", async () => { - beforeEach(() => { - render(Navigation, { pathname: "/" }); - }); - - it("should not include a link to itself", async () => { - const item = screen.queryByRole("link", { name: "johnhooks.io" }); - expect(item).not.toBeInTheDocument(); - }); - - it("should include a link to the about page", async () => { - const link = screen.getByRole("link", { name: /about/ }); - expect(link).toBeInTheDocument(); - }); - }); - describe("about page navigation", async () => { - beforeEach(() => { - render(Navigation, { pathname: "/about" }); - }); - - it("should not include a link to itself", async () => { - const item = screen.queryByRole("link", { name: "about" }); - expect(item).not.toBeInTheDocument(); - }); - - it("should include a link to the home page", async () => { - const link = screen.getByRole("link", { name: /johnhooks\.io/ }); - expect(link).toBeInTheDocument(); - }); - }); -}); diff --git a/apps/website/src/lib/constants.ts b/apps/website/src/lib/constants.ts deleted file mode 100644 index 095e1d1..0000000 --- a/apps/website/src/lib/constants.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { dev } from "$app/environment"; - -/** - * The root url of the site. - * - * ? This isn't a prefect system but might work for now. - */ -export const BASE_URL = dev ? "http://localhost:5173" : "https://johnhooks.io"; diff --git a/apps/website/src/lib/data/NOTES.md b/apps/website/src/lib/data/NOTES.md deleted file mode 100644 index d78e474..0000000 --- a/apps/website/src/lib/data/NOTES.md +++ /dev/null @@ -1,3 +0,0 @@ -## Todo - -- [ ] Remove duplication between `posts.ts` and `projects.ts` diff --git a/apps/website/src/lib/stores/audio.ts b/apps/website/src/lib/stores/audio.ts deleted file mode 100644 index 6263960..0000000 --- a/apps/website/src/lib/stores/audio.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { writable } from "svelte/store"; - -type AudioState = { - readonly playing: boolean; -}; - -function createAudio(initial: AudioState = { playing: false }) { - const { subscribe, set, update } = writable(); - - return { - subscribe, - play: () => { - update((state) => { - return { ...state, playing: true }; - }); - }, - stop: () => { - update((state) => { - return { ...state, playing: false }; - }); - }, - reset: () => { - set(initial); - }, - }; -} - -export const audio = createAudio(); diff --git a/apps/website/src/lib/types/audio.ts b/apps/website/src/lib/types/audio.ts deleted file mode 100644 index 7aa5380..0000000 --- a/apps/website/src/lib/types/audio.ts +++ /dev/null @@ -1,9 +0,0 @@ -export type AudioParams = { - gate: number; - note: number; - velocity: number; - brightness: number; - envelope: number; -}; - -export type AudioParamsKey = keyof AudioParams; diff --git a/apps/website/src/lib/types/input.ts b/apps/website/src/lib/types/input.ts deleted file mode 100644 index 80f475a..0000000 --- a/apps/website/src/lib/types/input.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type InputEvent = Event & { - currentTarget: EventTarget & HTMLInputElement; -}; diff --git a/apps/website/src/lib/types/mod.ts b/apps/website/src/lib/types/mod.ts deleted file mode 100644 index 22a7ac2..0000000 --- a/apps/website/src/lib/types/mod.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./audio"; -export * from "./input"; -export * from "./observer"; -export * from "./utils"; diff --git a/apps/website/src/lib/types/observer.ts b/apps/website/src/lib/types/observer.ts deleted file mode 100644 index ffff768..0000000 --- a/apps/website/src/lib/types/observer.ts +++ /dev/null @@ -1,9 +0,0 @@ -type ObserverFn = (value: TValue) => void; - -type ObserverObj = { - next: (value: TValue) => void; - error?: (error: Error) => void; - done?: () => void; -}; - -export type Observer = ObserverFn | ObserverObj; diff --git a/apps/website/src/lib/types/utils.ts b/apps/website/src/lib/types/utils.ts deleted file mode 100644 index 9678eb9..0000000 --- a/apps/website/src/lib/types/utils.ts +++ /dev/null @@ -1,2 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type Constructor = new (...args: any[]) => object; diff --git a/apps/website/src/routes/midi/+page.svelte b/apps/website/src/routes/midi/+page.svelte deleted file mode 100644 index ea1439a..0000000 --- a/apps/website/src/routes/midi/+page.svelte +++ /dev/null @@ -1,27 +0,0 @@ - - -
- - {#each keyPos as { x, y, width }} - - {/each} - -
diff --git a/apps/website/src/routes/midi/key.svelte b/apps/website/src/routes/midi/key.svelte deleted file mode 100644 index cd0027b..0000000 --- a/apps/website/src/routes/midi/key.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/apps/website/src/routes/midi/keyboard.ts b/apps/website/src/routes/midi/keyboard.ts deleted file mode 100644 index d1551ee..0000000 --- a/apps/website/src/routes/midi/keyboard.ts +++ /dev/null @@ -1,56 +0,0 @@ -type Point = { - x: number; - y: number; -}; - -type KeyPos = Point & { - width: number; -}; - -/** - * The structure of a simple keyboard, sans the bottom row. - */ -const structure = [ - [...fill(13), 1.5], - [1.5, ...fill(13)], - [1.8, ...fill(11), 1.8], - [2.25, ...fill(10), 2.25], -] as const; - -/** - * Calculate positions and width of keyboard keys. - */ -export function calcKeyPos(size: number, spacing: number, offset: Point = { x: 0, y: 0 }) { - const result: KeyPos[] = []; - for (let i = 0; i < structure.length; i++) { - const row = structure[i]; - - const y = (size + spacing) * i; - let x = 0; - - for (let j = 0; j < row.length; j++) { - const ratio = row[j]; - // Pretty hacky, maybe I can find a better solution. - const adjust = ratio === 1 ? 0 : ratio > 2 ? 1.25 : 0.5; - const width = size * ratio + adjust * spacing; - - result.push({ x: x + offset.x, y: y + offset.y, width }); - - // Update the offset - x = x + width + spacing; - } - } - - // Push in space bar - result.push({ - x: 4.25 * size + 4.25 * spacing + offset.x, - y: (size + spacing) * 4 + offset.y, - width: (size + spacing) * 5 + size, - }); - - return result; -} - -function fill(length: number, value = 1): number[] { - return Array.from({ length }, () => value); -} diff --git a/apps/website/static/.nojekyll b/apps/website/static/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/apps/website/static/worklets/six_op_processor.js b/apps/website/static/worklets/six_op_processor.js deleted file mode 100644 index 201452d..0000000 --- a/apps/website/static/worklets/six_op_processor.js +++ /dev/null @@ -1,1283 +0,0 @@ -// Copyright 2022 Emilie Gillet. -// -// Author: Emilie Gillet (emilie.o.gillet@gmail.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -// See http://creativecommons.org/licenses/MIT/ for more information. -// -// ----------------------------------------------------------------------------- -// -// DX7-compatible six op FM synth. - -// Conversion from DX7 patch values to usable units. - -const DXUnits = {}; - -DXUnits.lutCoarse = [ - -12.0, 0.0, 12.0, 19.01955, 24.0, 27.863137, 31.01955, 33.688259, 36.0, 38.0391, 39.863137, - 41.51318, 43.01955, 44.405276, 45.688259, 46.882687, 48.0, 49.049554, 50.0391, 50.97513, - 51.863137, 52.707809, 53.51318, 54.282743, 55.01955, 55.726274, 56.405276, 57.05865, 57.688259, - 58.295772, 58.882687, 59.450356, -]; - -DXUnits.lutAmpModSensitivity = [0.0, 0.2588, 0.4274, 1.0]; - -DXUnits.lutPitchModSensitivity = [ - 0.0, 0.078125, 0.15625, 0.2578125, 0.4296875, 0.71875, 1.1953125, 2.0, -]; - -DXUnits.operatorLevel = function (level) { - let tlc = level; - if (level < 20) { - tlc = tlc < 15 ? (tlc * (36 - tlc)) >> 3 : 27 + tlc; - } else { - tlc += 28; - } - return tlc; -}; - -DXUnits.pitchEnvelopeLevel = function (level) { - const l = (level - 50.0) / 32.0; - const tail = Math.max(Math.abs(l + 0.02) - 1.0, 0.0); - return l * (1.0 + tail * tail * 5.3056); -}; - -DXUnits.operatorEnvelopeIncrement = function (rate) { - const rateScaled = (rate * 41) >> 6; - const mantissa = 4 + (rateScaled & 3); - const exponent = 2 + (rateScaled >> 2); - return (mantissa << exponent) / (1 << 24); -}; - -DXUnits.pitchEnvelopeIncrement = function (rate) { - const r = rate * 0.01; - return (1.0 + 192.0 * r * (r * r * r * r + 0.3333)) / (21.3 * 44100.0); -}; - -DXUnits.minLFOFrequency = 0.005865; - -DXUnits.LFOFrequency = function (rate) { - let rateScaled = rate == 0 ? 1 : (rate * 165) >> 6; - rateScaled *= rateScaled < 160 ? 11 : 11 + ((rateScaled - 160) >> 4); - return rateScaled * DXUnits.minLFOFrequency; -}; - -DXUnits.LFODelay = function (delay) { - const increments = [0.0, 0.0]; - if (delay == 0) { - increments[0] = increments[1] = 100000.0; - } else { - let d = 99 - delay; - d = (16 + (d & 15)) << (1 + (d >> 4)); - increments[0] = d * DXUnits.minLFOFrequency; - increments[1] = Math.max(0x80, d & 0xff80) * DXUnits.minLFOFrequency; - } - return increments; -}; - -DXUnits.normalizeVelocity = function (velocity) { - return 16.0 * (Math.pow(velocity, 1 / 3.0) - 0.918); -}; - -DXUnits.rateScaling = function (note, rateScaling) { - return Math.pow(2.0, rateScaling * (note * 0.333 - 7.0) * 0.03125); -}; - -DXUnits.ampModSensitivity = function (ampMS) { - return DXUnits.lutAmpModSensitivity[ampMS]; -}; - -DXUnits.pitchModSensitivity = function (pitchMS) { - return DXUnits.lutPitchModSensitivity[pitchMS]; -}; - -DXUnits.keyboardScaling = function (note, ks) { - const x = note - ks.breakpoint - 15.0; - const curve = x > 0.0 ? ks.rightCurve : ks.leftCurve; - - let t = Math.abs(x); - if (curve == 1 || curve == 2) { - t = Math.min(t * 0.010467, 1.0); - t = t * t * t; - t *= 96.0; - } - if (curve < 2) { - t = -t; - } - - const depth = x > 0.0 ? ks.rightDepth : ks.leftDepth; - return t * depth * 0.02677; -}; - -DXUnits.frequencyRatio = function (op) { - const detune = op.mode == 0 && op.fine ? 1.0 + 0.01 * op.fine : 1.0; - - let base = - op.mode == 0 ? DXUnits.lutCoarse[op.coarse] : ((op.coarse & 3) * 100 + op.fine) * 0.39864; - base += (op.detune - 7.0) * 0.015; - return Math.pow(2, base / 12.0) * detune; -}; - -// DX7 patch - -class DXPatch { - constructor(data) { - this.op = Array(6); - for (let i = 0; i < 6; i++) { - const op = {}; - const opData = data.slice(i * 17); - - op.envelope = { rate: Array(4), level: Array(4) }; - for (let j = 0; j < 4; j++) { - op.envelope.rate[j] = Math.min(opData[j] & 0x7f, 99); - op.envelope.level[j] = Math.min(opData[4 + j] & 0x7f, 99); - } - - op.keyboardScaling = {}; - op.keyboardScaling.breakpoint = Math.min(opData[8] & 0x7f, 99); - op.keyboardScaling.leftDepth = Math.min(opData[9] & 0x7f, 99); - op.keyboardScaling.rightDepth = Math.min(opData[10] & 0x7f, 99); - op.keyboardScaling.leftCurve = opData[11] & 0x3; - op.keyboardScaling.rightCurve = (opData[11] >>> 2) & 0x3; - op.rateScaling = opData[12] & 0x7; - op.ampModSensitivity = opData[13] & 0x3; - op.velocitySensitivity = (opData[13] >>> 2) & 0x7; - op.level = Math.min(opData[14] & 0x7f, 99); - op.mode = opData[15] & 0x1; - op.coarse = (opData[15] >>> 1) & 0x1f; - op.fine = Math.min(opData[16] & 0x7f, 99); - op.detune = Math.min((opData[12] >>> 3) & 0xf, 14); - this.op[i] = op; - } - this.pitchEnvelope = { rate: Array(4), level: Array(4) }; - for (let j = 0; j < 4; j++) { - this.pitchEnvelope.rate[j] = Math.min(data[102 + j] & 0x7f, 99); - this.pitchEnvelope.level[j] = Math.min(data[106 + j] & 0x7f, 99); - } - this.algorithm = data[110] & 0x1f; - this.feedback = data[111] & 0x7; - this.resetPhase = (data[111] >>> 3) & 0x1; - const modulations = {}; - modulations.rate = Math.min(data[112] & 0x7f, 99); - modulations.delay = Math.min(data[113] & 0x7f, 99); - modulations.pitchModDepth = Math.min(data[114] & 0x7f, 99); - modulations.ampModDepth = Math.min(data[115] & 0x7f, 99); - modulations.resetPhase = data[116] & 0x1; - modulations.waveform = Math.min((data[116] >>> 1) & 0x7, 5); - modulations.pitchModSensitivity = data[116] >>> 4; - this.modulations = modulations; - this.transpose = Math.min(data[117] & 0x7f, 48); - this.name = String.fromCharCode.apply(String, data.slice(118, 128)); - } -} - -// Operator state. - -class Operator { - constructor() { - this.reset(); - } - - reset() { - this.phase = 0; - this.amplitude = 0; - } -} - -// Algorithms. - -const Algorithms = {}; -Algorithms.renderers = new Map(); - -// n: number of operators to render (height of the stack) -// modulationSource: -2 for external, -1 for none, n for feedback -Algorithms.renderer = function (n, modulationSource, additive) { - const key = [n, modulationSource, additive].join("|"); - const r = Algorithms.renderers.get(key); - if (r) { - return r; - } - - const f = function (ops, f, a, fbState, fbAmount, modulation, out) { - const size = out.length; - const scale = 1.0 / size; - const amplitudeIncrement = new Float32Array(n); - for (let i = 0; i < n; i++) { - amplitudeIncrement[i] = (Math.min(a[i], 4.0) - ops[i].amplitude) * scale; - } - const fbScale = fbAmount ? (1 << fbAmount) / 512.0 : 0.0; - - for (let i = 0; i < size; i++) { - let pm = 0.0; - if (modulationSource >= 0) { - pm = (fbState[0] + fbState[1]) * fbScale; - } else if (modulationSource == -2) { - pm = modulation[i]; - } - for (let j = 0; j < n; j++) { - ops[j].phase += f[j]; - if (ops[j].phase >= 1.0) { - ops[j].phase - 1.0; - } - pm = Math.sin(2 * Math.PI * (ops[j].phase + pm)) * ops[j].amplitude; - ops[j].amplitude += amplitudeIncrement[j]; - if (j == modulationSource) { - fbState[1] = fbState[0]; - fbState[0] = pm; - } - } - if (additive) { - out[i] += pm; - } else { - out[i] = pm; - } - } - }; - - Algorithms.renderers.set(key, f); - return f; -}; - -Algorithms.dx7 = [ - // Algorithm 1 - [ - { n: 4, renderFn: Algorithms.renderer(4, 0, true), input: 0, output: 0 }, - {}, - {}, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 2 - [ - { n: 4, renderFn: Algorithms.renderer(4, -1, true), input: 0, output: 0 }, - {}, - {}, - {}, - { n: 2, renderFn: Algorithms.renderer(2, 0, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 3 - [ - { n: 3, renderFn: Algorithms.renderer(3, 0, true), input: 0, output: 0 }, - {}, - {}, - { n: 3, renderFn: Algorithms.renderer(3, -1, true), input: 0, output: 0 }, - {}, - {}, - ], - - // Algorithm 4 - [ - { n: 3, renderFn: Algorithms.renderer(3, 2, true), input: 0, output: 0 }, - {}, - {}, - { n: 3, renderFn: Algorithms.renderer(3, -1, true), input: 0, output: 0 }, - {}, - {}, - ], - - // Algorithm 5 - [ - { n: 2, renderFn: Algorithms.renderer(2, 0, true), input: 0, output: 0 }, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 6 - [ - { n: 2, renderFn: Algorithms.renderer(2, 1, true), input: 0, output: 0 }, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 7 - [ - { n: 2, renderFn: Algorithms.renderer(2, 0, false), input: 0, output: 1 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 8 - [ - { n: 2, renderFn: Algorithms.renderer(2, -1, false), input: 0, output: 1 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, 0, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 9 - [ - { n: 2, renderFn: Algorithms.renderer(2, -1, false), input: 0, output: 1 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 2, renderFn: Algorithms.renderer(2, 0, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 10 - [ - { n: 1, renderFn: Algorithms.renderer(1, -1, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 3, renderFn: Algorithms.renderer(3, 0, true), input: 0, output: 0 }, - {}, - {}, - ], - - // Algorithm 11 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 3, renderFn: Algorithms.renderer(3, -1, true), input: 0, output: 0 }, - {}, - {}, - ], - - // Algorithm 12 - [ - { n: 1, renderFn: Algorithms.renderer(1, -1, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 2, renderFn: Algorithms.renderer(2, 0, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 13 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 14 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 2, renderFn: Algorithms.renderer(2, -2, true), input: 1, output: 0 }, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 15 - [ - { n: 1, renderFn: Algorithms.renderer(1, -1, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 2, renderFn: Algorithms.renderer(2, -2, true), input: 1, output: 0 }, - {}, - { n: 2, renderFn: Algorithms.renderer(2, 0, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 16 - [ - { n: 2, renderFn: Algorithms.renderer(2, 0, false), input: 0, output: 1 }, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 1 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - ], - - // Algorithm 17 - [ - { n: 2, renderFn: Algorithms.renderer(2, -1, false), input: 0, output: 1 }, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 1 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, 0, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - ], - - // Algorithm 18 - [ - { n: 3, renderFn: Algorithms.renderer(3, -1, false), input: 0, output: 1 }, - {}, - {}, - { n: 1, renderFn: Algorithms.renderer(1, 0, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - ], - - // Algorithm 19 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 3, renderFn: Algorithms.renderer(3, -1, true), input: 0, output: 0 }, - {}, - {}, - ], - - // Algorithm 20 - [ - { n: 1, renderFn: Algorithms.renderer(1, -1, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - ], - - // Algorithm 21 - [ - { n: 1, renderFn: Algorithms.renderer(1, -1, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - ], - - // Algorithm 22 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 23 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], - - // Algorithm 24 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], - - // Algorithm 25 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], - - // Algorithm 26 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], - - // Algorithm 27 - [ - { n: 1, renderFn: Algorithms.renderer(1, -1, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 2, renderFn: Algorithms.renderer(2, 0, true), input: 0, output: 0 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], - - // Algorithm 28 - [ - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 3, renderFn: Algorithms.renderer(3, 0, true), input: 0, output: 0 }, - {}, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 29 - [ - { n: 2, renderFn: Algorithms.renderer(2, 0, true), input: 0, output: 0 }, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], - - // Algorithm 30 - [ - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 3, renderFn: Algorithms.renderer(3, 0, true), input: 0, output: 0 }, - {}, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], - - // Algorithm 31 - [ - { n: 2, renderFn: Algorithms.renderer(2, 0, true), input: 0, output: 0 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], - - // Algorithm 32 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], -]; - -Algorithms.dx100 = [ - // Algorithm 1 - [{ n: 4, renderFn: Algorithms.renderer(4, 0, true), input: 0, output: 0 }, {}, {}, {}], - - // Algorithm 2 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, false), input: 1, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - ], - - // Algorithm 3 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 1 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - ], - - // Algorithm 4 - [ - { n: 2, renderFn: Algorithms.renderer(2, 0, false), input: 0, output: 1 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - ], - - // Algorithm 5 - [ - { n: 2, renderFn: Algorithms.renderer(2, 0, true), input: 0, output: 0 }, - {}, - { n: 2, renderFn: Algorithms.renderer(2, -1, true), input: 0, output: 0 }, - {}, - ], - - // Algorithm 6 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, false), input: 0, output: 1 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -2, true), input: 1, output: 0 }, - ], - - // Algorithm 7 - [ - { n: 2, renderFn: Algorithms.renderer(2, 0, true), input: 0, output: 0 }, - {}, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], - - // Algorithm 8 - [ - { n: 1, renderFn: Algorithms.renderer(1, 0, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - { n: 1, renderFn: Algorithms.renderer(1, -1, true), input: 0, output: 0 }, - ], -]; - -Algorithms.modulators = function (algorithm) { - const modulators = new Set(); - for (let from = 0; from < algorithm.length; ) { - const to = from + algorithm[from].n - 1; - for (let op = from; op <= to; ++op) { - if (algorithm[from].output == 1 || op < to) { - modulators.add(op); - } - } - from += algorithm[from].n; - } - return modulators; -}; - -// Envelope. - -class Envelope { - constructor(scale, numStages) { - this.numStages = numStages; - this.scale = scale; - this.stage = this.numStages - 1; - this.phase = 1.0; - this.start = 0.0; - - this.increment = new Float32Array(numStages); - this.level = new Float32Array(numStages); - - for (let i = 0; i < this.numStages; i++) { - this.increment[i] = 0.001; - this.level[i] = 1.0 / (1 << i); - } - this.level[this.numStages - 1] = 0.0; - this.reshapeAscendingSegments = false; - } - - render(gate, rate, adScale, rScale) { - if (gate) { - if (this.stage == this.numStages - 1) { - this.start = this.value(); - this.stage = 0; - this.phase = 0.0; - } - } else { - if (this.stage != this.numStages - 1) { - this.start = this.value(); - this.stage = this.numStages - 1; - this.phase = 0.0; - } - } - const scale = this.stage == this.numStages - 1 ? rScale : adScale; - this.phase += this.increment[this.stage] * rate * scale; - if (this.phase >= 1.0) { - if (this.stage >= this.numStages - 2) { - this.phase = 1.0; - } else { - this.phase = 0.0; - ++this.stage; - } - this.start = -100.0; - } - - return this.value(); - } - - value() { - let from = - this.start == -100.0 - ? this.level[(this.stage - 1 + this.numStages) % this.numStages] - : this.start; - let to = this.level[this.stage]; - - let phase = this.phase; - if (this.reshapeAscendingSegments && from < to) { - from = Math.max(6.7, from); - to = Math.max(6.7, to); - phase *= (2.5 - phase) * 0.666667; - } - - return phase * (to - from) + from; - } -} - -class OperatorEnvelope extends Envelope { - constructor(scale) { - super(scale, 4); - } - - set(params, globalLevel) { - for (let i = 0; i < this.numStages; i++) { - let levelScaled = DXUnits.operatorLevel(params.level[i]); - levelScaled = (levelScaled & ~1) + globalLevel - 133; - this.level[i] = 0.125 * (levelScaled < 1 ? 0.5 : levelScaled); - } - - for (let i = 0; i < this.numStages; i++) { - let increment = DXUnits.operatorEnvelopeIncrement(params.rate[i]); - let from = this.level[(i - 1 + this.numStages) % this.numStages]; - let to = this.level[i]; - - if (from == to) { - // Quirk: for plateaux, the increment is scaled. - increment *= 0.6; - if (i == 0 && !params.level[i]) { - // Quirk: the attack plateau is faster. - increment *= 20.0; - } - } else if (from < to) { - from = Math.max(6.7, from); - to = Math.max(6.7, to); - if (from == to) { - // Quirk: because of the jump, the attack might disappear. - increment = 1.0; - } else { - // Quirk: because of the weird shape, the rate is adjusted. - increment *= 7.2 / (to - from); - } - } else { - increment *= 1.0 / (from - to); - } - this.increment[i] = increment * this.scale; - } - this.reshapeAscendingSegments = true; - } -} - -class PitchEnvelope extends Envelope { - constructor(scale) { - super(scale, 4); - } - - set(params, globalLevel) { - for (let i = 0; i < this.numStages; i++) { - this.level[i] = DXUnits.pitchEnvelopeLevel(params.level[i]); - } - - // Configure increments. - for (let i = 0; i < this.numStages; i++) { - const from = this.level[(i - 1 + this.numStages) % this.numStages]; - const to = this.level[i]; - let increment = DXUnits.pitchEnvelopeIncrement(params.rate[i]); - if (from != to) { - increment *= 1.0 / Math.abs(from - to); - } else if (i != this.numStages - 1) { - increment = 0.2; - } - this.increment[i] = increment * this.scale; - } - } -} - -// LFO. - -class Lfo { - constructor(sampleRate) { - this.oneHz = 1.0 / sampleRate; - - this.phase = 0.0; - this.frequency = 0.1; - - this.delayPhase = 0.0; - this.delayIncrement = this.delayIncrement = [0.1, 0.1]; - - this.randomValue = 0.0; - - this.ampModDepth = 0.0; - this.pitchModDepth = 0.0; - - this.waveform = 0; - this.resetPhase = false; - } - - set(modulations) { - this.frequency = DXUnits.LFOFrequency(modulations.rate) * this.oneHz; - - this.delayIncrement = DXUnits.LFODelay(modulations.delay); - this.delayIncrement[0] *= this.oneHz; - this.delayIncrement[1] *= this.oneHz; - - this.waveform = modulations.waveform; - this.resetPhase = modulations.resetPhase; - - this.ampModDepth = modulations.ampModDepth * 0.01; - let pitchMS = DXUnits.pitchModSensitivity(modulations.pitchModSensitivity); - this.pitchModDepth = modulations.pitchModDepth * 0.01 * pitchMS; - } - - reset() { - if (this.resetPhase) { - this.phase = 0.0; - } - this.delayPhase = 0.0; - } - - step(scale) { - this.phase += scale * this.frequency; - this.delayPhase += scale * this.delayIncrement[this.delayPhase < 0.5 ? 0 : 1]; - - if (this.phase >= 1.0) { - this.phase -= 1.0; - this.randomValue = Math.random(); - } - - if (this.delayPhase >= 1.0) { - this.delayPhase = 1.0; - } - - const value = this.rawValue(); - const ramp = this.delayPhase < 0.5 ? 0.0 : (this.delayPhase - 0.5) * 2.0; - - return { - pitchMod: (value - 0.5) * ramp * this.pitchModDepth, - ampMod: (1.0 - value) * ramp * this.ampModDepth, - }; - } - - rawValue() { - switch (this.waveform) { - case 0: - return 2.0 * (this.phase < 0.5 ? 0.5 - this.phase : this.phase - 0.5); - - case 1: - return 1.0 - this.phase; - - case 2: - return this.phase; - - case 3: - return this.phase < 0.5 ? 0.0 : 1.0; - - case 4: - return 0.5 + 0.5 * Math.sin(Math.PI * (2.0 * this.phase + 1.0)); - - case 5: - return this.randomValue; - } - return 0.0; - } -} - -class Voice { - constructor(algorithms, sampleRate) { - this.numOperators = algorithms[0].length; - this.algorithms = algorithms; - - this.sampleRate = sampleRate; - this.oneHz = 1.0 / sampleRate; - this.a0 = 55.0 / sampleRate; - - const nativeSR = 44100.0; // Legacy sample rate. - const envelopeScale = nativeSR * this.oneHz; - - this.operator = Array(this.numOperators); - this.operatorEnvelope = Array(this.numOperators); - this.levelHeadroom = new Float32Array(this.numOperators); - this.ratios = new Float32Array(this.numOperators); - - for (let i = 0; i < this.numOperators; i++) { - this.operator[i] = new Operator(); - this.operatorEnvelope[i] = new OperatorEnvelope(envelopeScale); - } - this.pitchEnvelope = new PitchEnvelope(envelopeScale); - - this.feedbackState = [0.0, 0.0]; - this.patch = null; - this.gate = false; - this.note = 48.0; - - this.normalizedVelocity = 10.0; - - this.dirty = true; - } - - setPatch(patch) { - this.patch = patch; - this.dirty = true; - } - - setup() { - if (!this.dirty) { - return false; - } - - this.pitchEnvelope.set(this.patch.pitchEnvelope); - for (let i = 0; i < this.numOperators; i++) { - const op = this.patch.op[i]; - const level = DXUnits.operatorLevel(op.level); - this.operatorEnvelope[i].set(op.envelope, level); - this.levelHeadroom[i] = 127 - level; - const sign = this.patch.op[i].mode == 0 ? 1.0 : -1.0; - this.ratios[i] = sign * DXUnits.frequencyRatio(this.patch.op[i]); - } - this.algorithm = this.algorithms[this.patch.algorithm]; - this.modulators = Algorithms.modulators(this.algorithm); - this.dirty = false; - return true; - } - - render(parameters, out) { - if (!this.patch) { - return; - } - - const size = out.length; - const buffers = [out, new Float32Array(size), new Float32Array(size), null]; - this.setup(); - - const adScale = Math.pow(2.0, (0.5 - parameters.envelopeControl) * 8.0); - const rScale = Math.pow(2.0, -Math.abs(parameters.envelopeControl - 0.3) * 8.0); - - // Apply LFO and pitch envelope modulations. - const pitchEnvelope = this.pitchEnvelope.render(parameters.gate, size, adScale, rScale); - const pitchMod = pitchEnvelope + parameters.pitchMod; - const f0 = this.a0 * 0.25 * Math.pow(2.0, (parameters.note - 9.0) / 12.0 + pitchMod); - - const noteOn = parameters.gate && !this.gate; - this.gate = parameters.gate; - if (noteOn) { - this.normalizedVelocity = DXUnits.normalizeVelocity(parameters.velocity); - this.note = parameters.note; - } - - // Reset operator phase if a note on is detected & if the patch requires it. - if (noteOn && this.patch.resetPhase) { - for (let i = 0; i < this.numOperators; i++) { - this.operator[i].phase = 0; - } - } - - // Compute operator frequencies and amplitudes. - const f = new Float32Array(this.numOperators); - const a = new Float32Array(this.numOperators); - - for (let i = 0; i < this.numOperators; i++) { - f[i] = this.ratios[i] * (this.ratios[i] < 0.0 ? -this.oneHz : f0); - - const op = this.patch.op[i]; - const rateScaling = DXUnits.rateScaling(this.note, op.rateScaling); - const kbScaling = DXUnits.keyboardScaling(this.note, op.keyboardScaling); - const velocityScaling = this.normalizedVelocity * op.velocitySensitivity; - const brightness = this.modulators.has(i) ? (parameters.brightness - 0.5) * 32.0 : 0.0; - - let level = this.operatorEnvelope[i].render( - parameters.gate, - size * rateScaling, - adScale, - rScale - ); - level += 0.125 * Math.min(kbScaling + velocityScaling + brightness, this.levelHeadroom[i]); - - const sensitivity = DXUnits.ampModSensitivity(op.ampModSensitivity); - const logLevelMod = sensitivity * parameters.ampMod - 1.0; - const levelMod = 1.0 - Math.pow(2.0, 6.4 * logLevelMod); - a[i] = Math.pow(2.0, -14.0 + level * levelMod); - } - - for (let i = 0; i < this.numOperators; ) { - const step = this.algorithm[i]; - step.renderFn( - this.operator.slice(i), - f.slice(i), - a.slice(i), - this.feedbackState, - this.patch.feedback, - buffers[step.input], - buffers[step.output], - size - ); - i += step.n; - } - } -} - -const Debug = {}; -Debug.downloadWAV = function (name, buffers) { - let totalSize = 0; - for (let buffer of buffers) { - totalSize += buffer.length; - } - - let output = new Float32Array(totalSize); - let i = 0; - for (let buffer of buffers) { - output.set(buffer, i); - i += buffer.length; - } - - let buffer = Encoder.create().toWAV(output); - let blob = new Blob([buffer], { type: "audio/wav" }); - let a = document.createElement("a"); - a.href = URL.createObjectURL(blob); - a.download = name + ".wav"; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); -}; - -// let ops = [{ phase: 0, amplitude: 0 }, { phase: 0, amplitude: 0 }]; -// const r1 = Algorithms.renderer(1, -1, false); -// const r2 = Algorithms.renderer(1, -2, false); -// -// const buffers = []; -// const fbState = [0, 0]; -// const f = [220 / 48000.0, 110 / 48000.0]; -// const a = [0.5, 0.75]; -// for (let i = 0; i < 1000; i++) { -// let out = new Float32Array(48); -// a[0] = 0.5 + 0.5 * Math.sin(i / 1000 * 2 * Math.PI); -// -// r1(ops, f, a, fbState, 0, null, out, 48); -// r2(ops.slice(1), f.slice(1), a.slice(1), fbState, 0, out, out, 48); -// -// buffers.push(out); -// } -// -// Debug.downloadWAV('test', buffers); -// -// const BRASS1 = [ 49, 99, 28, 68, 98, 98, 91, 0, 39, 54, 50, 5, 60, 8, 82, 2, 0, 77, 36, 41, 71, 99, 98, 98, 0, 39, 0, 0, 15, 64, 8, 98, 2, 0, 77, 36, 41, 71, 99, 98, 98, 0, 39, 0, 0, 15, 56, 8, 99, 2, 0, 77, 76, 82, 71, 99, 98, 98, 0, 39, 0, 0, 15, 40, 8, 99, 2, 0, 62, 51, 29, 71, 82, 95, 96, 0, 27, 0, 7, 7, 112, 0, 86, 0, 0, 72, 76, 99, 71, 99, 88, 96, 0, 39, 0, 14, 15, 112, 0, 98, 0, 0, 84, 95, 95, 60, 50, 50, 50, 50, 21, 15, 37, 0, 5, 0, 56, 24, 66, 82, 65, 83, 83, 32, 32, 32, 49, 32 ]; -// -// console.log(new DXPatch(BRASS1)); - -// const testCases = [ -// [ 30, 90, 20, 99, 1, 0, 7 ], -// [ 40, 70, 40, 80, 1, 1, 7 ], -// [ 50, 60, 60, 60, 1, 2, 7 ], -// [ 60, 50, 80, 40, 1, 3, 7 ], -// [ 70, 40, 99, 20, 1, 4, 7 ], -// [ 80, 20, 20, 0, 1, 5, 5 ], -// [ 90, 80, 40, 20, 0, 0, 3 ], -// [ 90, 80, 60, 40, 0, 0, 1 ] ] -// -// const buffers = []; -// lfo = new Lfo(48000.0); -// for (let i = 0; i < testCases.length; i++) { -// const testCase = testCases[i]; -// -// const modulations = { } -// modulations.rate = testCase[0]; -// modulations.delay = testCase[1]; -// modulations.pitchModDepth = testCase[2]; -// modulations.ampModDepth = testCase[3]; -// modulations.resetPhase = testCase[4]; -// modulations.waveform = testCase[5]; -// modulations.pitchModSensitivity = testCase[6]; -// lfo.set(modulations); -// -// let out = new Float32Array(48000 * 4); -// for (let j = 0; j < out.length; j++) { -// if (j % 96000 == 0) { -// lfo.reset(); -// } -// const mods = lfo.step(1); -// out[j] = mods.ampMod; -// } -// buffers.push(out); -// } -// Debug.downloadWAV('lfo', buffers); -// -// const testCases = [ -// [ [ 30, 60, 50, 40 ], [ 82, 18, 50, 50 ] ], -// [ [ 50, 50, 50, 40 ], [ 99, 0, 50, 50 ] ], -// [ [ 60, 70, 45, 65 ], [ 66, 34, 60, 40 ] ], -// [ [ 50, 60, 90, 40 ], [ 0, 99, 40, 60 ] ], -// [ [ 70, 60, 90, 40 ], [ 99, 96, 40, 50 ] ], -// [ [ 70, 60, 90, 40 ], [ 99, 99, 40, 50 ] ], -// [ [ 50, 60, 90, 40 ], [ 82, 18, 60, 50 ] ], -// [ [ 70, 80, 99, 60 ], [ 82, 18, 60, 50 ] ] ]; -// -// const envelope = new PitchEnvelope(44100.0 / 48000.0); -// const buffers = []; -// for (let i = 0; i < testCases.length; i++) { -// const params = { rate: testCases[i][0], level: testCases[i][1] }; -// envelope.set(params); -// -// const n = 48000 * 4; -// let out = new Float32Array(n); -// for (let j = 0; j < out.length; j++) { -// let gate = j > (n * 0.1) && j < (n * 0.6); -// out[j] = envelope.render(gate, 1.0, 1.0, 1.0) / 4.0; -// } -// buffers.push(out); -// } -// -// Debug.downloadWAV('pitch_envelope', buffers); - -// const testCases = [ -// [ [ 30, 60, 50, 40 ], [ 80, 50, 30, 15 ] ], -// [ [ 30, 60, 50, 40 ], [ 99, 75, 60, 0 ] ], -// [ [ 20, 70, 45, 65 ], [ 90, 75, 60, 0 ] ], -// [ [ 30, 60, 77, 40 ], [ 99, 10, 75, 0 ] ], -// [ [ 30, 60, 50, 40 ], [ 50, 40, 30, 0 ] ], -// [ [ 30, 45, 50, 40 ], [ 99, 99, 50, 0 ] ], -// [ [ 20, 60, 50, 40 ], [ 0, 0, 60, 99 ] ], -// [ [ 23, 99, 37, 45 ], [ 0, 98, 0, 0 ] ], -// [ [ 25, 99, 60, 77 ], [ 0, 99, 0, 0 ] ], -// [ [ 9, 99, 60, 81 ], [ 0, 99, 0, 0 ] ], -// [ [ 26, 99, 20, 33 ], [ 0, 90, 80, 0 ] ], -// [ [ 99, 99, 60, 65 ], [ 0, 99, 0, 0 ] ], -// [ [ 5, 99, 99, 60 ], [ 0, 0, 99, 0 ] ], -// [ [ 22, 99, 99, 60 ], [ 0, 0, 99, 0 ] ], -// [ [ 99, 99, 99, 60 ], [ 0, 0, 99, 0 ] ], -// [ [ 28, 20, 99, 18 ], [ 0, 0, 99, 90 ] ] ]; -// -// const envelope = new OperatorEnvelope(44100.0 / 48000.0); -// const buffers = []; -// for (let i = 0; i < testCases.length; i++) { -// const params = { rate: testCases[i][0], level: testCases[i][1] }; -// envelope.set(params, 99); -// -// const n = 48000 * 4; -// let out = new Float32Array(n); -// for (let j = 0; j < out.length; j++) { -// let gate = j > (n * 0.1) && j < (n * 0.6); -// out[j] = envelope.render(gate, 1.0, 1.0, 1.0) / 16.0; -// } -// buffers.push(out); -// } -// -// Debug.downloadWAV('operator_envelope', buffers); -// - -// const BRASS1 = [ 49, 99, 28, 68, 98, 98, 91, 0, 39, 54, 50, 5, 60, 8, 82, 2, 0, 77, 36, 41, 71, 99, 98, 98, 0, 39, 0, 0, 15, 64, 8, 98, 2, 0, 77, 36, 41, 71, 99, 98, 98, 0, 39, 0, 0, 15, 56, 8, 99, 2, 0, 77, 76, 82, 71, 99, 98, 98, 0, 39, 0, 0, 15, 40, 8, 99, 2, 0, 62, 51, 29, 71, 82, 95, 96, 0, 27, 0, 7, 7, 112, 0, 86, 0, 0, 72, 76, 99, 71, 99, 88, 96, 0, 39, 0, 14, 15, 112, 0, 98, 0, 0, 84, 95, 95, 60, 50, 50, 50, 50, 21, 15, 37, 0, 5, 0, 56, 24, 66, 82, 65, 83, 83, 32, 32, 32, 49, 32 ]; -// -// const patch = new DXPatch(BRASS1); -// const voice = new Voice(Algorithms.dx7, 48000.0); -// voice.setPatch(patch); - -// const parameters = { }; -// parameters.note = 48.0; -// parameters.velocity = 0.8; -// parameters.envelopeControl = 0.5; -// parameters.brightness = 0.5; -// parameters.pitchMod = 0; -// parameters.ampMod = 0; -// -// const buffers = []; -// for (let i = 0; i < 1000; i++) { -// parameters.gate = i % 200 < 100; -// let out = new Float32Array(128); -// voice.render(parameters, out); -// for (let j = 0; j < out.length; ++j) { out[j] *= 0.125; } -// buffers.push(out); -// } -// -// Debug.downloadWAV('voice', buffers); - -class SixOpProcessor extends AudioWorkletProcessor { - constructor() { - super(); - this.running = true; - - this.voice = new Voice(Algorithms.dx7, 48000.0); - this.lfo = new Lfo(48000.0); - this.gate = false; - this.retrigger = false; - - this.port.onmessage = (event) => { - // AudioWorkletProcessor can't have custom methods. Oh well... - if (event.data[0] == "stop") { - this.running = false; - } else if (event.data[0] == "setPatch") { - const patch = new DXPatch(event.data[1]); - this.voice.setPatch(patch); - this.lfo.set(patch.modulations); - this.retrigger = true; - } - }; - } - - process(inputs, outputs, parameters) { - const output = outputs[0]; - - const numChannels = output.length; - const size = output[0].length; - - let modulations = this.lfo.step(size); - - let p = {}; - p.gate = parameters["gate"][0] > 0.5 && !this.retrigger; - p.note = parameters["note"][0]; - p.velocity = parameters["velocity"][0]; - p.envelopeControl = parameters["envelopeControl"][0]; - p.brightness = parameters["brightness"][0]; - p.pitchMod = modulations.pitchMod; - p.ampMod = modulations.ampMod; - - if (p.gate && !this.gate) { - this.lfo.reset(); - } - this.gate = p.gate; - this.retrigger = false; - - let out = new Float32Array(size); - this.voice.render(p, out); - for (let i = 0; i < size; ++i) { - for (let j = 0; j < numChannels; ++j) { - output[j][i] = out[i] * 0.125; - } - } - return this.running; - } - - static get parameterDescriptors() { - return [ - { - name: "gate", - defaultValue: 0.0, - minValue: 0.0, - maxValue: 1.0, - automationRate: "k-rate", - }, - { - name: "note", - defaultValue: 60.0, - minValue: 0.0, - maxValue: 127.0, - automationRate: "k-rate", - }, - { - name: "velocity", - defaultValue: 0.8, - minValue: 0.0, - maxValue: 1.0, - automationRate: "k-rate", - }, - { - name: "envelopeControl", - defaultValue: 0.5, - minValue: 0.0, - maxValue: 1.0, - automationRate: "k-rate", - }, - { - name: "brightness", - defaultValue: 0.5, - minValue: 0.0, - maxValue: 1.0, - automationRate: "k-rate", - }, - ]; - } -} - -registerProcessor("six_op_processor", SixOpProcessor); diff --git a/apps/website/svelte.config.js b/apps/website/svelte.config.js deleted file mode 100644 index 2376a2f..0000000 --- a/apps/website/svelte.config.js +++ /dev/null @@ -1,25 +0,0 @@ -import adapter from "@sveltejs/adapter-static"; -import { mdsvex } from "mdsvex"; -import preprocess from "svelte-preprocess"; - -import mdsvexConfig from "./mdsvex.config.js"; - -/** @type {import('@sveltejs/kit').Config} */ -const config = { - extensions: [".svelte", ...mdsvexConfig.extensions], - - // Consult https://github.com/sveltejs/svelte-preprocess - // for more information about preprocessors - preprocess: [ - preprocess({ - postcss: true, - }), - mdsvex(mdsvexConfig), - ], - - kit: { - adapter: adapter(), - }, -}; - -export default config; diff --git a/apps/website/tsconfig.json b/apps/website/tsconfig.json deleted file mode 100644 index 12cfc21..0000000 --- a/apps/website/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": "./.svelte-kit/tsconfig.json", - "compilerOptions": { - "noEmit": true, - "allowJs": true, - "checkJs": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "skipLibCheck": true, - "sourceMap": true, - "strict": true, - "types": ["vitest/globals", "@testing-library/jest-dom", "audioworklet", "webmidi"] - } - // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias - // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes - // from the referenced tsconfig.json - TypeScript does not merge them in -} diff --git a/apps/website/vite.config.ts b/apps/website/vite.config.ts deleted file mode 100644 index 5682ca9..0000000 --- a/apps/website/vite.config.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { sveltekit } from "@sveltejs/kit/vite"; -import type { UserConfig } from "vite"; -import { defineConfig } from "vite"; -import type { InlineConfig } from "vitest"; - -interface VitestConfigExport extends UserConfig { - test: InlineConfig; -} - -export default defineConfig({ - plugins: [sveltekit()], - server: { - port: 5173, - strictPort: false, - }, - preview: { - port: 4173, - strictPort: false, - }, - test: { - include: ["src/**/*.{test,spec}.{js,mjs,cjs,ts}"], - globals: true, - environment: "jsdom", - setupFiles: ["./setupTests.js"], - }, -} as VitestConfigExport); diff --git a/config/rollup.config.js b/config/rollup.config.js deleted file mode 100644 index 7524ba8..0000000 --- a/config/rollup.config.js +++ /dev/null @@ -1,19 +0,0 @@ -import resolve from "@rollup/plugin-node-resolve"; -import sucrase from "@rollup/plugin-sucrase"; -import terser from "@rollup/plugin-terser"; - -/** - * @type {import('rollup').RollupOptions} - */ -export default { - plugins: [ - resolve({ - extensions: [".js", ".ts"], - }), - sucrase({ - exclude: ["node_modules/**"], - transforms: ["typescript"], - }), - terser(), - ], -}; diff --git a/docs/plans/sitemap.md b/docs/plans/sitemap.md new file mode 100644 index 0000000..e21b29b --- /dev/null +++ b/docs/plans/sitemap.md @@ -0,0 +1,77 @@ +# Sitemap Generation Plan + +## Overview + +Generate a `sitemap.xml` at build time using a prerendered SvelteKit endpoint that reuses existing data loaders. + +## Approach + +Create `src/routes/sitemap.xml/+server.ts` with `prerender = true` to generate a static sitemap at build time. + +## Implementation + +### 1. Create the endpoint + +```ts +// src/routes/sitemap.xml/+server.ts +import type { RequestHandler } from "./$types"; +import { SITE_URL } from "$lib/constants"; +import { loadPosts } from "$lib/data/posts"; +import { loadProjects } from "$lib/data/projects"; + +export const prerender = true; + +export const GET: RequestHandler = async () => { + const posts = await loadPosts(); + const projects = await loadProjects(); + + const staticPages = ["", "/about"]; + + const postUrls = posts + .filter((post) => post.isPublished) + .map((post) => `/posts/${post.slug}`); + + const projectUrls = projects + .filter((project) => project.isPublished) + .map((project) => `/projects/${project.slug}`); + + const allUrls = [...staticPages, ...postUrls, ...projectUrls]; + + const sitemap = ` + +${allUrls + .map( + (url) => ` + ${SITE_URL}${url} + `, + ) + .join("\n")} +`; + + return new Response(sitemap, { + headers: { + "Content-Type": "application/xml", + }, + }); +}; +``` + +### 2. Optional enhancements + +- Add `` using post/project `updatedOn` or `publishedOn` dates +- Add `` and `` hints +- Add `` entries for og:image URLs + +## Considerations + +- **SITE_URL at build time**: The sitemap uses `SITE_URL` from constants, which is set via env var at build time. This matches the canonical URLs in page meta tags. +- **Prerendering**: Since `prerender = true`, the sitemap is generated once at build time, not on every request. +- **No additional dependencies**: Reuses existing `loadPosts()` and `loadProjects()` functions. + +## Verification + +After implementation: + +1. Run `pnpm build` and check `.svelte-kit/cloudflare/sitemap.xml` exists +2. Validate XML structure at https://www.xml-sitemaps.com/validate-xml-sitemap.html +3. Submit to Google Search Console when ready diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..2b8332c --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,40 @@ +import js from "@eslint/js"; +import ts from "typescript-eslint"; +import svelte from "eslint-plugin-svelte"; +import globals from "globals"; + +export default ts.config( + js.configs.recommended, + ...ts.configs.recommended, + ...svelte.configs["flat/recommended"], + { + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + }, + }, + }, + { + files: ["**/*.svelte"], + languageOptions: { + parserOptions: { + parser: ts.parser, + }, + }, + rules: { + // Disable strict navigation rules for now + "svelte/no-navigation-without-resolve": "off", + "svelte/require-each-key": "warn", + }, + }, + { + files: ["**/*.cjs"], + rules: { + "@typescript-eslint/no-require-imports": "off", + }, + }, + { + ignores: ["build/", ".svelte-kit/", "dist/", ".wrangler/", "node_modules/"], + }, +); diff --git a/lint-staged.config.cjs b/lint-staged.config.cjs deleted file mode 100644 index 2d95853..0000000 --- a/lint-staged.config.cjs +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - "**/*.(ts|svelte)": () => "yarn run check", - "!(apps/)**/*.(js|cjs|mjs|ts|svelte)": (filenames) => [ - `eslint --ext .js,.cjs,.mjs,.ts,.svelte --fix ${filenames.join(" ")}`, - `prettier --write ${filenames.join(" ")}`, - ], - "apps/website/**/*.(js|cjs|mjs|ts|svelte)": (filenames) => [ - `yarn website:lint --fix ${filenames.join(" ")}`, - `yarn website:format --write ${filenames.join(" ")}`, - ], -}; diff --git a/apps/website/mdsvex.config.js b/mdsvex.config.js similarity index 92% rename from apps/website/mdsvex.config.js rename to mdsvex.config.js index 85a0593..5822ecf 100644 --- a/apps/website/mdsvex.config.js +++ b/mdsvex.config.js @@ -49,7 +49,10 @@ const config = { class: "flex flex-row flex-wrap content-center", }, content(node) { - return [h("span.hidden", "Read the “", toString(node), "” section"), linkIcon()]; + return [ + h("span.hidden", "Read the “", toString(node), "” section"), + linkIcon(), + ]; }, }, ], diff --git a/apps/website/mdsvex/link-icon.js b/mdsvex/link-icon.js similarity index 84% rename from apps/website/mdsvex/link-icon.js rename to mdsvex/link-icon.js index 11b3efd..01c0590 100644 --- a/apps/website/mdsvex/link-icon.js +++ b/mdsvex/link-icon.js @@ -9,7 +9,8 @@ export default function () { viewbox: "0 0 24 24", strokeWidth: "1.5", stroke: "currentColor", - class: "w-5 h-5 ml-2 inline-block text-gray-400 hover:text-gray-700 autolink", + class: + "w-5 h-5 ml-2 inline-block text-gray-400 hover:text-gray-700 autolink", ariaHidden: "true", }, [ @@ -18,6 +19,6 @@ export default function () { strokeLinejoin: "round", d: "M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244", }), - ] + ], ); } diff --git a/package.json b/package.json index 98d09a7..6c73ef0 100644 --- a/package.json +++ b/package.json @@ -1,68 +1,65 @@ { - "name": "johnhooks.github.io", - "version": "1.0.0-alpha.1", - "repository": "git@github.com:johnhooks/johnhooks.github.io.git", - "author": "John Hooks ", - "license": "MIT", + "name": "johnhooks.io", + "version": "0.1.0", "type": "module", "private": true, - "workspaces": [ - "apps/*", - "packages/*" - ], + "packageManager": "pnpm@10.24.0", + "homepage": "https://github.com/johnhooks/johnhooks.github.io#readme", + "bugs": "https://github.com/johnhooks/johnhooks.github.io/issues", + "repository": { + "type": "git", + "url": "https://github.com/johnhooks/johnhooks.github.io.git" + }, + "author": { + "name": "John Hooks", + "url": "https://johnhooks.io" + }, + "license": "MIT", "scripts": { - "check": "turbo check", - "clean": "turbo clean", - "clean:tsc": "turbo clean:tsc", - "clean:all": "turbo clean:all", - "build:esm": "turbo build:esm --filter=./packages/*", - "build:definitions": "turbo build:definitions --filter=./packages/*", - "build:types": "turbo build:types --filter=./packages/*", - "build:umd:cjs": "turbo build:umd:cjs --filter=./packages/*", - "build": "turbo build --filter=./packages/*", - "format": "prettier --write .", - "lint": "turbo lint", - "prepare": "husky install && turbo prepare", - "test": "turbo test", - "website:dev": "yarn --cwd apps/website/ dev", - "website:start": "yarn --cwd apps/website/ start", - "website:build": "turbo build --filter=./packages/* --filter=./apps/website", - "website:format": "yarn --cwd ./apps/website format", - "website:lint": "yarn --cwd ./apps/website lint", - "website:preview": "yarn --cwd ./apps/website preview" + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "deploy": "pnpm build && wrangler deploy --env production", + "deploy:staging": "pnpm build && wrangler deploy --env staging", + "prepare": "svelte-kit sync", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "prettier --check . && eslint .", + "format": "prettier --write ." }, "devDependencies": { - "@microsoft/api-extractor": "7.33.7", - "@rollup/plugin-json": "6.0.0", - "@rollup/plugin-node-resolve": "15.0.1", - "@rollup/plugin-replace": "5.0.2", - "@rollup/plugin-sucrase": "5.0.1", - "@rollup/plugin-terser": "0.2.1", - "@testing-library/jest-dom": "5.16.5", - "@testing-library/svelte": "3.2.2", - "@types/node": "18.11.11", - "@types/testing-library__jest-dom": "5.14.5", - "@typescript-eslint/eslint-plugin": "5.46.1", - "@typescript-eslint/parser": "5.46.1", - "eslint": "8.29.0", - "eslint-config-prettier": "8.5.0", - "eslint-import-resolver-typescript": "3.5.2", - "eslint-plugin-import": "2.26.0", - "eslint-plugin-jest-dom": "4.0.3", - "eslint-plugin-svelte3": "4.0.0", - "eslint-plugin-testing-library": "5.9.1", - "husky": "8.0.2", - "jsdom": "20.0.3", - "lint-staged": "13.1.0", - "prettier": "2.8.1", - "prettier-plugin-svelte": "2.9.0", - "rollup-plugin-filesize": "9.1.2", - "svelte": "3.55.0", - "ts-node": "10.9.1", - "tslib": "2.4.1", - "turbo": "1.6.3", - "typescript": "4.9.4", - "vite": "4.0.1", - "vitest": "0.25.8" + "@bitmachina/highlighter": "^1.0.0-alpha.6", + "@cloudflare/workers-types": "^4.20241218.0", + "@eslint/js": "^9.39.2", + "@sveltejs/adapter-cloudflare": "^7.2.4", + "@sveltejs/kit": "^2.15.1", + "@sveltejs/vite-plugin-svelte": "^5.0.2", + "@tailwindcss/typography": "^0.5.15", + "@types/lodash-es": "^4.17.12", + "autoprefixer": "^10.4.20", + "eslint": "^9.39.2", + "eslint-plugin-svelte": "^3.13.1", + "globals": "^16.5.0", + "hast-util-select": "^6.0.3", + "hast-util-to-string": "^3.0.1", + "hastscript": "^9.0.0", + "mdsvex": "^0.12.3", + "postcss": "^8.4.49", + "prettier": "^3.4.2", + "prettier-plugin-svelte": "^3.3.2", + "rehype-autolink-headings": "^7.1.0", + "rehype-slug": "^6.0.0", + "remark-gfm": "^4.0.0", + "svelte": "^5.16.0", + "svelte-check": "^4.1.1", + "tailwindcss": "^3.4.17", + "typescript": "^5.7.2", + "typescript-eslint": "^8.50.0", + "vite": "^6.0.6", + "wrangler": "^4" + }, + "dependencies": { + "lodash-es": "^4.17.21", + "zod": "^3.24.1" } } diff --git a/packages/audio/api-extractor.json b/packages/audio/api-extractor.json deleted file mode 100644 index 2a0356e..0000000 --- a/packages/audio/api-extractor.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "extends": "../../api-extractor.json", - "projectFolder": "." -} diff --git a/packages/audio/etc/audio.api.md b/packages/audio/etc/audio.api.md deleted file mode 100644 index acfc590..0000000 --- a/packages/audio/etc/audio.api.md +++ /dev/null @@ -1,42 +0,0 @@ -## API Report File for "@bitmachina/audio" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts - -// @public -export type AudioParams = Record; - -// @public -class AudioWorklet_2 { - constructor({ name, url, worklet }: AudioWorkletConstructorArgs); - // (undocumented) - readonly connect: (destinationNode: AudioNode) => void; - static create({ context, ...args }: { - context: AudioContext; - name: string; - url: string; - }): Promise>; - // (undocumented) - readonly disconnect: (destinationNode: AudioNode) => void; - getParam(key: Param): number; - // (undocumented) - static readonly loaded: Map; - // (undocumented) - postMessage(data: any): void; - transfer(data: Uint8Array): void; - updateParam(key: Param, value: number): void; - updateParams(params: Partial>): void; -} -export { AudioWorklet_2 as AudioWorklet } - -// @public -export type AudioWorkletConstructorArgs = { - name: string; - url: string; - worklet: AudioWorkletNode; -}; - -// (No @packageDocumentation comment for this package) - -``` diff --git a/packages/audio/package.json b/packages/audio/package.json deleted file mode 100644 index 6d37101..0000000 --- a/packages/audio/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "@bitmachina/audio", - "version": "1.0.0-alpha.1", - "type": "module", - "description": "Web audio functions", - "homepage": "https://johnhooks.io", - "bugs": "https://github.com/johnhooks/johnhooks.github.io/issues", - "repository": { - "type": "git", - "url": "https://github.com/johnhooks/johnhooks.github.io.git" - }, - "author": { - "name": "John Hooks", - "url": "https://johnhooks.io" - }, - "license": "MIT", - "sideEffects": false, - "main": "dist/esm/index.js", - "module": "dist/esm/index.js", - "source": "src/index.ts", - "types": "dist/index.d.ts", - "files": [ - "dist/" - ], - "scripts": { - "clean": "rimraf ./{dist,temp}", - "clean:tsc": "rimraf ./lib", - "clean:all": "yarn clean && yarn clean:tsc", - "build:esm": "../../scripts/build/esm.sh", - "build:tsc": "tsc -b", - "build:types": "../../scripts/build/build-types.sh", - "build:umd:cjs": "rollup --config", - "build:pkg": "../../scripts/build/build-pkg.sh", - "check": "tsc --noEmit", - "lint": "../../scripts/build/lint.sh" - }, - "devDependencies": { - "@types/audioworklet": "0.0.35", - "mdsvex": "0.10.6" - } -} diff --git a/packages/audio/rollup.config.js b/packages/audio/rollup.config.js deleted file mode 100644 index 91be57a..0000000 --- a/packages/audio/rollup.config.js +++ /dev/null @@ -1,5 +0,0 @@ -import { createRollupConfigs } from "../../scripts/rollup/config.js"; - -import pkg from "./package.json" assert { type: "json" }; - -export default createRollupConfigs({ pkg }); diff --git a/packages/audio/src/audio-worklet.ts b/packages/audio/src/audio-worklet.ts deleted file mode 100644 index 4a901c9..0000000 --- a/packages/audio/src/audio-worklet.ts +++ /dev/null @@ -1,108 +0,0 @@ -import type { AudioParams, AudioWorkletConstructorArgs } from "./types"; - -/** - * TODO add 'processorerror' event listener - */ - -/** - * Wrap `AudioWorkletNode` to handle initialization, posting messages and passing `AudioParam`s. - * - * @public - */ -export class AudioWorklet { - #worklet: AudioWorkletNode; - - #name: string; - #url: string; - - readonly connect: (destinationNode: AudioNode) => void; - readonly disconnect: (destinationNode: AudioNode) => void; - - static readonly loaded = new Map(); - - constructor({ name, url, worklet }: AudioWorkletConstructorArgs) { - this.#name = name; - this.#url = url; - this.#worklet = worklet; - - this.connect = this.#worklet.connect.bind(this.#worklet); - this.disconnect = this.#worklet.disconnect.bind(this.#worklet); - } - - /** - * Create an initialized `AudioWorklet`. - */ - static async create({ - context, - ...args - }: { - context: AudioContext; - name: string; - url: string; - }): Promise> { - const { name, url } = args; - if (!AudioWorklet.loaded.get(name)) { - try { - await context.audioWorklet.addModule(url); - AudioWorklet.loaded.set(name, true); - } catch (error) { - if (error instanceof DOMException) { - if (error.name === "AbortError") { - throw new Error(`failed to load worklet ${args.url} `); - } - } - throw error; - } - } - const worklet = new AudioWorkletNode(context, name); - - // TODO Remove this and add better logging - // worklet.port.onmessage = (event) => { - // console.log(event.data); - // }; - - return new AudioWorklet({ worklet, ...args }); - } - - /** - * Get a single worklet parameter. - */ - getParam(key: Param): number { - const audioParam = this.#worklet.parameters.get(key); - // Expect audio parameter keys to have values. - return audioParam?.value as number; - } - - /** - * Update a single worklet parameters. - */ - updateParam(key: Param, value: number): void { - const audioParam = this.#worklet.parameters.get(key); - if (audioParam) audioParam.value = value; - } - - /** - * Update multiple worklet parameters. - */ - updateParams(params: Partial>): void { - for (const [key, value] of Object.entries(params)) { - const audioParam = this.#worklet.parameters.get(key); - if (audioParam) audioParam.value = value as number; - } - } - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - postMessage(data: any): void { - this.#worklet.port.postMessage(data); - } - - /** - * Transfer data to the underlying `AudioWorklet` node. - * - * WARNING: Ownership of the `Uint8Array`'s `ArrayBuffer` is transferred to the worklet. - * Attempting to use it afterwards will result in an error. - */ - transfer(data: Uint8Array): void { - this.#worklet.port.postMessage(data, [data.buffer]); - } -} diff --git a/packages/audio/src/constants.ts b/packages/audio/src/constants.ts deleted file mode 100644 index b8a5965..0000000 --- a/packages/audio/src/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const SAMPLE_RATE = 48000.0; diff --git a/packages/audio/src/index.ts b/packages/audio/src/index.ts deleted file mode 100644 index 93b11c0..0000000 --- a/packages/audio/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./audio-worklet.js"; -export * from "./types.js"; diff --git a/packages/audio/src/types.ts b/packages/audio/src/types.ts deleted file mode 100644 index ad3a66c..0000000 --- a/packages/audio/src/types.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Audio Worklet Parameters Type - * - * @public - */ -export type AudioParams = Record; - -/** - * `AudioWorklet` Constructor Arguments. - * - * @public - */ -export type AudioWorkletConstructorArgs = { - name: string; - url: string; - worklet: AudioWorkletNode; -}; diff --git a/packages/audio/tsconfig.json b/packages/audio/tsconfig.json deleted file mode 100644 index 83fd306..0000000 --- a/packages/audio/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.base", - "compilerOptions": { - "outDir": "lib", - "rootDir": "src", - "tsBuildInfoFile": "lib/tsconfig.tsbuildinfo" - }, - "include": ["src"] -} diff --git a/packages/midi/NOTES.md b/packages/midi/NOTES.md deleted file mode 100644 index b3fbf46..0000000 --- a/packages/midi/NOTES.md +++ /dev/null @@ -1,39 +0,0 @@ -## ideas - -- send raw midi directly into worklets. - -## status - -> Running Status is especially helpful when sending long strings of Note On/Off messages, where "Note On with Velocity of 0" is used for Note Off. - -MIDI 1.0 Detailed Specification 4.2.1 - - -## notes - -> Middle C has a reference value of 60 - -MIDI 1.0 Detailed Specification 4.2.1 - -## velocity - -> 64: if not velocity sensitive -> 0: Note-Off (with velocity of 64) - -MIDI 1.0 Detailed Specification 4.2.1 - -## timber - -> Bn 4A vv Brightness - -> Brightness should be treated as a relative controller, with a data value of 40H meaning no change, values less than 40H meaning progressively less bright, and values greater than 40H meaning progressively more bright. - -## envelope - -Bn 48 vv Release Time Bn 49 vv Attack Time -vv = 00 - 3F = shorter times (00 = shortest adjustment) vv = 40 = no change in times -vv = 41 - 7F = longer times (7F = longest adjustment) - -## info - -`{NUMBER}H` means a base 16 number. diff --git a/packages/midi/api-extractor.json b/packages/midi/api-extractor.json deleted file mode 100644 index 2a0356e..0000000 --- a/packages/midi/api-extractor.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "extends": "../../api-extractor.json", - "projectFolder": "." -} diff --git a/packages/midi/etc/midi.api.md b/packages/midi/etc/midi.api.md deleted file mode 100644 index 6cb1331..0000000 --- a/packages/midi/etc/midi.api.md +++ /dev/null @@ -1,90 +0,0 @@ -## API Report File for "@bitmachina/midi" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts - -/// - -import { BaseActionObject } from 'xstate'; -import { Observable } from '@bitmachina/reactive'; -import { ResolveTypegenMeta } from 'xstate'; -import { ServiceMap } from 'xstate'; -import { StateMachine } from 'xstate'; -import { TypegenDisabled } from 'xstate'; - -// Warning: (ae-forgotten-export) The symbol "Channel" needs to be exported by the entry point index.d.ts -// -// @public -export function encodeAllSoundOff(channel: Channel): Uint8Array; - -// Warning: (ae-forgotten-export) The symbol "MidiPortInterface" needs to be exported by the entry point index.d.ts -// -// @public -export abstract class MidiDecoder implements MidiPortInterface { - // (undocumented) - abstract allNotesOff(channel: Channel): void; - // (undocumented) - abstract allSoundOff(channel: Channel): void; - // (undocumented) - abstract channelPressure(channel: Channel, value: number): void; - // (undocumented) - abstract controlChange(channel: Channel, controller: number, value: number): void; - // (undocumented) - decode(message: Uint8Array): void; - // (undocumented) - abstract noteOff(channel: Channel, note: number, velocity?: number): void; - // (undocumented) - abstract noteOn(channel: Channel, note: number, velocity: number): void; - // (undocumented) - abstract pitchBend(channel: Channel, value: number): void; - // (undocumented) - abstract polyphonicAfterTouch(channel: Channel, note: number, value: number): void; - // (undocumented) - abstract programChange(channel: Channel, patchIndex: number): void; -} - -// @public -export class MidiEncoder implements MidiPortInterface { - // (undocumented) - allNotesOff(channel: Channel): Uint8Array; - // (undocumented) - allSoundOff(channel: Channel): Uint8Array; - // (undocumented) - channelPressure(channel: Channel, value: number): Uint8Array; - // (undocumented) - controlChange(channel: Channel, controller: number, value: number): Uint8Array; - // (undocumented) - noteOff(channel: Channel, note: number): Uint8Array; - // (undocumented) - noteOn(channel: Channel, note: number, velocity: number): Uint8Array; - // (undocumented) - pitchBend(channel: Channel, value: number): Uint8Array; - // (undocumented) - polyphonicAfterTouch(channel: Channel, note: number, value: number): Uint8Array; - // (undocumented) - programChange(channel: Channel, patchIndex: number): Uint8Array; -} - -// @public -export class MidiKeyboard extends Observable { - // Warning: (ae-forgotten-export) The symbol "Octave" needs to be exported by the entry point index.d.ts - constructor(channel?: Channel, octave?: Octave); - // (undocumented) - handleKeyEvent: (event: KeyboardEvent) => void; - // (undocumented) - register(): void; - // (undocumented) - unregister(): void; -} - -// Warning: (ae-forgotten-export) The symbol "Context" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "MidiEvent" needs to be exported by the entry point index.d.ts -// Warning: (ae-forgotten-export) The symbol "MidiTypestate" needs to be exported by the entry point index.d.ts -// -// @public -export const midiMachine: StateMachine>; - -// (No @packageDocumentation comment for this package) - -``` diff --git a/packages/midi/package.json b/packages/midi/package.json deleted file mode 100644 index 032e38e..0000000 --- a/packages/midi/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "@bitmachina/midi", - "version": "1.0.0-alpha.1", - "type": "module", - "description": "Web MIDI helpers", - "homepage": "https://johnhooks.io", - "bugs": "https://github.com/johnhooks/johnhooks.github.io/issues", - "repository": { - "type": "git", - "url": "https://github.com/johnhooks/johnhooks.github.io.git" - }, - "author": { - "name": "John Hooks", - "url": "https://johnhooks.io" - }, - "license": "MIT", - "sideEffects": false, - "main": "dist/esm/index.js", - "module": "dist/esm/index.js", - "source": "src/index.ts", - "types": "dist/index.d.ts", - "files": [ - "dist/" - ], - "scripts": { - "clean": "rimraf ./{dist,temp}", - "clean:tsc": "rimraf ./lib", - "clean:all": "yarn clean && yarn clean:tsc", - "build:esm": "../../scripts/build/esm.sh", - "build:tsc": "tsc -b", - "build:types": "../../scripts/build/build-types.sh", - "build:umd:cjs": "rollup --config", - "build:pkg": "../../scripts/build/build-pkg.sh", - "check": "tsc --noEmit", - "lint": "../../scripts/build/lint.sh" - }, - "dependencies": { - "@bitmachina/reactive": "1.0.0-alpha.1", - "xstate": "4.35.1" - }, - "devDependencies": { - "@types/webmidi": "2.0.6" - } -} diff --git a/packages/midi/rollup.config.js b/packages/midi/rollup.config.js deleted file mode 100644 index 91be57a..0000000 --- a/packages/midi/rollup.config.js +++ /dev/null @@ -1,5 +0,0 @@ -import { createRollupConfigs } from "../../scripts/rollup/config.js"; - -import pkg from "./package.json" assert { type: "json" }; - -export default createRollupConfigs({ pkg }); diff --git a/packages/midi/src/constants.ts b/packages/midi/src/constants.ts deleted file mode 100644 index 2eed4b7..0000000 --- a/packages/midi/src/constants.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const STATUS_MASK = 0xf0; -export const CHANNEL_MASK = 0x0f; -export const DATA_MASK = 0x7f; - -export const START_BYTE = 0b11111010; -export const CONTINUE_BYTE = 0b11111011; -export const STOP_BYTE = 0b11111100; diff --git a/packages/midi/src/decode.ts b/packages/midi/src/decode.ts deleted file mode 100644 index c3ef517..0000000 --- a/packages/midi/src/decode.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { CHANNEL_MASK, DATA_MASK } from "./constants.js"; -import type { MidiPortInterface } from "./types.js"; -import { CCModeValues, StatusByte, type Channel } from "./types.js"; - -/** - * MIDI Decoder Abstract Class. - * - * The intent is to directly call the abstract methods, rather than create an over elaborate - * MIDI event system. - * @public - */ -export abstract class MidiDecoder implements MidiPortInterface { - /** - * Current status byte of the decoder. - * - * Useful for receiving a running status. - * Initial status will not match any status nibbles. - */ - #status = 0; - - decode(message: Uint8Array) { - const byte = message[0]; - const runningStatus = byte >> 7 === 0; - this.#status = runningStatus ? this.#status : byte; - const status = this.#status >> 4; - const channel = (this.#status & CHANNEL_MASK) as Channel; - const data = runningStatus ? message : message.slice(1); - - switch (status) { - case StatusByte.NoteOn: { - const note = data[0]; - const velocity = data[1]; - if (runningStatus && velocity === 0) { - this.noteOff(channel, note); - } else { - this.noteOn(channel, note, velocity); - } - break; - } - case StatusByte.NoteOff: { - // Ignore velocity of note off message. - this.noteOff(channel, data[0], 0); - break; - } - case StatusByte.CC: { - const controller = data[0] & DATA_MASK; - if (controller < 120) { - this.controlChange(channel, controller, data[1]); - } else { - switch (controller) { - case CCModeValues.AllSoundOff: { - this.allSoundOff(channel); - break; - } - case CCModeValues.AllNotesOff: { - this.allNotesOff(channel); - break; - } - default: { - // Unimplemented MIDI Messages - return; - } - } - } - break; - } - case StatusByte.PitchBend: { - const lsb = data[0] & DATA_MASK; - const msb = data[1] & DATA_MASK; - // little-endian order, contrasting with the default big-endian order of Standard Midi Files - const value = (msb << 7) | lsb; - this.pitchBend(channel, value); - break; - } - default: { - // Unimplemented MIDI Messages - return; - } - } - } - - abstract noteOn(channel: Channel, note: number, velocity: number): void; - - abstract noteOff(channel: Channel, note: number, velocity?: number): void; - - abstract polyphonicAfterTouch(channel: Channel, note: number, value: number): void; - - abstract controlChange(channel: Channel, controller: number, value: number): void; - - abstract programChange(channel: Channel, patchIndex: number): void; - - abstract channelPressure(channel: Channel, value: number): void; - - abstract pitchBend(channel: Channel, value: number): void; - - abstract allSoundOff(channel: Channel): void; - - abstract allNotesOff(channel: Channel): void; -} diff --git a/packages/midi/src/encode.ts b/packages/midi/src/encode.ts deleted file mode 100644 index d6c8cba..0000000 --- a/packages/midi/src/encode.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { CHANNEL_MASK } from "./constants.js"; -import { - StatusByte, - CCModeValues, - type MidiPortInterface, - type MidiStatus, - type Channel, -} from "./types.js"; - -/** - * MIDI Encoder Class. - * - * @public - */ -export class MidiEncoder implements MidiPortInterface { - /** - * Current status of the encoder. - * - * Useful for outputting a running status. - */ - #status: number | null = null; - - noteOn(channel: Channel, note: number, velocity: number): Uint8Array { - const status = (StatusByte.NoteOn << 4) | channel; - if (status === this.#status) { - return encode(note, velocity); - } else { - this.#status = status; - return encode(StatusByte.NoteOn, channel, note, velocity); - } - } - - noteOff(channel: Channel, note: number): Uint8Array { - const runningStatus = (StatusByte.NoteOn << 4) | channel; - if (this.#status === runningStatus) { - return encode(note, 0); - } else { - return encode(StatusByte.NoteOff, channel, note, 0); - } - } - - polyphonicAfterTouch(channel: Channel, note: number, value: number): Uint8Array { - return encode(StatusByte.AfterTouch, channel, note, value); - } - - controlChange(channel: Channel, controller: number, value: number): Uint8Array { - return encode(StatusByte.CC, channel, controller, value); - } - - programChange(channel: Channel, patchIndex: number): Uint8Array { - return encode(StatusByte.ProgramChange, channel, patchIndex); - } - - // The single greatest pressure value (of all the current depressed keys). - channelPressure(channel: Channel, value: number): Uint8Array { - return encode(StatusByte.ChannelPressure, channel, value); - } - - // The pitch bender is measured by a fourteen bit value. Center (no pitch change) is 2000H. Sensitivity is a function of the receiver, but may be set using RPN 0. (lllllll) are the least significant 7 bits. (mmmmmmm) are the most significant 7 bits. - pitchBend(channel: Channel, value: number): Uint8Array { - return encodePitchBend(channel, value); - } - - // Channel Modes - - allSoundOff(channel: Channel): Uint8Array { - return encodeAllSoundOff(channel); - } - - allNotesOff(channel: Channel): Uint8Array { - return encode(StatusByte.CC, channel, CCModeValues.AllNotesOff, 0); - } -} - -/** - * Encode an all sounds off MIDI message. - * - * @param channel - The channel to address the message. - * @public - */ -export function encodeAllSoundOff(channel: Channel) { - return encode(StatusByte.CC, channel, CCModeValues.AllSoundOff, 0); -} - -/** - * Clamp `value` to an unsigned 7 bit integer. - */ -function u7(value: number): number { - return Math.max(0, Math.min(127, value)) || 0; -} - -/** - * Clamp `value` to an unsigned 14 bit integer. - */ -function u14(value: number): number { - return Math.max(0, Math.min(16383, value)) || 0; -} - -/** - * Encode pitch bend MIDI message. - * - * @param channel - The MIDI channel of the message. - * @param value - The pitch bend value. Clamped to u14. - */ -function encodePitchBend(channel: Channel, value: number): Uint8Array { - const clamped = u14(value); - const message = new Uint8Array(3); - message[0] = (StatusByte.PitchBend << 4) | (channel & CHANNEL_MASK); - // lsb - message[1] = clamped & 0x7f; - // msb - message[2] = (clamped >> 7) & 0x7f; - return message; -} - -/** - * Encode Midi message. - */ -function encode(...data: [number, number]): Uint8Array; -function encode(status: MidiStatus, channel: Channel, ...data: [number]): Uint8Array; -function encode(status: MidiStatus, channel: Channel, ...data: [number, number]): Uint8Array; -function encode(...data: number[]): Uint8Array { - if (data.length === 2) { - return new Uint8Array([u7(data[0]), u7(data[1])]); - } else { - return new Uint8Array([(data[0] << 4) | u7(data[1]), ...data.slice(2).map(u7)]); - } -} diff --git a/packages/midi/src/index.ts b/packages/midi/src/index.ts deleted file mode 100644 index ea4ac9e..0000000 --- a/packages/midi/src/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./keyboard/index.js"; -export * from "./decode.js"; -export * from "./encode.js"; -export * from "./midi-machine.js"; diff --git a/packages/midi/src/keyboard/constants.ts b/packages/midi/src/keyboard/constants.ts deleted file mode 100644 index 3449359..0000000 --- a/packages/midi/src/keyboard/constants.ts +++ /dev/null @@ -1,79 +0,0 @@ -export const UpperKeyboardOrder = [ - // C0 - "KeyQ", - // Db0 - "Digit2", - // D0 - "KeyW", - // Eb0 - "Digit3", - // E0 - "KeyE", - // F0 - "KeyR", - // Gb0 - "Digit5", - // G0 - "KeyT", - // Ab0 - "Digit6", - // A0 - "KeyY", - // Bb0 - "Digit7", - // B0 - "KeyU", - // C1 - "KeyI", - // Db - "Digit9", - // D - "KeyO", - //Eb - "Digit0", - // E - "KeyP", - // F - "BracketLeft", - // Gb - "Equal", - // G - "BracketRight", -] as const; - -export const LowerKeyboardOrder = [ - // C0 - "KeyZ", - // Db0 - "KeyS", - // D0 - "KeyX", - // Eb0 - "KeyD", - // E0 - "KeyC", - // F0 - "KeyV", - // Gb0 - "KeyG", - // G0 - "KeyB", - // Ab0 - "KeyH", - // A0 - "KeyN", - // Bb0 - "KeyJ", - // B0 - "KeyM", - // C1 - "Comma", - // Db - "KeyL", - // D - "Period", - //Eb - "Semicolon", - // E - "Slash", -] as const; diff --git a/packages/midi/src/keyboard/helpers.ts b/packages/midi/src/keyboard/helpers.ts deleted file mode 100644 index 4c4ea93..0000000 --- a/packages/midi/src/keyboard/helpers.ts +++ /dev/null @@ -1,63 +0,0 @@ -import type { Octave } from "../types"; - -import { UpperKeyboardOrder, LowerKeyboardOrder } from "./constants"; - -type KeyboardKey = typeof UpperKeyboardOrder[number] | typeof LowerKeyboardOrder[number]; - -type MidiNoteMap = { midi: number; note: string }; -type KeyboardMidiMap = { key: KeyboardKey } & MidiNoteMap; -type KeyboardMidiIndex = Map; - -const Notes = ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"] as const; -const MidiNotes = genMidiNotes(); - -// type Note = typeof Notes[number] - -/** - * Generate an array of MIDI note values for 8 octaves. - */ -export function genMidiNotes(): MidiNoteMap[] { - // Reference: https://newt.phys.unsw.edu.au/jw/notes.html - const list: MidiNoteMap[] = []; - for (let octave = 0; octave < 9; octave++) { - for (const [index, note] of Notes.entries()) { - list.push({ note: `${note}${octave}`, midi: octave * 12 + 12 + index }); - } - } - return list; -} - -export function getMidiRange(startNote: string, length: number): MidiNoteMap[] { - const startIndex = MidiNotes.findIndex((value) => value.note === startNote); - if (startIndex === -1) { - throw new RangeError(`out of range MIDI note: ${startNote}`); - } - if (startIndex + length > MidiNotes.length) { - const maxValue = MidiNotes.length - startIndex; - throw new RangeError(`out of range slice length: ${length}, max possible value: ${maxValue} `); - } - return MidiNotes.slice(startIndex, startIndex + length); -} - -export function genKeyboardMidiIndex( - upperOctave: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 -): KeyboardMidiIndex { - const lowerOctave = upperOctave - 1; - const upper = genKeyboardMidiMap(upperOctave as Octave, UpperKeyboardOrder); - const lower = genKeyboardMidiMap(lowerOctave as Octave, LowerKeyboardOrder); - const map: KeyboardMidiIndex = new Map(); - for (const { key, ...rest } of [...upper, ...lower]) { - map.set(key, { key, ...rest }); - } - return map; -} - -function genKeyboardMidiMap(octave: Octave, keys: readonly KeyboardKey[]): KeyboardMidiMap[] { - const range = getMidiRange(`C${octave}`, keys.length); - const result: KeyboardMidiMap[] = []; - for (const [index, midi] of range.entries()) { - const key = keys[index]; - result.push({ key, ...midi }); - } - return result; -} diff --git a/packages/midi/src/keyboard/index.ts b/packages/midi/src/keyboard/index.ts deleted file mode 100644 index c28dd5c..0000000 --- a/packages/midi/src/keyboard/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./keyboard"; diff --git a/packages/midi/src/keyboard/keyboard.ts b/packages/midi/src/keyboard/keyboard.ts deleted file mode 100644 index bc9e146..0000000 --- a/packages/midi/src/keyboard/keyboard.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Observable } from "@bitmachina/reactive"; - -import { MidiEncoder, encodeAllSoundOff } from "../encode.js"; -import type { Channel } from "../types.js"; - -import { genKeyboardMidiIndex } from "./helpers.js"; - -type Octave = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8; - -// TODO Add `Shift` modifier to hold -// TODO Add arpeggiator -// TODO Add tempo -// TODO Add polyphonic mode -// TODO Index keypresses and revert to previous key when one is released in mono mode - -/** - * MIDI Computer Keyboard Controller Interface. - * - * @public - */ -export class MidiKeyboard extends Observable { - #keyboardMidiIndex: ReturnType; - - #encoder = new MidiEncoder(); - #down = new Map(); - - #outputChannel: Channel = 0; - #octave: Octave; - - constructor(channel: Channel = 0, octave: Octave = 4) { - super(encodeAllSoundOff(channel)); - this.#outputChannel = channel; - this.#octave = octave; - this.#keyboardMidiIndex = genKeyboardMidiIndex(this.#octave); - } - - handleKeyEvent = (event: KeyboardEvent) => { - if (event.defaultPrevented) { - return; // Do nothing if event already handled - } - - const keyMap = this.#keyboardMidiIndex.get(event.code); - - if (keyMap) { - const { midi: note } = keyMap; - if (event.type === "keydown") { - const down = Array.from(this.#down.entries()) - .filter(([, value]) => value) - .map(([key]) => key); - - if (down.length > 0) console.log(down.join(" ").replaceAll("Key", "")); - - if (this.#down.get(event.code)) { - // key already depressed - return; - } else { - this.#down.set(event.code, true); - // `velocity` is 64, the default for devices that are not velocity sensitive. - this.next(this.#encoder.noteOn(this.#outputChannel, note, 64)); - } - } else if (event.type === "keyup") { - console.log("key up"); - this.#down.set(event.code, false); - this.next(this.#encoder.noteOff(this.#outputChannel, note)); - } - } - - switch (event.code) { - case "Backquote": { - this.#shiftOctave(-1); - break; - } - case "Digit1": { - this.#shiftOctave(1); - break; - } - } - }; - - register() { - if (typeof document !== "undefined") { - window.addEventListener("keydown", this.handleKeyEvent); - window.addEventListener("keyup", this.handleKeyEvent); - } - } - - unregister() { - if (typeof document !== "undefined") { - window.removeEventListener("keydown", this.handleKeyEvent); - window.removeEventListener("keyup", this.handleKeyEvent); - } - } - - #shiftOctave(direction: -1 | 1): void { - if ((direction === -1 && this.#octave === 1) || (direction === 1 && this.#octave === 7)) return; - this.#octave = (this.#octave + direction) as Octave; - this.#keyboardMidiIndex = genKeyboardMidiIndex(this.#octave); - } -} diff --git a/packages/midi/src/midi-machine.ts b/packages/midi/src/midi-machine.ts deleted file mode 100644 index 4132489..0000000 --- a/packages/midi/src/midi-machine.ts +++ /dev/null @@ -1,346 +0,0 @@ -import { createMachine, assign, type DoneInvokeEvent } from "xstate"; - -type Connection = { - using: boolean; - port: Port; -}; - -type Context = { - /** - * Reference to MIDI access instance. - */ - access: WebMidi.MIDIAccess; - /** - * Open input ports - */ - inputs: Connection[]; - /** - * Open output ports - */ - outputs: Connection[]; - /** - * The failure reason message. - */ - reason?: string; - /** - * The raised error of a failure. - */ - error?: Error; -}; - -type RequestEvent = { type: "REQUEST" }; -type GrantEvent = { type: "GRANT"; access: WebMidi.MIDIAccess }; -type UseEvent = { type: "USE"; id: string }; -type DropEvent = { type: "DROP"; id: string }; -type ConnectionEvent = { type: "OPEN" | "CLOSE"; id: string }; -type ErrorEvent = { type: "ERROR"; reason: "unsupported" | "denied" | "error" }; - -type MidiEvent = RequestEvent | GrantEvent | UseEvent | DropEvent | ConnectionEvent | ErrorEvent; - -type InitialContext = { - value: "initial" | "ungranted" | "requesting"; - context: Context & { - access: undefined; - }; -}; - -type FailureContext = { - value: "failure"; - context: Context & { - reason: "unsupported" | "denied" | "error"; - error: Error; - }; -}; - -type SuccessContext = { - value: "success"; - context: Context & { - access: WebMidi.MIDIAccess; - }; -}; - -type MidiTypestate = InitialContext | FailureContext | SuccessContext; - -/** - * MIDI Access State Machine. - * - * @public - */ -export const midiMachine = createMachine( - { - id: "midi", - - initial: "initial", - - predictableActionArguments: true, - - context: { - // This is a hack. The success state is the only one using MIDIAccess, and its presence should - // be implied in this state. Consider using an Actor for the success state and eliminate this. - access: null as unknown as WebMidi.MIDIAccess, - inputs: [], - outputs: [], - }, - - states: { - initial: { - invoke: { - id: "checkMidiPermission", - src: () => { - if (typeof document === "undefined") return Promise.reject(Error("Not in browser")); - return navigator.permissions - .query({ name: "midi" } as unknown as PermissionDescriptor) - .then(() => { - return navigator.requestMIDIAccess(); - }) - .catch((error) => { - console.log(error); - }); - }, - onDone: { - target: "success", - actions: [ - "logGranted", - assign>({ - access: (_context, { data: access }) => access, - inputs: (_context, { data: access }) => { - return toInputs(access, (port) => ({ using: false, port })); - }, - outputs: (_context, { data: access }) => { - return toOutputs(access, (port) => ({ using: false, port })); - }, - }), - ], - }, - onError: { - target: "ungranted", - }, - }, - on: { - REQUEST: { target: "requesting" }, - }, - }, - ungranted: { - on: { - REQUEST: { target: "requesting" }, - }, - }, - requesting: { - invoke: { - id: "midiRequestAccess", - src: () => { - if (typeof document === "undefined") return Promise.reject(Error("Not in browser")); - return navigator.requestMIDIAccess(); - }, - onDone: { - target: "success", - actions: [ - "logGranted", - assign>({ - access: (_context, { data: access }) => access, - inputs: (_context, { data: access }) => { - return toInputs(access, (port) => ({ using: false, port })); - }, - outputs: (_context, { data: access }) => { - return toOutputs(access, (port) => ({ using: false, port })); - }, - }), - ], - }, - onError: { - target: "failure", - actions: assign>({ - reason: (_context, event) => { - const error = event.data; - if (error instanceof DOMException) { - switch (error.name) { - case "NotSupportedError": - return "unsupported"; - case "SecurityError": - return "denied"; - default: - return "error"; - } - } - throw event.data; - }, - error: (_context, event) => { - return event.data; - }, - }), - }, - }, - }, - success: { - // example https://github.com/statelyai/xstate/discussions/2885#discussioncomment-1856173 - invoke: { - id: "midiInitializeAccess", - src: (context) => (send) => { - // This should already be insured by the current state. - function handleStateChange({ port }: WebMidi.MIDIConnectionEvent): void { - switch (port.connection) { - case "open": - send({ type: "OPEN", id: port.id }); - break; - case "closed": - send({ type: "CLOSE", id: port.id }); - break; - case "pending": - break; - } - } - - context.access.addEventListener("statechange", handleStateChange); - - return function () { - context.access.removeEventListener("statechange", handleStateChange as EventListener); - }; - }, - }, - on: { - OPEN: { - actions: [ - "logNewConnection", - assign({ - inputs: ({ access, inputs }, { id }) => { - const [device, rest] = extract(inputs, id); - if (device) return [...rest, { ...device, using: true }]; - const port = access.inputs.get(id); - if (!port) return inputs; // TODO fire a connection error? - return [...rest, { port, using: false } as Connection]; - }, - }), - ], - }, - - CLOSE: { - actions: [ - "logLostConnection", - assign({ - inputs: ({ inputs }, { id }) => { - const device = inputs.find(({ port }) => port.id === id); - if (device && device.port.connection === "closed") { - // TODO perhaps not remove but set a status property to `closed`. - return inputs.filter(({ port }) => port.id !== id); - } - return inputs; - }, - }), - ], - }, - - DROP: { - actions: [ - "logDropDevice", - assign({ - inputs: ({ inputs }, { id }) => - update(inputs, id, (connection) => ({ ...connection, using: false })), - }), - ], - }, - - USE: { - actions: [ - "logUseDevice", - assign({ - inputs: ({ inputs }, { id }) => { - const [device, rest] = extract(inputs, id); - if (!device) return inputs; - if (device.port.state !== "connected") return inputs; // TODO should notify the user. - return [...rest, { ...device, using: true }]; - }, - }), - ], - }, - }, - }, - failure: { - type: "final", - }, - }, - }, - { - actions: { - // action implementations - logGranted: (): void => { - console.log("MIDI access granted"); - }, - logNewConnection: (context, event): void => { - if (event.type === "OPEN") { - const input = context.access.inputs.get(event.id); - if (!input) return; - console.log(`MIDI new device connection ${input.name || input.id}`); - } - }, - logLostConnection: (context, event): void => { - if (event.type === "CLOSE") { - const input = context.access.inputs.get(event.id); - if (!input) return; - console.log(`MIDI lost device connection ${input.name || input.id}`); - } - }, - logDropDevice: ({ inputs }, event): void => { - if (event.type === "DROP") { - const device = inputs.find(({ port }) => port.id === event.id); - if (!device) return; - console.log(`MIDI stop using device ${device.port.name || device.port.id}`); - } - }, - logUseDevice: ({ inputs }, event): void => { - if (event.type === "USE") { - const device = inputs.find(({ port }) => port.id === event.id); - if (!device) return; - console.log(`MIDI use device ${device.port.name || device.port.id}`); - } - }, - }, - } -); - -type Transformer = (port: Port) => Connection; - -function toInputs( - access: WebMidi.MIDIAccess | undefined, - transformer: Transformer -): Connection[] { - if (!access) return []; - const inputs = Array.from(access.inputs.values()); - return inputs.map(transformer); -} - -function toOutputs( - access: WebMidi.MIDIAccess | undefined, - transformer: Transformer -): Connection[] { - if (!access) return []; - const inputs = Array.from(access.outputs.values()); - return inputs.map(transformer); -} - -function update( - list: Connection[], - id: string, - transformer: (connection: Connection) => Connection -): Connection[] { - const result: Connection[] = []; - for (const conn of list) { - result.push(conn.port.id === id ? transformer(conn) : conn); - } - return result; -} - -function extract( - list: Connection[], - id: string -): [Connection | null, Connection[]] { - let item: Connection | null = null; - const rest: Connection[] = []; - for (const conn of list) { - if (conn.port.id === id) { - item = conn; - } else { - rest.push(conn); - } - } - return [item, rest]; -} diff --git a/packages/midi/src/types.ts b/packages/midi/src/types.ts deleted file mode 100644 index fa11a69..0000000 --- a/packages/midi/src/types.ts +++ /dev/null @@ -1,84 +0,0 @@ -// Status byte values that indicate the different midi notes -export const StatusByte = { - NoteOff: 0x8, - NoteOn: 0x9, - AfterTouch: 0xa, - CC: 0xb, - ProgramChange: 0xc, - ChannelPressure: 0xd, - PitchBend: 0xe, -} as const; - -// CC values that indicate special CC Modes. -export const CCModeValues = { - AllSoundOff: 120, - ResetAll: 121, - LocalController: 122, - AllNotesOff: 123, - OmniOff: 124, - OmniOn: 125, - MonoOn: 126, - PloyOn: 127, -} as const; - -type ValueOf = T[keyof T]; - -export type MidiStatus = ValueOf; - -export type Octave = 0 | 1 | 2 | 4 | 5 | 6 | 7 | 8; - -export type Channel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15; - -export type MidiNoteStatus = typeof StatusByte.NoteOn | typeof StatusByte.NoteOff; - -type BaseMidiMessage = { - status: MidiStatus; -}; - -export type MidiControlChangeMessage = { - status: typeof StatusByte.CC; - controller: number; - value: number; -} & BaseMidiMessage; - -export type AllSoundOff = { - status: typeof StatusByte.CC; -} & BaseMidiMessage; - -export type MidiNoteMessage = { - status: MidiNoteStatus; - channel: number; - note: number; - velocity: number; -} & BaseMidiMessage; - -export type MidiMessage = MidiNoteMessage | MidiControlChangeMessage | AllSoundOff; - -export type AudioParamKey = "gate" | "note" | "velocity" | "brightness" | "envelope"; -export type AudioParams = Partial>; - -export type MidiPortInterface = { - noteOn(channel: Channel, note: number, velocity: number): TValue; - - noteOff(channel: Channel, note: number, velocity?: number): TValue; - - polyphonicAfterTouch(channel: Channel, note: number, value: number): TValue; - - controlChange(channel: Channel, controller: number, value: number): TValue; - - programChange(channel: Channel, patchIndex: number): TValue; - - // The single greatest pressure value (of all the current depressed keys). - channelPressure(channel: Channel, value: number): TValue; - - // The pitch bender is measured by a fourteen bit value. Center (no pitch change) is 2000H. Sensitivity is a function of the receiver, but may be set using RPN 0. (lllllll) are the least significant 7 bits. (mmmmmmm) are the most significant 7 bits. - pitchBend(channel: Channel, value: number): TValue; - - // Channel Modes - - allSoundOff(channel: Channel): TValue; - - allNotesOff(channel: Channel): TValue; -}; - -export type MidiReceiver = MidiPortInterface; diff --git a/packages/midi/tsconfig.json b/packages/midi/tsconfig.json deleted file mode 100644 index 804ea83..0000000 --- a/packages/midi/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base", - "compilerOptions": { - "outDir": "lib", - "rootDir": "src", - "tsBuildInfoFile": "lib/tsconfig.tsbuildinfo" - }, - "include": ["src"], - "references": [{ "path": "../reactive" }] -} diff --git a/packages/reactive/api-extractor.json b/packages/reactive/api-extractor.json deleted file mode 100644 index 2a0356e..0000000 --- a/packages/reactive/api-extractor.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "extends": "../../api-extractor.json", - "projectFolder": "." -} diff --git a/packages/reactive/etc/core.api.md b/packages/reactive/etc/core.api.md deleted file mode 100644 index b627596..0000000 --- a/packages/reactive/etc/core.api.md +++ /dev/null @@ -1,20 +0,0 @@ -## API Report File for "@bitmachina/core" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts - -// @public -export class Observable { - constructor(initialValue: TValue); - close(): void; - error(error: TError): void; - next(value: TValue): void; - // Warning: (ae-forgotten-export) The symbol "Observer" needs to be exported by the entry point index.d.ts - subscribe(listener: Observer): () => void; - get value(): TValue; -} - -// (No @packageDocumentation comment for this package) - -``` diff --git a/packages/reactive/etc/reactive.api.md b/packages/reactive/etc/reactive.api.md deleted file mode 100644 index 78f1749..0000000 --- a/packages/reactive/etc/reactive.api.md +++ /dev/null @@ -1,20 +0,0 @@ -## API Report File for "@bitmachina/reactive" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts - -// @public -export class Observable { - constructor(initialValue: TValue); - close(): void; - error(error: TError): void; - next(value: TValue): void; - // Warning: (ae-forgotten-export) The symbol "Observer" needs to be exported by the entry point index.d.ts - subscribe(listener: Observer): () => void; - get value(): TValue; -} - -// (No @packageDocumentation comment for this package) - -``` diff --git a/packages/reactive/etc/tools.api.md b/packages/reactive/etc/tools.api.md deleted file mode 100644 index 8a776fb..0000000 --- a/packages/reactive/etc/tools.api.md +++ /dev/null @@ -1,20 +0,0 @@ -## API Report File for "@bitmachina/tools" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts - -// @public -export class Observable { - constructor(initialValue: TValue); - close(): void; - error(error: TError): void; - next(value: TValue): void; - // Warning: (ae-forgotten-export) The symbol "Observer" needs to be exported by the entry point index.d.ts - subscribe(listener: Observer): () => void; - get value(): TValue; -} - -// (No @packageDocumentation comment for this package) - -``` diff --git a/packages/reactive/package.json b/packages/reactive/package.json deleted file mode 100644 index d8bca98..0000000 --- a/packages/reactive/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "@bitmachina/reactive", - "version": "1.0.0-alpha.1", - "type": "module", - "description": "Collection of utilities", - "homepage": "https://johnhooks.io", - "bugs": "https://github.com/johnhooks/johnhooks.github.io/issues", - "repository": { - "type": "git", - "url": "https://github.com/johnhooks/johnhooks.github.io.git" - }, - "author": { - "name": "John Hooks", - "url": "https://johnhooks.io" - }, - "license": "MIT", - "sideEffects": false, - "main": "dist/esm/index.js", - "module": "dist/esm/index.js", - "source": "src/index.ts", - "types": "dist/index.d.ts", - "files": [ - "dist/" - ], - "scripts": { - "clean": "rimraf ./{dist,temp}", - "clean:tsc": "rimraf ./lib", - "clean:all": "yarn clean && yarn clean:tsc", - "build:esm": "../../scripts/build/esm.sh", - "build:tsc": "tsc -b", - "build:types": "../../scripts/build/build-types.sh", - "build:umd:cjs": "rollup --config", - "build:pkg": "../../scripts/build/build-pkg.sh", - "check": "tsc --noEmit", - "lint": "../../scripts/build/lint.sh" - } -} diff --git a/packages/reactive/rollup.config.js b/packages/reactive/rollup.config.js deleted file mode 100644 index 91be57a..0000000 --- a/packages/reactive/rollup.config.js +++ /dev/null @@ -1,5 +0,0 @@ -import { createRollupConfigs } from "../../scripts/rollup/config.js"; - -import pkg from "./package.json" assert { type: "json" }; - -export default createRollupConfigs({ pkg }); diff --git a/packages/reactive/src/index.ts b/packages/reactive/src/index.ts deleted file mode 100644 index 3a85e12..0000000 --- a/packages/reactive/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./observable.js"; diff --git a/packages/reactive/src/observable.ts b/packages/reactive/src/observable.ts deleted file mode 100644 index 793d601..0000000 --- a/packages/reactive/src/observable.ts +++ /dev/null @@ -1,103 +0,0 @@ -import type { Observer } from "./types/index.js"; - -/** - * A simple observable class. - * - * Intended for use in Svelte. Adding a `subscribe` method to the `Base` class implements the Svelte - * store contract and enables reactivity by prefixing the `$` character. - * @public - */ -export class Observable { - #listeners = new Map>(); - #isClosed = false; - /** - * Svelte expects stores to maintain a current value. Subscription functions must be immediately - * and synchronously called when registered through `subscribe`. - */ - #value: TValue; - - /** - * @param initialValue - The initial value, immediately passed to observers on initializing a subscription. - */ - constructor(initialValue: TValue) { - this.#value = initialValue; - } - - /** - * Get current value. - * - * @public - */ - public get value(): TValue { - return this.#value; - } - - /** - * Close subscriptions. - * - * @public - */ - public close(): void { - if (this.#isClosed) return; - for (const listener of this.#listeners.values()) { - if (typeof listener !== "function" && listener.done) { - listener.done(); - } - } - this.#isClosed = true; - this.#listeners.clear(); - } - - /** - * Close subscriptions with an error. - * - * @public - */ - public error(error: TError) { - if (this.#isClosed) throw new Error("Subscribable mixin method `error` called after `close`"); - for (const listener of this.#listeners.values()) { - if (typeof listener !== "function" && listener?.error) { - listener.error(error); - } - } - this.#isClosed = true; - this.#listeners.clear(); - } - - /** - * Push next `value` to subscribers. - * - * @public - */ - public next(value: TValue) { - if (this.#isClosed) return; - for (const listener of this.#listeners.values()) { - if (typeof listener === "function") { - listener(value); - } else { - listener.next(value); - } - } - } - - /** - * Add subscription. - * - * @public - */ - public subscribe(listener: Observer): () => void { - const symbol = Symbol(); - this.#listeners.set(symbol, listener); - - // Immediately call the subscription function with the current value. - if (typeof listener === "function") { - listener(this.#value); - } else { - listener.next(this.#value); - } - - return () => { - this.#listeners.delete(symbol); - }; - } -} diff --git a/packages/reactive/src/types/index.ts b/packages/reactive/src/types/index.ts deleted file mode 100644 index de78bbe..0000000 --- a/packages/reactive/src/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./observer.js"; diff --git a/packages/reactive/src/types/observer.ts b/packages/reactive/src/types/observer.ts deleted file mode 100644 index ffff768..0000000 --- a/packages/reactive/src/types/observer.ts +++ /dev/null @@ -1,9 +0,0 @@ -type ObserverFn = (value: TValue) => void; - -type ObserverObj = { - next: (value: TValue) => void; - error?: (error: Error) => void; - done?: () => void; -}; - -export type Observer = ObserverFn | ObserverObj; diff --git a/packages/reactive/tsconfig.json b/packages/reactive/tsconfig.json deleted file mode 100644 index 83fd306..0000000 --- a/packages/reactive/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.base", - "compilerOptions": { - "outDir": "lib", - "rootDir": "src", - "tsBuildInfoFile": "lib/tsconfig.tsbuildinfo" - }, - "include": ["src"] -} diff --git a/packages/tsconfig.json b/packages/tsconfig.json deleted file mode 100644 index 2b12d4d..0000000 --- a/packages/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { "path": "./audio" }, - { "path": "./midi" }, - { "path": "./reactive" } - ] -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..6009d23 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,4473 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + lodash-es: + specifier: ^4.17.21 + version: 4.17.22 + zod: + specifier: ^3.24.1 + version: 3.25.76 + devDependencies: + '@bitmachina/highlighter': + specifier: ^1.0.0-alpha.6 + version: 1.0.0-alpha.7 + '@cloudflare/workers-types': + specifier: ^4.20241218.0 + version: 4.20251221.0 + '@eslint/js': + specifier: ^9.39.2 + version: 9.39.2 + '@sveltejs/adapter-cloudflare': + specifier: ^7.2.4 + version: 7.2.4(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)))(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)))(wrangler@4.56.0(@cloudflare/workers-types@4.20251221.0)) + '@sveltejs/kit': + specifier: ^2.15.1 + version: 2.49.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)))(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)) + '@sveltejs/vite-plugin-svelte': + specifier: ^5.0.2 + version: 5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)) + '@tailwindcss/typography': + specifier: ^0.5.15 + version: 0.5.19(tailwindcss@3.4.19) + '@types/lodash-es': + specifier: ^4.17.12 + version: 4.17.12 + autoprefixer: + specifier: ^10.4.20 + version: 10.4.23(postcss@8.5.6) + eslint: + specifier: ^9.39.2 + version: 9.39.2(jiti@1.21.7) + eslint-plugin-svelte: + specifier: ^3.13.1 + version: 3.13.1(eslint@9.39.2(jiti@1.21.7))(svelte@5.46.0) + globals: + specifier: ^16.5.0 + version: 16.5.0 + hast-util-select: + specifier: ^6.0.3 + version: 6.0.4 + hast-util-to-string: + specifier: ^3.0.1 + version: 3.0.1 + hastscript: + specifier: ^9.0.0 + version: 9.0.1 + mdsvex: + specifier: ^0.12.3 + version: 0.12.6(svelte@5.46.0) + postcss: + specifier: ^8.4.49 + version: 8.5.6 + prettier: + specifier: ^3.4.2 + version: 3.7.4 + prettier-plugin-svelte: + specifier: ^3.3.2 + version: 3.4.1(prettier@3.7.4)(svelte@5.46.0) + rehype-autolink-headings: + specifier: ^7.1.0 + version: 7.1.0 + rehype-slug: + specifier: ^6.0.0 + version: 6.0.0 + remark-gfm: + specifier: ^4.0.0 + version: 4.0.1 + svelte: + specifier: ^5.16.0 + version: 5.46.0 + svelte-check: + specifier: ^4.1.1 + version: 4.3.5(picomatch@4.0.3)(svelte@5.46.0)(typescript@5.9.3) + tailwindcss: + specifier: ^3.4.17 + version: 3.4.19 + typescript: + specifier: ^5.7.2 + version: 5.9.3 + typescript-eslint: + specifier: ^8.50.0 + version: 8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + vite: + specifier: ^6.0.6 + version: 6.4.1(jiti@1.21.7) + wrangler: + specifier: ^4 + version: 4.56.0(@cloudflare/workers-types@4.20251221.0) + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@bitmachina/highlighter@1.0.0-alpha.7': + resolution: {integrity: sha512-ZYhqASsdh/Xh65Iz9VcAM0PSKXCt6ie/ZIYiAOHL2Q5I8k5rXdVdThVvRTF4HK/Ee++GO0EfMyqdbQ68vKjuUQ==} + + '@cloudflare/kv-asset-handler@0.4.1': + resolution: {integrity: sha512-Nu8ahitGFFJztxUml9oD/DLb7Z28C8cd8F46IVQ7y5Btz575pvMY8AqZsXkX7Gds29eCKdMgIHjIvzskHgPSFg==} + engines: {node: '>=18.0.0'} + + '@cloudflare/unenv-preset@2.7.13': + resolution: {integrity: sha512-NulO1H8R/DzsJguLC0ndMuk4Ufv0KSlN+E54ay9rn9ZCQo0kpAPwwh3LhgpZ96a3Dr6L9LqW57M4CqC34iLOvw==} + peerDependencies: + unenv: 2.0.0-rc.24 + workerd: ^1.20251202.0 + peerDependenciesMeta: + workerd: + optional: true + + '@cloudflare/workerd-darwin-64@1.20251217.0': + resolution: {integrity: sha512-DN6vT+9ho61d/1/YuILW4VS+N1JBLaixWRL1vqNmhgbf8J8VHwWWotrRruEUYigJKx2yZyw6YsasE+yLXgx/Fw==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + + '@cloudflare/workerd-darwin-arm64@1.20251217.0': + resolution: {integrity: sha512-5nZOpRTkHmtcTc4Wbr1mj/O3dLb6aHZSiJuVBgtdbVcVmOXueSay3hnw1PXEyR+vpTKGUPkM+omUIslKHWnXDw==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + + '@cloudflare/workerd-linux-64@1.20251217.0': + resolution: {integrity: sha512-uoPGhMaZVXPpCsU0oG3HQzyVpXCGi5rU+jcHRjUI7DXM4EwctBGvZ380Knkja36qtl+ZvSKVR1pUFSGdK+45Pg==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + + '@cloudflare/workerd-linux-arm64@1.20251217.0': + resolution: {integrity: sha512-ixHnHKsiz1Xko+eDgCJOZ7EEUZKtmnYq3AjW3nkVcLFypSLks4C29E45zVewdaN4wq8sCLeyQCl6r1kS17+DQQ==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + + '@cloudflare/workerd-windows-64@1.20251217.0': + resolution: {integrity: sha512-rP6USX+7ctynz3AtmKi+EvlLP3Xdr1ETrSdcnv693/I5QdUwBxq4yE1Lj6CV7GJizX6opXKYg8QMq0Q4eB9zRQ==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + + '@cloudflare/workers-types@4.20251221.0': + resolution: {integrity: sha512-VVTEhY29TtwIwjBjpRrdT51Oqu0JlXijc5TiEKFCjwouUSn+5VhzoTSaz7UBjVOu4vfvcQmjqt/dzwBUR7c95w==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@emnapi/runtime@1.7.1': + resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.27.0': + resolution: {integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.27.0': + resolution: {integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.27.0': + resolution: {integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.27.0': + resolution: {integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.27.0': + resolution: {integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.0': + resolution: {integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.27.0': + resolution: {integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.0': + resolution: {integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.27.0': + resolution: {integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.27.0': + resolution: {integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.27.0': + resolution: {integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.27.0': + resolution: {integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.27.0': + resolution: {integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.27.0': + resolution: {integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.0': + resolution: {integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.27.0': + resolution: {integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.27.0': + resolution: {integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.27.0': + resolution: {integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.0': + resolution: {integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.27.0': + resolution: {integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.0': + resolution: {integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.27.0': + resolution: {integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.27.0': + resolution: {integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.27.0': + resolution: {integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.27.0': + resolution: {integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.27.0': + resolution: {integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + 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.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + 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.3': + resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.2': + resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} + 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} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + 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/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@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'} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@poppinss/colors@4.1.6': + resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} + + '@poppinss/dumper@0.6.5': + resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==} + + '@poppinss/exception@1.2.3': + resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + + '@rollup/rollup-android-arm-eabi@4.54.0': + resolution: {integrity: sha512-OywsdRHrFvCdvsewAInDKCNyR3laPA2mc9bRYJ6LBp5IyvF3fvXbbNR0bSzHlZVFtn6E0xw2oZlyjg4rKCVcng==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.54.0': + resolution: {integrity: sha512-Skx39Uv+u7H224Af+bDgNinitlmHyQX1K/atIA32JP3JQw6hVODX5tkbi2zof/E69M1qH2UoN3Xdxgs90mmNYw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.54.0': + resolution: {integrity: sha512-k43D4qta/+6Fq+nCDhhv9yP2HdeKeP56QrUUTW7E6PhZP1US6NDqpJj4MY0jBHlJivVJD5P8NxrjuobZBJTCRw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.54.0': + resolution: {integrity: sha512-cOo7biqwkpawslEfox5Vs8/qj83M/aZCSSNIWpVzfU2CYHa2G3P1UN5WF01RdTHSgCkri7XOlTdtk17BezlV3A==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.54.0': + resolution: {integrity: sha512-miSvuFkmvFbgJ1BevMa4CPCFt5MPGw094knM64W9I0giUIMMmRYcGW/JWZDriaw/k1kOBtsWh1z6nIFV1vPNtA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.54.0': + resolution: {integrity: sha512-KGXIs55+b/ZfZsq9aR026tmr/+7tq6VG6MsnrvF4H8VhwflTIuYh+LFUlIsRdQSgrgmtM3fVATzEAj4hBQlaqQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.54.0': + resolution: {integrity: sha512-EHMUcDwhtdRGlXZsGSIuXSYwD5kOT9NVnx9sqzYiwAc91wfYOE1g1djOEDseZJKKqtHAHGwnGPQu3kytmfaXLQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.54.0': + resolution: {integrity: sha512-+pBrqEjaakN2ySv5RVrj/qLytYhPKEUwk+e3SFU5jTLHIcAtqh2rLrd/OkbNuHJpsBgxsD8ccJt5ga/SeG0JmA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.54.0': + resolution: {integrity: sha512-NSqc7rE9wuUaRBsBp5ckQ5CVz5aIRKCwsoa6WMF7G01sX3/qHUw/z4pv+D+ahL1EIKy6Enpcnz1RY8pf7bjwng==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.54.0': + resolution: {integrity: sha512-gr5vDbg3Bakga5kbdpqx81m2n9IX8M6gIMlQQIXiLTNeQW6CucvuInJ91EuCJ/JYvc+rcLLsDFcfAD1K7fMofg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.54.0': + resolution: {integrity: sha512-gsrtB1NA3ZYj2vq0Rzkylo9ylCtW/PhpLEivlgWe0bpgtX5+9j9EZa0wtZiCjgu6zmSeZWyI/e2YRX1URozpIw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.54.0': + resolution: {integrity: sha512-y3qNOfTBStmFNq+t4s7Tmc9hW2ENtPg8FeUD/VShI7rKxNW7O4fFeaYbMsd3tpFlIg1Q8IapFgy7Q9i2BqeBvA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.54.0': + resolution: {integrity: sha512-89sepv7h2lIVPsFma8iwmccN7Yjjtgz0Rj/Ou6fEqg3HDhpCa+Et+YSufy27i6b0Wav69Qv4WBNl3Rs6pwhebQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.54.0': + resolution: {integrity: sha512-ZcU77ieh0M2Q8Ur7D5X7KvK+UxbXeDHwiOt/CPSBTI1fBmeDMivW0dPkdqkT4rOgDjrDDBUed9x4EgraIKoR2A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.54.0': + resolution: {integrity: sha512-2AdWy5RdDF5+4YfG/YesGDDtbyJlC9LHmL6rZw6FurBJ5n4vFGupsOBGfwMRjBYH7qRQowT8D/U4LoSvVwOhSQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.54.0': + resolution: {integrity: sha512-WGt5J8Ij/rvyqpFexxk3ffKqqbLf9AqrTBbWDk7ApGUzaIs6V+s2s84kAxklFwmMF/vBNGrVdYgbblCOFFezMQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.54.0': + resolution: {integrity: sha512-JzQmb38ATzHjxlPHuTH6tE7ojnMKM2kYNzt44LO/jJi8BpceEC8QuXYA908n8r3CNuG/B3BV8VR3Hi1rYtmPiw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.54.0': + resolution: {integrity: sha512-huT3fd0iC7jigGh7n3q/+lfPcXxBi+om/Rs3yiFxjvSxbSB6aohDFXbWvlspaqjeOh+hx7DDHS+5Es5qRkWkZg==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.54.0': + resolution: {integrity: sha512-c2V0W1bsKIKfbLMBu/WGBz6Yci8nJ/ZJdheE0EwB73N3MvHYKiKGs3mVilX4Gs70eGeDaMqEob25Tw2Gb9Nqyw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.54.0': + resolution: {integrity: sha512-woEHgqQqDCkAzrDhvDipnSirm5vxUXtSKDYTVpZG3nUdW/VVB5VdCYA2iReSj/u3yCZzXID4kuKG7OynPnB3WQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.54.0': + resolution: {integrity: sha512-dzAc53LOuFvHwbCEOS0rPbXp6SIhAf2txMP5p6mGyOXXw5mWY8NGGbPMPrs4P1WItkfApDathBj/NzMLUZ9rtQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.54.0': + resolution: {integrity: sha512-hYT5d3YNdSh3mbCU1gwQyPgQd3T2ne0A3KG8KSBdav5TiBg6eInVmV+TeR5uHufiIgSFg0XsOWGW5/RhNcSvPg==} + cpu: [x64] + os: [win32] + + '@sindresorhus/is@7.1.1': + resolution: {integrity: sha512-rO92VvpgMc3kfiTjGT52LEtJ8Yc5kCWhZjLQ3LwlA4pSgPpQO7bVpYXParOD8Jwf+cVQECJo3yP/4I8aZtUQTQ==} + engines: {node: '>=18'} + + '@speed-highlight/core@1.2.12': + resolution: {integrity: sha512-uilwrK0Ygyri5dToHYdZSjcvpS2ZwX0w5aSt3GCEN9hrjxWCoeV4Z2DTXuxjwbntaLQIEEAlCeNQss5SoHvAEA==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@sveltejs/acorn-typescript@1.0.8': + resolution: {integrity: sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA==} + peerDependencies: + acorn: ^8.9.0 + + '@sveltejs/adapter-cloudflare@7.2.4': + resolution: {integrity: sha512-uD8VlOuGXGuZWL+zbBYSjtmC4WDtlonUodfqAZ/COd5uIy2Z0QptIicB/nkTrGNI9sbmzgf7z0N09CHyWYlUvQ==} + peerDependencies: + '@sveltejs/kit': ^2.0.0 + wrangler: ^4.0.0 + + '@sveltejs/kit@2.49.2': + resolution: {integrity: sha512-Vp3zX/qlwerQmHMP6x0Ry1oY7eKKRcOWGc2P59srOp4zcqyn+etJyQpELgOi4+ZSUgteX8Y387NuwruLgGXLUQ==} + engines: {node: '>=18.13'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.0.0 + '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + + '@sveltejs/vite-plugin-svelte-inspector@4.0.1': + resolution: {integrity: sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22} + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^5.0.0 + svelte: ^5.0.0 + vite: ^6.0.0 + + '@sveltejs/vite-plugin-svelte@5.1.1': + resolution: {integrity: sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22} + peerDependencies: + svelte: ^5.0.0 + vite: ^6.0.0 + + '@tailwindcss/typography@0.5.19': + resolution: {integrity: sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/hast@2.3.10': + resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.21': + resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@typescript-eslint/eslint-plugin@8.50.0': + resolution: {integrity: sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.50.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.50.0': + resolution: {integrity: sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.50.0': + resolution: {integrity: sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.50.0': + resolution: {integrity: sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.50.0': + resolution: {integrity: sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.50.0': + resolution: {integrity: sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.50.0': + resolution: {integrity: sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.50.0': + resolution: {integrity: sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.50.0': + resolution: {integrity: sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.50.0': + resolution: {integrity: sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@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'} + + autoprefixer@10.4.23: + resolution: {integrity: sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + baseline-browser-mapping@2.9.11: + resolution: {integrity: sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==} + hasBin: true + + bcp-47-match@2.0.3: + resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + caniuse-lite@1.0.30001761: + resolution: {integrity: sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-selector-parser@3.3.0: + resolution: {integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.2.0: + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devalue@5.6.1: + resolution: {integrity: sha512-jDwizj+IlEZBunHcOuuFVBnIMPAEHvTsJj0BcIp94xYguLRVBcXO853px/MyIJvbVzWdsGvrRweIUWJw8hBP7A==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + direction@2.0.1: + resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} + hasBin: true + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + electron-to-chromium@1.5.267: + resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.27.0: + resolution: {integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + eslint-plugin-svelte@3.13.1: + resolution: {integrity: sha512-Ng+kV/qGS8P/isbNYVE3sJORtubB+yLEcYICMkUWNaDTb0SwZni/JhAYXh/Dz/q2eThUwWY0VMPZ//KYD1n3eQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.1 || ^9.0.0 + svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + svelte: + optional: true + + 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@9.39.2: + resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrap@2.2.1: + resolution: {integrity: sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==} + + 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'} + + exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + 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.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + 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.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} + engines: {node: '>=18'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-from-parse5@7.1.2: + resolution: {integrity: sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==} + + hast-util-has-property@3.0.0: + resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + + hast-util-heading-rank@3.0.0: + resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-parse-selector@3.1.1: + resolution: {integrity: sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-select@6.0.4: + resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} + + hast-util-to-string@2.0.0: + resolution: {integrity: sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@7.2.0: + resolution: {integrity: sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + 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'} + + 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'} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + 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==} + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + known-css-properties@0.37.0: + resolution: {integrity: sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash-es@4.17.22: + resolution: {integrity: sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdsvex@0.12.6: + resolution: {integrity: sha512-pupx2gzWh3hDtm/iDW4WuCpljmyHbHi34r7ktOqpPGvyiM4MyfNgdJ3qMizXdgCErmvYC9Nn/qyjePy+4ss9Wg==} + peerDependencies: + svelte: ^3.56.0 || ^4.0.0 || ^5.0.0-next.120 + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + miniflare@4.20251217.0: + resolution: {integrity: sha512-8xsTQbPS6YV+ABZl9qiJIbsum6hbpbhqiyKpOVdzZrhK+1N8EFpT8R6aBZff7kezGmxYZSntjgjqTwJmj3JLgA==} + engines: {node: '>=18.0.0'} + hasBin: true + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + 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'} + + parse-numeric-range@1.3.0: + resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@3.1.4: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-safe-parser@7.0.1: + resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==} + engines: {node: '>=18.0'} + peerDependencies: + postcss: ^8.4.31 + + postcss-scss@4.0.9: + resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.4.29 + + postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-plugin-svelte@3.4.1: + resolution: {integrity: sha512-xL49LCloMoZRvSwa6IEdN2GV6cq2IqpYGstYtMT+5wmml1/dClEoI0MZR78MiVPpu6BdQFfN0/y73yO6+br5Pg==} + peerDependencies: + prettier: ^3.0.0 + svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 + + prettier@3.7.4: + resolution: {integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==} + engines: {node: '>=14'} + hasBin: true + + prism-svelte@0.4.7: + resolution: {integrity: sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==} + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + property-information@6.2.0: + resolution: {integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + regexparam@3.0.0: + resolution: {integrity: sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==} + engines: {node: '>=8'} + + rehype-autolink-headings@7.1.0: + resolution: {integrity: sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==} + + rehype-parse@8.0.4: + resolution: {integrity: sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==} + + rehype-slug@6.0.0: + resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.54.0: + resolution: {integrity: sha512-3nk8Y3a9Ea8szgKhinMlGMhGMw89mqule3KWczxhIzqudyHdCIOHw8WJlj/r329fACjKLEh13ZSk7oE22kyeIw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shiki@0.11.1: + resolution: {integrity: sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + + 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'} + + svelte-check@4.3.5: + resolution: {integrity: sha512-e4VWZETyXaKGhpkxOXP+B/d0Fp/zKViZoJmneZWe/05Y2aqSKj3YN2nLfYPJBQ87WEiY4BQCQ9hWGu9mPT1a1Q==} + engines: {node: '>= 18.0.0'} + hasBin: true + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: '>=5.0.0' + + svelte-eslint-parser@1.4.1: + resolution: {integrity: sha512-1eqkfQ93goAhjAXxZiu1SaKI9+0/sxp4JIWQwUpsz7ybehRE5L8dNuz7Iry7K22R47p5/+s9EM+38nHV2OlgXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0, pnpm: 10.24.0} + peerDependencies: + svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + svelte: + optional: true + + svelte@5.46.0: + resolution: {integrity: sha512-ZhLtvroYxUxr+HQJfMZEDRsGsmU46x12RvAv/zi9584f5KOX7bUrEbhPJ7cKFmUvZTJXi/CFZUYwDC6M1FigPw==} + engines: {node: '>=18'} + + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + 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'} + + typescript-eslint@8.50.0: + resolution: {integrity: sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici@7.14.0: + resolution: {integrity: sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==} + engines: {node: '>=20.18.1'} + + unenv@2.0.0-rc.24: + resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + + unified@10.1.2: + resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@4.1.0: + resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} + + unist-util-is@5.2.1: + resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + + unist-util-stringify-position@3.0.3: + resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@3.1.1: + resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} + + unist-util-visit-parents@5.1.3: + resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@2.0.3: + resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} + + unist-util-visit@4.1.1: + resolution: {integrity: sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vfile-location@4.1.0: + resolution: {integrity: sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==} + + vfile-message@2.0.4: + resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} + + vfile-message@3.1.4: + resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@5.3.7: + resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@6.4.1: + resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitefu@1.1.1: + resolution: {integrity: sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + vite: + optional: true + + vscode-oniguruma@1.7.0: + resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} + + vscode-textmate@6.0.0: + resolution: {integrity: sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + 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'} + + workerd@1.20251217.0: + resolution: {integrity: sha512-s3mHDSWwHTduyY8kpHOsl27ZJ4ziDBJlc18PfBvNMqNnhO7yBeemlxH7bo7yQyU1foJrIZ6IENHDDg0Z9N8zQA==} + engines: {node: '>=16'} + hasBin: true + + worktop@0.8.0-next.18: + resolution: {integrity: sha512-+TvsA6VAVoMC3XDKR5MoC/qlLqDixEfOBysDEKnPIPou/NvoPWCAuXHXMsswwlvmEuvX56lQjvELLyLuzTKvRw==} + engines: {node: '>=12'} + + wrangler@4.56.0: + resolution: {integrity: sha512-Nqi8duQeRbA+31QrD6QlWHW3IZVnuuRxMy7DEg46deUzywivmaRV/euBN5KKXDPtA24VyhYsK7I0tkb7P5DM2w==} + engines: {node: '>=20.0.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20251217.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + youch-core@0.3.3: + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} + + youch@4.1.0-beta.10: + resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} + + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + + zod@3.22.3: + resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@bitmachina/highlighter@1.0.0-alpha.7': + dependencies: + hast-util-to-string: 2.0.0 + parse-numeric-range: 1.3.0 + property-information: 6.2.0 + rehype-parse: 8.0.4 + shiki: 0.11.1 + unified: 10.1.2 + unist-util-visit: 4.1.1 + + '@cloudflare/kv-asset-handler@0.4.1': + dependencies: + mime: 3.0.0 + + '@cloudflare/unenv-preset@2.7.13(unenv@2.0.0-rc.24)(workerd@1.20251217.0)': + dependencies: + unenv: 2.0.0-rc.24 + optionalDependencies: + workerd: 1.20251217.0 + + '@cloudflare/workerd-darwin-64@1.20251217.0': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20251217.0': + optional: true + + '@cloudflare/workerd-linux-64@1.20251217.0': + optional: true + + '@cloudflare/workerd-linux-arm64@1.20251217.0': + optional: true + + '@cloudflare/workerd-windows-64@1.20251217.0': + optional: true + + '@cloudflare/workers-types@4.20251221.0': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@emnapi/runtime@1.7.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/aix-ppc64@0.27.0': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.27.0': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-arm@0.27.0': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/android-x64@0.27.0': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.27.0': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.27.0': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.27.0': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.27.0': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.27.0': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-arm@0.27.0': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.27.0': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.27.0': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.27.0': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.27.0': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.27.0': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.27.0': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/linux-x64@0.27.0': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.27.0': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.27.0': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.27.0': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.27.0': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.27.0': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.27.0': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.27.0': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.27.0': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@esbuild/win32-x64@0.27.0': + optional: true + + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2(jiti@1.21.7))': + dependencies: + eslint: 9.39.2(jiti@1.21.7) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.1': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.2 + 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.3': + dependencies: + ajv: 6.12.6 + 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.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.2': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.7.1 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@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.19.1 + + '@polka/url@1.0.0-next.29': {} + + '@poppinss/colors@4.1.6': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.6.5': + dependencies: + '@poppinss/colors': 4.1.6 + '@sindresorhus/is': 7.1.1 + supports-color: 10.2.2 + + '@poppinss/exception@1.2.3': {} + + '@rollup/rollup-android-arm-eabi@4.54.0': + optional: true + + '@rollup/rollup-android-arm64@4.54.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.54.0': + optional: true + + '@rollup/rollup-darwin-x64@4.54.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.54.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.54.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.54.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.54.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.54.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.54.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.54.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.54.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.54.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.54.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.54.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.54.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.54.0': + optional: true + + '@sindresorhus/is@7.1.1': {} + + '@speed-highlight/core@1.2.12': {} + + '@standard-schema/spec@1.1.0': {} + + '@sveltejs/acorn-typescript@1.0.8(acorn@8.15.0)': + dependencies: + acorn: 8.15.0 + + '@sveltejs/adapter-cloudflare@7.2.4(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)))(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)))(wrangler@4.56.0(@cloudflare/workers-types@4.20251221.0))': + dependencies: + '@cloudflare/workers-types': 4.20251221.0 + '@sveltejs/kit': 2.49.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)))(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)) + worktop: 0.8.0-next.18 + wrangler: 4.56.0(@cloudflare/workers-types@4.20251221.0) + + '@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)))(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7))': + dependencies: + '@standard-schema/spec': 1.1.0 + '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) + '@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)) + '@types/cookie': 0.6.0 + acorn: 8.15.0 + cookie: 0.6.0 + devalue: 5.6.1 + esm-env: 1.2.2 + kleur: 4.1.5 + magic-string: 0.30.21 + mrmime: 2.0.1 + sade: 1.8.1 + set-cookie-parser: 2.7.2 + sirv: 3.0.2 + svelte: 5.46.0 + vite: 6.4.1(jiti@1.21.7) + + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)))(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7))': + dependencies: + '@sveltejs/vite-plugin-svelte': 5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)) + debug: 4.4.3 + svelte: 5.46.0 + vite: 6.4.1(jiti@1.21.7) + transitivePeerDependencies: + - supports-color + + '@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.1(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)))(svelte@5.46.0)(vite@6.4.1(jiti@1.21.7)) + debug: 4.4.3 + deepmerge: 4.3.1 + kleur: 4.1.5 + magic-string: 0.30.21 + svelte: 5.46.0 + vite: 6.4.1(jiti@1.21.7) + vitefu: 1.1.1(vite@6.4.1(jiti@1.21.7)) + transitivePeerDependencies: + - supports-color + + '@tailwindcss/typography@0.5.19(tailwindcss@3.4.19)': + dependencies: + postcss-selector-parser: 6.0.10 + tailwindcss: 3.4.19 + + '@types/cookie@0.6.0': {} + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree@1.0.8': {} + + '@types/hast@2.3.10': + dependencies: + '@types/unist': 2.0.11 + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.21 + + '@types/lodash@4.17.21': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 2.0.11 + + '@types/ms@2.1.0': {} + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.50.0 + '@typescript-eslint/type-utils': 8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.50.0 + eslint: 9.39.2(jiti@1.21.7) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.50.0 + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.50.0 + debug: 4.4.3 + eslint: 9.39.2(jiti@1.21.7) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.50.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) + '@typescript-eslint/types': 8.50.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.50.0': + dependencies: + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/visitor-keys': 8.50.0 + + '@typescript-eslint/tsconfig-utils@8.50.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.2(jiti@1.21.7) + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.50.0': {} + + '@typescript-eslint/typescript-estree@8.50.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.50.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/visitor-keys': 8.50.0 + debug: 4.4.3 + minimatch: 9.0.5 + semver: 7.7.3 + tinyglobby: 0.2.15 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7)) + '@typescript-eslint/scope-manager': 8.50.0 + '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) + eslint: 9.39.2(jiti@1.21.7) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.50.0': + dependencies: + '@typescript-eslint/types': 8.50.0 + eslint-visitor-keys: 4.2.1 + + '@ungap/structured-clone@1.3.0': {} + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-walk@8.3.2: {} + + acorn@8.14.0: {} + + acorn@8.15.0: {} + + ajv@6.12.6: + 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 + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + autoprefixer@10.4.23(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + caniuse-lite: 1.0.30001761 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + + axobject-query@4.1.0: {} + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + baseline-browser-mapping@2.9.11: {} + + bcp-47-match@2.0.3: {} + + binary-extensions@2.3.0: {} + + blake3-wasm@2.1.5: {} + + boolbase@1.0.0: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.11 + caniuse-lite: 1.0.30001761 + electron-to-chromium: 1.5.267 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + callsites@3.1.0: {} + + camelcase-css@2.0.1: {} + + caniuse-lite@1.0.30001761: {} + + ccount@2.0.1: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + character-entities@2.0.2: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + clsx@2.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + comma-separated-tokens@2.0.3: {} + + commander@4.1.1: {} + + concat-map@0.0.1: {} + + cookie@0.6.0: {} + + cookie@1.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-selector-parser@3.3.0: {} + + cssesc@3.0.0: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.2.0: + dependencies: + character-entities: 2.0.2 + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + dequal@2.0.3: {} + + detect-libc@2.1.2: {} + + devalue@5.6.1: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + didyoumean@1.2.2: {} + + direction@2.0.1: {} + + dlv@1.1.3: {} + + electron-to-chromium@1.5.267: {} + + error-stack-parser-es@1.0.5: {} + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + esbuild@0.27.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.0 + '@esbuild/android-arm': 0.27.0 + '@esbuild/android-arm64': 0.27.0 + '@esbuild/android-x64': 0.27.0 + '@esbuild/darwin-arm64': 0.27.0 + '@esbuild/darwin-x64': 0.27.0 + '@esbuild/freebsd-arm64': 0.27.0 + '@esbuild/freebsd-x64': 0.27.0 + '@esbuild/linux-arm': 0.27.0 + '@esbuild/linux-arm64': 0.27.0 + '@esbuild/linux-ia32': 0.27.0 + '@esbuild/linux-loong64': 0.27.0 + '@esbuild/linux-mips64el': 0.27.0 + '@esbuild/linux-ppc64': 0.27.0 + '@esbuild/linux-riscv64': 0.27.0 + '@esbuild/linux-s390x': 0.27.0 + '@esbuild/linux-x64': 0.27.0 + '@esbuild/netbsd-arm64': 0.27.0 + '@esbuild/netbsd-x64': 0.27.0 + '@esbuild/openbsd-arm64': 0.27.0 + '@esbuild/openbsd-x64': 0.27.0 + '@esbuild/openharmony-arm64': 0.27.0 + '@esbuild/sunos-x64': 0.27.0 + '@esbuild/win32-arm64': 0.27.0 + '@esbuild/win32-ia32': 0.27.0 + '@esbuild/win32-x64': 0.27.0 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-plugin-svelte@3.13.1(eslint@9.39.2(jiti@1.21.7))(svelte@5.46.0): + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7)) + '@jridgewell/sourcemap-codec': 1.5.5 + eslint: 9.39.2(jiti@1.21.7) + esutils: 2.0.3 + globals: 16.5.0 + known-css-properties: 0.37.0 + postcss: 8.5.6 + postcss-load-config: 3.1.4(postcss@8.5.6) + postcss-safe-parser: 7.0.1(postcss@8.5.6) + semver: 7.7.3 + svelte-eslint-parser: 1.4.1(svelte@5.46.0) + optionalDependencies: + svelte: 5.46.0 + transitivePeerDependencies: + - ts-node + + 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@9.39.2(jiti@1.21.7): + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@1.21.7)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.3 + '@eslint/js': 9.39.2 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.12.6 + 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.6.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.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 1.21.7 + transitivePeerDependencies: + - supports-color + + esm-env@1.2.2: {} + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrap@2.2.1: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + exit-hook@2.2.1: {} + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + 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.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + fraction.js@5.3.4: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + github-slugger@2.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + + globals@14.0.0: {} + + globals@16.5.0: {} + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-from-parse5@7.1.2: + dependencies: + '@types/hast': 2.3.10 + '@types/unist': 2.0.11 + hastscript: 7.2.0 + property-information: 6.2.0 + vfile: 5.3.7 + vfile-location: 4.1.0 + web-namespaces: 2.0.1 + + hast-util-has-property@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-heading-rank@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-parse-selector@3.1.1: + dependencies: + '@types/hast': 2.3.10 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-select@6.0.4: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + bcp-47-match: 2.0.3 + comma-separated-tokens: 2.0.3 + css-selector-parser: 3.3.0 + devlop: 1.1.0 + direction: 2.0.1 + hast-util-has-property: 3.0.0 + hast-util-to-string: 3.0.1 + hast-util-whitespace: 3.0.0 + nth-check: 2.1.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + hast-util-to-string@2.0.0: + dependencies: + '@types/hast': 2.3.10 + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@7.2.0: + dependencies: + '@types/hast': 2.3.10 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 3.1.1 + property-information: 6.2.0 + space-separated-tokens: 2.0.2 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + is-arrayish@0.3.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-buffer@2.0.5: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-plain-obj@4.1.0: {} + + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + isexe@2.0.0: {} + + jiti@1.21.7: {} + + 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: {} + + jsonc-parser@3.3.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@4.1.5: {} + + known-css-properties@0.37.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@2.1.0: {} + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + locate-character@3.0.0: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.17.22: {} + + lodash.merge@4.6.2: {} + + longest-streak@3.1.0: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + markdown-table@3.0.4: {} + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdsvex@0.12.6(svelte@5.46.0): + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 2.0.11 + prism-svelte: 0.4.7 + prismjs: 1.30.0 + svelte: 5.46.0 + unist-util-visit: 2.0.3 + vfile-message: 2.0.4 + + merge2@1.4.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.2.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime@3.0.0: {} + + miniflare@4.20251217.0: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.14.0 + acorn-walk: 8.3.2 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + sharp: 0.33.5 + stoppable: 1.1.0 + undici: 7.14.0 + workerd: 1.20251217.0 + ws: 8.18.0 + youch: 4.1.0-beta.10 + zod: 3.22.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + mri@1.2.0: {} + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + node-releases@2.0.27: {} + + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + 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 + + 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 + + parse-numeric-range@1.3.0: {} + + parse5@6.0.1: {} + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-to-regexp@6.3.0: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pify@2.3.0: {} + + pirates@4.0.7: {} + + postcss-import@15.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.11 + + postcss-js@4.1.0(postcss@8.5.6): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.6 + + postcss-load-config@3.1.4(postcss@8.5.6): + dependencies: + lilconfig: 2.1.0 + yaml: 1.10.2 + optionalDependencies: + postcss: 8.5.6 + + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 1.21.7 + postcss: 8.5.6 + + postcss-nested@6.2.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + + postcss-safe-parser@7.0.1(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-scss@4.0.9(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + + postcss-selector-parser@6.0.10: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-plugin-svelte@3.4.1(prettier@3.7.4)(svelte@5.46.0): + dependencies: + prettier: 3.7.4 + svelte: 5.46.0 + + prettier@3.7.4: {} + + prism-svelte@0.4.7: {} + + prismjs@1.30.0: {} + + property-information@6.2.0: {} + + property-information@7.1.0: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + regexparam@3.0.0: {} + + rehype-autolink-headings@7.1.0: + dependencies: + '@types/hast': 3.0.4 + '@ungap/structured-clone': 1.3.0 + hast-util-heading-rank: 3.0.0 + hast-util-is-element: 3.0.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + + rehype-parse@8.0.4: + dependencies: + '@types/hast': 2.3.10 + hast-util-from-parse5: 7.1.2 + parse5: 6.0.1 + unified: 10.1.2 + + rehype-slug@6.0.0: + dependencies: + '@types/hast': 3.0.4 + github-slugger: 2.0.0 + hast-util-heading-rank: 3.0.0 + hast-util-to-string: 3.0.1 + unist-util-visit: 5.0.0 + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + resolve-from@4.0.0: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rollup@4.54.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.54.0 + '@rollup/rollup-android-arm64': 4.54.0 + '@rollup/rollup-darwin-arm64': 4.54.0 + '@rollup/rollup-darwin-x64': 4.54.0 + '@rollup/rollup-freebsd-arm64': 4.54.0 + '@rollup/rollup-freebsd-x64': 4.54.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.54.0 + '@rollup/rollup-linux-arm-musleabihf': 4.54.0 + '@rollup/rollup-linux-arm64-gnu': 4.54.0 + '@rollup/rollup-linux-arm64-musl': 4.54.0 + '@rollup/rollup-linux-loong64-gnu': 4.54.0 + '@rollup/rollup-linux-ppc64-gnu': 4.54.0 + '@rollup/rollup-linux-riscv64-gnu': 4.54.0 + '@rollup/rollup-linux-riscv64-musl': 4.54.0 + '@rollup/rollup-linux-s390x-gnu': 4.54.0 + '@rollup/rollup-linux-x64-gnu': 4.54.0 + '@rollup/rollup-linux-x64-musl': 4.54.0 + '@rollup/rollup-openharmony-arm64': 4.54.0 + '@rollup/rollup-win32-arm64-msvc': 4.54.0 + '@rollup/rollup-win32-ia32-msvc': 4.54.0 + '@rollup/rollup-win32-x64-gnu': 4.54.0 + '@rollup/rollup-win32-x64-msvc': 4.54.0 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + semver@7.7.3: {} + + set-cookie-parser@2.7.2: {} + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.1.2 + semver: 7.7.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shiki@0.11.1: + dependencies: + jsonc-parser: 3.3.1 + vscode-oniguruma: 1.7.0 + vscode-textmate: 6.0.0 + + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + + sirv@3.0.2: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + source-map-js@1.2.1: {} + + space-separated-tokens@2.0.2: {} + + stoppable@1.1.0: {} + + strip-json-comments@3.1.1: {} + + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + + supports-color@10.2.2: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svelte-check@4.3.5(picomatch@4.0.3)(svelte@5.46.0)(typescript@5.9.3): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + chokidar: 4.0.3 + fdir: 6.5.0(picomatch@4.0.3) + picocolors: 1.1.1 + sade: 1.8.1 + svelte: 5.46.0 + typescript: 5.9.3 + transitivePeerDependencies: + - picomatch + + svelte-eslint-parser@1.4.1(svelte@5.46.0): + dependencies: + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + postcss: 8.5.6 + postcss-scss: 4.0.9(postcss@8.5.6) + postcss-selector-parser: 7.1.1 + optionalDependencies: + svelte: 5.46.0 + + svelte@5.46.0: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) + '@types/estree': 1.0.8 + acorn: 8.15.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.6.1 + esm-env: 1.2.2 + esrap: 2.2.1 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + zimmerframe: 1.1.4 + + tailwindcss@3.4.19: + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-import: 15.1.0(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6) + postcss-nested: 6.2.0(postcss@8.5.6) + postcss-selector-parser: 6.1.2 + resolve: 1.22.11 + sucrase: 3.35.1 + transitivePeerDependencies: + - tsx + - yaml + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + totalist@3.0.1: {} + + trough@2.2.0: {} + + ts-api-utils@2.1.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-interface-checker@0.1.13: {} + + tslib@2.8.1: + optional: true + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3))(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/parser': 8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.0(eslint@9.39.2(jiti@1.21.7))(typescript@5.9.3) + eslint: 9.39.2(jiti@1.21.7) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + undici@7.14.0: {} + + unenv@2.0.0-rc.24: + dependencies: + pathe: 2.0.3 + + unified@10.1.2: + dependencies: + '@types/unist': 2.0.11 + bail: 2.0.2 + extend: 3.0.2 + is-buffer: 2.0.5 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 5.3.7 + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@4.1.0: {} + + unist-util-is@5.2.1: + dependencies: + '@types/unist': 2.0.11 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@2.0.3: + dependencies: + '@types/unist': 2.0.11 + + unist-util-stringify-position@3.0.3: + dependencies: + '@types/unist': 2.0.11 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@3.1.1: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 4.1.0 + + unist-util-visit-parents@5.1.3: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 5.2.1 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@2.0.3: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 4.1.0 + unist-util-visit-parents: 3.1.1 + + unist-util-visit@4.1.1: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 5.2.1 + unist-util-visit-parents: 5.1.3 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + vfile-location@4.1.0: + dependencies: + '@types/unist': 2.0.11 + vfile: 5.3.7 + + vfile-message@2.0.4: + dependencies: + '@types/unist': 2.0.11 + unist-util-stringify-position: 2.0.3 + + vfile-message@3.1.4: + dependencies: + '@types/unist': 2.0.11 + unist-util-stringify-position: 3.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@5.3.7: + dependencies: + '@types/unist': 2.0.11 + is-buffer: 2.0.5 + unist-util-stringify-position: 3.0.3 + vfile-message: 3.1.4 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vite@6.4.1(jiti@1.21.7): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.54.0 + tinyglobby: 0.2.15 + optionalDependencies: + fsevents: 2.3.3 + jiti: 1.21.7 + + vitefu@1.1.1(vite@6.4.1(jiti@1.21.7)): + optionalDependencies: + vite: 6.4.1(jiti@1.21.7) + + vscode-oniguruma@1.7.0: {} + + vscode-textmate@6.0.0: {} + + web-namespaces@2.0.1: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + workerd@1.20251217.0: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20251217.0 + '@cloudflare/workerd-darwin-arm64': 1.20251217.0 + '@cloudflare/workerd-linux-64': 1.20251217.0 + '@cloudflare/workerd-linux-arm64': 1.20251217.0 + '@cloudflare/workerd-windows-64': 1.20251217.0 + + worktop@0.8.0-next.18: + dependencies: + mrmime: 2.0.1 + regexparam: 3.0.0 + + wrangler@4.56.0(@cloudflare/workers-types@4.20251221.0): + dependencies: + '@cloudflare/kv-asset-handler': 0.4.1 + '@cloudflare/unenv-preset': 2.7.13(unenv@2.0.0-rc.24)(workerd@1.20251217.0) + blake3-wasm: 2.1.5 + esbuild: 0.27.0 + miniflare: 4.20251217.0 + path-to-regexp: 6.3.0 + unenv: 2.0.0-rc.24 + workerd: 1.20251217.0 + optionalDependencies: + '@cloudflare/workers-types': 4.20251221.0 + fsevents: 2.3.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ws@8.18.0: {} + + yaml@1.10.2: {} + + yocto-queue@0.1.0: {} + + youch-core@0.3.3: + dependencies: + '@poppinss/exception': 1.2.3 + error-stack-parser-es: 1.0.5 + + youch@4.1.0-beta.10: + dependencies: + '@poppinss/colors': 4.1.6 + '@poppinss/dumper': 0.6.5 + '@speed-highlight/core': 1.2.12 + cookie: 1.1.1 + youch-core: 0.3.3 + + zimmerframe@1.1.4: {} + + zod@3.22.3: {} + + zod@3.25.76: {} + + zwitch@2.0.4: {} diff --git a/apps/website/postcss.config.cjs b/postcss.config.cjs similarity index 100% rename from apps/website/postcss.config.cjs rename to postcss.config.cjs diff --git a/scripts/build/build-pkg.sh b/scripts/build/build-pkg.sh deleted file mode 100755 index 15b2494..0000000 --- a/scripts/build/build-pkg.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -# Usage: Build a package. -# The build pipeline is typically handled by `turbo`, though its handy to have a -# script for building locally, rather than from the monorepo root directory. - -# Note: To be run from inside a `packages/*/` directory. - -yarn clean:all -yarn build:tsc -yarn build:esm -yarn build:types diff --git a/scripts/build/build-types.sh b/scripts/build/build-types.sh deleted file mode 100755 index e14855a..0000000 --- a/scripts/build/build-types.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash - -args=() - -# Strip out `--local` flag in CI -if [ -z $CI ] || [ $CI = false ] ; then - # CI is either unset or false - args=$@ - if [[ ! " ${args[*]} " =~ " --local " ]] ; then - args+=("--local") - fi -elif [ $CI = true ] ; then - for arg in "$@" ; do - case "$arg" in - '--local') - true - ;; - *) - args+=($arg) - ;; - esac - done -fi - -echo "api-extractor run ${args[@]}" -../../node_modules/.bin/api-extractor run ${args[@]} diff --git a/scripts/build/esm.sh b/scripts/build/esm.sh deleted file mode 100755 index 60274f3..0000000 --- a/scripts/build/esm.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -echo "copying ./lib/**/*.js to ./dist/esm/" -mkdir -p dist/esm -rsync -a --prune-empty-dirs --include '*/' --include '*.js' --exclude '*' lib/ dist/esm diff --git a/scripts/build/lint.sh b/scripts/build/lint.sh deleted file mode 100755 index a8435b7..0000000 --- a/scripts/build/lint.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -args="--config=../../.eslintrc.cjs --ignore-path=../../.eslintignore --ext .js,.ts . $@" -echo "eslint $args" -../../node_modules/.bin/eslint $args diff --git a/scripts/build/test.js b/scripts/build/test.js deleted file mode 100644 index bcf4b66..0000000 --- a/scripts/build/test.js +++ /dev/null @@ -1,32 +0,0 @@ -import path from 'path'; -import * as url from 'url'; - -import { exec } from '../utils/exec.js'; - -// TODO update to use `vitest` - -const __dirname = url.fileURLToPath(new URL('.', import.meta.url)); - -// Jest needs to be run from the monorepo root directory. -const rootDir = path.resolve(__dirname, '../../'); - -const jestPath = path.resolve(__dirname, '../../node_modules/.bin/jest'); - -const args = process.argv.slice(2); - -// When in CI, Jest should only use 4 workers to avoid out of memory errors. -const maxWorkers = process.env.CI ? ['--maxWorkers=4'] : []; - -/** - * Jest CLI arguments - */ -const jestArgs = [...args, ...maxWorkers]; - -console.log(`jest ${jestArgs.join(' ')}`); - -exec(jestPath, jestArgs, { cwd: rootDir }) - .then(() => process.exit(0)) - .catch((err) => { - console.error(err); - process.exit(1); - }); diff --git a/scripts/build/worklets.sh b/scripts/build/worklets.sh deleted file mode 100755 index 790e6e5..0000000 --- a/scripts/build/worklets.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -out=./static/worklets - -[ -d $out ] && rm -rf $out -mkdir -p $out - -for f in ./src/worklets/*/ -do - - input="./src/worklets/$(basename $f)/index.ts" - output="./static/worklets/$(basename $f).js" - args="$input --config ./config/rollup.config.js --file $output --format iife" - echo "\nrollup $args" - ./node_modules/.bin/rollup $args -done diff --git a/scripts/rollup/cjs.js b/scripts/rollup/cjs.js deleted file mode 100644 index b22ca41..0000000 --- a/scripts/rollup/cjs.js +++ /dev/null @@ -1,5 +0,0 @@ -if (process.env.NODE_ENV === "production") { - module.exports = require(`./__BUNDLE__.production.js`); -} else { - module.exports = require(`./__BUNDLE__.development.js`); -} diff --git a/scripts/rollup/config.js b/scripts/rollup/config.js deleted file mode 100644 index ec4247a..0000000 --- a/scripts/rollup/config.js +++ /dev/null @@ -1,130 +0,0 @@ -import json from "@rollup/plugin-json"; -import resolve from "@rollup/plugin-node-resolve"; -import replace from "@rollup/plugin-replace"; -import sucrase from "@rollup/plugin-sucrase"; -import terser from "@rollup/plugin-terser"; -import filesize from "rollup-plugin-filesize"; - -import { getBundleBanner } from "./getBundleBanner.mjs"; - -const BUILD_MODES = ["development", "production"]; -const extensions = [".js", ".ts", ".json"]; - -function createRollupConfig({ mode, format, input, pkg, config }) { - if (!BUILD_MODES.includes(mode)) { - throw new Error(`The Rollup configuration ${JSON.stringify(mode)} mode is not supported.`); - } - - const bundles = []; - - if (format === "cjs") { - bundles.push({ - ...config, - input: "../../scripts/rollup/cjs.js", - output: { - file: `dist/cjs/${input}.js`, - format, - sourcemap: false, - ...config.output, - }, - plugins: [ - replace({ - preventAssignment: false, - delimiters: ["", ""], - values: { - __BUNDLE__: input, - }, - }), - json(), - resolve({ - extensions, - }), - sucrase({ - exclude: ["node_modules/**"], - transforms: ["typescript"], - }), - filesize({ - showMinifiedSize: false, - showGzippedSize: true, - }), - ...(config.plugins || []), - ].filter(Boolean), - }); - } - - bundles.push({ - ...config, - input: `src/${input}.ts`, - output: { - file: `dist/${format}/${input}.${mode}.js`, - format, - sourcemap: true, - name: pkg.name, - banner: getBundleBanner(pkg), - ...config.output, - }, - plugins: [ - replace({ - preventAssignment: false, - delimiters: ["", ""], - values: { - "process.env.NODE_ENV": JSON.stringify(mode), - "@dinerojs": "@dinero.js", - }, - }), - json(), - resolve({ - extensions, - }), - sucrase({ - exclude: ["node_modules/**"], - transforms: ["typescript"], - }), - mode === "production" && terser({ sourceMap: true }), - filesize({ - showMinifiedSize: false, - showGzippedSize: true, - }), - ...(config.plugins || []), - ].filter(Boolean), - }); - - return bundles; -} - -export function createRollupConfigs({ pkg, inputs = ["index"], config = {} }) { - return inputs - .map((input) => { - return [ - createRollupConfig({ - mode: "development", - format: "umd", - input, - pkg, - config, - }), - createRollupConfig({ - mode: "production", - format: "umd", - input, - pkg, - config, - }), - createRollupConfig({ - mode: "development", - format: "cjs", - input, - pkg, - config, - }), - createRollupConfig({ - mode: "production", - format: "cjs", - input, - pkg, - config, - }), - ]; - }) - .flat(2); -} diff --git a/scripts/rollup/getBundleBanner.mjs b/scripts/rollup/getBundleBanner.mjs deleted file mode 100644 index 7539f4d..0000000 --- a/scripts/rollup/getBundleBanner.mjs +++ /dev/null @@ -1,11 +0,0 @@ -import { execSync } from "child_process"; - -export function getBundleBanner(pkg) { - const lastCommitHash = execSync("git rev-parse --short HEAD").toString().trim(); - const version = process.env.SHIPJS - ? pkg.version - : `${pkg.version} (UNRELEASED ${lastCommitHash})`; - const authors = `© ${pkg.author.name} and contributors`; - - return `/*! ${pkg.name} ${version} | MIT License | ${authors} | ${pkg.homepage} */`; -} diff --git a/scripts/utils/exec.js b/scripts/utils/exec.js deleted file mode 100644 index a6f0039..0000000 --- a/scripts/utils/exec.js +++ /dev/null @@ -1,38 +0,0 @@ -import { spawn } from "node:child_process"; - -/** - * Async `exec`. - * - * Inspired by `remix-run` build scripts - * https://github.com/remix-run/remix/blob/534e1ec071f17654a4db8622e30d6ff70548ce26/scripts/build.mjs - * - * @param {string} command - Shell command to execute. - * @param {string[]} [args] - Command arguments. - * @param {import('node:child_process').SpawnOptions} options - Options to pass to `cross-spawn`. - */ -export function exec(command, args = [], options = {}) { - /** @type {(data: Error) => any} */ - const handleError = (data) => console.error(data.toString().trim()); - - return new Promise((resolve, reject) => { - const child = spawn(command, args, { - cwd: process.cwd(), - stdio: "inherit", - ...options, - }); - - const onExit = () => child.kill("SIGINT"); - - process.on("SIGINT", onExit); - process.on("SIGTERM", onExit); - - child.on("error", handleError); - child.on("close", (code) => { - if (code === 0) { - resolve(void 0); - } else { - reject(new Error(`${command} exited with code ${code}`)); - } - }); - }); -} diff --git a/apps/website/src/app.css b/src/app.css similarity index 89% rename from apps/website/src/app.css rename to src/app.css index 4bae6fa..83888ec 100644 --- a/apps/website/src/app.css +++ b/src/app.css @@ -73,9 +73,21 @@ pre[data-code-title]:before { background: rgb(39 39 42); font-size: 0.8125rem; font-weight: 600; - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, - "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", - "Segoe UI Symbol", "Noto Color Emoji"; + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + "Helvetica Neue", + Arial, + "Noto Sans", + sans-serif, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji"; line-height: 1.5rem; min-height: calc(3rem + 1px); content: attr(data-code-title); diff --git a/src/app.d.ts b/src/app.d.ts new file mode 100644 index 0000000..2428e5f --- /dev/null +++ b/src/app.d.ts @@ -0,0 +1,17 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +declare global { + namespace App { + // interface Locals {} + // interface PageData {} + // interface Error {} + interface Platform { + env: { + ENVIRONMENT: "production" | "staging"; + SITE_URL: string; + }; + } + } +} + +export {}; diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000..293f797 --- /dev/null +++ b/src/app.html @@ -0,0 +1,28 @@ + + + + + + + + %sveltekit.head% + + + +
%sveltekit.body%
+ + diff --git a/src/globals.d.ts b/src/globals.d.ts new file mode 100644 index 0000000..6932976 --- /dev/null +++ b/src/globals.d.ts @@ -0,0 +1,8 @@ +/// + +declare module "*.md" { + import type { Component } from "svelte"; + const component: Component; + export default component; + export const metadata: Record; +} diff --git a/src/hooks.server.ts b/src/hooks.server.ts new file mode 100644 index 0000000..3abe135 --- /dev/null +++ b/src/hooks.server.ts @@ -0,0 +1,17 @@ +import { building, dev } from "$app/environment"; +import type { Handle } from "@sveltejs/kit"; + +export const handle: Handle = async ({ event, resolve }) => { + const response = await resolve(event); + + // Add noindex headers for non-production environments + // platform.env is only available in Cloudflare runtime (not during dev/build/prerender) + if (!dev && !building) { + const environment = event.platform?.env?.ENVIRONMENT; + if (environment !== "production") { + response.headers.set("X-Robots-Tag", "noindex, nofollow"); + } + } + + return response; +}; diff --git a/apps/website/src/lib/components/article-template.svelte b/src/lib/components/article-template.svelte similarity index 100% rename from apps/website/src/lib/components/article-template.svelte rename to src/lib/components/article-template.svelte diff --git a/apps/website/src/lib/components/doc-info.svelte b/src/lib/components/doc-info.svelte similarity index 100% rename from apps/website/src/lib/components/doc-info.svelte rename to src/lib/components/doc-info.svelte diff --git a/apps/website/src/lib/components/footer.svelte b/src/lib/components/footer.svelte similarity index 100% rename from apps/website/src/lib/components/footer.svelte rename to src/lib/components/footer.svelte diff --git a/apps/website/src/lib/components/icons/speaker-wave.svelte b/src/lib/components/icons/speaker-wave.svelte similarity index 100% rename from apps/website/src/lib/components/icons/speaker-wave.svelte rename to src/lib/components/icons/speaker-wave.svelte diff --git a/apps/website/src/lib/components/image.svelte b/src/lib/components/image.svelte similarity index 100% rename from apps/website/src/lib/components/image.svelte rename to src/lib/components/image.svelte diff --git a/apps/website/src/lib/components/meta-card.svelte b/src/lib/components/meta-card.svelte similarity index 85% rename from apps/website/src/lib/components/meta-card.svelte rename to src/lib/components/meta-card.svelte index ebff510..dee78d9 100644 --- a/apps/website/src/lib/components/meta-card.svelte +++ b/src/lib/components/meta-card.svelte @@ -1,8 +1,10 @@ diff --git a/apps/website/src/lib/components/navigation-link.svelte b/src/lib/components/navigation-link.svelte similarity index 100% rename from apps/website/src/lib/components/navigation-link.svelte rename to src/lib/components/navigation-link.svelte diff --git a/apps/website/src/lib/components/navigation.svelte b/src/lib/components/navigation.svelte similarity index 100% rename from apps/website/src/lib/components/navigation.svelte rename to src/lib/components/navigation.svelte diff --git a/apps/website/src/lib/components/post-layout.svelte b/src/lib/components/post-layout.svelte similarity index 100% rename from apps/website/src/lib/components/post-layout.svelte rename to src/lib/components/post-layout.svelte diff --git a/src/lib/constants.ts b/src/lib/constants.ts new file mode 100644 index 0000000..b3f84bc --- /dev/null +++ b/src/lib/constants.ts @@ -0,0 +1,7 @@ +/** + * The root url of the site. + * + * Set via SITE_URL environment variable at build time. + * Must match the SITE_URL in wrangler.jsonc for each environment. + */ +export const SITE_URL = import.meta.env.SITE_URL ?? "http://localhost:5173"; diff --git a/apps/website/src/lib/data/posts.ts b/src/lib/data/posts.ts similarity index 99% rename from apps/website/src/lib/data/posts.ts rename to src/lib/data/posts.ts index 1a10fcf..f95d240 100644 --- a/apps/website/src/lib/data/posts.ts +++ b/src/lib/data/posts.ts @@ -38,7 +38,7 @@ export async function loadPosts(): Promise { } else { throw new Error(`error parsing slug from ${filePath}`); } - }) + }), )) as [string, MdsvexModule][]; return mdsvex diff --git a/apps/website/src/lib/data/projects.ts b/src/lib/data/projects.ts similarity index 99% rename from apps/website/src/lib/data/projects.ts rename to src/lib/data/projects.ts index 3c4b0b0..caa882d 100644 --- a/apps/website/src/lib/data/projects.ts +++ b/src/lib/data/projects.ts @@ -38,7 +38,7 @@ export async function loadProjects(): Promise { } else { throw new Error(`error parsing slug from ${filePath}`); } - }) + }), )) as [string, MdsvexModule][]; return mdsvex diff --git a/apps/website/src/lib/schema/metadata-schema.ts b/src/lib/schema/metadata-schema.ts similarity index 100% rename from apps/website/src/lib/schema/metadata-schema.ts rename to src/lib/schema/metadata-schema.ts diff --git a/apps/website/src/posts/learning-admin.md b/src/posts/learning-admin.md similarity index 100% rename from apps/website/src/posts/learning-admin.md rename to src/posts/learning-admin.md diff --git a/apps/website/src/posts/learning-git.md b/src/posts/learning-git.md similarity index 100% rename from apps/website/src/posts/learning-git.md rename to src/posts/learning-git.md diff --git a/apps/website/src/posts/learning-github-actions.md b/src/posts/learning-github-actions.md similarity index 100% rename from apps/website/src/posts/learning-github-actions.md rename to src/posts/learning-github-actions.md diff --git a/apps/website/src/posts/learning-github-collaboration.md b/src/posts/learning-github-collaboration.md similarity index 100% rename from apps/website/src/posts/learning-github-collaboration.md rename to src/posts/learning-github-collaboration.md diff --git a/apps/website/src/posts/learning-github-pages.md b/src/posts/learning-github-pages.md similarity index 100% rename from apps/website/src/posts/learning-github-pages.md rename to src/posts/learning-github-pages.md diff --git a/apps/website/src/posts/learning-javascript-testing.md b/src/posts/learning-javascript-testing.md similarity index 100% rename from apps/website/src/posts/learning-javascript-testing.md rename to src/posts/learning-javascript-testing.md diff --git a/apps/website/src/posts/learning-mdsvex.md b/src/posts/learning-mdsvex.md similarity index 100% rename from apps/website/src/posts/learning-mdsvex.md rename to src/posts/learning-mdsvex.md diff --git a/apps/website/src/posts/learning-postgres.md b/src/posts/learning-postgres.md similarity index 97% rename from apps/website/src/posts/learning-postgres.md rename to src/posts/learning-postgres.md index 6e1e82f..859faf3 100644 --- a/apps/website/src/posts/learning-postgres.md +++ b/src/posts/learning-postgres.md @@ -78,7 +78,7 @@ ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO {u #### Login in to `psql` as a different user to a specific database. -[psql: FATAL: database "" does not exist](https://stackoverflow.com/a/21827460/3586344) +[psql: FATAL: database "``" does not exist](https://stackoverflow.com/a/21827460/3586344) ```sh psql -U {user_name} {database_name} diff --git a/apps/website/src/posts/learning-prisma.md b/src/posts/learning-prisma.md similarity index 100% rename from apps/website/src/posts/learning-prisma.md rename to src/posts/learning-prisma.md diff --git a/apps/website/src/posts/learning-service-workers.md b/src/posts/learning-service-workers.md similarity index 100% rename from apps/website/src/posts/learning-service-workers.md rename to src/posts/learning-service-workers.md diff --git a/apps/website/src/posts/learning-sveltekit.md b/src/posts/learning-sveltekit.md similarity index 100% rename from apps/website/src/posts/learning-sveltekit.md rename to src/posts/learning-sveltekit.md diff --git a/apps/website/src/posts/learning-typescript-optional-generic-arguments.md b/src/posts/learning-typescript-optional-generic-arguments.md similarity index 92% rename from apps/website/src/posts/learning-typescript-optional-generic-arguments.md rename to src/posts/learning-typescript-optional-generic-arguments.md index 0dc7c08..482130e 100644 --- a/apps/website/src/posts/learning-typescript-optional-generic-arguments.md +++ b/src/posts/learning-typescript-optional-generic-arguments.md @@ -18,7 +18,10 @@ An optional `transformer` parameter had recently been added to the function. If ## The Problem ```ts title="Simplified example of the original type declaration" -function toDecimal(dineroObject: Dinero, transformer?: (value: string) => TOutput); +function toDecimal( + dineroObject: Dinero, + transformer?: (value: string) => TOutput, +); ``` The intent was for `TOutput` to be inferred by the transform function return type. The default argument to `transformer` is a function that returns a string representation of a decimal. @@ -65,9 +68,15 @@ Since `TOutput` can't be inferred by the return type of a default `transformer` ```ts title="Simplified example of the solution to add an optional generic argument" showLineNumbers function toDecimal(dineroObject: Dinero): string; -function toDecimal(dineroObject: Dinero, transformer: (value: string) => TOutput): TOutput; +function toDecimal( + dineroObject: Dinero, + transformer: (value: string) => TOutput, +): TOutput; -function toDecimal(dineroObject: Dinero, transformer?: (value: string) => TOutput) { +function toDecimal( + dineroObject: Dinero, + transformer?: (value: string) => TOutput, +) { const value: string = toDecimalFn(dineroObject); if (!transformer) return value; return transformer(value); diff --git a/apps/website/src/posts/learning-vscode.md b/src/posts/learning-vscode.md similarity index 100% rename from apps/website/src/posts/learning-vscode.md rename to src/posts/learning-vscode.md diff --git a/apps/website/src/posts/sveltekit-on-github-pages.md b/src/posts/sveltekit-on-github-pages.md similarity index 100% rename from apps/website/src/posts/sveltekit-on-github-pages.md rename to src/posts/sveltekit-on-github-pages.md diff --git a/apps/website/src/posts/teaching-web.md b/src/posts/teaching-web.md similarity index 100% rename from apps/website/src/posts/teaching-web.md rename to src/posts/teaching-web.md diff --git a/apps/website/src/projects/highlighter.md b/src/projects/highlighter.md similarity index 92% rename from apps/website/src/projects/highlighter.md rename to src/projects/highlighter.md index 7c964b3..143a42c 100644 --- a/apps/website/src/projects/highlighter.md +++ b/src/projects/highlighter.md @@ -94,9 +94,21 @@ pre[data-code-title]:before { background: rgb(39 39 42); font-size: 0.8125rem; font-weight: 600; - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, - "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", - "Segoe UI Symbol", "Noto Color Emoji"; + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + "Helvetica Neue", + Arial, + "Noto Sans", + sans-serif, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol", + "Noto Color Emoji"; line-height: 1.5rem; min-height: calc(3rem + 1px); content: attr(data-code-title); @@ -122,8 +134,8 @@ console.log("Show me more!") ```` ```js title="example rendered" showLineNumbers -console.log("Show me the numbers!") -console.log("Show me more!") +console.log("Show me the numbers!"); +console.log("Show me more!"); ``` ```js title="example of generated html" @@ -142,7 +154,7 @@ const example="The first line of this code block will start at 64" ```` ```js showLineNumbers{64} title="example rendered" -const example="The first line of this code block will start at 64" +const example = "The first line of this code block will start at 64"; ``` #### CSS Example @@ -189,7 +201,9 @@ export declare function parseMetadata(metastring: string | undefined): TMetadata * @returns Parsed metadata values object. * @public */ -export declare function parseMetadata(metastring: string | undefined): TMetadata; +export declare function parseMetadata( + metastring: string | undefined, +): TMetadata; ``` #### CSS Example @@ -214,8 +228,8 @@ export default { highlight: { highlighter: createHighlighter({ // ...rest of the Shiki options - lang: ["css", "html", "js", "ts", "sh"] - }), + lang: ["css", "html", "js", "ts", "sh"], + }), }, }; ``` diff --git a/apps/website/src/routes/+error.svelte b/src/routes/+error.svelte similarity index 100% rename from apps/website/src/routes/+error.svelte rename to src/routes/+error.svelte diff --git a/apps/website/src/routes/+layout.js b/src/routes/+layout.js similarity index 100% rename from apps/website/src/routes/+layout.js rename to src/routes/+layout.js diff --git a/apps/website/src/routes/+layout.svelte b/src/routes/+layout.svelte similarity index 100% rename from apps/website/src/routes/+layout.svelte rename to src/routes/+layout.svelte diff --git a/apps/website/src/routes/+page.js b/src/routes/+page.js similarity index 96% rename from apps/website/src/routes/+page.js rename to src/routes/+page.js index 717ebd3..c52f384 100644 --- a/apps/website/src/routes/+page.js +++ b/src/routes/+page.js @@ -21,8 +21,8 @@ export async function load() { }), (post) => { return post.publishedOn.getTime(); - } - ) + }, + ), ), projects: reverse( sortBy( @@ -36,8 +36,8 @@ export async function load() { }), (post) => { return post.publishedOn.getTime(); - } - ) + }, + ), ), }; } diff --git a/apps/website/src/routes/+page.svelte b/src/routes/+page.svelte similarity index 95% rename from apps/website/src/routes/+page.svelte rename to src/routes/+page.svelte index d2434ff..4bf50ee 100644 --- a/apps/website/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,6 +1,7 @@