├── tsconfig.dist.json ├── tsdown.config.ts ├── src ├── index.ts ├── spanToPlainText.ts ├── toPlainText.ts ├── sortMarksByOccurences.ts ├── asserters.ts ├── buildMarksTree.ts ├── types.ts └── nestLists.ts ├── tsconfig.json ├── typedoc.json ├── .editorconfig ├── .changeset └── config.json ├── .oxfmtrc.json ├── .github ├── workflows │ ├── format-if-needed.yml │ ├── release.yml │ ├── renovate.yml │ ├── deploy.yml │ └── main.yml └── renovate.json ├── .oxlintrc.json ├── .gitignore ├── test ├── spanToPlainText.test.ts ├── sortMarksByOccurences.test.ts ├── toPlainText.test.ts ├── buildMarksTree.test.ts ├── nestLists.test.ts ├── __snapshots__ │ ├── buildMarksTree.test.ts.snap │ └── nestLists.test.ts.snap └── asserters.test.ts ├── LICENSE ├── README.md ├── package.json ├── CHANGELOG.md └── pnpm-lock.yaml /tsconfig.dist.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["./tsconfig.json", "@sanity/tsconfig/isolated-declarations"], 3 | "include": ["./src"] 4 | } 5 | -------------------------------------------------------------------------------- /tsdown.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from '@sanity/tsdown-config' 2 | 3 | export default defineConfig({ 4 | tsconfig: './tsconfig.dist.json', 5 | }) 6 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './asserters' 2 | export * from './buildMarksTree' 3 | export * from './nestLists' 4 | export * from './sortMarksByOccurences' 5 | export * from './spanToPlainText' 6 | export * from './toPlainText' 7 | export * from './types' 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@sanity/tsconfig/strictest", 3 | "exclude": ["dist", "docs", "node_modules"], 4 | "compilerOptions": { 5 | "rootDir": ".", 6 | "outDir": "./dist", 7 | 8 | "noUncheckedIndexedAccess": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://typedoc.org/schema.json", 3 | "tsconfig": "./tsconfig.dist.json", 4 | "entryPoints": ["./src/index.ts"], 5 | "includeVersion": true, 6 | "disableSources": true, 7 | "sort": ["required-first", "source-order"] 8 | } 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ; editorconfig.org 2 | root = true 3 | charset= utf8 4 | 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | indent_style = space 10 | indent_size = 2 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config/schema.json", 3 | "changelog": ["@changesets/changelog-github", {"repo": "portabletext/toolkit"}], 4 | "commit": false, 5 | "access": "public", 6 | "baseBranch": "main", 7 | "updateInternalDependencies": "patch" 8 | } 9 | -------------------------------------------------------------------------------- /.oxfmtrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/oxfmt/configuration_schema.json", 3 | "printWidth": 100, 4 | "semi": false, 5 | "singleQuote": true, 6 | "bracketSpacing": false, 7 | "experimentalSortImports": {}, 8 | "ignorePatterns": ["dist/**", "docs/**", "pnpm-lock.yaml", ".changeset/*.md"] 9 | } 10 | -------------------------------------------------------------------------------- /.github/workflows/format-if-needed.yml: -------------------------------------------------------------------------------- 1 | name: Auto format 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | concurrency: ${{ github.workflow }}-${{ github.ref }} 8 | 9 | permissions: 10 | contents: read # for checkout 11 | 12 | jobs: 13 | if-needed: 14 | uses: portabletext/.github/.github/workflows/format.yml@main 15 | secrets: inherit 16 | -------------------------------------------------------------------------------- /.github/renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["github>sanity-io/renovate-config"], 4 | "packageRules": [ 5 | { 6 | "matchDepTypes": ["dependencies"], 7 | "matchPackageNames": ["@portabletext/types"], 8 | "rangeStrategy": "bump", 9 | "groupName": null, 10 | "groupSlug": null, 11 | "semanticCommitType": "fix" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: ${{ github.workflow }}-${{ github.ref }} 9 | 10 | permissions: 11 | contents: read # for checkout 12 | 13 | jobs: 14 | release: 15 | uses: portabletext/.github/.github/workflows/changesets.yml@main 16 | permissions: 17 | contents: read # for checkout 18 | id-token: write # to enable use of OIDC for npm provenance 19 | secrets: inherit 20 | -------------------------------------------------------------------------------- /.github/workflows/renovate.yml: -------------------------------------------------------------------------------- 1 | name: Add changeset to Renovate updates 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened, synchronize] 6 | 7 | concurrency: ${{ github.workflow }}-${{ github.ref }} 8 | 9 | permissions: 10 | contents: read # for checkout 11 | 12 | jobs: 13 | call: 14 | uses: portabletext/.github/.github/workflows/changesets-from-conventional-commits.yml@main 15 | if: github.event.pull_request.user.login == 'renovate[bot]' 16 | secrets: inherit 17 | -------------------------------------------------------------------------------- /.oxlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/oxlint/configuration_schema.json", 3 | "ignorePatterns": ["dist/**", "coverage/**", "docs/**", ".nyc_output/**"], 4 | "categories": { 5 | "correctness": "error", 6 | "perf": "error", 7 | "suspicious": "warn" 8 | }, 9 | "rules": { 10 | "no-console": "error", 11 | "no-array-sort": "off", 12 | // @TODO these rules should be enabled, and the violations fixed 13 | "no-unsafe-type-assertion": "off" 14 | }, 15 | "overrides": [ 16 | { 17 | "files": ["test/**"], 18 | "rules": { 19 | "no-console": "off", 20 | "no-unsafe-type-assertion": "off" 21 | } 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | # macOS finder cache file 40 | .DS_Store 41 | 42 | # VS Code settings 43 | .vscode 44 | 45 | # Cache 46 | .cache 47 | 48 | # Compiled Portable Text toolkit + docs 49 | /dist 50 | /docs 51 | -------------------------------------------------------------------------------- /src/spanToPlainText.ts: -------------------------------------------------------------------------------- 1 | import type {ToolkitNestedPortableTextSpan} from './types' 2 | 3 | import {isPortableTextToolkitSpan, isPortableTextToolkitTextNode} from './asserters' 4 | 5 | /** 6 | * Returns the plain-text representation of a 7 | * {@link ToolkitNestedPortableTextSpan | toolkit-specific Portable Text span}. 8 | * 9 | * Useful if you have a subset of nested nodes and want the text from just those, 10 | * instead of for the entire Portable Text block. 11 | * 12 | * @param span - Span node to get text from (Portable Text toolkit specific type) 13 | * @returns The plain-text version of the span 14 | */ 15 | export function spanToPlainText(span: ToolkitNestedPortableTextSpan): string { 16 | let text = '' 17 | span.children.forEach((current) => { 18 | if (isPortableTextToolkitTextNode(current)) { 19 | text += current.text 20 | } else if (isPortableTextToolkitSpan(current)) { 21 | text += spanToPlainText(current) 22 | } 23 | }) 24 | return text 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to GitHub Pages 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | concurrency: ${{ github.workflow }}-${{ github.ref }} 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | deploy: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/create-github-app-token@v2 17 | id: generate-token 18 | with: 19 | app-id: ${{ secrets.ECOSCRIPT_APP_ID }} 20 | private-key: ${{ secrets.ECOSCRIPT_APP_PRIVATE_KEY }} 21 | - uses: actions/checkout@v6 22 | - uses: pnpm/action-setup@v4 23 | - uses: actions/setup-node@v6 24 | with: 25 | cache: pnpm 26 | node-version: lts/* 27 | - run: pnpm install 28 | - run: pnpm build 29 | - run: pnpm docs:build 30 | - uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4 31 | with: 32 | github_token: ${{ steps.generate-token.outputs.token }} 33 | publish_dir: ./docs 34 | -------------------------------------------------------------------------------- /test/spanToPlainText.test.ts: -------------------------------------------------------------------------------- 1 | import {spanToPlainText} from '@portabletext/toolkit' 2 | import {expect, test} from 'vitest' 3 | 4 | test('spanToPlainText: converts single-span correctly', () => { 5 | expect( 6 | spanToPlainText({ 7 | _type: '@span', 8 | _key: 'a', 9 | children: [{_type: '@text', text: 'Just a plain text thing'}], 10 | markType: 'em', 11 | }), 12 | ).toEqual('Just a plain text thing') 13 | }) 14 | 15 | test('spanToPlainText: converts nested spans correctly', () => { 16 | expect( 17 | spanToPlainText({ 18 | _type: '@span', 19 | children: [ 20 | {_type: '@text', text: 'Just a '}, 21 | { 22 | _type: '@span', 23 | markType: 'strong', 24 | children: [ 25 | {_type: '@text', text: 'very'}, 26 | {_type: '@span', markType: 'code', children: [{_type: '@text', text: ' nested'}]}, 27 | {_type: '@text', text: ' span'}, 28 | ], 29 | }, 30 | {_type: '@text', text: ' of marks.'}, 31 | ], 32 | markType: 'em', 33 | }), 34 | ).toEqual('Just a very nested span of marks.') 35 | }) 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Sanity.io 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @portabletext/toolkit 2 | 3 | [![npm version](https://img.shields.io/npm/v/@portabletext/toolkit.svg?style=flat-square)](https://www.npmjs.com/package/@portabletext/toolkit)[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@portabletext/toolkit?style=flat-square)](https://bundlephobia.com/result?p=@portabletext/toolkit)[![Build Status](https://img.shields.io/github/actions/workflow/status/portabletext/toolkit/main.yml?branch=main&style=flat-square)](https://github.com/portabletext/toolkit/actions?query=workflow%3Atest) 4 | 5 | Javascript toolkit of handy utility functions for dealing with Portable Text. 6 | 7 | Particularly useful for building rendering libraries for Portable Text that outputs HTML. 8 | 9 | ## Installation 10 | 11 | ``` 12 | npm install --save @portabletext/toolkit 13 | ``` 14 | 15 | ## Documentation 16 | 17 | See [https://portabletext.github.io/toolkit/](https://portabletext.github.io/toolkit/) 18 | 19 | ## Usage 20 | 21 | ```ts 22 | import {toPlainText} from '@portabletext/toolkit' 23 | 24 | console.log(toPlainText(myPortableTextBlocks)) 25 | ``` 26 | 27 | ## License 28 | 29 | MIT © [Sanity.io](https://www.sanity.io/) 30 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | merge_group: 5 | push: 6 | branches: 7 | - main 8 | pull_request: 9 | branches: 10 | - main 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 14 | cancel-in-progress: true 15 | 16 | permissions: 17 | contents: read # for checkout 18 | 19 | jobs: 20 | build: 21 | runs-on: ubuntu-latest 22 | name: Lint & Build 23 | steps: 24 | - uses: actions/checkout@v6 25 | - uses: pnpm/action-setup@v4 26 | - uses: actions/setup-node@v6 27 | with: 28 | cache: pnpm 29 | node-version: lts/* 30 | - run: pnpm install 31 | - run: pnpm lint -f github 32 | - run: pnpm build 33 | 34 | test: 35 | runs-on: ${{ matrix.platform }} 36 | name: Node.js ${{ matrix.node-version }} / ${{ matrix.platform }} 37 | strategy: 38 | fail-fast: false 39 | matrix: 40 | platform: [macos-latest, ubuntu-latest, windows-latest] 41 | node-version: [lts/*] 42 | include: 43 | - platform: ubuntu-latest 44 | node-version: current 45 | steps: 46 | - uses: actions/checkout@v6 47 | - uses: pnpm/action-setup@v4 48 | - uses: actions/setup-node@v6 49 | with: 50 | cache: pnpm 51 | node-version: ${{ matrix.node-version }} 52 | - run: pnpm install 53 | - run: pnpm test 54 | -------------------------------------------------------------------------------- /src/toPlainText.ts: -------------------------------------------------------------------------------- 1 | import type {ArbitraryTypedObject, PortableTextBlock} from '@portabletext/types' 2 | 3 | import {isPortableTextBlock, isPortableTextSpan} from './asserters' 4 | 5 | const leadingSpace = /^\s/ 6 | const trailingSpace = /\s$/ 7 | 8 | /** 9 | * Takes a Portable Text block (or an array of them) and returns the text value 10 | * of all the Portable Text span nodes. Adds whitespace when encountering inline, 11 | * non-span nodes to ensure text flow is optimal. 12 | * 13 | * Note that this only accounts for regular Portable Text blocks - any text inside 14 | * custom content types are not included in the output. 15 | * 16 | * @param block - Single block or an array of blocks to extract text from 17 | * @returns The plain-text content of the blocks 18 | */ 19 | export function toPlainText( 20 | block: PortableTextBlock | ArbitraryTypedObject[] | PortableTextBlock[], 21 | ): string { 22 | const blocks = Array.isArray(block) ? block : [block] 23 | let text = '' 24 | 25 | blocks.forEach((current, index) => { 26 | if (!isPortableTextBlock(current)) { 27 | return 28 | } 29 | 30 | let pad = false 31 | current.children.forEach((span) => { 32 | if (isPortableTextSpan(span)) { 33 | // If the previous element was a non-span, and we have no natural whitespace 34 | // between the previous and the next span, insert it to give the spans some 35 | // room to breathe. However, don't do so if this is the first span. 36 | text += pad && text && !trailingSpace.test(text) && !leadingSpace.test(span.text) ? ' ' : '' 37 | text += span.text 38 | pad = false 39 | } else { 40 | pad = true 41 | } 42 | }) 43 | 44 | if (index !== blocks.length - 1) { 45 | text += '\n\n' 46 | } 47 | }) 48 | 49 | return text 50 | } 51 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@portabletext/toolkit", 3 | "version": "5.0.0", 4 | "description": "Toolkit of handy utility functions for dealing with Portable Text", 5 | "keywords": [ 6 | "cms", 7 | "content", 8 | "headless", 9 | "portable-text-toolkit", 10 | "realtime", 11 | "sanity" 12 | ], 13 | "homepage": "https://github.com/portabletext/toolkit#readme", 14 | "bugs": { 15 | "url": "https://github.com/portabletext/toolkit/issues" 16 | }, 17 | "repository": { 18 | "type": "git", 19 | "url": "git+ssh://git@github.com/portabletext/toolkit.git" 20 | }, 21 | "author": "Sanity.io ", 22 | "license": "MIT", 23 | "sideEffects": false, 24 | "type": "module", 25 | "main": "./dist/index.js", 26 | "exports": { 27 | ".": "./src/index.ts", 28 | "./package.json": "./package.json" 29 | }, 30 | "module": "./dist/index.js", 31 | "types": "./dist/index.d.ts", 32 | "files": [ 33 | "dist" 34 | ], 35 | "scripts": { 36 | "build": "tsdown", 37 | "coverage": "vitest run --coverage", 38 | "docs:build": "typedoc", 39 | "format": "oxfmt .", 40 | "lint": "oxlint --type-aware --type-check --deny-warnings --report-unused-disable-directives", 41 | "prepublishOnly": "pnpm build", 42 | "release": "changeset publish", 43 | "test": "vitest" 44 | }, 45 | "dependencies": { 46 | "@portabletext/types": "^4.0.0" 47 | }, 48 | "devDependencies": { 49 | "@changesets/changelog-github": "^0.5.2", 50 | "@changesets/cli": "^2.29.8", 51 | "@sanity/tsconfig": "^2.1.0", 52 | "@sanity/tsdown-config": "^0.4.2", 53 | "@types/node": "^24.10.4", 54 | "@vitest/coverage-v8": "^4.0.15", 55 | "oxfmt": "^0.18.0", 56 | "oxlint": "^1.33.0", 57 | "oxlint-tsgolint": "^0.9.1", 58 | "tsdown": "^0.17.2", 59 | "typedoc": "^0.28.15", 60 | "typescript": "5.9.3", 61 | "vitest": "^4.0.15" 62 | }, 63 | "packageManager": "pnpm@10.26.0", 64 | "engines": { 65 | "node": ">=20.19 <22 || >=22.12" 66 | }, 67 | "publishConfig": { 68 | "exports": { 69 | ".": "./dist/index.js", 70 | "./package.json": "./package.json" 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /test/sortMarksByOccurences.test.ts: -------------------------------------------------------------------------------- 1 | import type {PortableTextBlock} from '@portabletext/types' 2 | 3 | import {sortMarksByOccurences} from '@portabletext/toolkit' 4 | import {expect, test} from 'vitest' 5 | 6 | test('sortMarksByOccurences: sorts correctly', () => { 7 | const block: PortableTextBlock = { 8 | _type: 'block', 9 | children: [ 10 | {_type: 'span', text: 'This block '}, 11 | {_type: 'span', text: '', marks: []}, 12 | {_type: 'span', text: 'contains', marks: ['strong']}, 13 | {_type: 'span', text: 'a link', marks: ['s0m3l1nk', 'strong']}, 14 | {_type: 'span', text: ' and some bolded text', marks: ['strong']}, 15 | ], 16 | } 17 | 18 | expect(block.children.map(sortMarksByOccurences)).toEqual([ 19 | [], 20 | [], 21 | ['strong'], 22 | ['strong', 's0m3l1nk'], 23 | ['strong'], 24 | ]) 25 | }) 26 | 27 | test('sortMarksByOccurences: sorts correctly on tied decorator usage', () => { 28 | const block: PortableTextBlock = { 29 | _type: 'block', 30 | children: [ 31 | {_type: 'span', text: 'Some ', marks: ['em', 'strong']}, 32 | {_type: 'span', text: 'marks ', marks: ['strong', 'em']}, 33 | {_type: 'span', text: 'might be tied.', marks: []}, 34 | ], 35 | } 36 | 37 | expect(block.children.map(sortMarksByOccurences)).toEqual([ 38 | ['strong', 'em'], 39 | ['strong', 'em'], 40 | [], 41 | ]) 42 | }) 43 | 44 | test('sortMarksByOccurences: sorts correctly on tied decorator usage with annotations', () => { 45 | const block: PortableTextBlock = { 46 | _type: 'block', 47 | children: [ 48 | {_type: 'span', text: 'Some ', marks: ['em', 'a', 'strong', 'b']}, 49 | {_type: 'span', text: 'marks ', marks: ['b', 'strong', 'em', 'a']}, 50 | {_type: 'span', text: 'might be tied.', marks: []}, 51 | ], 52 | } 53 | 54 | expect(block.children.map(sortMarksByOccurences)).toEqual([ 55 | ['a', 'b', 'strong', 'em'], 56 | ['a', 'b', 'strong', 'em'], 57 | [], 58 | ]) 59 | }) 60 | 61 | test('sortMarksByOccurences: returns empty array on invalid marks', () => { 62 | const block: PortableTextBlock = { 63 | _type: 'block', 64 | children: [ 65 | {_type: 'span', text: 'Some ', marks: ['em', 'a', undefined, '', 'b', true]}, 66 | {_type: 'span', text: 'marks ', marks: ['b', '', 'em', 'a', false]}, 67 | {_type: 'span', text: 'might be tied.', marks: [null]}, 68 | ], 69 | } 70 | 71 | expect(block.children.map(sortMarksByOccurences)).toEqual([[], [], []]) 72 | }) 73 | -------------------------------------------------------------------------------- /src/sortMarksByOccurences.ts: -------------------------------------------------------------------------------- 1 | import type {PortableTextSpan, TypedObject} from '@portabletext/types' 2 | 3 | import {isPortableTextSpan} from './asserters' 4 | 5 | const knownDecorators = ['strong', 'em', 'code', 'underline', 'strike-through'] 6 | 7 | /** 8 | * Figures out the optimal order of marks, in order to minimize the amount of 9 | * nesting/repeated elements in environments such as HTML. For instance, a naive 10 | * implementation might render something like: 11 | * 12 | * ```html 13 | * This block contains 14 | * a link 15 | * and some bolded text 16 | * ``` 17 | * 18 | * ...whereas an optimal order would be: 19 | * 20 | * ```html 21 | * 22 | * This block contains a link and some bolded text 23 | * 24 | * ``` 25 | * 26 | * This is particularly necessary for cases like links, where you don't want multiple 27 | * individual links for different segments of the link text, even if parts of it are 28 | * bolded/italicized. 29 | * 30 | * This function is meant to be used like: `block.children.map(sortMarksByOccurences)`, 31 | * and is used internally in {@link buildMarksTree | `buildMarksTree()`}. 32 | * 33 | * The marks are sorted in the following order: 34 | * 35 | * 1. Marks that are shared amongst the most adjacent siblings 36 | * 2. Non-default marks (links, custom metadata) 37 | * 3. Decorators (bold, emphasis, code etc), in a predefined, preferred order 38 | * 39 | * @param span - The current span to sort 40 | * @param index - The index of the current span within the block 41 | * @param blockChildren - All children of the block being sorted 42 | * @returns Array of decorators and annotations, sorted by "most adjacent siblings" 43 | */ 44 | export function sortMarksByOccurences( 45 | span: PortableTextSpan | TypedObject, 46 | index: number, 47 | blockChildren: (PortableTextSpan | TypedObject)[], 48 | ): string[] { 49 | if (!isPortableTextSpan(span) || !span.marks) { 50 | return [] 51 | } 52 | 53 | if (!span.marks.length) { 54 | return [] 55 | } 56 | 57 | // Slicing because we'll be sorting with `sort()`, which mutates 58 | const marks = span.marks.slice() 59 | const occurences: Record = {} 60 | marks.forEach((mark) => { 61 | occurences[mark] = 1 62 | 63 | for (let siblingIndex = index + 1; siblingIndex < blockChildren.length; siblingIndex++) { 64 | const sibling = blockChildren[siblingIndex] 65 | 66 | if ( 67 | sibling && 68 | isPortableTextSpan(sibling) && 69 | Array.isArray(sibling.marks) && 70 | sibling.marks.indexOf(mark) !== -1 71 | ) { 72 | occurences[mark]++ 73 | } else { 74 | break 75 | } 76 | } 77 | }) 78 | 79 | return marks.sort((markA, markB) => sortMarks(occurences, markA, markB)) 80 | } 81 | 82 | function sortMarks>( 83 | occurences: T, 84 | markA: U, 85 | markB: U, 86 | ): number { 87 | const aOccurences = occurences[markA] 88 | const bOccurences = occurences[markB] 89 | 90 | if (aOccurences !== bOccurences) { 91 | return bOccurences - aOccurences 92 | } 93 | 94 | const aKnownPos = knownDecorators.indexOf(markA) 95 | const bKnownPos = knownDecorators.indexOf(markB) 96 | 97 | // Sort known decorators last 98 | if (aKnownPos !== bKnownPos) { 99 | return aKnownPos - bKnownPos 100 | } 101 | 102 | // Sort other marks simply by key 103 | return markA.localeCompare(markB) 104 | } 105 | -------------------------------------------------------------------------------- /src/asserters.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ArbitraryTypedObject, 3 | PortableTextBlock, 4 | PortableTextListItemBlock, 5 | PortableTextSpan, 6 | TypedObject, 7 | } from '@portabletext/types' 8 | 9 | import type {ToolkitNestedPortableTextSpan, ToolkitPortableTextList, ToolkitTextNode} from './types' 10 | 11 | /** 12 | * Strict check to determine if node is a correctly formatted Portable Text span. 13 | * 14 | * @param node - Node to check 15 | * @returns True if valid Portable Text span, otherwise false 16 | */ 17 | export function isPortableTextSpan( 18 | node: ArbitraryTypedObject | PortableTextSpan, 19 | ): node is PortableTextSpan { 20 | return ( 21 | node._type === 'span' && 22 | 'text' in node && 23 | typeof node.text === 'string' && 24 | (typeof node.marks === 'undefined' || 25 | (Array.isArray(node.marks) && node.marks.every((mark) => typeof mark === 'string'))) 26 | ) 27 | } 28 | 29 | /** 30 | * Strict check to determine if node is a correctly formatted Portable Text block. 31 | * 32 | * @param node - Node to check 33 | * @returns True if valid Portable Text block, otherwise false 34 | */ 35 | export function isPortableTextBlock( 36 | node: PortableTextBlock | TypedObject, 37 | ): node is PortableTextBlock { 38 | return ( 39 | // A block doesn't _have_ to be named 'block' - to differentiate between 40 | // allowed child types and marks, one might name them differently 41 | typeof node._type === 'string' && 42 | // Toolkit-types like nested spans are @-prefixed 43 | node._type[0] !== '@' && 44 | // `markDefs` isn't _required_ per say, but if it's there, it needs to be an array 45 | (!('markDefs' in node) || 46 | !node.markDefs || 47 | (Array.isArray(node.markDefs) && 48 | // Every mark definition needs to have an `_key` to be mappable in child spans 49 | node.markDefs.every((def) => typeof def._key === 'string'))) && 50 | // `children` is required and needs to be an array 51 | 'children' in node && 52 | Array.isArray(node.children) && 53 | // All children are objects with `_type` (usually spans, but can contain other stuff) 54 | node.children.every((child) => typeof child === 'object' && '_type' in child) 55 | ) 56 | } 57 | 58 | /** 59 | * Strict check to determine if node is a correctly formatted portable list item block. 60 | * 61 | * @param block - Block to check 62 | * @returns True if valid Portable Text list item block, otherwise false 63 | */ 64 | export function isPortableTextListItemBlock( 65 | block: PortableTextBlock | TypedObject, 66 | ): block is PortableTextListItemBlock { 67 | return ( 68 | isPortableTextBlock(block) && 69 | 'listItem' in block && 70 | typeof block.listItem === 'string' && 71 | (typeof block.level === 'undefined' || typeof block.level === 'number') 72 | ) 73 | } 74 | 75 | /** 76 | * Loose check to determine if block is a toolkit list node. 77 | * Only checks `_type`, assumes correct structure. 78 | * 79 | * @param block - Block to check 80 | * @returns True if toolkit list, otherwise false 81 | */ 82 | export function isPortableTextToolkitList( 83 | block: TypedObject | ToolkitPortableTextList, 84 | ): block is ToolkitPortableTextList { 85 | return block._type === '@list' 86 | } 87 | 88 | /** 89 | * Loose check to determine if span is a toolkit span node. 90 | * Only checks `_type`, assumes correct structure. 91 | * 92 | * @param span - Span to check 93 | * @returns True if toolkit span, otherwise false 94 | */ 95 | export function isPortableTextToolkitSpan( 96 | span: TypedObject | ToolkitNestedPortableTextSpan, 97 | ): span is ToolkitNestedPortableTextSpan { 98 | return span._type === '@span' 99 | } 100 | 101 | /** 102 | * Loose check to determine if node is a toolkit text node. 103 | * Only checks `_type`, assumes correct structure. 104 | * 105 | * @param node - Node to check 106 | * @returns True if toolkit text node, otherwise false 107 | */ 108 | export function isPortableTextToolkitTextNode( 109 | node: TypedObject | ToolkitTextNode, 110 | ): node is ToolkitTextNode { 111 | return node._type === '@text' 112 | } 113 | -------------------------------------------------------------------------------- /src/buildMarksTree.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ArbitraryTypedObject, 3 | PortableTextBlock, 4 | PortableTextMarkDefinition, 5 | } from '@portabletext/types' 6 | 7 | import type {ToolkitNestedPortableTextSpan, ToolkitTextNode} from './types' 8 | 9 | import {isPortableTextSpan} from './asserters' 10 | import {sortMarksByOccurences} from './sortMarksByOccurences' 11 | 12 | /** 13 | * Takes a Portable Text block and returns a nested tree of nodes optimized for rendering 14 | * in HTML-like environments where you want marks/annotations to be nested inside of eachother. 15 | * For instance, a naive span-by-span rendering might yield: 16 | * 17 | * ```html 18 | * This block contains 19 | * a link 20 | * and some bolded and 21 | * italicized text 22 | * ``` 23 | * 24 | * ...whereas an optimal order would be: 25 | * 26 | * ```html 27 | * 28 | * This block contains a link 29 | * and some bolded and italicized text 30 | * 31 | * ``` 32 | * 33 | * Note that since "native" Portable Text spans cannot be nested, 34 | * this function returns an array of "toolkit specific" types: 35 | * {@link ToolkitTextNode | `@text`} and {@link ToolkitNestedPortableTextSpan | `@span` }. 36 | * 37 | * The toolkit-specific type can hold both types, as well as any arbitrary inline objects, 38 | * creating an actual tree. 39 | * 40 | * @param block - The Portable Text block to create a tree of nodes from 41 | * @returns Array of (potentially) nested spans, text nodes and/or arbitrary inline objects 42 | */ 43 | export function buildMarksTree( 44 | block: PortableTextBlock, 45 | ): (ToolkitNestedPortableTextSpan | ToolkitTextNode | ArbitraryTypedObject)[] { 46 | const {children} = block 47 | const markDefs = block.markDefs ?? [] 48 | if (!children || !children.length) { 49 | return [] 50 | } 51 | 52 | const sortedMarks = children.map(sortMarksByOccurences) 53 | 54 | const rootNode: ToolkitNestedPortableTextSpan = { 55 | _type: '@span', 56 | children: [], 57 | markType: '', 58 | } 59 | 60 | let nodeStack: ToolkitNestedPortableTextSpan[] = [rootNode] 61 | 62 | for (let i = 0; i < children.length; i++) { 63 | const span = children[i] 64 | if (!span) { 65 | continue 66 | } 67 | 68 | const marksNeeded = sortedMarks[i] || [] 69 | let pos = 1 70 | 71 | // Start at position one. Root is always plain and should never be removed 72 | if (nodeStack.length > 1) { 73 | for (pos; pos < nodeStack.length; pos++) { 74 | const mark = nodeStack[pos]?.markKey || '' 75 | const index = marksNeeded.indexOf(mark) 76 | 77 | if (index === -1) { 78 | break 79 | } 80 | 81 | marksNeeded.splice(index, 1) 82 | } 83 | } 84 | 85 | // Keep from beginning to first miss 86 | nodeStack = nodeStack.slice(0, pos) 87 | 88 | // Add needed nodes 89 | let currentNode = nodeStack[nodeStack.length - 1] 90 | if (!currentNode) { 91 | continue 92 | } 93 | 94 | for (const markKey of marksNeeded) { 95 | const markDef = markDefs?.find((def) => def._key === markKey) 96 | const markType = markDef ? markDef._type : markKey 97 | const node: ToolkitNestedPortableTextSpan = { 98 | _type: '@span', 99 | _key: span._key, 100 | children: [], 101 | markDef, 102 | markType, 103 | markKey, 104 | } 105 | 106 | currentNode.children.push(node) 107 | nodeStack.push(node) 108 | currentNode = node 109 | } 110 | 111 | // Split at newlines to make individual line chunks, but keep newline 112 | // characters as individual elements in the array. We use these characters 113 | // in the span serializer to trigger hard-break rendering 114 | if (isPortableTextSpan(span)) { 115 | const lines = span.text.split('\n') 116 | for (let line = lines.length; line-- > 1; ) { 117 | lines.splice(line, 0, '\n') 118 | } 119 | 120 | currentNode.children = currentNode.children.concat( 121 | lines.map((text) => ({_type: '@text', text})), 122 | ) 123 | } else { 124 | // This is some other inline object, not a text span 125 | currentNode.children = currentNode.children.concat(span) 126 | } 127 | } 128 | 129 | return rootNode.children 130 | } 131 | -------------------------------------------------------------------------------- /test/toPlainText.test.ts: -------------------------------------------------------------------------------- 1 | import {toPlainText} from '@portabletext/toolkit' 2 | import {expect, test} from 'vitest' 3 | 4 | test('toPlainText: converts single-block, single-span with no formatting correctly', () => { 5 | expect( 6 | toPlainText({ 7 | _type: 'block', 8 | _key: 'a', 9 | style: 'normal', 10 | children: [{_type: 'span', _key: 's', text: 'Portable Text'}], 11 | markDefs: [], 12 | }), 13 | ).toEqual('Portable Text') 14 | }) 15 | 16 | test('toPlainText: converts single-block, multi-span with no formatting correctly', () => { 17 | expect( 18 | toPlainText({ 19 | _type: 'block', 20 | _key: 'a', 21 | style: 'normal', 22 | children: [ 23 | {_type: 'span', _key: 'a', text: 'Portable '}, 24 | {_type: 'span', _key: 'z', text: 'Text'}, 25 | ], 26 | markDefs: [], 27 | }), 28 | ).toEqual('Portable Text') 29 | }) 30 | 31 | test('toPlainText: converts single-block, multi-span with formatting correctly', () => { 32 | expect( 33 | toPlainText({ 34 | _type: 'block', 35 | _key: 'a', 36 | style: 'normal', 37 | children: [ 38 | {_type: 'span', _key: 'a', text: 'Portable', marks: ['em']}, 39 | {_type: 'span', _key: 'z', text: ' Text!'}, 40 | ], 41 | markDefs: [], 42 | }), 43 | ).toEqual('Portable Text!') 44 | }) 45 | 46 | test('toPlainText: converts multi-block, multi-span with formatting correctly', () => { 47 | expect( 48 | toPlainText([ 49 | { 50 | _type: 'block', 51 | _key: 'a', 52 | style: 'normal', 53 | children: [ 54 | {_type: 'span', _key: 'a', text: 'Portable', marks: ['link']}, 55 | {_type: 'span', _key: 'z', text: ' Text!', marks: ['link']}, 56 | ], 57 | markDefs: [{_key: 'link', _type: 'link', href: 'https://portabletext.org'}], 58 | }, 59 | { 60 | _type: 'block', 61 | _key: 'b', 62 | style: 'normal', 63 | children: [{_type: 'span', _key: 'a', text: 'Use it!', marks: []}], 64 | }, 65 | ]), 66 | ).toEqual('Portable Text!\n\nUse it!') 67 | }) 68 | 69 | test('toPlainText: ignores non-blocks, non-spans', () => { 70 | expect( 71 | toPlainText([ 72 | { 73 | _type: 'block', 74 | _key: 'a', 75 | style: 'normal', 76 | children: [ 77 | {_type: 'span', _key: 'a', text: 'Ignore'}, 78 | {_type: 'image', _key: 'h', src: '/some/image.png'}, 79 | {_type: 'span', _key: 'z', text: ' the image.'}, 80 | ], 81 | markDefs: [], 82 | }, 83 | { 84 | _type: 'map', 85 | lat: 59, 86 | lng: 13, 87 | }, 88 | { 89 | _type: 'block', 90 | _key: 'b', 91 | style: 'normal', 92 | children: [{_type: 'span', _key: 'a', text: '...and the map!', marks: []}], 93 | }, 94 | ]), 95 | ).toEqual('Ignore the image.\n\n...and the map!') 96 | }) 97 | 98 | test('toPlainText: does not add unnecessary whitespace on non-spans', () => { 99 | expect( 100 | toPlainText({ 101 | _type: 'block', 102 | children: [ 103 | {_type: 'span', text: 'Ignore'}, 104 | {_type: 'image', src: '/some/image.png'}, 105 | {_type: 'span', text: ' the image.'}, 106 | ], 107 | }), 108 | 'Ignore the image.', 109 | ) 110 | }) 111 | 112 | test('toPlainText: adds whitespace on span-hugging non-spans', () => { 113 | expect( 114 | toPlainText({ 115 | _type: 'block', 116 | children: [ 117 | {_type: 'span', text: 'Ignore'}, 118 | {_type: 'image', src: '/some/image.png'}, 119 | {_type: 'span', text: 'the image.'}, 120 | ], 121 | }), 122 | ).toEqual('Ignore the image.') 123 | }) 124 | 125 | test('toPlainText: does not add leading whitespace on span-hugging non-span', () => { 126 | expect( 127 | toPlainText({ 128 | _type: 'block', 129 | children: [ 130 | {_type: 'image', src: '/some/image.png'}, 131 | {_type: 'span', text: 'Now that is an image.'}, 132 | ], 133 | }), 134 | ).toEqual('Now that is an image.') 135 | }) 136 | 137 | test('toPlainText: does not add leading whitespace on span-hugging non-span (trailing)', () => { 138 | expect( 139 | toPlainText({ 140 | _type: 'block', 141 | children: [ 142 | {_type: 'span', text: 'Now that is a '}, 143 | {_type: 'image', src: '/some/image.png'}, 144 | {_type: 'span', text: 'beautiful image.'}, 145 | ], 146 | }), 147 | ).toEqual('Now that is a beautiful image.') 148 | }) 149 | -------------------------------------------------------------------------------- /test/buildMarksTree.test.ts: -------------------------------------------------------------------------------- 1 | import type {PortableTextBlock} from '@portabletext/types' 2 | 3 | import {buildMarksTree} from '@portabletext/toolkit' 4 | import {expect, test} from 'vitest' 5 | 6 | test('buildMarksTree: returns empty tree on empty blocks', () => { 7 | expect(buildMarksTree({_type: 'block', children: []})).toEqual([]) 8 | expect(buildMarksTree({_type: 'block'} as any)).toEqual([]) 9 | }) 10 | 11 | test('buildMarksTree: returns newlines as individual text nodes', () => { 12 | expect( 13 | buildMarksTree({_type: 'block', children: [{_type: 'span', text: 'Portable\nText'}]}), 14 | ).toEqual([ 15 | {_type: '@text', text: 'Portable'}, 16 | {_type: '@text', text: '\n'}, 17 | {_type: '@text', text: 'Text'}, 18 | ]) 19 | }) 20 | 21 | test('buildMarksTree: nests correctly, extracts correct `markDef`', () => { 22 | const block: PortableTextBlock = { 23 | _type: 'block', 24 | children: [ 25 | {_type: 'span', text: 'This block '}, 26 | {_type: 'span', text: '', marks: []}, 27 | {_type: 'span', text: 'contains', marks: ['strong']}, 28 | {_type: 'span', text: 'a link', marks: ['s0m3l1nk', 'strong']}, 29 | {_type: 'span', text: ' and some bolded text', marks: ['strong']}, 30 | ], 31 | markDefs: [ 32 | { 33 | _key: 's0m3l1nk', 34 | _type: 'link', 35 | href: 'https://some.example/', 36 | }, 37 | ], 38 | } 39 | 40 | expect(buildMarksTree(block)).toMatchSnapshot() 41 | }) 42 | 43 | test('buildMarksTree: joins on adjacent spans with same annotation', () => { 44 | const block: PortableTextBlock = { 45 | _type: 'block', 46 | _key: 'a', 47 | style: 'normal', 48 | children: [ 49 | {_type: 'span', _key: 'a', text: 'Portable', marks: ['link']}, 50 | {_type: 'span', _key: 'z', text: ' Text!', marks: ['link']}, 51 | ], 52 | markDefs: [{_key: 'link', _type: 'link', href: 'https://portabletext.org'}], 53 | } 54 | 55 | expect(buildMarksTree(block)).toMatchSnapshot() 56 | }) 57 | 58 | test('buildMarksTree: nests decorators and annotations correctly, extracts correct `markDef`', () => { 59 | const block: PortableTextBlock = { 60 | _type: 'block', 61 | children: [ 62 | {_type: 'span', text: 'This block '}, 63 | {_type: 'span', text: 'contains', marks: ['em', 's0m3l1nk']}, 64 | {_type: 'span', text: 'a link', marks: ['s0m3l1nk', 'strong']}, 65 | {_type: 'span', text: ' and some bolded text', marks: ['strong']}, 66 | ], 67 | markDefs: [ 68 | { 69 | _key: 's0m3l1nk', 70 | _type: 'link', 71 | href: 'https://some.example/', 72 | }, 73 | ], 74 | } 75 | 76 | expect(buildMarksTree(block)).toMatchSnapshot() 77 | }) 78 | 79 | test('buildMarksTree: includes inline objects in tree', () => { 80 | const block: PortableTextBlock = { 81 | _type: 'block', 82 | _key: 'a', 83 | style: 'normal', 84 | children: [ 85 | {_type: 'span', _key: 'a', text: 'Include'}, 86 | {_type: 'image', _key: 'h', src: '/some/image.png'}, 87 | {_type: 'span', _key: 'z', text: ' the image.'}, 88 | ], 89 | markDefs: [], 90 | } 91 | 92 | expect(buildMarksTree(block)).toMatchSnapshot() 93 | }) 94 | 95 | test('buildMarksTree: handles leading inline objects in tree', () => { 96 | const block: PortableTextBlock = { 97 | _type: 'block', 98 | _key: 'a', 99 | style: 'normal', 100 | children: [ 101 | {_type: 'image', _key: 'a', src: '/some/image.png'}, 102 | {_type: 'span', _key: 'b', text: 'Include'}, 103 | {_type: 'span', _key: 'c', text: ' the image.'}, 104 | ], 105 | markDefs: [], 106 | } 107 | 108 | expect(buildMarksTree(block)).toMatchSnapshot() 109 | }) 110 | 111 | test('buildMarksTree: handles trailing inline objects in tree', () => { 112 | const block: PortableTextBlock = { 113 | _type: 'block', 114 | _key: 'a', 115 | style: 'normal', 116 | children: [ 117 | {_type: 'span', _key: 'a', text: 'Include'}, 118 | {_type: 'span', _key: 'b', text: ' the image.'}, 119 | {_type: 'image', _key: 'c', src: '/some/image.png'}, 120 | ], 121 | markDefs: [], 122 | } 123 | 124 | expect(buildMarksTree(block)).toMatchSnapshot() 125 | }) 126 | 127 | test('buildMarksTree: includes inline objects in tree, with surrounding marks', () => { 128 | const block: PortableTextBlock = { 129 | _type: 'block', 130 | _key: 'a', 131 | style: 'normal', 132 | children: [ 133 | {_type: 'span', _key: 'a', text: 'Include', marks: ['em', 'strong']}, 134 | {_type: 'image', _key: 'h', src: '/some/image.png'}, 135 | {_type: 'span', _key: 'z', text: ' the image.', marks: ['strong', 'em']}, 136 | ], 137 | markDefs: [], 138 | } 139 | 140 | expect(buildMarksTree(block)).toMatchSnapshot() 141 | }) 142 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ArbitraryTypedObject, 3 | PortableTextListItemBlock, 4 | PortableTextMarkDefinition, 5 | PortableTextSpan, 6 | } from '@portabletext/types' 7 | 8 | /** 9 | * List nesting mode for HTML, see the {@link nestLists | `nestLists()` function} 10 | */ 11 | export const LIST_NEST_MODE_HTML = 'html' 12 | 13 | /** 14 | * List nesting mode for direct, nested lists, see the {@link nestLists | `nestLists()` function} 15 | */ 16 | export const LIST_NEST_MODE_DIRECT = 'direct' 17 | 18 | /** 19 | * List nesting mode, see the {@link nestLists | `nestLists()` function} 20 | */ 21 | export type ToolkitListNestMode = 'html' | 'direct' 22 | 23 | /** 24 | * Toolkit-specific type representing a nested list 25 | * 26 | * See the `nestLists()` function for more info 27 | */ 28 | export type ToolkitPortableTextList = ToolkitPortableTextHtmlList | ToolkitPortableTextDirectList 29 | 30 | /** 31 | * Toolkit-specific type representing a nested list in HTML mode, where deeper lists are nested 32 | * inside of the _list items_, eg `
  • Some text
    • Deeper
` 33 | */ 34 | export interface ToolkitPortableTextHtmlList { 35 | /** 36 | * Type name, prefixed with `@` to signal that this is a toolkit-specific node. 37 | */ 38 | _type: '@list' 39 | 40 | /** 41 | * Unique key for this list (within its parent) 42 | */ 43 | _key: string 44 | 45 | /** 46 | * List mode, signaling that list nodes will appear as children of the _list items_ 47 | */ 48 | mode: 'html' 49 | 50 | /** 51 | * Level/depth of this list node (starts at `1`) 52 | */ 53 | level: number 54 | 55 | /** 56 | * Style of this list item (`bullet`, `number` are common values, but can be customized) 57 | */ 58 | listItem: string 59 | 60 | /** 61 | * Child nodes of this list - toolkit-specific list items which can themselves hold deeper lists 62 | */ 63 | children: ToolkitPortableTextListItem[] 64 | } 65 | 66 | /** 67 | * Toolkit-specific type representing a nested list in "direct" mode, where deeper lists are nested 68 | * inside of the lists children, alongside other blocks. 69 | */ 70 | export interface ToolkitPortableTextDirectList { 71 | /** 72 | * Type name, prefixed with `@` to signal that this is a toolkit-specific node. 73 | */ 74 | _type: '@list' 75 | 76 | /** 77 | * Unique key for this list (within its parent) 78 | */ 79 | _key: string 80 | 81 | /** 82 | * List mode, signaling that list nodes can appear as direct children 83 | */ 84 | mode: 'direct' 85 | 86 | /** 87 | * Level/depth of this list node (starts at `1`) 88 | */ 89 | level: number 90 | 91 | /** 92 | * Style of this list item (`bullet`, `number` are common values, but can be customized) 93 | */ 94 | listItem: string 95 | 96 | /** 97 | * Child nodes of this list - either portable text list items, or another, deeper list 98 | */ 99 | children: (PortableTextListItemBlock | ToolkitPortableTextDirectList)[] 100 | } 101 | 102 | /** 103 | * Toolkit-specific type representing a list item block, but where the children can be another list 104 | */ 105 | export interface ToolkitPortableTextListItem extends PortableTextListItemBlock< 106 | PortableTextMarkDefinition, 107 | PortableTextSpan | ToolkitPortableTextList 108 | > {} 109 | 110 | /** 111 | * Toolkit-specific type representing a text node, used when nesting spans. 112 | * 113 | * See the {@link buildMarksTree | `buildMarksTree()` function} 114 | */ 115 | export interface ToolkitTextNode { 116 | /** 117 | * Type name, prefixed with `@` to signal that this is a toolkit-specific node. 118 | */ 119 | _type: '@text' 120 | 121 | /** 122 | * The actual string value of the text node 123 | */ 124 | text: string 125 | } 126 | 127 | /** 128 | * Toolkit-specific type representing a portable text span that can hold other spans. 129 | * In this type, each span only has a single mark, instead of an array of them. 130 | */ 131 | export interface ToolkitNestedPortableTextSpan< 132 | M extends PortableTextMarkDefinition = PortableTextMarkDefinition, 133 | > { 134 | /** 135 | * Type name, prefixed with `@` to signal that this is a toolkit-specific node. 136 | */ 137 | _type: '@span' 138 | 139 | /** 140 | * Unique key for this span 141 | */ 142 | _key?: string 143 | 144 | /** 145 | * Holds the value (definition) of the mark in the case of annotations. 146 | * `undefined` if the mark is a decorator (strong, em or similar). 147 | */ 148 | markDef?: M 149 | 150 | /** 151 | * The key of the mark definition (in the case of annotations). 152 | * `undefined` if the mark is a decorator (strong, em or similar). 153 | */ 154 | markKey?: string 155 | 156 | /** 157 | * Type of the mark. For annotations, this is the `_type` property of the value. 158 | * For decorators, it will hold the name of the decorator (strong, em or similar). 159 | */ 160 | markType: string 161 | 162 | /** 163 | * Child nodes of this span. Can be toolkit-specific text nodes, nested spans 164 | * or any inline object type. 165 | */ 166 | children: (ToolkitTextNode | ToolkitNestedPortableTextSpan | ArbitraryTypedObject)[] 167 | } 168 | -------------------------------------------------------------------------------- /test/nestLists.test.ts: -------------------------------------------------------------------------------- 1 | import type {PortableTextListItemBlock} from '@portabletext/types' 2 | 3 | import {LIST_NEST_MODE_DIRECT, LIST_NEST_MODE_HTML, nestLists} from '@portabletext/toolkit' 4 | import {expect, test} from 'vitest' 5 | 6 | test('nestLists: returns empty tree on no blocks', () => { 7 | expect(nestLists([], LIST_NEST_MODE_HTML)).toEqual([]) 8 | }) 9 | 10 | test('nestLists: returns non-list blocks verbatim', () => { 11 | const block = {_type: 'block', children: [{_type: 'span', text: 'Verbatim, please'}]} 12 | expect(nestLists([block], LIST_NEST_MODE_HTML)).toEqual([block]) 13 | }) 14 | 15 | test('nestLists: wraps list items in toolkit list node', () => { 16 | const block = { 17 | _type: 'block', 18 | _key: 'a', 19 | children: [{_type: 'span', text: 'Verbatim, please'}], 20 | listItem: 'bullet', 21 | } 22 | expect(nestLists([block], LIST_NEST_MODE_HTML)).toEqual([ 23 | { 24 | _type: '@list', 25 | _key: 'a-parent', 26 | mode: 'html', 27 | level: 1, 28 | listItem: 'bullet', 29 | children: [block], 30 | }, 31 | ]) 32 | 33 | // Uses index as key if no _key is present 34 | expect(nestLists([{...block, _key: undefined}], LIST_NEST_MODE_HTML)[0]?._key).toBe('0-parent') 35 | }) 36 | 37 | test('nestLists: wraps adjacent list items of same type/level in toolkit list node', () => { 38 | const blocks = createBlocks(['First', 'Second', 'Third']) 39 | expect(nestLists(blocks, LIST_NEST_MODE_HTML)).toMatchSnapshot() 40 | }) 41 | 42 | test('nestLists: wraps adjacent list items of different types in separate list nodes', () => { 43 | const blocks = [ 44 | ...createBlocks(['Bullet 1', 'Bullet 2']), 45 | ...createBlocks(['Number 1', 'Number 2'], {type: 'number', startIndex: 2}), 46 | ] 47 | expect(nestLists(blocks, LIST_NEST_MODE_HTML)).toMatchSnapshot() 48 | }) 49 | 50 | test('nestLists: ends lists when non-list item occurs', () => { 51 | const blocks = [ 52 | ...createBlocks(['Bullet 1', 'Bullet 2']), 53 | {_type: 'map'}, 54 | ...createBlocks(['Number 1', 'Number 2'], {type: 'number', startIndex: 2}), 55 | ] 56 | expect(nestLists(blocks, LIST_NEST_MODE_HTML)).toMatchSnapshot() 57 | }) 58 | 59 | test('nestLists: wraps deeper lists inside of last list item in html mode', () => { 60 | const blocks = [ 61 | ...createBlocks(['Bullet 1', 'Bullet 2']), 62 | ...createBlocks(['Number 1', 'Number 2'], {type: 'number', level: 2, startIndex: 2}), 63 | ] 64 | expect(nestLists(blocks, LIST_NEST_MODE_HTML)).toMatchSnapshot() 65 | }) 66 | 67 | test('nestLists: nests deeper lists inside of parent list in direct mode', () => { 68 | const blocks = [ 69 | ...createBlocks(['Bullet 1', 'Bullet 2']), 70 | ...createBlocks(['Number 1', 'Number 2'], {type: 'number', level: 2, startIndex: 2}), 71 | ] 72 | expect(nestLists(blocks, LIST_NEST_MODE_DIRECT)).toMatchSnapshot() 73 | }) 74 | 75 | test('nestLists: assumes level is 1 if not set', () => { 76 | const blocks = [ 77 | ...createBlocks(['Bullet 1']).map(({level: _level, ...block}) => block), 78 | ...createBlocks(['Bullet 2'], {startIndex: 1, type: 'number'}).map( 79 | ({level: _level, ...block}) => block, 80 | ), 81 | ] 82 | expect(nestLists(blocks, LIST_NEST_MODE_HTML)).toMatchSnapshot() 83 | }) 84 | 85 | test('nestLists: handles deeper/shallower transitions correctly in html mode', () => { 86 | const blocks = [ 87 | ...createBlocks(['Level 1, A', 'Level 1, B']), 88 | ...createBlocks(['Level 2, C', 'Level 2, D'], {level: 2, startIndex: 2}), 89 | ...createBlocks(['Level 3, E', 'Level 3, F'], {level: 3, startIndex: 4}), 90 | ...createBlocks(['Level 2, G', 'Level 2, H'], {level: 2, startIndex: 6}), 91 | ...createBlocks(['Level 3, I', 'Level 3, J'], {level: 3, startIndex: 8}), 92 | ...createBlocks(['Level 1, K', 'Level 1, L'], {level: 1, startIndex: 10, type: 'number'}), 93 | ] 94 | expect(nestLists(blocks, LIST_NEST_MODE_HTML)).toMatchSnapshot() 95 | }) 96 | 97 | test('nestLists: handles deeper/shallower transitions correctly in direct mode', () => { 98 | const blocks = [ 99 | ...createBlocks(['Level 1, A', 'Level 1, B']), 100 | ...createBlocks(['Level 2, C', 'Level 2, D'], {level: 2, startIndex: 2}), 101 | ...createBlocks(['Level 3, E', 'Level 3, F'], {level: 3, startIndex: 4}), 102 | ...createBlocks(['Level 2, G', 'Level 2, H'], {level: 2, startIndex: 6}), 103 | ...createBlocks(['Level 3, I', 'Level 3, J'], {level: 3, startIndex: 8}), 104 | ...createBlocks(['Level 1, K', 'Level 1, L'], {level: 1, startIndex: 10, type: 'number'}), 105 | ] 106 | expect(nestLists(blocks, LIST_NEST_MODE_DIRECT)).toMatchSnapshot() 107 | }) 108 | 109 | test('nestLists: wraps adjacent list items of different types in separate list nodes', () => { 110 | const blocks = [ 111 | ...createBlocks(['Bullet 1', 'Bullet 2'], {type: 'bullet', startIndex: 0}), 112 | ...createBlocks(['Number 1', 'Number 2'], {type: 'number', startIndex: 2}), 113 | ] 114 | expect(nestLists(blocks, LIST_NEST_MODE_HTML)).toMatchSnapshot() 115 | }) 116 | 117 | function createBlocks( 118 | spans: string[], 119 | options: {level?: number; type?: string; startIndex?: number} = {}, 120 | ): PortableTextListItemBlock[] { 121 | const {level = 1, type = 'bullet', startIndex = 0} = options 122 | return spans.map((span, i) => ({ 123 | _type: 'block', 124 | _key: `${String.fromCharCode(65 + startIndex + i)}${i}`, 125 | children: [{_type: 'span', text: span}], 126 | listItem: type, 127 | level, 128 | })) 129 | } 130 | -------------------------------------------------------------------------------- /test/__snapshots__/buildMarksTree.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`buildMarksTree: handles leading inline objects in tree 1`] = ` 4 | [ 5 | { 6 | "_key": "a", 7 | "_type": "image", 8 | "src": "/some/image.png", 9 | }, 10 | { 11 | "_type": "@text", 12 | "text": "Include", 13 | }, 14 | { 15 | "_type": "@text", 16 | "text": " the image.", 17 | }, 18 | ] 19 | `; 20 | 21 | exports[`buildMarksTree: handles trailing inline objects in tree 1`] = ` 22 | [ 23 | { 24 | "_type": "@text", 25 | "text": "Include", 26 | }, 27 | { 28 | "_type": "@text", 29 | "text": " the image.", 30 | }, 31 | { 32 | "_key": "c", 33 | "_type": "image", 34 | "src": "/some/image.png", 35 | }, 36 | ] 37 | `; 38 | 39 | exports[`buildMarksTree: includes inline objects in tree 1`] = ` 40 | [ 41 | { 42 | "_type": "@text", 43 | "text": "Include", 44 | }, 45 | { 46 | "_key": "h", 47 | "_type": "image", 48 | "src": "/some/image.png", 49 | }, 50 | { 51 | "_type": "@text", 52 | "text": " the image.", 53 | }, 54 | ] 55 | `; 56 | 57 | exports[`buildMarksTree: includes inline objects in tree, with surrounding marks 1`] = ` 58 | [ 59 | { 60 | "_key": "a", 61 | "_type": "@span", 62 | "children": [ 63 | { 64 | "_key": "a", 65 | "_type": "@span", 66 | "children": [ 67 | { 68 | "_type": "@text", 69 | "text": "Include", 70 | }, 71 | ], 72 | "markDef": undefined, 73 | "markKey": "em", 74 | "markType": "em", 75 | }, 76 | ], 77 | "markDef": undefined, 78 | "markKey": "strong", 79 | "markType": "strong", 80 | }, 81 | { 82 | "_key": "h", 83 | "_type": "image", 84 | "src": "/some/image.png", 85 | }, 86 | { 87 | "_key": "z", 88 | "_type": "@span", 89 | "children": [ 90 | { 91 | "_key": "z", 92 | "_type": "@span", 93 | "children": [ 94 | { 95 | "_type": "@text", 96 | "text": " the image.", 97 | }, 98 | ], 99 | "markDef": undefined, 100 | "markKey": "em", 101 | "markType": "em", 102 | }, 103 | ], 104 | "markDef": undefined, 105 | "markKey": "strong", 106 | "markType": "strong", 107 | }, 108 | ] 109 | `; 110 | 111 | exports[`buildMarksTree: joins on adjacent spans with same annotation 1`] = ` 112 | [ 113 | { 114 | "_key": "a", 115 | "_type": "@span", 116 | "children": [ 117 | { 118 | "_type": "@text", 119 | "text": "Portable", 120 | }, 121 | { 122 | "_type": "@text", 123 | "text": " Text!", 124 | }, 125 | ], 126 | "markDef": { 127 | "_key": "link", 128 | "_type": "link", 129 | "href": "https://portabletext.org", 130 | }, 131 | "markKey": "link", 132 | "markType": "link", 133 | }, 134 | ] 135 | `; 136 | 137 | exports[`buildMarksTree: nests correctly, extracts correct \`markDef\` 1`] = ` 138 | [ 139 | { 140 | "_type": "@text", 141 | "text": "This block ", 142 | }, 143 | { 144 | "_type": "@text", 145 | "text": "", 146 | }, 147 | { 148 | "_key": undefined, 149 | "_type": "@span", 150 | "children": [ 151 | { 152 | "_type": "@text", 153 | "text": "contains", 154 | }, 155 | { 156 | "_key": undefined, 157 | "_type": "@span", 158 | "children": [ 159 | { 160 | "_type": "@text", 161 | "text": "a link", 162 | }, 163 | ], 164 | "markDef": { 165 | "_key": "s0m3l1nk", 166 | "_type": "link", 167 | "href": "https://some.example/", 168 | }, 169 | "markKey": "s0m3l1nk", 170 | "markType": "link", 171 | }, 172 | { 173 | "_type": "@text", 174 | "text": " and some bolded text", 175 | }, 176 | ], 177 | "markDef": undefined, 178 | "markKey": "strong", 179 | "markType": "strong", 180 | }, 181 | ] 182 | `; 183 | 184 | exports[`buildMarksTree: nests decorators and annotations correctly, extracts correct \`markDef\` 1`] = ` 185 | [ 186 | { 187 | "_type": "@text", 188 | "text": "This block ", 189 | }, 190 | { 191 | "_key": undefined, 192 | "_type": "@span", 193 | "children": [ 194 | { 195 | "_key": undefined, 196 | "_type": "@span", 197 | "children": [ 198 | { 199 | "_type": "@text", 200 | "text": "contains", 201 | }, 202 | ], 203 | "markDef": undefined, 204 | "markKey": "em", 205 | "markType": "em", 206 | }, 207 | { 208 | "_key": undefined, 209 | "_type": "@span", 210 | "children": [ 211 | { 212 | "_type": "@text", 213 | "text": "a link", 214 | }, 215 | ], 216 | "markDef": undefined, 217 | "markKey": "strong", 218 | "markType": "strong", 219 | }, 220 | ], 221 | "markDef": { 222 | "_key": "s0m3l1nk", 223 | "_type": "link", 224 | "href": "https://some.example/", 225 | }, 226 | "markKey": "s0m3l1nk", 227 | "markType": "link", 228 | }, 229 | { 230 | "_key": undefined, 231 | "_type": "@span", 232 | "children": [ 233 | { 234 | "_type": "@text", 235 | "text": " and some bolded text", 236 | }, 237 | ], 238 | "markDef": undefined, 239 | "markKey": "strong", 240 | "markType": "strong", 241 | }, 242 | ] 243 | `; 244 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @portabletext/toolkit 2 | 3 | ## 5.0.0 4 | 5 | ### Major Changes 6 | 7 | - [#137](https://github.com/portabletext/toolkit/pull/137) [`cb5ee07`](https://github.com/portabletext/toolkit/commit/cb5ee078509d98f941edde215531f406f61c7f8d) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency @portabletext/types to v4 8 | 9 | ## 4.0.0 10 | 11 | ### Major Changes 12 | 13 | - [#123](https://github.com/portabletext/toolkit/pull/123) [`2852611`](https://github.com/portabletext/toolkit/commit/28526114775f4ead49ec4b004474e02bece7eccb) Thanks [@stipsan](https://github.com/stipsan)! - Support for node versions older than v20.19 dropped 14 | 15 | - [#123](https://github.com/portabletext/toolkit/pull/123) [`2852611`](https://github.com/portabletext/toolkit/commit/28526114775f4ead49ec4b004474e02bece7eccb) Thanks [@stipsan](https://github.com/stipsan)! - Upgrade @portabletext/types to v3 16 | 17 | - [#123](https://github.com/portabletext/toolkit/pull/123) [`2852611`](https://github.com/portabletext/toolkit/commit/28526114775f4ead49ec4b004474e02bece7eccb) Thanks [@stipsan](https://github.com/stipsan)! - CJS exports removed 18 | 19 | ## 3.0.1 20 | 21 | ### Patch Changes 22 | 23 | - [#107](https://github.com/portabletext/toolkit/pull/107) [`12c0bba`](https://github.com/portabletext/toolkit/commit/12c0bba3e9e92a6c29c6af7909f9015be3ea6ace) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency @portabletext/types to ^2.0.15 24 | 25 | ## 3.0.0 26 | 27 | ### Major Changes 28 | 29 | - [`06c95e3`](https://github.com/portabletext/toolkit/commit/06c95e3713d9b0aa8ea13882a39c7b64cebaf10a) Thanks [@stipsan](https://github.com/stipsan)! - Drop support for Sanity Studio v2 30 | 31 | ### Patch Changes 32 | 33 | - [`1eef3d9`](https://github.com/portabletext/toolkit/commit/1eef3d9b8915c366720d295aa731ee51169a89e8) Thanks [@stipsan](https://github.com/stipsan)! - update build tooling 34 | 35 | ## 2.0.18 36 | 37 | ### Patch Changes 38 | 39 | - [`aace023`](https://github.com/portabletext/toolkit/commit/aace02390d270708caf3768fdbb5ba1116cfa284) Thanks [@stipsan](https://github.com/stipsan)! - Update LICENSE year to 2025 40 | 41 | ## [2.0.17](https://github.com/portabletext/toolkit/compare/v2.0.16...v2.0.17) (2025-02-06) 42 | 43 | ### Bug Fixes 44 | 45 | - guard against `markDefs` being `null` ([#92](https://github.com/portabletext/toolkit/issues/92)) ([1f1644a](https://github.com/portabletext/toolkit/commit/1f1644a67d8e41f022d8626c193f7044ccc4469e)) 46 | - **typeError:** Marking `markDefs` as optional to resolve TS error when markDefs array is missing ([#96](https://github.com/portabletext/toolkit/issues/96)) ([eedd7c7](https://github.com/portabletext/toolkit/commit/eedd7c77c1551f79d883d115c77eaf1a2906011f)) 47 | 48 | ## [2.0.16](https://github.com/portabletext/toolkit/compare/v2.0.15...v2.0.16) (2024-11-02) 49 | 50 | ### Bug Fixes 51 | 52 | - prevent double spaces in `toPlainText` when span follows non-span ([#93](https://github.com/portabletext/toolkit/issues/93)) ([43b963f](https://github.com/portabletext/toolkit/commit/43b963fc0182c304564d2f460029609efabcb8c5)) 53 | 54 | ## [2.0.15](https://github.com/portabletext/toolkit/compare/v2.0.14...v2.0.15) (2024-04-11) 55 | 56 | ### Bug Fixes 57 | 58 | - **deps:** update dependency @portabletext/types to ^2.0.13 ([#85](https://github.com/portabletext/toolkit/issues/85)) ([e5a0247](https://github.com/portabletext/toolkit/commit/e5a024795279f43cbd6712af67d8eb686652fd16)) 59 | 60 | ## [2.0.14](https://github.com/portabletext/toolkit/compare/v2.0.13...v2.0.14) (2024-04-05) 61 | 62 | ### Bug Fixes 63 | 64 | - **deps:** update dependency @portabletext/types to ^2.0.12 ([#78](https://github.com/portabletext/toolkit/issues/78)) ([eaaa9a1](https://github.com/portabletext/toolkit/commit/eaaa9a1952c8200ad20c59e434d2ac53cfe19c45)) 65 | 66 | ## [2.0.13](https://github.com/portabletext/toolkit/compare/v2.0.12...v2.0.13) (2024-03-20) 67 | 68 | ### Bug Fixes 69 | 70 | - **deps:** update dependency @portabletext/types to ^2.0.11 ([#73](https://github.com/portabletext/toolkit/issues/73)) ([e85b103](https://github.com/portabletext/toolkit/commit/e85b10331997f24e60348b96b174df36fea69230)) 71 | 72 | ## [2.0.12](https://github.com/portabletext/toolkit/compare/v2.0.11...v2.0.12) (2024-03-18) 73 | 74 | ### Bug Fixes 75 | 76 | - **deps:** update dependency @portabletext/types to ^2.0.10 ([#70](https://github.com/portabletext/toolkit/issues/70)) ([2b8e7f6](https://github.com/portabletext/toolkit/commit/2b8e7f63f609f8917b72ee655fd0907e626dafe3)) 77 | 78 | ## [2.0.11](https://github.com/portabletext/toolkit/compare/v2.0.10...v2.0.11) (2024-03-16) 79 | 80 | ### Bug Fixes 81 | 82 | - **deps:** update dependency @portabletext/types to ^2.0.9 ([#65](https://github.com/portabletext/toolkit/issues/65)) ([83c5700](https://github.com/portabletext/toolkit/commit/83c5700720afa12c2856c60881931c05ec549741)) 83 | 84 | ## [2.0.10](https://github.com/portabletext/toolkit/compare/v2.0.9...v2.0.10) (2023-10-10) 85 | 86 | ### Bug Fixes 87 | 88 | - **deps:** update dependency @portabletext/types to ^2.0.8 ([#48](https://github.com/portabletext/toolkit/issues/48)) ([36cdd6f](https://github.com/portabletext/toolkit/commit/36cdd6f8786cc5474eb1a1f1306120691d852d8f)) 89 | 90 | ## [2.0.9](https://github.com/portabletext/toolkit/compare/v2.0.8...v2.0.9) (2023-09-28) 91 | 92 | ### Bug Fixes 93 | 94 | - **deps:** update dependency @portabletext/types to ^2.0.7 ([#40](https://github.com/portabletext/toolkit/issues/40)) ([16f8ee7](https://github.com/portabletext/toolkit/commit/16f8ee75322c1bb290dcff4d666f5e87a9c67f46)) 95 | 96 | ## [2.0.8](https://github.com/portabletext/toolkit/compare/v2.0.7...v2.0.8) (2023-08-23) 97 | 98 | ### Bug Fixes 99 | 100 | - **deps:** update dependency @portabletext/types to ^2.0.6 ([#35](https://github.com/portabletext/toolkit/issues/35)) ([0eadb67](https://github.com/portabletext/toolkit/commit/0eadb67f0c85736d2e64e37186ec2224f92399e9)) 101 | 102 | ## [2.0.7](https://github.com/portabletext/toolkit/compare/v2.0.6...v2.0.7) (2023-08-23) 103 | 104 | ### Bug Fixes 105 | 106 | - setup provenance ([94ec5cf](https://github.com/portabletext/toolkit/commit/94ec5cf0f3e83d0df3ba0649339fb58195686a45)) 107 | 108 | ## [2.0.6](https://github.com/portabletext/toolkit/compare/v2.0.5...v2.0.6) (2023-08-23) 109 | 110 | ### Bug Fixes 111 | 112 | - isPortableTextBlock not accounting for `markDefs: undefined` ([#25](https://github.com/portabletext/toolkit/issues/25)) ([db076c8](https://github.com/portabletext/toolkit/commit/db076c869e816c151308c47ce50858ef80d4eb76)) 113 | 114 | ## [2.0.5](https://github.com/portabletext/toolkit/compare/v2.0.4...v2.0.5) (2023-08-23) 115 | 116 | ### Bug Fixes 117 | 118 | - add `node.module` condition ([1b369ba](https://github.com/portabletext/toolkit/commit/1b369bac105ccdb78df28f1b95b2cbbdf0e7ee74)) 119 | 120 | ## [2.0.4](https://github.com/portabletext/toolkit/compare/v2.0.3...v2.0.4) (2023-06-26) 121 | 122 | ### Bug Fixes 123 | 124 | - **deps:** update non-major ([6a9347a](https://github.com/portabletext/toolkit/commit/6a9347ad8ad08400f3eb2284e072997bf4067d59)) 125 | 126 | ## [2.0.3](https://github.com/portabletext/toolkit/compare/v2.0.2...v2.0.3) (2023-06-26) 127 | 128 | ### Bug Fixes 129 | 130 | - refactor to `type: module` ([1dc6579](https://github.com/portabletext/toolkit/commit/1dc6579053980f6191007985bc9ca9a9d4532f7b)) 131 | 132 | ## [2.0.2](https://github.com/portabletext/toolkit/compare/v2.0.1...v2.0.2) (2023-06-23) 133 | 134 | ### Bug Fixes 135 | 136 | - remove ESM wrapper (not needed) ([be72cb2](https://github.com/portabletext/toolkit/commit/be72cb258481d95343bda35e20b3c063ca30e0e2)) 137 | -------------------------------------------------------------------------------- /src/nestLists.ts: -------------------------------------------------------------------------------- 1 | import type {PortableTextBlock, PortableTextListItemBlock, TypedObject} from '@portabletext/types' 2 | 3 | import type { 4 | ToolkitListNestMode, 5 | ToolkitPortableTextDirectList, 6 | ToolkitPortableTextHtmlList, 7 | ToolkitPortableTextList, 8 | ToolkitPortableTextListItem, 9 | } from './types' 10 | 11 | import { 12 | isPortableTextListItemBlock, 13 | isPortableTextSpan, 14 | isPortableTextToolkitList, 15 | } from './asserters' 16 | 17 | export type ToolkitNestListsOutputNode = 18 | | T 19 | | ToolkitPortableTextHtmlList 20 | | ToolkitPortableTextDirectList 21 | 22 | /** 23 | * Takes an array of blocks and returns an array of nodes optimized for rendering in HTML-like 24 | * environment, where lists are nested inside of eachother instead of appearing "flat" as in 25 | * native Portable Text data structures. 26 | * 27 | * Note that the list node is not a native Portable Text node type, and thus is represented 28 | * using the {@link ToolkitPortableTextList | `@list`} type name (`{_type: '@list'}`). 29 | * 30 | * The nesting can be configured in two modes: 31 | * 32 | * - `direct`: deeper list nodes will appear as a direct child of the parent list 33 | * - `html`, deeper list nodes will appear as a child of the last _list item_ in the parent list 34 | * 35 | * When using `direct`, all list nodes will be of type {@link ToolkitPortableTextDirectList}, 36 | * while with `html` they will be of type {@link ToolkitPortableTextHtmlList} 37 | * 38 | * These modes are available as {@link LIST_NEST_MODE_HTML} and {@link LIST_NEST_MODE_DIRECT}. 39 | * 40 | * @param blocks - Array of Portable Text blocks and other arbitrary types 41 | * @param mode - Mode to use for nesting, `direct` or `html` 42 | * @returns Array of potentially nested nodes optimized for rendering 43 | */ 44 | export function nestLists( 45 | blocks: T[], 46 | mode: 'direct', 47 | ): (T | ToolkitPortableTextDirectList)[] 48 | export function nestLists( 49 | blocks: T[], 50 | mode: 'html', 51 | ): (T | ToolkitPortableTextHtmlList)[] 52 | export function nestLists( 53 | blocks: T[], 54 | mode: 'direct' | 'html', 55 | ): (T | ToolkitPortableTextHtmlList | ToolkitPortableTextDirectList)[] 56 | export function nestLists( 57 | blocks: T[], 58 | mode: ToolkitListNestMode, 59 | ): ToolkitNestListsOutputNode[] { 60 | const tree: ToolkitNestListsOutputNode[] = [] 61 | let currentList: ToolkitPortableTextList | undefined 62 | 63 | for (let i = 0; i < blocks.length; i++) { 64 | const block = blocks[i] 65 | if (!block) { 66 | continue 67 | } 68 | 69 | if (!isPortableTextListItemBlock(block)) { 70 | tree.push(block) 71 | currentList = undefined 72 | continue 73 | } 74 | 75 | // Start of a new list? 76 | if (!currentList) { 77 | currentList = listFromBlock(block, i, mode) 78 | tree.push(currentList) 79 | continue 80 | } 81 | 82 | // New list item within same list? 83 | if (blockMatchesList(block, currentList)) { 84 | currentList.children.push(block) 85 | continue 86 | } 87 | 88 | // Different list props, are we going deeper? 89 | if ((block.level || 1) > currentList.level) { 90 | const newList = listFromBlock(block, i, mode) 91 | 92 | if (mode === 'html') { 93 | // Because HTML is kinda weird, nested lists needs to be nested within list items. 94 | // So while you would think that we could populate the parent list with a new sub-list, 95 | // we actually have to target the last list element (child) of the parent. 96 | // However, at this point we need to be very careful - simply pushing to the list of children 97 | // will mutate the input, and we don't want to blindly clone the entire tree. 98 | 99 | // Clone the last child while adding our new list as the last child of it 100 | const lastListItem = currentList.children[ 101 | currentList.children.length - 1 102 | ] as ToolkitPortableTextListItem 103 | 104 | const newLastChild: ToolkitPortableTextListItem = { 105 | ...lastListItem, 106 | children: [...lastListItem.children, newList], 107 | } 108 | 109 | // Swap the last child 110 | currentList.children[currentList.children.length - 1] = newLastChild 111 | } else { 112 | ;(currentList as ToolkitPortableTextDirectList).children.push( 113 | newList as ToolkitPortableTextDirectList, 114 | ) 115 | } 116 | 117 | // Set the newly created, deeper list as the current 118 | currentList = newList 119 | continue 120 | } 121 | 122 | // Different list props, are we going back up the tree? 123 | if ((block.level || 1) < currentList.level) { 124 | // Current list has ended, and we need to hook up with a parent of the same level and type 125 | const matchingBranch = tree[tree.length - 1] 126 | const match = matchingBranch && findListMatching(matchingBranch, block) 127 | if (match) { 128 | currentList = match 129 | currentList.children.push(block) 130 | continue 131 | } 132 | 133 | // Similar parent can't be found, assume new list 134 | currentList = listFromBlock(block, i, mode) 135 | tree.push(currentList) 136 | continue 137 | } 138 | 139 | // Different list props, different list style? 140 | if (block.listItem !== currentList.listItem) { 141 | const matchingBranch = tree[tree.length - 1] 142 | const match = matchingBranch && findListMatching(matchingBranch, {level: block.level || 1}) 143 | if (match && match.listItem === block.listItem) { 144 | currentList = match 145 | currentList.children.push(block) 146 | continue 147 | } else { 148 | currentList = listFromBlock(block, i, mode) 149 | tree.push(currentList) 150 | continue 151 | } 152 | } 153 | 154 | // oxlint-disable-next-line no-console 155 | console.warn('Unknown state encountered for block', block) 156 | tree.push(block) 157 | } 158 | 159 | return tree 160 | } 161 | 162 | function blockMatchesList(block: PortableTextBlock, list: ToolkitPortableTextList) { 163 | return (block.level || 1) === list.level && block.listItem === list.listItem 164 | } 165 | 166 | function listFromBlock( 167 | block: PortableTextListItemBlock, 168 | index: number, 169 | mode: ToolkitListNestMode, 170 | ): ToolkitPortableTextList { 171 | return { 172 | _type: '@list', 173 | _key: `${block._key || `${index}`}-parent`, 174 | mode, 175 | level: block.level || 1, 176 | listItem: block.listItem, 177 | children: [block], 178 | } 179 | } 180 | 181 | function findListMatching( 182 | rootNode: T, 183 | matching: Partial, 184 | ): ToolkitPortableTextList | undefined { 185 | const level = matching.level || 1 186 | const style = matching.listItem || 'normal' 187 | const filterOnType = typeof matching.listItem === 'string' 188 | if ( 189 | isPortableTextToolkitList(rootNode) && 190 | (rootNode.level || 1) === level && 191 | filterOnType && 192 | (rootNode.listItem || 'normal') === style 193 | ) { 194 | return rootNode 195 | } 196 | 197 | if (!('children' in rootNode)) { 198 | return undefined 199 | } 200 | 201 | const node = rootNode.children[rootNode.children.length - 1] 202 | return node && !isPortableTextSpan(node) ? findListMatching(node, matching) : undefined 203 | } 204 | -------------------------------------------------------------------------------- /test/asserters.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | isPortableTextBlock, 3 | isPortableTextListItemBlock, 4 | isPortableTextSpan, 5 | isPortableTextToolkitList, 6 | isPortableTextToolkitSpan, 7 | isPortableTextToolkitTextNode, 8 | } from '@portabletext/toolkit' 9 | import {expect, test} from 'vitest' 10 | 11 | test('isPortableTextBlock: all possible non-list properties', () => { 12 | expect( 13 | isPortableTextBlock({ 14 | _type: 'block', 15 | _key: 'a', 16 | style: 'normal', 17 | children: [{_type: 'span', _key: 's', text: 'Portable Text', marks: ['l']}], 18 | markDefs: [{_key: 'l', _type: 'link', href: 'https://portabletext.org/'}], 19 | }), 20 | '`true` if all possible non-list properties are present', 21 | ).toBe(true) 22 | }) 23 | 24 | test('isPortableTextBlock: all possible list properties', () => { 25 | expect( 26 | isPortableTextBlock({ 27 | _type: 'block', 28 | _key: 'a', 29 | style: 'normal', 30 | children: [{_type: 'span', _key: 's', text: 'Portable Text', marks: ['l']}], 31 | markDefs: [{_key: 'l', _type: 'link', href: 'https://portabletext.org/'}], 32 | listItem: 'bullet', 33 | level: 1, 34 | }), 35 | '`true` if all possible list properties are present', 36 | ).toBe(true) 37 | }) 38 | 39 | test('isPortableTextBlock: absolute minimum properties', () => { 40 | expect( 41 | isPortableTextBlock({ 42 | _type: 'any-type', 43 | children: [], 44 | }), 45 | '`true` on stripped to the bone block', 46 | ).toBe(true) 47 | }) 48 | 49 | test('isPortableTextBlock: minimum properties (with span)', () => { 50 | expect( 51 | isPortableTextBlock({ 52 | _type: 'any-type', 53 | children: [{_type: 'span', text: 'Portable Text'}], 54 | }), 55 | '`true` on single span child', 56 | ).toBe(true) 57 | }) 58 | 59 | test('isPortableTextBlock: minimum properties (non-span child)', () => { 60 | expect( 61 | isPortableTextBlock({ 62 | _type: 'any-type', 63 | children: [{_type: 'other', arb: 'itrary'}], 64 | }), 65 | '`true` on single non-span child', 66 | ).toBe(true) 67 | }) 68 | 69 | test('isPortableTextBlock: false on markDefs without a `_key`', () => { 70 | expect( 71 | isPortableTextBlock({ 72 | _type: 'block', 73 | _key: 'a', 74 | style: 'normal', 75 | children: [{_type: 'span', _key: 's', text: 'Portable Text', marks: ['l']}], 76 | markDefs: [{_type: 'link', href: 'https://portabletext.org/'} as any], 77 | }), 78 | '`false` on mark def with no `_type`', 79 | ).toBe(false) 80 | }) 81 | 82 | test('isPortableTextBlock: false on non-string `_type`', () => { 83 | expect( 84 | isPortableTextBlock({ 85 | _type: 123 as any, 86 | children: [], 87 | }), 88 | '`false` on non-string `_type`', 89 | ).toBe(false) 90 | }) 91 | 92 | test('isPortableTextBlock: false on non-array `markDefs`', () => { 93 | expect( 94 | isPortableTextBlock({ 95 | _type: 'block', 96 | children: [], 97 | markDefs: 123 as any, 98 | }), 99 | '`false` on non-array `markDefs`', 100 | ).toBe(false) 101 | }) 102 | 103 | test('isPortableTextBlock: false on missing `children`', () => { 104 | expect( 105 | isPortableTextBlock({ 106 | _type: 'block', 107 | _key: 'a', 108 | style: 'normal', 109 | markDefs: [{_key: 'l', _type: 'link', href: 'https://portabletext.org/'}], 110 | }), 111 | '`false` on missing `children`', 112 | ).toBe(false) 113 | }) 114 | 115 | test('isPortableTextBlock: false on `children` without `_type`', () => { 116 | expect( 117 | isPortableTextBlock({ 118 | _type: 'block', 119 | _key: 'a', 120 | style: 'normal', 121 | children: [{yep: ''} as any], 122 | }), 123 | '`false` on children missing `_type`', 124 | ).toBe(false) 125 | }) 126 | 127 | test('isPortableTextListItemBlock: true on all properties present', () => { 128 | expect( 129 | isPortableTextListItemBlock({ 130 | _type: 'block', 131 | _key: 'a', 132 | style: 'normal', 133 | children: [{_type: 'span', _key: 's', text: 'Portable Text', marks: ['l']}], 134 | markDefs: [{_key: 'l', _type: 'link', href: 'https://portabletext.org/'}], 135 | level: 3, 136 | listItem: 'bullet', 137 | }), 138 | '`true` if all list properties are present', 139 | ).toBe(true) 140 | }) 141 | 142 | test('isPortableTextListItemBlock: true on `level` missing', () => { 143 | expect( 144 | isPortableTextListItemBlock({ 145 | _type: 'block', 146 | _key: 'a', 147 | style: 'normal', 148 | children: [{_type: 'span', _key: 's', text: 'Portable Text', marks: ['l']}], 149 | markDefs: [{_key: 'l', _type: 'link', href: 'https://portabletext.org/'}], 150 | listItem: 'bullet', 151 | }), 152 | '`true` if all block properties + listItem are present', 153 | ).toBe(true) 154 | }) 155 | 156 | test('isPortableTextListItemBlock: false on `level` of incorrect type', () => { 157 | expect( 158 | isPortableTextListItemBlock({ 159 | _type: 'block', 160 | _key: 'a', 161 | style: 'normal', 162 | children: [{_type: 'span', _key: 's', text: 'Portable Text', marks: ['l']}], 163 | markDefs: [{_key: 'l', _type: 'link', href: 'https://portabletext.org/'}], 164 | listItem: 'bullet', 165 | level: 'nope' as any, 166 | }), 167 | '`false` if `level` is not a number', 168 | ).toBe(false) 169 | }) 170 | 171 | test('isPortableTextListItemBlock: false on `listItem` of incorrect type', () => { 172 | expect( 173 | isPortableTextListItemBlock({ 174 | _type: 'block', 175 | _key: 'a', 176 | style: 'normal', 177 | children: [{_type: 'span', _key: 's', text: 'Portable Text', marks: ['l']}], 178 | markDefs: [{_key: 'l', _type: 'link', href: 'https://portabletext.org/'}], 179 | listItem: 13 as any, 180 | }), 181 | '`false` if `listItem` is not a string', 182 | ).toBe(false) 183 | }) 184 | 185 | test('isPortableTextListItemBlock: false if no `listItem`', () => { 186 | expect( 187 | isPortableTextListItemBlock({ 188 | _type: 'block', 189 | _key: 'a', 190 | style: 'normal', 191 | children: [{_type: 'span', _key: 's', text: 'Portable Text', marks: ['l']}], 192 | markDefs: [{_key: 'l', _type: 'link', href: 'https://portabletext.org/'}], 193 | }), 194 | '`false` if `listItem` is missing', 195 | ).toBe(false) 196 | }) 197 | 198 | test('isPortableTextSpan: true on all valid span properties', () => { 199 | expect( 200 | isPortableTextSpan({ 201 | _type: 'span', 202 | _key: 'a', 203 | text: 'Portable Text', 204 | marks: ['l'], 205 | }), 206 | '`true` if all properties are present', 207 | ).toBe(true) 208 | }) 209 | 210 | test('isPortableTextSpan: true on all required span properties', () => { 211 | expect( 212 | isPortableTextSpan({ 213 | _type: 'span', 214 | text: 'Portable Text', 215 | }), 216 | '`true` if all required properties are present', 217 | ).toBe(true) 218 | }) 219 | 220 | test('isPortableTextSpan: false on non-`span` type', () => { 221 | expect( 222 | isPortableTextSpan({ 223 | _type: 'nonSpan', 224 | text: 'Portable Text', 225 | }), 226 | '`false` if `_type` is not `span`', 227 | ).toBe(false) 228 | }) 229 | 230 | test('isPortableTextSpan: false on missing `text`', () => { 231 | expect( 232 | isPortableTextSpan({ 233 | _type: 'span', 234 | foo: 'bar', 235 | }), 236 | '`false` if `text` is missing', 237 | ).toBe(false) 238 | }) 239 | 240 | test('isPortableTextSpan: false on non-string `text`', () => { 241 | expect( 242 | isPortableTextSpan({ 243 | _type: 'span', 244 | text: 123, 245 | }), 246 | '`false` if `text` is not a string', 247 | ).toBe(false) 248 | }) 249 | 250 | test('isPortableTextSpan: false on non-array `marks`', () => { 251 | expect( 252 | isPortableTextSpan({ 253 | _type: 'span', 254 | text: 'yes', 255 | marks: 'also yes', 256 | }), 257 | '`false` if `marks` is not an array', 258 | ).toBe(false) 259 | }) 260 | 261 | test('isPortableTextSpan: false on non-string `marks` item', () => { 262 | expect( 263 | isPortableTextSpan({ 264 | _type: 'span', 265 | text: 'yes', 266 | marks: ['yep', 123], 267 | }), 268 | '`false` if `marks` contains non-strings', 269 | ).toBe(false) 270 | }) 271 | 272 | /** 273 | * WEAK ASSERTERS FOLLOWS - THESE ARE NOT THOROUGH, ONLY SURFACE-LEVEL 274 | */ 275 | test('isPortableTextToolkitList: true on correct _type', () => { 276 | expect(isPortableTextToolkitList({_type: '@list'}), '`true` if `_type` is `@list`').toBe(true) 277 | }) 278 | 279 | test('isPortableTextToolkitList: false on incorrect _type', () => { 280 | expect(isPortableTextToolkitList({_type: 'list'}), '`false` if `_type` is not `@list`').toBe( 281 | false, 282 | ) 283 | }) 284 | 285 | test('isPortableTextToolkitSpan: true on correct _type', () => { 286 | expect(isPortableTextToolkitSpan({_type: '@span'}), '`true` if `_type` is `@span`').toBe(true) 287 | }) 288 | 289 | test('isPortableTextToolkitSpan: false on incorrect _type', () => { 290 | expect(isPortableTextToolkitSpan({_type: 'span'}), '`false` if `_type` is not `@span`').toBe( 291 | false, 292 | ) 293 | }) 294 | 295 | test('isPortableTextToolkitTextNode: true on correct _type', () => { 296 | expect(isPortableTextToolkitTextNode({_type: '@text'}), '`true` if `_type` is `@text`').toBe(true) 297 | }) 298 | 299 | test('isPortableTextToolkitTextNode: false on incorrect _type', () => { 300 | expect(isPortableTextToolkitTextNode({_type: 'text'}), '`false` if `_type` is not `@text`').toBe( 301 | false, 302 | ) 303 | }) 304 | -------------------------------------------------------------------------------- /test/__snapshots__/nestLists.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html 2 | 3 | exports[`nestLists: assumes level is 1 if not set 1`] = ` 4 | [ 5 | { 6 | "_key": "A0-parent", 7 | "_type": "@list", 8 | "children": [ 9 | { 10 | "_key": "A0", 11 | "_type": "block", 12 | "children": [ 13 | { 14 | "_type": "span", 15 | "text": "Bullet 1", 16 | }, 17 | ], 18 | "listItem": "bullet", 19 | }, 20 | ], 21 | "level": 1, 22 | "listItem": "bullet", 23 | "mode": "html", 24 | }, 25 | { 26 | "_key": "B0-parent", 27 | "_type": "@list", 28 | "children": [ 29 | { 30 | "_key": "B0", 31 | "_type": "block", 32 | "children": [ 33 | { 34 | "_type": "span", 35 | "text": "Bullet 2", 36 | }, 37 | ], 38 | "listItem": "number", 39 | }, 40 | ], 41 | "level": 1, 42 | "listItem": "number", 43 | "mode": "html", 44 | }, 45 | ] 46 | `; 47 | 48 | exports[`nestLists: ends lists when non-list item occurs 1`] = ` 49 | [ 50 | { 51 | "_key": "A0-parent", 52 | "_type": "@list", 53 | "children": [ 54 | { 55 | "_key": "A0", 56 | "_type": "block", 57 | "children": [ 58 | { 59 | "_type": "span", 60 | "text": "Bullet 1", 61 | }, 62 | ], 63 | "level": 1, 64 | "listItem": "bullet", 65 | }, 66 | { 67 | "_key": "B1", 68 | "_type": "block", 69 | "children": [ 70 | { 71 | "_type": "span", 72 | "text": "Bullet 2", 73 | }, 74 | ], 75 | "level": 1, 76 | "listItem": "bullet", 77 | }, 78 | ], 79 | "level": 1, 80 | "listItem": "bullet", 81 | "mode": "html", 82 | }, 83 | { 84 | "_type": "map", 85 | }, 86 | { 87 | "_key": "C0-parent", 88 | "_type": "@list", 89 | "children": [ 90 | { 91 | "_key": "C0", 92 | "_type": "block", 93 | "children": [ 94 | { 95 | "_type": "span", 96 | "text": "Number 1", 97 | }, 98 | ], 99 | "level": 1, 100 | "listItem": "number", 101 | }, 102 | { 103 | "_key": "D1", 104 | "_type": "block", 105 | "children": [ 106 | { 107 | "_type": "span", 108 | "text": "Number 2", 109 | }, 110 | ], 111 | "level": 1, 112 | "listItem": "number", 113 | }, 114 | ], 115 | "level": 1, 116 | "listItem": "number", 117 | "mode": "html", 118 | }, 119 | ] 120 | `; 121 | 122 | exports[`nestLists: handles deeper/shallower transitions correctly in direct mode 1`] = ` 123 | [ 124 | { 125 | "_key": "A0-parent", 126 | "_type": "@list", 127 | "children": [ 128 | { 129 | "_key": "A0", 130 | "_type": "block", 131 | "children": [ 132 | { 133 | "_type": "span", 134 | "text": "Level 1, A", 135 | }, 136 | ], 137 | "level": 1, 138 | "listItem": "bullet", 139 | }, 140 | { 141 | "_key": "B1", 142 | "_type": "block", 143 | "children": [ 144 | { 145 | "_type": "span", 146 | "text": "Level 1, B", 147 | }, 148 | ], 149 | "level": 1, 150 | "listItem": "bullet", 151 | }, 152 | { 153 | "_key": "C0-parent", 154 | "_type": "@list", 155 | "children": [ 156 | { 157 | "_key": "C0", 158 | "_type": "block", 159 | "children": [ 160 | { 161 | "_type": "span", 162 | "text": "Level 2, C", 163 | }, 164 | ], 165 | "level": 2, 166 | "listItem": "bullet", 167 | }, 168 | { 169 | "_key": "D1", 170 | "_type": "block", 171 | "children": [ 172 | { 173 | "_type": "span", 174 | "text": "Level 2, D", 175 | }, 176 | ], 177 | "level": 2, 178 | "listItem": "bullet", 179 | }, 180 | { 181 | "_key": "E0-parent", 182 | "_type": "@list", 183 | "children": [ 184 | { 185 | "_key": "E0", 186 | "_type": "block", 187 | "children": [ 188 | { 189 | "_type": "span", 190 | "text": "Level 3, E", 191 | }, 192 | ], 193 | "level": 3, 194 | "listItem": "bullet", 195 | }, 196 | { 197 | "_key": "F1", 198 | "_type": "block", 199 | "children": [ 200 | { 201 | "_type": "span", 202 | "text": "Level 3, F", 203 | }, 204 | ], 205 | "level": 3, 206 | "listItem": "bullet", 207 | }, 208 | ], 209 | "level": 3, 210 | "listItem": "bullet", 211 | "mode": "direct", 212 | }, 213 | { 214 | "_key": "G0", 215 | "_type": "block", 216 | "children": [ 217 | { 218 | "_type": "span", 219 | "text": "Level 2, G", 220 | }, 221 | ], 222 | "level": 2, 223 | "listItem": "bullet", 224 | }, 225 | { 226 | "_key": "H1", 227 | "_type": "block", 228 | "children": [ 229 | { 230 | "_type": "span", 231 | "text": "Level 2, H", 232 | }, 233 | ], 234 | "level": 2, 235 | "listItem": "bullet", 236 | }, 237 | { 238 | "_key": "I0-parent", 239 | "_type": "@list", 240 | "children": [ 241 | { 242 | "_key": "I0", 243 | "_type": "block", 244 | "children": [ 245 | { 246 | "_type": "span", 247 | "text": "Level 3, I", 248 | }, 249 | ], 250 | "level": 3, 251 | "listItem": "bullet", 252 | }, 253 | { 254 | "_key": "J1", 255 | "_type": "block", 256 | "children": [ 257 | { 258 | "_type": "span", 259 | "text": "Level 3, J", 260 | }, 261 | ], 262 | "level": 3, 263 | "listItem": "bullet", 264 | }, 265 | ], 266 | "level": 3, 267 | "listItem": "bullet", 268 | "mode": "direct", 269 | }, 270 | ], 271 | "level": 2, 272 | "listItem": "bullet", 273 | "mode": "direct", 274 | }, 275 | ], 276 | "level": 1, 277 | "listItem": "bullet", 278 | "mode": "direct", 279 | }, 280 | { 281 | "_key": "K0-parent", 282 | "_type": "@list", 283 | "children": [ 284 | { 285 | "_key": "K0", 286 | "_type": "block", 287 | "children": [ 288 | { 289 | "_type": "span", 290 | "text": "Level 1, K", 291 | }, 292 | ], 293 | "level": 1, 294 | "listItem": "number", 295 | }, 296 | { 297 | "_key": "L1", 298 | "_type": "block", 299 | "children": [ 300 | { 301 | "_type": "span", 302 | "text": "Level 1, L", 303 | }, 304 | ], 305 | "level": 1, 306 | "listItem": "number", 307 | }, 308 | ], 309 | "level": 1, 310 | "listItem": "number", 311 | "mode": "direct", 312 | }, 313 | ] 314 | `; 315 | 316 | exports[`nestLists: handles deeper/shallower transitions correctly in html mode 1`] = ` 317 | [ 318 | { 319 | "_key": "A0-parent", 320 | "_type": "@list", 321 | "children": [ 322 | { 323 | "_key": "A0", 324 | "_type": "block", 325 | "children": [ 326 | { 327 | "_type": "span", 328 | "text": "Level 1, A", 329 | }, 330 | ], 331 | "level": 1, 332 | "listItem": "bullet", 333 | }, 334 | { 335 | "_key": "B1", 336 | "_type": "block", 337 | "children": [ 338 | { 339 | "_type": "span", 340 | "text": "Level 1, B", 341 | }, 342 | { 343 | "_key": "C0-parent", 344 | "_type": "@list", 345 | "children": [ 346 | { 347 | "_key": "C0", 348 | "_type": "block", 349 | "children": [ 350 | { 351 | "_type": "span", 352 | "text": "Level 2, C", 353 | }, 354 | ], 355 | "level": 2, 356 | "listItem": "bullet", 357 | }, 358 | { 359 | "_key": "D1", 360 | "_type": "block", 361 | "children": [ 362 | { 363 | "_type": "span", 364 | "text": "Level 2, D", 365 | }, 366 | { 367 | "_key": "E0-parent", 368 | "_type": "@list", 369 | "children": [ 370 | { 371 | "_key": "E0", 372 | "_type": "block", 373 | "children": [ 374 | { 375 | "_type": "span", 376 | "text": "Level 3, E", 377 | }, 378 | ], 379 | "level": 3, 380 | "listItem": "bullet", 381 | }, 382 | { 383 | "_key": "F1", 384 | "_type": "block", 385 | "children": [ 386 | { 387 | "_type": "span", 388 | "text": "Level 3, F", 389 | }, 390 | ], 391 | "level": 3, 392 | "listItem": "bullet", 393 | }, 394 | ], 395 | "level": 3, 396 | "listItem": "bullet", 397 | "mode": "html", 398 | }, 399 | ], 400 | "level": 2, 401 | "listItem": "bullet", 402 | }, 403 | { 404 | "_key": "G0", 405 | "_type": "block", 406 | "children": [ 407 | { 408 | "_type": "span", 409 | "text": "Level 2, G", 410 | }, 411 | ], 412 | "level": 2, 413 | "listItem": "bullet", 414 | }, 415 | { 416 | "_key": "H1", 417 | "_type": "block", 418 | "children": [ 419 | { 420 | "_type": "span", 421 | "text": "Level 2, H", 422 | }, 423 | { 424 | "_key": "I0-parent", 425 | "_type": "@list", 426 | "children": [ 427 | { 428 | "_key": "I0", 429 | "_type": "block", 430 | "children": [ 431 | { 432 | "_type": "span", 433 | "text": "Level 3, I", 434 | }, 435 | ], 436 | "level": 3, 437 | "listItem": "bullet", 438 | }, 439 | { 440 | "_key": "J1", 441 | "_type": "block", 442 | "children": [ 443 | { 444 | "_type": "span", 445 | "text": "Level 3, J", 446 | }, 447 | ], 448 | "level": 3, 449 | "listItem": "bullet", 450 | }, 451 | ], 452 | "level": 3, 453 | "listItem": "bullet", 454 | "mode": "html", 455 | }, 456 | ], 457 | "level": 2, 458 | "listItem": "bullet", 459 | }, 460 | ], 461 | "level": 2, 462 | "listItem": "bullet", 463 | "mode": "html", 464 | }, 465 | ], 466 | "level": 1, 467 | "listItem": "bullet", 468 | }, 469 | ], 470 | "level": 1, 471 | "listItem": "bullet", 472 | "mode": "html", 473 | }, 474 | { 475 | "_key": "K0-parent", 476 | "_type": "@list", 477 | "children": [ 478 | { 479 | "_key": "K0", 480 | "_type": "block", 481 | "children": [ 482 | { 483 | "_type": "span", 484 | "text": "Level 1, K", 485 | }, 486 | ], 487 | "level": 1, 488 | "listItem": "number", 489 | }, 490 | { 491 | "_key": "L1", 492 | "_type": "block", 493 | "children": [ 494 | { 495 | "_type": "span", 496 | "text": "Level 1, L", 497 | }, 498 | ], 499 | "level": 1, 500 | "listItem": "number", 501 | }, 502 | ], 503 | "level": 1, 504 | "listItem": "number", 505 | "mode": "html", 506 | }, 507 | ] 508 | `; 509 | 510 | exports[`nestLists: nests deeper lists inside of parent list in direct mode 1`] = ` 511 | [ 512 | { 513 | "_key": "A0-parent", 514 | "_type": "@list", 515 | "children": [ 516 | { 517 | "_key": "A0", 518 | "_type": "block", 519 | "children": [ 520 | { 521 | "_type": "span", 522 | "text": "Bullet 1", 523 | }, 524 | ], 525 | "level": 1, 526 | "listItem": "bullet", 527 | }, 528 | { 529 | "_key": "B1", 530 | "_type": "block", 531 | "children": [ 532 | { 533 | "_type": "span", 534 | "text": "Bullet 2", 535 | }, 536 | ], 537 | "level": 1, 538 | "listItem": "bullet", 539 | }, 540 | { 541 | "_key": "C0-parent", 542 | "_type": "@list", 543 | "children": [ 544 | { 545 | "_key": "C0", 546 | "_type": "block", 547 | "children": [ 548 | { 549 | "_type": "span", 550 | "text": "Number 1", 551 | }, 552 | ], 553 | "level": 2, 554 | "listItem": "number", 555 | }, 556 | { 557 | "_key": "D1", 558 | "_type": "block", 559 | "children": [ 560 | { 561 | "_type": "span", 562 | "text": "Number 2", 563 | }, 564 | ], 565 | "level": 2, 566 | "listItem": "number", 567 | }, 568 | ], 569 | "level": 2, 570 | "listItem": "number", 571 | "mode": "direct", 572 | }, 573 | ], 574 | "level": 1, 575 | "listItem": "bullet", 576 | "mode": "direct", 577 | }, 578 | ] 579 | `; 580 | 581 | exports[`nestLists: wraps adjacent list items of different types in separate list nodes 1`] = ` 582 | [ 583 | { 584 | "_key": "A0-parent", 585 | "_type": "@list", 586 | "children": [ 587 | { 588 | "_key": "A0", 589 | "_type": "block", 590 | "children": [ 591 | { 592 | "_type": "span", 593 | "text": "Bullet 1", 594 | }, 595 | ], 596 | "level": 1, 597 | "listItem": "bullet", 598 | }, 599 | { 600 | "_key": "B1", 601 | "_type": "block", 602 | "children": [ 603 | { 604 | "_type": "span", 605 | "text": "Bullet 2", 606 | }, 607 | ], 608 | "level": 1, 609 | "listItem": "bullet", 610 | }, 611 | ], 612 | "level": 1, 613 | "listItem": "bullet", 614 | "mode": "html", 615 | }, 616 | { 617 | "_key": "C0-parent", 618 | "_type": "@list", 619 | "children": [ 620 | { 621 | "_key": "C0", 622 | "_type": "block", 623 | "children": [ 624 | { 625 | "_type": "span", 626 | "text": "Number 1", 627 | }, 628 | ], 629 | "level": 1, 630 | "listItem": "number", 631 | }, 632 | { 633 | "_key": "D1", 634 | "_type": "block", 635 | "children": [ 636 | { 637 | "_type": "span", 638 | "text": "Number 2", 639 | }, 640 | ], 641 | "level": 1, 642 | "listItem": "number", 643 | }, 644 | ], 645 | "level": 1, 646 | "listItem": "number", 647 | "mode": "html", 648 | }, 649 | ] 650 | `; 651 | 652 | exports[`nestLists: wraps adjacent list items of different types in separate list nodes 2`] = ` 653 | [ 654 | { 655 | "_key": "A0-parent", 656 | "_type": "@list", 657 | "children": [ 658 | { 659 | "_key": "A0", 660 | "_type": "block", 661 | "children": [ 662 | { 663 | "_type": "span", 664 | "text": "Bullet 1", 665 | }, 666 | ], 667 | "level": 1, 668 | "listItem": "bullet", 669 | }, 670 | { 671 | "_key": "B1", 672 | "_type": "block", 673 | "children": [ 674 | { 675 | "_type": "span", 676 | "text": "Bullet 2", 677 | }, 678 | ], 679 | "level": 1, 680 | "listItem": "bullet", 681 | }, 682 | ], 683 | "level": 1, 684 | "listItem": "bullet", 685 | "mode": "html", 686 | }, 687 | { 688 | "_key": "C0-parent", 689 | "_type": "@list", 690 | "children": [ 691 | { 692 | "_key": "C0", 693 | "_type": "block", 694 | "children": [ 695 | { 696 | "_type": "span", 697 | "text": "Number 1", 698 | }, 699 | ], 700 | "level": 1, 701 | "listItem": "number", 702 | }, 703 | { 704 | "_key": "D1", 705 | "_type": "block", 706 | "children": [ 707 | { 708 | "_type": "span", 709 | "text": "Number 2", 710 | }, 711 | ], 712 | "level": 1, 713 | "listItem": "number", 714 | }, 715 | ], 716 | "level": 1, 717 | "listItem": "number", 718 | "mode": "html", 719 | }, 720 | ] 721 | `; 722 | 723 | exports[`nestLists: wraps adjacent list items of same type/level in toolkit list node 1`] = ` 724 | [ 725 | { 726 | "_key": "A0-parent", 727 | "_type": "@list", 728 | "children": [ 729 | { 730 | "_key": "A0", 731 | "_type": "block", 732 | "children": [ 733 | { 734 | "_type": "span", 735 | "text": "First", 736 | }, 737 | ], 738 | "level": 1, 739 | "listItem": "bullet", 740 | }, 741 | { 742 | "_key": "B1", 743 | "_type": "block", 744 | "children": [ 745 | { 746 | "_type": "span", 747 | "text": "Second", 748 | }, 749 | ], 750 | "level": 1, 751 | "listItem": "bullet", 752 | }, 753 | { 754 | "_key": "C2", 755 | "_type": "block", 756 | "children": [ 757 | { 758 | "_type": "span", 759 | "text": "Third", 760 | }, 761 | ], 762 | "level": 1, 763 | "listItem": "bullet", 764 | }, 765 | ], 766 | "level": 1, 767 | "listItem": "bullet", 768 | "mode": "html", 769 | }, 770 | ] 771 | `; 772 | 773 | exports[`nestLists: wraps deeper lists inside of last list item in html mode 1`] = ` 774 | [ 775 | { 776 | "_key": "A0-parent", 777 | "_type": "@list", 778 | "children": [ 779 | { 780 | "_key": "A0", 781 | "_type": "block", 782 | "children": [ 783 | { 784 | "_type": "span", 785 | "text": "Bullet 1", 786 | }, 787 | ], 788 | "level": 1, 789 | "listItem": "bullet", 790 | }, 791 | { 792 | "_key": "B1", 793 | "_type": "block", 794 | "children": [ 795 | { 796 | "_type": "span", 797 | "text": "Bullet 2", 798 | }, 799 | { 800 | "_key": "C0-parent", 801 | "_type": "@list", 802 | "children": [ 803 | { 804 | "_key": "C0", 805 | "_type": "block", 806 | "children": [ 807 | { 808 | "_type": "span", 809 | "text": "Number 1", 810 | }, 811 | ], 812 | "level": 2, 813 | "listItem": "number", 814 | }, 815 | { 816 | "_key": "D1", 817 | "_type": "block", 818 | "children": [ 819 | { 820 | "_type": "span", 821 | "text": "Number 2", 822 | }, 823 | ], 824 | "level": 2, 825 | "listItem": "number", 826 | }, 827 | ], 828 | "level": 2, 829 | "listItem": "number", 830 | "mode": "html", 831 | }, 832 | ], 833 | "level": 1, 834 | "listItem": "bullet", 835 | }, 836 | ], 837 | "level": 1, 838 | "listItem": "bullet", 839 | "mode": "html", 840 | }, 841 | ] 842 | `; 843 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@portabletext/types': 12 | specifier: ^4.0.0 13 | version: 4.0.0 14 | devDependencies: 15 | '@changesets/changelog-github': 16 | specifier: ^0.5.2 17 | version: 0.5.2 18 | '@changesets/cli': 19 | specifier: ^2.29.8 20 | version: 2.29.8(@types/node@24.10.4) 21 | '@sanity/tsconfig': 22 | specifier: ^2.1.0 23 | version: 2.1.0 24 | '@sanity/tsdown-config': 25 | specifier: ^0.4.2 26 | version: 0.4.2(tsdown@0.17.2(publint@0.3.16)(typescript@5.9.3))(typescript@5.9.3) 27 | '@types/node': 28 | specifier: ^24.10.4 29 | version: 24.10.4 30 | '@vitest/coverage-v8': 31 | specifier: ^4.0.15 32 | version: 4.0.15(vitest@4.0.15(@types/node@24.10.4)(lightningcss@1.30.2)(terser@5.30.3)(tsx@4.20.6)(yaml@2.8.1)) 33 | oxfmt: 34 | specifier: ^0.18.0 35 | version: 0.18.0 36 | oxlint: 37 | specifier: ^1.33.0 38 | version: 1.33.0(oxlint-tsgolint@0.9.1) 39 | oxlint-tsgolint: 40 | specifier: ^0.9.1 41 | version: 0.9.1 42 | tsdown: 43 | specifier: ^0.17.2 44 | version: 0.17.2(publint@0.3.16)(typescript@5.9.3) 45 | typedoc: 46 | specifier: ^0.28.15 47 | version: 0.28.15(typescript@5.9.3) 48 | typescript: 49 | specifier: 5.9.3 50 | version: 5.9.3 51 | vitest: 52 | specifier: ^4.0.15 53 | version: 4.0.15(@types/node@24.10.4)(lightningcss@1.30.2)(terser@5.30.3)(tsx@4.20.6)(yaml@2.8.1) 54 | 55 | packages: 56 | 57 | '@babel/generator@7.28.5': 58 | resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} 59 | engines: {node: '>=6.9.0'} 60 | 61 | '@babel/helper-string-parser@7.27.1': 62 | resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} 63 | engines: {node: '>=6.9.0'} 64 | 65 | '@babel/helper-validator-identifier@7.28.5': 66 | resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} 67 | engines: {node: '>=6.9.0'} 68 | 69 | '@babel/parser@7.28.5': 70 | resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} 71 | engines: {node: '>=6.0.0'} 72 | hasBin: true 73 | 74 | '@babel/runtime@7.28.3': 75 | resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==} 76 | engines: {node: '>=6.9.0'} 77 | 78 | '@babel/types@7.28.5': 79 | resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} 80 | engines: {node: '>=6.9.0'} 81 | 82 | '@bcoe/v8-coverage@1.0.2': 83 | resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} 84 | engines: {node: '>=18'} 85 | 86 | '@changesets/apply-release-plan@7.0.14': 87 | resolution: {integrity: sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==} 88 | 89 | '@changesets/assemble-release-plan@6.0.9': 90 | resolution: {integrity: sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==} 91 | 92 | '@changesets/changelog-git@0.2.1': 93 | resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} 94 | 95 | '@changesets/changelog-github@0.5.2': 96 | resolution: {integrity: sha512-HeGeDl8HaIGj9fQHo/tv5XKQ2SNEi9+9yl1Bss1jttPqeiASRXhfi0A2wv8yFKCp07kR1gpOI5ge6+CWNm1jPw==} 97 | 98 | '@changesets/cli@2.29.8': 99 | resolution: {integrity: sha512-1weuGZpP63YWUYjay/E84qqwcnt5yJMM0tep10Up7Q5cS/DGe2IZ0Uj3HNMxGhCINZuR7aO9WBMdKnPit5ZDPA==} 100 | hasBin: true 101 | 102 | '@changesets/config@3.1.2': 103 | resolution: {integrity: sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==} 104 | 105 | '@changesets/errors@0.2.0': 106 | resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} 107 | 108 | '@changesets/get-dependents-graph@2.1.3': 109 | resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} 110 | 111 | '@changesets/get-github-info@0.7.0': 112 | resolution: {integrity: sha512-+i67Bmhfj9V4KfDeS1+Tz3iF32btKZB2AAx+cYMqDSRFP7r3/ZdGbjCo+c6qkyViN9ygDuBjzageuPGJtKGe5A==} 113 | 114 | '@changesets/get-release-plan@4.0.14': 115 | resolution: {integrity: sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==} 116 | 117 | '@changesets/get-version-range-type@0.4.0': 118 | resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} 119 | 120 | '@changesets/git@3.0.4': 121 | resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==} 122 | 123 | '@changesets/logger@0.1.1': 124 | resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} 125 | 126 | '@changesets/parse@0.4.2': 127 | resolution: {integrity: sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==} 128 | 129 | '@changesets/pre@2.0.2': 130 | resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} 131 | 132 | '@changesets/read@0.6.6': 133 | resolution: {integrity: sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==} 134 | 135 | '@changesets/should-skip-package@0.1.2': 136 | resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} 137 | 138 | '@changesets/types@4.1.0': 139 | resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} 140 | 141 | '@changesets/types@6.1.0': 142 | resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} 143 | 144 | '@changesets/write@0.4.0': 145 | resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} 146 | 147 | '@emnapi/core@1.7.1': 148 | resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} 149 | 150 | '@emnapi/runtime@1.7.1': 151 | resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} 152 | 153 | '@emnapi/wasi-threads@1.1.0': 154 | resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} 155 | 156 | '@esbuild/aix-ppc64@0.25.12': 157 | resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} 158 | engines: {node: '>=18'} 159 | cpu: [ppc64] 160 | os: [aix] 161 | 162 | '@esbuild/android-arm64@0.25.12': 163 | resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} 164 | engines: {node: '>=18'} 165 | cpu: [arm64] 166 | os: [android] 167 | 168 | '@esbuild/android-arm@0.25.12': 169 | resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} 170 | engines: {node: '>=18'} 171 | cpu: [arm] 172 | os: [android] 173 | 174 | '@esbuild/android-x64@0.25.12': 175 | resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} 176 | engines: {node: '>=18'} 177 | cpu: [x64] 178 | os: [android] 179 | 180 | '@esbuild/darwin-arm64@0.25.12': 181 | resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} 182 | engines: {node: '>=18'} 183 | cpu: [arm64] 184 | os: [darwin] 185 | 186 | '@esbuild/darwin-x64@0.25.12': 187 | resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} 188 | engines: {node: '>=18'} 189 | cpu: [x64] 190 | os: [darwin] 191 | 192 | '@esbuild/freebsd-arm64@0.25.12': 193 | resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} 194 | engines: {node: '>=18'} 195 | cpu: [arm64] 196 | os: [freebsd] 197 | 198 | '@esbuild/freebsd-x64@0.25.12': 199 | resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} 200 | engines: {node: '>=18'} 201 | cpu: [x64] 202 | os: [freebsd] 203 | 204 | '@esbuild/linux-arm64@0.25.12': 205 | resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} 206 | engines: {node: '>=18'} 207 | cpu: [arm64] 208 | os: [linux] 209 | 210 | '@esbuild/linux-arm@0.25.12': 211 | resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} 212 | engines: {node: '>=18'} 213 | cpu: [arm] 214 | os: [linux] 215 | 216 | '@esbuild/linux-ia32@0.25.12': 217 | resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} 218 | engines: {node: '>=18'} 219 | cpu: [ia32] 220 | os: [linux] 221 | 222 | '@esbuild/linux-loong64@0.25.12': 223 | resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} 224 | engines: {node: '>=18'} 225 | cpu: [loong64] 226 | os: [linux] 227 | 228 | '@esbuild/linux-mips64el@0.25.12': 229 | resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} 230 | engines: {node: '>=18'} 231 | cpu: [mips64el] 232 | os: [linux] 233 | 234 | '@esbuild/linux-ppc64@0.25.12': 235 | resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} 236 | engines: {node: '>=18'} 237 | cpu: [ppc64] 238 | os: [linux] 239 | 240 | '@esbuild/linux-riscv64@0.25.12': 241 | resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} 242 | engines: {node: '>=18'} 243 | cpu: [riscv64] 244 | os: [linux] 245 | 246 | '@esbuild/linux-s390x@0.25.12': 247 | resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} 248 | engines: {node: '>=18'} 249 | cpu: [s390x] 250 | os: [linux] 251 | 252 | '@esbuild/linux-x64@0.25.12': 253 | resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} 254 | engines: {node: '>=18'} 255 | cpu: [x64] 256 | os: [linux] 257 | 258 | '@esbuild/netbsd-arm64@0.25.12': 259 | resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} 260 | engines: {node: '>=18'} 261 | cpu: [arm64] 262 | os: [netbsd] 263 | 264 | '@esbuild/netbsd-x64@0.25.12': 265 | resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} 266 | engines: {node: '>=18'} 267 | cpu: [x64] 268 | os: [netbsd] 269 | 270 | '@esbuild/openbsd-arm64@0.25.12': 271 | resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} 272 | engines: {node: '>=18'} 273 | cpu: [arm64] 274 | os: [openbsd] 275 | 276 | '@esbuild/openbsd-x64@0.25.12': 277 | resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} 278 | engines: {node: '>=18'} 279 | cpu: [x64] 280 | os: [openbsd] 281 | 282 | '@esbuild/openharmony-arm64@0.25.12': 283 | resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} 284 | engines: {node: '>=18'} 285 | cpu: [arm64] 286 | os: [openharmony] 287 | 288 | '@esbuild/sunos-x64@0.25.12': 289 | resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} 290 | engines: {node: '>=18'} 291 | cpu: [x64] 292 | os: [sunos] 293 | 294 | '@esbuild/win32-arm64@0.25.12': 295 | resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} 296 | engines: {node: '>=18'} 297 | cpu: [arm64] 298 | os: [win32] 299 | 300 | '@esbuild/win32-ia32@0.25.12': 301 | resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} 302 | engines: {node: '>=18'} 303 | cpu: [ia32] 304 | os: [win32] 305 | 306 | '@esbuild/win32-x64@0.25.12': 307 | resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} 308 | engines: {node: '>=18'} 309 | cpu: [x64] 310 | os: [win32] 311 | 312 | '@gerrit0/mini-shiki@3.18.0': 313 | resolution: {integrity: sha512-zTAG1cXK5Q+T6CBEa8mqEnCx/H9rrpWEn+vhMbWikzmeO2jltY6zVE2m9YCO+xDi+P0vpBrOG1Xgi8AZtlNoUA==} 314 | 315 | '@inquirer/external-editor@1.0.3': 316 | resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} 317 | engines: {node: '>=18'} 318 | peerDependencies: 319 | '@types/node': '>=18' 320 | peerDependenciesMeta: 321 | '@types/node': 322 | optional: true 323 | 324 | '@jridgewell/gen-mapping@0.3.13': 325 | resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} 326 | 327 | '@jridgewell/resolve-uri@3.1.2': 328 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 329 | engines: {node: '>=6.0.0'} 330 | 331 | '@jridgewell/source-map@0.3.6': 332 | resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} 333 | 334 | '@jridgewell/sourcemap-codec@1.5.5': 335 | resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} 336 | 337 | '@jridgewell/trace-mapping@0.3.31': 338 | resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} 339 | 340 | '@manypkg/find-root@1.1.0': 341 | resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} 342 | 343 | '@manypkg/get-packages@1.1.3': 344 | resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} 345 | 346 | '@napi-rs/wasm-runtime@1.1.0': 347 | resolution: {integrity: sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==} 348 | 349 | '@nodelib/fs.scandir@2.1.5': 350 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 351 | engines: {node: '>= 8'} 352 | 353 | '@nodelib/fs.stat@2.0.5': 354 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 355 | engines: {node: '>= 8'} 356 | 357 | '@nodelib/fs.walk@1.2.8': 358 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 359 | engines: {node: '>= 8'} 360 | 361 | '@oxc-project/types@0.101.0': 362 | resolution: {integrity: sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ==} 363 | 364 | '@oxfmt/darwin-arm64@0.18.0': 365 | resolution: {integrity: sha512-Dp3mOFUtLtG/0eDclI3rx2be5FEnUxh2T6zlq7Zx5Q1c+DS9LJF8H97nQx+O/OU+o0e0J90kN8Msf9v3j7Hhsg==} 366 | cpu: [arm64] 367 | os: [darwin] 368 | 369 | '@oxfmt/darwin-x64@0.18.0': 370 | resolution: {integrity: sha512-Oe3KS4tdfLq+f1Ebje7D9BF7/0xmBYSMN6dWatSko1xfvu8oCZzKcNCcbwz0a8rBnoH/BnIiGFUEbgJDnA/JLQ==} 371 | cpu: [x64] 372 | os: [darwin] 373 | 374 | '@oxfmt/linux-arm64-gnu@0.18.0': 375 | resolution: {integrity: sha512-zW9z8LrAgL9bswgsaFOnQmoImCbq9YQST8B15FAoTeZYr9sb/VfdD6/PQEBLCptYlFmoTvmDNHjppi9g61NwHQ==} 376 | cpu: [arm64] 377 | os: [linux] 378 | 379 | '@oxfmt/linux-arm64-musl@0.18.0': 380 | resolution: {integrity: sha512-mFnpcasZZv1s/+6YDPradhIgR2G7GWr+mnzgJMIKQOJAtX3b0vzG+FE4f7hDIZPEUhC0hvZSd8f31FjAtrX0aQ==} 381 | cpu: [arm64] 382 | os: [linux] 383 | 384 | '@oxfmt/linux-x64-gnu@0.18.0': 385 | resolution: {integrity: sha512-G1AXQNHVkPgVgRrAvDYdNi0x3gkvVyEmpL6WLMwoSjMnwYWQLt5/jrndHbS2Db8/CcmMo6VPP8lUQGvM4TRVaQ==} 386 | cpu: [x64] 387 | os: [linux] 388 | 389 | '@oxfmt/linux-x64-musl@0.18.0': 390 | resolution: {integrity: sha512-M/KEIMHDr5lcK9gDxgIGr9xVwX7Pfl3PZs+6e8SySuckMgoJMkee6uWxhMdxws3dfU94saAkVmNQzM2+l3hvtA==} 391 | cpu: [x64] 392 | os: [linux] 393 | 394 | '@oxfmt/win32-arm64@0.18.0': 395 | resolution: {integrity: sha512-LunuNBTLOgfkYFjiHOeNHD/Ii5paO/GVyNPSEYBwEPULbdeMGnjHqxzQHLGU8QIQjwu55mp4uuBP0DAXTli2TQ==} 396 | cpu: [arm64] 397 | os: [win32] 398 | 399 | '@oxfmt/win32-x64@0.18.0': 400 | resolution: {integrity: sha512-0kJJwn4FPeGJ4uV6ofOCiY+oBKWg+RWpRjYc9bywTjDbxWR6JAqtuXkiARCJej8UD/rJeXnHYTF78sFALkwZyA==} 401 | cpu: [x64] 402 | os: [win32] 403 | 404 | '@oxlint-tsgolint/darwin-arm64@0.9.1': 405 | resolution: {integrity: sha512-vk+8kChWqN+F+QUOvp4/6jDTlDCzXPgYGkxdi6EOUSOmCP1ix0uYOlIi/ytH2imXmC8YfPgLR/1BhqbsuDKuew==} 406 | cpu: [arm64] 407 | os: [darwin] 408 | 409 | '@oxlint-tsgolint/darwin-x64@0.9.1': 410 | resolution: {integrity: sha512-yXmqr7El17+Oo56fWkPdUluU8d0jWxwRwAe1QZ0Xprxul9FHJeR/O2oYuBUngvCi02dbt0VZlwgJXcljQEdHlQ==} 411 | cpu: [x64] 412 | os: [darwin] 413 | 414 | '@oxlint-tsgolint/linux-arm64@0.9.1': 415 | resolution: {integrity: sha512-ukLb35BHSsxXaVEe8eIvYXMTxOdv8K4CySmtkWyc0pJT0q8zh85by1bsREWAP2hZc0wN0ClHjZHPdKY3958Jwg==} 416 | cpu: [arm64] 417 | os: [linux] 418 | 419 | '@oxlint-tsgolint/linux-x64@0.9.1': 420 | resolution: {integrity: sha512-kkxSS/meANLun4dHep2wnfvo8OHJKgdxzuY3RoooSWorVqw3/K5Qttmo0OQFt7UNq/oisn0YTaNhV28S0nAWyQ==} 421 | cpu: [x64] 422 | os: [linux] 423 | 424 | '@oxlint-tsgolint/win32-arm64@0.9.1': 425 | resolution: {integrity: sha512-F9tiZZRn3x+kjXJC8GAE5C5xkvD8b8unoFeh7mS5W4USAH8+AzYydzLev5rAW2uXdOqtkO30EJl0ygl68Zlb8w==} 426 | cpu: [arm64] 427 | os: [win32] 428 | 429 | '@oxlint-tsgolint/win32-x64@0.9.1': 430 | resolution: {integrity: sha512-DKTBgKUbycKNYgpWpglEHzkgiNVSG1rZmfiqw7w31keAq8q7avNGhz2WNmsRvXh8IGNw1PMb7vgxwUK8eyXIeg==} 431 | cpu: [x64] 432 | os: [win32] 433 | 434 | '@oxlint/darwin-arm64@1.33.0': 435 | resolution: {integrity: sha512-PmEQDLHAxiAdyttQ1ZWXd+5VpHLbHf3FTMJL9bg5TZamDnhNiW/v0Pamv3MTAdymnoDI3H8IVLAN/SAseV/adw==} 436 | cpu: [arm64] 437 | os: [darwin] 438 | 439 | '@oxlint/darwin-x64@1.33.0': 440 | resolution: {integrity: sha512-2R9aH3kR0X2M30z5agGikv3tfNTi8/uLhU5/tYktu33VGUXpbf0OLZSlD25UEuwOKAlf3RVtzV5oDyjoq93JuQ==} 441 | cpu: [x64] 442 | os: [darwin] 443 | 444 | '@oxlint/linux-arm64-gnu@1.33.0': 445 | resolution: {integrity: sha512-yb/k8GaMDgnX2LyO6km33kKItZ/n573SlbiHBBFU2HmeU7tzEHL5jHkHQXXcysUkapmqHd7UsDhOZDqPmXaQRg==} 446 | cpu: [arm64] 447 | os: [linux] 448 | 449 | '@oxlint/linux-arm64-musl@1.33.0': 450 | resolution: {integrity: sha512-03pt9IO1C4ZfVOW6SQiOK26mzklAhLM3Kc79OXpX1kgZRlxk+rvFoMhlgCOzn7tEdrEgbePkBoxNnwDnJDFqJQ==} 451 | cpu: [arm64] 452 | os: [linux] 453 | 454 | '@oxlint/linux-x64-gnu@1.33.0': 455 | resolution: {integrity: sha512-Z7ImLWM50FoVXzYvyxUQ+QwBkBfRyK4YdLEGonyAGMp7iT3DksonDaTK9ODnJ1qHyAyAZCvuqXD7AEDsDvzDbA==} 456 | cpu: [x64] 457 | os: [linux] 458 | 459 | '@oxlint/linux-x64-musl@1.33.0': 460 | resolution: {integrity: sha512-idb55Uzu5kkqqpMiVUfI9nP7zOqPZinQKsIRQAIU40wILcf/ijvhNZKIu3ucDMmye0n6IWOaSnxIRL5W2fNoUQ==} 461 | cpu: [x64] 462 | os: [linux] 463 | 464 | '@oxlint/win32-arm64@1.33.0': 465 | resolution: {integrity: sha512-wKKFt7cubfrLelNzdmDsNSmtBrlSUe1fWus587+uSxDZdpFbQ7liU0gsUlCbcHvym0H1Tc2O3K3cnLrgQORLPQ==} 466 | cpu: [arm64] 467 | os: [win32] 468 | 469 | '@oxlint/win32-x64@1.33.0': 470 | resolution: {integrity: sha512-ReyR8rNHjKNnO7dxGny9RCPELRAdhm3y780FNBcA07E1wvxSCkB+Mn5db0Pa5bRmxrsU/MTZ/aaBFa+ERXDdXw==} 471 | cpu: [x64] 472 | os: [win32] 473 | 474 | '@portabletext/types@4.0.0': 475 | resolution: {integrity: sha512-mEoN82OQckrshqRx8idp+x8B/OpMfUMSjQp1w1wZFM3hf8cplGhK59Sa/UuGU6XdgAnFq90vJtnj5ejOmZmhvw==} 476 | engines: {node: '>=20.19 <22 || >=22.12'} 477 | 478 | '@publint/pack@0.1.2': 479 | resolution: {integrity: sha512-S+9ANAvUmjutrshV4jZjaiG8XQyuJIZ8a4utWmN/vW1sgQ9IfBnPndwkmQYw53QmouOIytT874u65HEmu6H5jw==} 480 | engines: {node: '>=18'} 481 | 482 | '@quansync/fs@1.0.0': 483 | resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} 484 | 485 | '@rolldown/binding-android-arm64@1.0.0-beta.53': 486 | resolution: {integrity: sha512-Ok9V8o7o6YfSdTTYA/uHH30r3YtOxLD6G3wih/U9DO0ucBBFq8WPt/DslU53OgfteLRHITZny9N/qCUxMf9kjQ==} 487 | engines: {node: ^20.19.0 || >=22.12.0} 488 | cpu: [arm64] 489 | os: [android] 490 | 491 | '@rolldown/binding-darwin-arm64@1.0.0-beta.53': 492 | resolution: {integrity: sha512-yIsKqMz0CtRnVa6x3Pa+mzTihr4Ty+Z6HfPbZ7RVbk1Uxnco4+CUn7Qbm/5SBol1JD/7nvY8rphAgyAi7Lj6Vg==} 493 | engines: {node: ^20.19.0 || >=22.12.0} 494 | cpu: [arm64] 495 | os: [darwin] 496 | 497 | '@rolldown/binding-darwin-x64@1.0.0-beta.53': 498 | resolution: {integrity: sha512-GTXe+mxsCGUnJOFMhfGWmefP7Q9TpYUseHvhAhr21nCTgdS8jPsvirb0tJwM3lN0/u/cg7bpFNa16fQrjKrCjQ==} 499 | engines: {node: ^20.19.0 || >=22.12.0} 500 | cpu: [x64] 501 | os: [darwin] 502 | 503 | '@rolldown/binding-freebsd-x64@1.0.0-beta.53': 504 | resolution: {integrity: sha512-9Tmp7bBvKqyDkMcL4e089pH3RsjD3SUungjmqWtyhNOxoQMh0fSmINTyYV8KXtE+JkxYMPWvnEt+/mfpVCkk8w==} 505 | engines: {node: ^20.19.0 || >=22.12.0} 506 | cpu: [x64] 507 | os: [freebsd] 508 | 509 | '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.53': 510 | resolution: {integrity: sha512-a1y5fiB0iovuzdbjUxa7+Zcvgv+mTmlGGC4XydVIsyl48eoxgaYkA3l9079hyTyhECsPq+mbr0gVQsFU11OJAQ==} 511 | engines: {node: ^20.19.0 || >=22.12.0} 512 | cpu: [arm] 513 | os: [linux] 514 | 515 | '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.53': 516 | resolution: {integrity: sha512-bpIGX+ov9PhJYV+wHNXl9rzq4F0QvILiURn0y0oepbQx+7stmQsKA0DhPGwmhfvF856wq+gbM8L92SAa/CBcLg==} 517 | engines: {node: ^20.19.0 || >=22.12.0} 518 | cpu: [arm64] 519 | os: [linux] 520 | 521 | '@rolldown/binding-linux-arm64-musl@1.0.0-beta.53': 522 | resolution: {integrity: sha512-bGe5EBB8FVjHBR1mOLOPEFg1Lp3//7geqWkU5NIhxe+yH0W8FVrQ6WRYOap4SUTKdklD/dC4qPLREkMMQ855FA==} 523 | engines: {node: ^20.19.0 || >=22.12.0} 524 | cpu: [arm64] 525 | os: [linux] 526 | 527 | '@rolldown/binding-linux-x64-gnu@1.0.0-beta.53': 528 | resolution: {integrity: sha512-qL+63WKVQs1CMvFedlPt0U9PiEKJOAL/bsHMKUDS6Vp2Q+YAv/QLPu8rcvkfIMvQ0FPU2WL0aX4eWwF6e/GAnA==} 529 | engines: {node: ^20.19.0 || >=22.12.0} 530 | cpu: [x64] 531 | os: [linux] 532 | 533 | '@rolldown/binding-linux-x64-musl@1.0.0-beta.53': 534 | resolution: {integrity: sha512-VGl9JIGjoJh3H8Mb+7xnVqODajBmrdOOb9lxWXdcmxyI+zjB2sux69br0hZJDTyLJfvBoYm439zPACYbCjGRmw==} 535 | engines: {node: ^20.19.0 || >=22.12.0} 536 | cpu: [x64] 537 | os: [linux] 538 | 539 | '@rolldown/binding-openharmony-arm64@1.0.0-beta.53': 540 | resolution: {integrity: sha512-B4iIserJXuSnNzA5xBLFUIjTfhNy7d9sq4FUMQY3GhQWGVhS2RWWzzDnkSU6MUt7/aHUrep0CdQfXUJI9D3W7A==} 541 | engines: {node: ^20.19.0 || >=22.12.0} 542 | cpu: [arm64] 543 | os: [openharmony] 544 | 545 | '@rolldown/binding-wasm32-wasi@1.0.0-beta.53': 546 | resolution: {integrity: sha512-BUjAEgpABEJXilGq/BPh7jeU3WAJ5o15c1ZEgHaDWSz3LB881LQZnbNJHmUiM4d1JQWMYYyR1Y490IBHi2FPJg==} 547 | engines: {node: '>=14.0.0'} 548 | cpu: [wasm32] 549 | 550 | '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.53': 551 | resolution: {integrity: sha512-s27uU7tpCWSjHBnxyVXHt3rMrQdJq5MHNv3BzsewCIroIw3DJFjMH1dzCPPMUFxnh1r52Nf9IJ/eWp6LDoyGcw==} 552 | engines: {node: ^20.19.0 || >=22.12.0} 553 | cpu: [arm64] 554 | os: [win32] 555 | 556 | '@rolldown/binding-win32-x64-msvc@1.0.0-beta.53': 557 | resolution: {integrity: sha512-cjWL/USPJ1g0en2htb4ssMjIycc36RvdQAx1WlXnS6DpULswiUTVXPDesTifSKYSyvx24E0YqQkEm0K/M2Z/AA==} 558 | engines: {node: ^20.19.0 || >=22.12.0} 559 | cpu: [x64] 560 | os: [win32] 561 | 562 | '@rolldown/pluginutils@1.0.0-beta.53': 563 | resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} 564 | 565 | '@rollup/rollup-android-arm-eabi@4.53.3': 566 | resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} 567 | cpu: [arm] 568 | os: [android] 569 | 570 | '@rollup/rollup-android-arm64@4.53.3': 571 | resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} 572 | cpu: [arm64] 573 | os: [android] 574 | 575 | '@rollup/rollup-darwin-arm64@4.53.3': 576 | resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} 577 | cpu: [arm64] 578 | os: [darwin] 579 | 580 | '@rollup/rollup-darwin-x64@4.53.3': 581 | resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} 582 | cpu: [x64] 583 | os: [darwin] 584 | 585 | '@rollup/rollup-freebsd-arm64@4.53.3': 586 | resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} 587 | cpu: [arm64] 588 | os: [freebsd] 589 | 590 | '@rollup/rollup-freebsd-x64@4.53.3': 591 | resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} 592 | cpu: [x64] 593 | os: [freebsd] 594 | 595 | '@rollup/rollup-linux-arm-gnueabihf@4.53.3': 596 | resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} 597 | cpu: [arm] 598 | os: [linux] 599 | 600 | '@rollup/rollup-linux-arm-musleabihf@4.53.3': 601 | resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} 602 | cpu: [arm] 603 | os: [linux] 604 | 605 | '@rollup/rollup-linux-arm64-gnu@4.53.3': 606 | resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} 607 | cpu: [arm64] 608 | os: [linux] 609 | 610 | '@rollup/rollup-linux-arm64-musl@4.53.3': 611 | resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} 612 | cpu: [arm64] 613 | os: [linux] 614 | 615 | '@rollup/rollup-linux-loong64-gnu@4.53.3': 616 | resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} 617 | cpu: [loong64] 618 | os: [linux] 619 | 620 | '@rollup/rollup-linux-ppc64-gnu@4.53.3': 621 | resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} 622 | cpu: [ppc64] 623 | os: [linux] 624 | 625 | '@rollup/rollup-linux-riscv64-gnu@4.53.3': 626 | resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} 627 | cpu: [riscv64] 628 | os: [linux] 629 | 630 | '@rollup/rollup-linux-riscv64-musl@4.53.3': 631 | resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} 632 | cpu: [riscv64] 633 | os: [linux] 634 | 635 | '@rollup/rollup-linux-s390x-gnu@4.53.3': 636 | resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} 637 | cpu: [s390x] 638 | os: [linux] 639 | 640 | '@rollup/rollup-linux-x64-gnu@4.53.3': 641 | resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} 642 | cpu: [x64] 643 | os: [linux] 644 | 645 | '@rollup/rollup-linux-x64-musl@4.53.3': 646 | resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} 647 | cpu: [x64] 648 | os: [linux] 649 | 650 | '@rollup/rollup-openharmony-arm64@4.53.3': 651 | resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} 652 | cpu: [arm64] 653 | os: [openharmony] 654 | 655 | '@rollup/rollup-win32-arm64-msvc@4.53.3': 656 | resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} 657 | cpu: [arm64] 658 | os: [win32] 659 | 660 | '@rollup/rollup-win32-ia32-msvc@4.53.3': 661 | resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} 662 | cpu: [ia32] 663 | os: [win32] 664 | 665 | '@rollup/rollup-win32-x64-gnu@4.53.3': 666 | resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} 667 | cpu: [x64] 668 | os: [win32] 669 | 670 | '@rollup/rollup-win32-x64-msvc@4.53.3': 671 | resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} 672 | cpu: [x64] 673 | os: [win32] 674 | 675 | '@sanity/parse-package-json@2.0.0': 676 | resolution: {integrity: sha512-C3gK7+Y/lGP1FV7YZ6WniFwXnROf/upgNXpMmJDty2aD2G2a/6XvQWBhy2qr8LEQyxNoU1qgEWatD31GGG6f6w==} 677 | engines: {node: '>=20.19 <22 || >=22.12'} 678 | 679 | '@sanity/tsconfig@2.1.0': 680 | resolution: {integrity: sha512-Cnz0EycMsfeILkxL/gYzzfPs511OzP3sjQxU4XkDtujdiFAc+bteMYXi4/SJ83m98cXLum63HbHDk+he6AbbIA==} 681 | 682 | '@sanity/tsdown-config@0.4.2': 683 | resolution: {integrity: sha512-kR+CwlVmaQe/FnYi1ncHQQtNnFLAiJd2M2sYnjDuCwg6imc2NIbLhCkB2FMz2LK8LMn4vnJ8pWlKbrLnjJy1DQ==} 684 | engines: {node: '>=20.19 <22 || >=22.12'} 685 | peerDependencies: 686 | tsdown: ^0.17 687 | typescript: 5.8.x || 5.9.x 688 | 689 | '@shikijs/engine-oniguruma@3.19.0': 690 | resolution: {integrity: sha512-1hRxtYIJfJSZeM5ivbUXv9hcJP3PWRo5prG/V2sWwiubUKTa+7P62d2qxCW8jiVFX4pgRHhnHNp+qeR7Xl+6kg==} 691 | 692 | '@shikijs/langs@3.19.0': 693 | resolution: {integrity: sha512-dBMFzzg1QiXqCVQ5ONc0z2ebyoi5BKz+MtfByLm0o5/nbUu3Iz8uaTCa5uzGiscQKm7lVShfZHU1+OG3t5hgwg==} 694 | 695 | '@shikijs/themes@3.19.0': 696 | resolution: {integrity: sha512-H36qw+oh91Y0s6OlFfdSuQ0Ld+5CgB/VE6gNPK+Hk4VRbVG/XQgkjnt4KzfnnoO6tZPtKJKHPjwebOCfjd6F8A==} 697 | 698 | '@shikijs/types@3.19.0': 699 | resolution: {integrity: sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ==} 700 | 701 | '@shikijs/vscode-textmate@10.0.2': 702 | resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} 703 | 704 | '@standard-schema/spec@1.0.0': 705 | resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} 706 | 707 | '@tybys/wasm-util@0.10.1': 708 | resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} 709 | 710 | '@types/chai@5.2.2': 711 | resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} 712 | 713 | '@types/deep-eql@4.0.2': 714 | resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} 715 | 716 | '@types/estree@1.0.8': 717 | resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} 718 | 719 | '@types/hast@3.0.4': 720 | resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} 721 | 722 | '@types/node@12.20.55': 723 | resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} 724 | 725 | '@types/node@24.10.4': 726 | resolution: {integrity: sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==} 727 | 728 | '@types/unist@3.0.3': 729 | resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} 730 | 731 | '@vitest/coverage-v8@4.0.15': 732 | resolution: {integrity: sha512-FUJ+1RkpTFW7rQITdgTi93qOCWJobWhBirEPCeXh2SW2wsTlFxy51apDz5gzG+ZEYt/THvWeNmhdAoS9DTwpCw==} 733 | peerDependencies: 734 | '@vitest/browser': 4.0.15 735 | vitest: 4.0.15 736 | peerDependenciesMeta: 737 | '@vitest/browser': 738 | optional: true 739 | 740 | '@vitest/expect@4.0.15': 741 | resolution: {integrity: sha512-Gfyva9/GxPAWXIWjyGDli9O+waHDC0Q0jaLdFP1qPAUUfo1FEXPXUfUkp3eZA0sSq340vPycSyOlYUeM15Ft1w==} 742 | 743 | '@vitest/mocker@4.0.15': 744 | resolution: {integrity: sha512-CZ28GLfOEIFkvCFngN8Sfx5h+Se0zN+h4B7yOsPVCcgtiO7t5jt9xQh2E1UkFep+eb9fjyMfuC5gBypwb07fvQ==} 745 | peerDependencies: 746 | msw: ^2.4.9 747 | vite: ^6.0.0 || ^7.0.0-0 748 | peerDependenciesMeta: 749 | msw: 750 | optional: true 751 | vite: 752 | optional: true 753 | 754 | '@vitest/pretty-format@4.0.15': 755 | resolution: {integrity: sha512-SWdqR8vEv83WtZcrfLNqlqeQXlQLh2iilO1Wk1gv4eiHKjEzvgHb2OVc3mIPyhZE6F+CtfYjNlDJwP5MN6Km7A==} 756 | 757 | '@vitest/runner@4.0.15': 758 | resolution: {integrity: sha512-+A+yMY8dGixUhHmNdPUxOh0la6uVzun86vAbuMT3hIDxMrAOmn5ILBHm8ajrqHE0t8R9T1dGnde1A5DTnmi3qw==} 759 | 760 | '@vitest/snapshot@4.0.15': 761 | resolution: {integrity: sha512-A7Ob8EdFZJIBjLjeO0DZF4lqR6U7Ydi5/5LIZ0xcI+23lYlsYJAfGn8PrIWTYdZQRNnSRlzhg0zyGu37mVdy5g==} 762 | 763 | '@vitest/spy@4.0.15': 764 | resolution: {integrity: sha512-+EIjOJmnY6mIfdXtE/bnozKEvTC4Uczg19yeZ2vtCz5Yyb0QQ31QWVQ8hswJ3Ysx/K2EqaNsVanjr//2+P3FHw==} 765 | 766 | '@vitest/utils@4.0.15': 767 | resolution: {integrity: sha512-HXjPW2w5dxhTD0dLwtYHDnelK3j8sR8cWIaLxr22evTyY6q8pRCjZSmhRWVjBaOVXChQd6AwMzi9pucorXCPZA==} 768 | 769 | acorn@8.11.3: 770 | resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} 771 | engines: {node: '>=0.4.0'} 772 | hasBin: true 773 | 774 | ansi-colors@4.1.3: 775 | resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} 776 | engines: {node: '>=6'} 777 | 778 | ansi-regex@5.0.1: 779 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 780 | engines: {node: '>=8'} 781 | 782 | ansis@4.2.0: 783 | resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} 784 | engines: {node: '>=14'} 785 | 786 | argparse@1.0.10: 787 | resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} 788 | 789 | argparse@2.0.1: 790 | resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 791 | 792 | array-union@2.1.0: 793 | resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} 794 | engines: {node: '>=8'} 795 | 796 | ast-kit@2.2.0: 797 | resolution: {integrity: sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==} 798 | engines: {node: '>=20.19.0'} 799 | 800 | ast-v8-to-istanbul@0.3.8: 801 | resolution: {integrity: sha512-szgSZqUxI5T8mLKvS7WTjF9is+MVbOeLADU73IseOcrqhxr/VAvy6wfoVE39KnKzA7JRhjF5eUagNlHwvZPlKQ==} 802 | 803 | balanced-match@1.0.2: 804 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 805 | 806 | better-path-resolve@1.0.0: 807 | resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} 808 | engines: {node: '>=4'} 809 | 810 | birpc@3.0.0: 811 | resolution: {integrity: sha512-by+04pHuxpCEQcucAXqzopqfhyI8TLK5Qg5MST0cB6MP+JhHna9ollrtK9moVh27aq6Q6MEJgebD0cVm//yBkg==} 812 | 813 | brace-expansion@2.0.1: 814 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 815 | 816 | braces@3.0.3: 817 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 818 | engines: {node: '>=8'} 819 | 820 | buffer-from@1.1.2: 821 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 822 | 823 | cac@6.7.14: 824 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 825 | engines: {node: '>=8'} 826 | 827 | chai@6.2.1: 828 | resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} 829 | engines: {node: '>=18'} 830 | 831 | chardet@2.1.1: 832 | resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} 833 | 834 | ci-info@3.9.0: 835 | resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} 836 | engines: {node: '>=8'} 837 | 838 | commander@2.20.3: 839 | resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} 840 | 841 | cross-spawn@7.0.6: 842 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} 843 | engines: {node: '>= 8'} 844 | 845 | dataloader@1.4.0: 846 | resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} 847 | 848 | debug@4.4.3: 849 | resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} 850 | engines: {node: '>=6.0'} 851 | peerDependencies: 852 | supports-color: '*' 853 | peerDependenciesMeta: 854 | supports-color: 855 | optional: true 856 | 857 | detect-indent@6.1.0: 858 | resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} 859 | engines: {node: '>=8'} 860 | 861 | detect-libc@2.0.4: 862 | resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} 863 | engines: {node: '>=8'} 864 | 865 | dir-glob@3.0.1: 866 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} 867 | engines: {node: '>=8'} 868 | 869 | dotenv@8.6.0: 870 | resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} 871 | engines: {node: '>=10'} 872 | 873 | dts-resolver@2.1.3: 874 | resolution: {integrity: sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==} 875 | engines: {node: '>=20.19.0'} 876 | peerDependencies: 877 | oxc-resolver: '>=11.0.0' 878 | peerDependenciesMeta: 879 | oxc-resolver: 880 | optional: true 881 | 882 | empathic@2.0.0: 883 | resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} 884 | engines: {node: '>=14'} 885 | 886 | enquirer@2.4.1: 887 | resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} 888 | engines: {node: '>=8.6'} 889 | 890 | entities@4.5.0: 891 | resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 892 | engines: {node: '>=0.12'} 893 | 894 | es-module-lexer@1.7.0: 895 | resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} 896 | 897 | esbuild@0.25.12: 898 | resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} 899 | engines: {node: '>=18'} 900 | hasBin: true 901 | 902 | esprima@4.0.1: 903 | resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} 904 | engines: {node: '>=4'} 905 | hasBin: true 906 | 907 | estree-walker@3.0.3: 908 | resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 909 | 910 | expect-type@1.2.2: 911 | resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} 912 | engines: {node: '>=12.0.0'} 913 | 914 | extendable-error@0.1.7: 915 | resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} 916 | 917 | fast-glob@3.3.3: 918 | resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} 919 | engines: {node: '>=8.6.0'} 920 | 921 | fastq@1.17.1: 922 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} 923 | 924 | fdir@6.5.0: 925 | resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} 926 | engines: {node: '>=12.0.0'} 927 | peerDependencies: 928 | picomatch: ^3 || ^4 929 | peerDependenciesMeta: 930 | picomatch: 931 | optional: true 932 | 933 | fill-range@7.1.1: 934 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 935 | engines: {node: '>=8'} 936 | 937 | find-up@4.1.0: 938 | resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} 939 | engines: {node: '>=8'} 940 | 941 | fs-extra@7.0.1: 942 | resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} 943 | engines: {node: '>=6 <7 || >=8'} 944 | 945 | fs-extra@8.1.0: 946 | resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} 947 | engines: {node: '>=6 <7 || >=8'} 948 | 949 | fsevents@2.3.3: 950 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 951 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 952 | os: [darwin] 953 | 954 | get-tsconfig@4.13.0: 955 | resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} 956 | 957 | glob-parent@5.1.2: 958 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 959 | engines: {node: '>= 6'} 960 | 961 | globby@11.1.0: 962 | resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} 963 | engines: {node: '>=10'} 964 | 965 | graceful-fs@4.2.11: 966 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 967 | 968 | has-flag@4.0.0: 969 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 970 | engines: {node: '>=8'} 971 | 972 | hookable@5.5.3: 973 | resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} 974 | 975 | html-escaper@2.0.2: 976 | resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} 977 | 978 | human-id@4.1.1: 979 | resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} 980 | hasBin: true 981 | 982 | iconv-lite@0.7.0: 983 | resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} 984 | engines: {node: '>=0.10.0'} 985 | 986 | ignore@5.3.1: 987 | resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} 988 | engines: {node: '>= 4'} 989 | 990 | import-without-cache@0.2.2: 991 | resolution: {integrity: sha512-4TTuRrZ0jBULXzac3EoX9ZviOs8Wn9iAbNhJEyLhTpAGF9eNmYSruaMMN/Tec/yqaO7H6yS2kALfQDJ5FxfatA==} 992 | engines: {node: '>=20.19.0'} 993 | 994 | is-extglob@2.1.1: 995 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 996 | engines: {node: '>=0.10.0'} 997 | 998 | is-glob@4.0.3: 999 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 1000 | engines: {node: '>=0.10.0'} 1001 | 1002 | is-number@7.0.0: 1003 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 1004 | engines: {node: '>=0.12.0'} 1005 | 1006 | is-subdir@1.2.0: 1007 | resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} 1008 | engines: {node: '>=4'} 1009 | 1010 | is-windows@1.0.2: 1011 | resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} 1012 | engines: {node: '>=0.10.0'} 1013 | 1014 | isexe@2.0.0: 1015 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 1016 | 1017 | istanbul-lib-coverage@3.2.2: 1018 | resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} 1019 | engines: {node: '>=8'} 1020 | 1021 | istanbul-lib-report@3.0.1: 1022 | resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} 1023 | engines: {node: '>=10'} 1024 | 1025 | istanbul-lib-source-maps@5.0.6: 1026 | resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} 1027 | engines: {node: '>=10'} 1028 | 1029 | istanbul-reports@3.2.0: 1030 | resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} 1031 | engines: {node: '>=8'} 1032 | 1033 | js-tokens@9.0.1: 1034 | resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} 1035 | 1036 | js-yaml@3.14.1: 1037 | resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} 1038 | hasBin: true 1039 | 1040 | js-yaml@4.1.1: 1041 | resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} 1042 | hasBin: true 1043 | 1044 | jsesc@3.1.0: 1045 | resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} 1046 | engines: {node: '>=6'} 1047 | hasBin: true 1048 | 1049 | jsonfile@4.0.0: 1050 | resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} 1051 | 1052 | lightningcss-android-arm64@1.30.2: 1053 | resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} 1054 | engines: {node: '>= 12.0.0'} 1055 | cpu: [arm64] 1056 | os: [android] 1057 | 1058 | lightningcss-darwin-arm64@1.30.2: 1059 | resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} 1060 | engines: {node: '>= 12.0.0'} 1061 | cpu: [arm64] 1062 | os: [darwin] 1063 | 1064 | lightningcss-darwin-x64@1.30.2: 1065 | resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} 1066 | engines: {node: '>= 12.0.0'} 1067 | cpu: [x64] 1068 | os: [darwin] 1069 | 1070 | lightningcss-freebsd-x64@1.30.2: 1071 | resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} 1072 | engines: {node: '>= 12.0.0'} 1073 | cpu: [x64] 1074 | os: [freebsd] 1075 | 1076 | lightningcss-linux-arm-gnueabihf@1.30.2: 1077 | resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} 1078 | engines: {node: '>= 12.0.0'} 1079 | cpu: [arm] 1080 | os: [linux] 1081 | 1082 | lightningcss-linux-arm64-gnu@1.30.2: 1083 | resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} 1084 | engines: {node: '>= 12.0.0'} 1085 | cpu: [arm64] 1086 | os: [linux] 1087 | 1088 | lightningcss-linux-arm64-musl@1.30.2: 1089 | resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} 1090 | engines: {node: '>= 12.0.0'} 1091 | cpu: [arm64] 1092 | os: [linux] 1093 | 1094 | lightningcss-linux-x64-gnu@1.30.2: 1095 | resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} 1096 | engines: {node: '>= 12.0.0'} 1097 | cpu: [x64] 1098 | os: [linux] 1099 | 1100 | lightningcss-linux-x64-musl@1.30.2: 1101 | resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} 1102 | engines: {node: '>= 12.0.0'} 1103 | cpu: [x64] 1104 | os: [linux] 1105 | 1106 | lightningcss-win32-arm64-msvc@1.30.2: 1107 | resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} 1108 | engines: {node: '>= 12.0.0'} 1109 | cpu: [arm64] 1110 | os: [win32] 1111 | 1112 | lightningcss-win32-x64-msvc@1.30.2: 1113 | resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} 1114 | engines: {node: '>= 12.0.0'} 1115 | cpu: [x64] 1116 | os: [win32] 1117 | 1118 | lightningcss@1.30.2: 1119 | resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} 1120 | engines: {node: '>= 12.0.0'} 1121 | 1122 | linkify-it@5.0.0: 1123 | resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} 1124 | 1125 | locate-path@5.0.0: 1126 | resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} 1127 | engines: {node: '>=8'} 1128 | 1129 | lodash.startcase@4.4.0: 1130 | resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} 1131 | 1132 | lunr@2.3.9: 1133 | resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} 1134 | 1135 | magic-string@0.30.21: 1136 | resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} 1137 | 1138 | magicast@0.5.1: 1139 | resolution: {integrity: sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==} 1140 | 1141 | make-dir@4.0.0: 1142 | resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} 1143 | engines: {node: '>=10'} 1144 | 1145 | markdown-it@14.1.0: 1146 | resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} 1147 | hasBin: true 1148 | 1149 | mdurl@2.0.0: 1150 | resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} 1151 | 1152 | merge2@1.4.1: 1153 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 1154 | engines: {node: '>= 8'} 1155 | 1156 | micromatch@4.0.8: 1157 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 1158 | engines: {node: '>=8.6'} 1159 | 1160 | minimatch@9.0.5: 1161 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 1162 | engines: {node: '>=16 || 14 >=14.17'} 1163 | 1164 | mri@1.2.0: 1165 | resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} 1166 | engines: {node: '>=4'} 1167 | 1168 | ms@2.1.3: 1169 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 1170 | 1171 | nanoid@3.3.11: 1172 | resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} 1173 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1174 | hasBin: true 1175 | 1176 | node-fetch@2.7.0: 1177 | resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} 1178 | engines: {node: 4.x || >=6.0.0} 1179 | peerDependencies: 1180 | encoding: ^0.1.0 1181 | peerDependenciesMeta: 1182 | encoding: 1183 | optional: true 1184 | 1185 | obug@2.1.1: 1186 | resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} 1187 | 1188 | outdent@0.5.0: 1189 | resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} 1190 | 1191 | oxfmt@0.18.0: 1192 | resolution: {integrity: sha512-XqVS+LQi7ARsFlIftB69+jGN2qQaJNBjQU2b9ZQYt+iaUV9digh+dBIsU0isQIZhaQ1ihxGFfsTYQXE/Oak8Qw==} 1193 | engines: {node: ^20.19.0 || >=22.12.0} 1194 | hasBin: true 1195 | 1196 | oxlint-tsgolint@0.9.1: 1197 | resolution: {integrity: sha512-w1lIvUDkkiAPFyo268SFGrdh1LQ3Lcs1XShES7I4X75TliQA0os5XJ5hNZ4lYsSevqcofgEtq4xq7rBumv69iQ==} 1198 | hasBin: true 1199 | 1200 | oxlint@1.33.0: 1201 | resolution: {integrity: sha512-4WCL0K8jiOshwJ8WrVk35VAuVaZHC0iX6asjKsrENOrynkAAGcTLLx0Urf0eXZ1Tq7r+qAe3Z9EyHMFPzVyUkg==} 1202 | engines: {node: ^20.19.0 || >=22.12.0} 1203 | hasBin: true 1204 | peerDependencies: 1205 | oxlint-tsgolint: '>=0.9.0' 1206 | peerDependenciesMeta: 1207 | oxlint-tsgolint: 1208 | optional: true 1209 | 1210 | p-filter@2.1.0: 1211 | resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} 1212 | engines: {node: '>=8'} 1213 | 1214 | p-limit@2.3.0: 1215 | resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} 1216 | engines: {node: '>=6'} 1217 | 1218 | p-locate@4.1.0: 1219 | resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} 1220 | engines: {node: '>=8'} 1221 | 1222 | p-map@2.1.0: 1223 | resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} 1224 | engines: {node: '>=6'} 1225 | 1226 | p-try@2.2.0: 1227 | resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} 1228 | engines: {node: '>=6'} 1229 | 1230 | package-manager-detector@0.2.11: 1231 | resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==} 1232 | 1233 | package-manager-detector@1.6.0: 1234 | resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} 1235 | 1236 | path-exists@4.0.0: 1237 | resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} 1238 | engines: {node: '>=8'} 1239 | 1240 | path-key@3.1.1: 1241 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 1242 | engines: {node: '>=8'} 1243 | 1244 | path-type@4.0.0: 1245 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 1246 | engines: {node: '>=8'} 1247 | 1248 | pathe@2.0.3: 1249 | resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} 1250 | 1251 | picocolors@1.1.1: 1252 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 1253 | 1254 | picomatch@2.3.1: 1255 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1256 | engines: {node: '>=8.6'} 1257 | 1258 | picomatch@4.0.3: 1259 | resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} 1260 | engines: {node: '>=12'} 1261 | 1262 | pify@4.0.1: 1263 | resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} 1264 | engines: {node: '>=6'} 1265 | 1266 | postcss@8.5.6: 1267 | resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} 1268 | engines: {node: ^10 || ^12 || >=14} 1269 | 1270 | prettier@2.8.8: 1271 | resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} 1272 | engines: {node: '>=10.13.0'} 1273 | hasBin: true 1274 | 1275 | publint@0.3.16: 1276 | resolution: {integrity: sha512-MFqyfRLAExPVZdTQFwkAQELzA8idyXzROVOytg6nEJ/GEypXBUmMGrVaID8cTuzRS1U5L8yTOdOJtMXgFUJAeA==} 1277 | engines: {node: '>=18'} 1278 | hasBin: true 1279 | 1280 | punycode.js@2.3.1: 1281 | resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} 1282 | engines: {node: '>=6'} 1283 | 1284 | quansync@0.2.11: 1285 | resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} 1286 | 1287 | quansync@1.0.0: 1288 | resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} 1289 | 1290 | queue-microtask@1.2.3: 1291 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 1292 | 1293 | read-yaml-file@1.1.0: 1294 | resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} 1295 | engines: {node: '>=6'} 1296 | 1297 | resolve-from@5.0.0: 1298 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} 1299 | engines: {node: '>=8'} 1300 | 1301 | resolve-pkg-maps@1.0.0: 1302 | resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} 1303 | 1304 | reusify@1.0.4: 1305 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1306 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1307 | 1308 | rolldown-plugin-dts@0.18.3: 1309 | resolution: {integrity: sha512-rd1LZ0Awwfyn89UndUF/HoFF4oH9a5j+2ZeuKSJYM80vmeN/p0gslYMnHTQHBEXPhUlvAlqGA3tVgXB/1qFNDg==} 1310 | engines: {node: '>=20.19.0'} 1311 | peerDependencies: 1312 | '@ts-macro/tsc': ^0.3.6 1313 | '@typescript/native-preview': '>=7.0.0-dev.20250601.1' 1314 | rolldown: ^1.0.0-beta.51 1315 | typescript: ^5.0.0 1316 | vue-tsc: ~3.1.0 1317 | peerDependenciesMeta: 1318 | '@ts-macro/tsc': 1319 | optional: true 1320 | '@typescript/native-preview': 1321 | optional: true 1322 | typescript: 1323 | optional: true 1324 | vue-tsc: 1325 | optional: true 1326 | 1327 | rolldown@1.0.0-beta.53: 1328 | resolution: {integrity: sha512-Qd9c2p0XKZdgT5AYd+KgAMggJ8ZmCs3JnS9PTMWkyUfteKlfmKtxJbWTHkVakxwXs1Ub7jrRYVeFeF7N0sQxyw==} 1329 | engines: {node: ^20.19.0 || >=22.12.0} 1330 | hasBin: true 1331 | 1332 | rollup@4.53.3: 1333 | resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} 1334 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 1335 | hasBin: true 1336 | 1337 | run-parallel@1.2.0: 1338 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1339 | 1340 | sade@1.8.1: 1341 | resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} 1342 | engines: {node: '>=6'} 1343 | 1344 | safer-buffer@2.1.2: 1345 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 1346 | 1347 | semver@7.7.3: 1348 | resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} 1349 | engines: {node: '>=10'} 1350 | hasBin: true 1351 | 1352 | shebang-command@2.0.0: 1353 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1354 | engines: {node: '>=8'} 1355 | 1356 | shebang-regex@3.0.0: 1357 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1358 | engines: {node: '>=8'} 1359 | 1360 | siginfo@2.0.0: 1361 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 1362 | 1363 | signal-exit@4.1.0: 1364 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 1365 | engines: {node: '>=14'} 1366 | 1367 | slash@3.0.0: 1368 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} 1369 | engines: {node: '>=8'} 1370 | 1371 | source-map-js@1.2.1: 1372 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 1373 | engines: {node: '>=0.10.0'} 1374 | 1375 | source-map-support@0.5.21: 1376 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 1377 | 1378 | source-map@0.6.1: 1379 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 1380 | engines: {node: '>=0.10.0'} 1381 | 1382 | spawndamnit@3.0.1: 1383 | resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} 1384 | 1385 | sprintf-js@1.0.3: 1386 | resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} 1387 | 1388 | stackback@0.0.2: 1389 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 1390 | 1391 | std-env@3.10.0: 1392 | resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} 1393 | 1394 | strip-ansi@6.0.1: 1395 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1396 | engines: {node: '>=8'} 1397 | 1398 | strip-bom@3.0.0: 1399 | resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 1400 | engines: {node: '>=4'} 1401 | 1402 | supports-color@7.2.0: 1403 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1404 | engines: {node: '>=8'} 1405 | 1406 | term-size@2.2.1: 1407 | resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} 1408 | engines: {node: '>=8'} 1409 | 1410 | terser@5.30.3: 1411 | resolution: {integrity: sha512-STdUgOUx8rLbMGO9IOwHLpCqolkDITFFQSMYYwKE1N2lY6MVSaeoi10z/EhWxRc6ybqoVmKSkhKYH/XUpl7vSA==} 1412 | engines: {node: '>=10'} 1413 | hasBin: true 1414 | 1415 | tinybench@2.9.0: 1416 | resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} 1417 | 1418 | tinyexec@1.0.2: 1419 | resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} 1420 | engines: {node: '>=18'} 1421 | 1422 | tinyglobby@0.2.15: 1423 | resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} 1424 | engines: {node: '>=12.0.0'} 1425 | 1426 | tinypool@2.0.0: 1427 | resolution: {integrity: sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg==} 1428 | engines: {node: ^20.0.0 || >=22.0.0} 1429 | 1430 | tinyrainbow@3.0.3: 1431 | resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} 1432 | engines: {node: '>=14.0.0'} 1433 | 1434 | to-regex-range@5.0.1: 1435 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1436 | engines: {node: '>=8.0'} 1437 | 1438 | tr46@0.0.3: 1439 | resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} 1440 | 1441 | tree-kill@1.2.2: 1442 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} 1443 | hasBin: true 1444 | 1445 | tsdown@0.17.2: 1446 | resolution: {integrity: sha512-SuU+0CWm/95KfXqojHTVuwcouIsdn7HpYcwDyOdKktJi285NxKwysjFUaxYLxpCNqqPvcFvokXLO4dZThRwzkw==} 1447 | engines: {node: '>=20.19.0'} 1448 | hasBin: true 1449 | peerDependencies: 1450 | '@arethetypeswrong/core': ^0.18.1 1451 | '@vitejs/devtools': ^0.0.0-alpha.19 1452 | publint: ^0.3.0 1453 | typescript: ^5.0.0 1454 | unplugin-lightningcss: ^0.4.0 1455 | unplugin-unused: ^0.5.0 1456 | peerDependenciesMeta: 1457 | '@arethetypeswrong/core': 1458 | optional: true 1459 | '@vitejs/devtools': 1460 | optional: true 1461 | publint: 1462 | optional: true 1463 | typescript: 1464 | optional: true 1465 | unplugin-lightningcss: 1466 | optional: true 1467 | unplugin-unused: 1468 | optional: true 1469 | 1470 | tslib@2.6.2: 1471 | resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} 1472 | 1473 | tsx@4.20.6: 1474 | resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} 1475 | engines: {node: '>=18.0.0'} 1476 | hasBin: true 1477 | 1478 | typedoc@0.28.15: 1479 | resolution: {integrity: sha512-mw2/2vTL7MlT+BVo43lOsufkkd2CJO4zeOSuWQQsiXoV2VuEn7f6IZp2jsUDPmBMABpgR0R5jlcJ2OGEFYmkyg==} 1480 | engines: {node: '>= 18', pnpm: '>= 10'} 1481 | hasBin: true 1482 | peerDependencies: 1483 | typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x 1484 | 1485 | typescript@5.9.3: 1486 | resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} 1487 | engines: {node: '>=14.17'} 1488 | hasBin: true 1489 | 1490 | uc.micro@2.1.0: 1491 | resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} 1492 | 1493 | unconfig-core@7.4.2: 1494 | resolution: {integrity: sha512-VgPCvLWugINbXvMQDf8Jh0mlbvNjNC6eSUziHsBCMpxR05OPrNrvDnyatdMjRgcHaaNsCqz+wjNXxNw1kRLHUg==} 1495 | 1496 | undici-types@7.16.0: 1497 | resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} 1498 | 1499 | universalify@0.1.2: 1500 | resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} 1501 | engines: {node: '>= 4.0.0'} 1502 | 1503 | unrun@0.2.19: 1504 | resolution: {integrity: sha512-DbwbJ9BvPEb3BeZnIpP9S5tGLO/JIgPQ3JrpMRFIfZMZfMG19f26OlLbC2ml8RRdrI2ZA7z2t+at5tsIHbh6Qw==} 1505 | engines: {node: '>=20.19.0'} 1506 | hasBin: true 1507 | peerDependencies: 1508 | synckit: ^0.11.11 1509 | peerDependenciesMeta: 1510 | synckit: 1511 | optional: true 1512 | 1513 | vite@7.1.12: 1514 | resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} 1515 | engines: {node: ^20.19.0 || >=22.12.0} 1516 | hasBin: true 1517 | peerDependencies: 1518 | '@types/node': ^20.19.0 || >=22.12.0 1519 | jiti: '>=1.21.0' 1520 | less: ^4.0.0 1521 | lightningcss: ^1.21.0 1522 | sass: ^1.70.0 1523 | sass-embedded: ^1.70.0 1524 | stylus: '>=0.54.8' 1525 | sugarss: ^5.0.0 1526 | terser: ^5.16.0 1527 | tsx: ^4.8.1 1528 | yaml: ^2.4.2 1529 | peerDependenciesMeta: 1530 | '@types/node': 1531 | optional: true 1532 | jiti: 1533 | optional: true 1534 | less: 1535 | optional: true 1536 | lightningcss: 1537 | optional: true 1538 | sass: 1539 | optional: true 1540 | sass-embedded: 1541 | optional: true 1542 | stylus: 1543 | optional: true 1544 | sugarss: 1545 | optional: true 1546 | terser: 1547 | optional: true 1548 | tsx: 1549 | optional: true 1550 | yaml: 1551 | optional: true 1552 | 1553 | vitest@4.0.15: 1554 | resolution: {integrity: sha512-n1RxDp8UJm6N0IbJLQo+yzLZ2sQCDyl1o0LeugbPWf8+8Fttp29GghsQBjYJVmWq3gBFfe9Hs1spR44vovn2wA==} 1555 | engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} 1556 | hasBin: true 1557 | peerDependencies: 1558 | '@edge-runtime/vm': '*' 1559 | '@opentelemetry/api': ^1.9.0 1560 | '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 1561 | '@vitest/browser-playwright': 4.0.15 1562 | '@vitest/browser-preview': 4.0.15 1563 | '@vitest/browser-webdriverio': 4.0.15 1564 | '@vitest/ui': 4.0.15 1565 | happy-dom: '*' 1566 | jsdom: '*' 1567 | peerDependenciesMeta: 1568 | '@edge-runtime/vm': 1569 | optional: true 1570 | '@opentelemetry/api': 1571 | optional: true 1572 | '@types/node': 1573 | optional: true 1574 | '@vitest/browser-playwright': 1575 | optional: true 1576 | '@vitest/browser-preview': 1577 | optional: true 1578 | '@vitest/browser-webdriverio': 1579 | optional: true 1580 | '@vitest/ui': 1581 | optional: true 1582 | happy-dom: 1583 | optional: true 1584 | jsdom: 1585 | optional: true 1586 | 1587 | webidl-conversions@3.0.1: 1588 | resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} 1589 | 1590 | whatwg-url@5.0.0: 1591 | resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} 1592 | 1593 | which@2.0.2: 1594 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1595 | engines: {node: '>= 8'} 1596 | hasBin: true 1597 | 1598 | why-is-node-running@2.3.0: 1599 | resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} 1600 | engines: {node: '>=8'} 1601 | hasBin: true 1602 | 1603 | yaml@2.8.1: 1604 | resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} 1605 | engines: {node: '>= 14.6'} 1606 | hasBin: true 1607 | 1608 | zod@4.1.13: 1609 | resolution: {integrity: sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==} 1610 | 1611 | snapshots: 1612 | 1613 | '@babel/generator@7.28.5': 1614 | dependencies: 1615 | '@babel/parser': 7.28.5 1616 | '@babel/types': 7.28.5 1617 | '@jridgewell/gen-mapping': 0.3.13 1618 | '@jridgewell/trace-mapping': 0.3.31 1619 | jsesc: 3.1.0 1620 | 1621 | '@babel/helper-string-parser@7.27.1': {} 1622 | 1623 | '@babel/helper-validator-identifier@7.28.5': {} 1624 | 1625 | '@babel/parser@7.28.5': 1626 | dependencies: 1627 | '@babel/types': 7.28.5 1628 | 1629 | '@babel/runtime@7.28.3': {} 1630 | 1631 | '@babel/types@7.28.5': 1632 | dependencies: 1633 | '@babel/helper-string-parser': 7.27.1 1634 | '@babel/helper-validator-identifier': 7.28.5 1635 | 1636 | '@bcoe/v8-coverage@1.0.2': {} 1637 | 1638 | '@changesets/apply-release-plan@7.0.14': 1639 | dependencies: 1640 | '@changesets/config': 3.1.2 1641 | '@changesets/get-version-range-type': 0.4.0 1642 | '@changesets/git': 3.0.4 1643 | '@changesets/should-skip-package': 0.1.2 1644 | '@changesets/types': 6.1.0 1645 | '@manypkg/get-packages': 1.1.3 1646 | detect-indent: 6.1.0 1647 | fs-extra: 7.0.1 1648 | lodash.startcase: 4.4.0 1649 | outdent: 0.5.0 1650 | prettier: 2.8.8 1651 | resolve-from: 5.0.0 1652 | semver: 7.7.3 1653 | 1654 | '@changesets/assemble-release-plan@6.0.9': 1655 | dependencies: 1656 | '@changesets/errors': 0.2.0 1657 | '@changesets/get-dependents-graph': 2.1.3 1658 | '@changesets/should-skip-package': 0.1.2 1659 | '@changesets/types': 6.1.0 1660 | '@manypkg/get-packages': 1.1.3 1661 | semver: 7.7.3 1662 | 1663 | '@changesets/changelog-git@0.2.1': 1664 | dependencies: 1665 | '@changesets/types': 6.1.0 1666 | 1667 | '@changesets/changelog-github@0.5.2': 1668 | dependencies: 1669 | '@changesets/get-github-info': 0.7.0 1670 | '@changesets/types': 6.1.0 1671 | dotenv: 8.6.0 1672 | transitivePeerDependencies: 1673 | - encoding 1674 | 1675 | '@changesets/cli@2.29.8(@types/node@24.10.4)': 1676 | dependencies: 1677 | '@changesets/apply-release-plan': 7.0.14 1678 | '@changesets/assemble-release-plan': 6.0.9 1679 | '@changesets/changelog-git': 0.2.1 1680 | '@changesets/config': 3.1.2 1681 | '@changesets/errors': 0.2.0 1682 | '@changesets/get-dependents-graph': 2.1.3 1683 | '@changesets/get-release-plan': 4.0.14 1684 | '@changesets/git': 3.0.4 1685 | '@changesets/logger': 0.1.1 1686 | '@changesets/pre': 2.0.2 1687 | '@changesets/read': 0.6.6 1688 | '@changesets/should-skip-package': 0.1.2 1689 | '@changesets/types': 6.1.0 1690 | '@changesets/write': 0.4.0 1691 | '@inquirer/external-editor': 1.0.3(@types/node@24.10.4) 1692 | '@manypkg/get-packages': 1.1.3 1693 | ansi-colors: 4.1.3 1694 | ci-info: 3.9.0 1695 | enquirer: 2.4.1 1696 | fs-extra: 7.0.1 1697 | mri: 1.2.0 1698 | p-limit: 2.3.0 1699 | package-manager-detector: 0.2.11 1700 | picocolors: 1.1.1 1701 | resolve-from: 5.0.0 1702 | semver: 7.7.3 1703 | spawndamnit: 3.0.1 1704 | term-size: 2.2.1 1705 | transitivePeerDependencies: 1706 | - '@types/node' 1707 | 1708 | '@changesets/config@3.1.2': 1709 | dependencies: 1710 | '@changesets/errors': 0.2.0 1711 | '@changesets/get-dependents-graph': 2.1.3 1712 | '@changesets/logger': 0.1.1 1713 | '@changesets/types': 6.1.0 1714 | '@manypkg/get-packages': 1.1.3 1715 | fs-extra: 7.0.1 1716 | micromatch: 4.0.8 1717 | 1718 | '@changesets/errors@0.2.0': 1719 | dependencies: 1720 | extendable-error: 0.1.7 1721 | 1722 | '@changesets/get-dependents-graph@2.1.3': 1723 | dependencies: 1724 | '@changesets/types': 6.1.0 1725 | '@manypkg/get-packages': 1.1.3 1726 | picocolors: 1.1.1 1727 | semver: 7.7.3 1728 | 1729 | '@changesets/get-github-info@0.7.0': 1730 | dependencies: 1731 | dataloader: 1.4.0 1732 | node-fetch: 2.7.0 1733 | transitivePeerDependencies: 1734 | - encoding 1735 | 1736 | '@changesets/get-release-plan@4.0.14': 1737 | dependencies: 1738 | '@changesets/assemble-release-plan': 6.0.9 1739 | '@changesets/config': 3.1.2 1740 | '@changesets/pre': 2.0.2 1741 | '@changesets/read': 0.6.6 1742 | '@changesets/types': 6.1.0 1743 | '@manypkg/get-packages': 1.1.3 1744 | 1745 | '@changesets/get-version-range-type@0.4.0': {} 1746 | 1747 | '@changesets/git@3.0.4': 1748 | dependencies: 1749 | '@changesets/errors': 0.2.0 1750 | '@manypkg/get-packages': 1.1.3 1751 | is-subdir: 1.2.0 1752 | micromatch: 4.0.8 1753 | spawndamnit: 3.0.1 1754 | 1755 | '@changesets/logger@0.1.1': 1756 | dependencies: 1757 | picocolors: 1.1.1 1758 | 1759 | '@changesets/parse@0.4.2': 1760 | dependencies: 1761 | '@changesets/types': 6.1.0 1762 | js-yaml: 4.1.1 1763 | 1764 | '@changesets/pre@2.0.2': 1765 | dependencies: 1766 | '@changesets/errors': 0.2.0 1767 | '@changesets/types': 6.1.0 1768 | '@manypkg/get-packages': 1.1.3 1769 | fs-extra: 7.0.1 1770 | 1771 | '@changesets/read@0.6.6': 1772 | dependencies: 1773 | '@changesets/git': 3.0.4 1774 | '@changesets/logger': 0.1.1 1775 | '@changesets/parse': 0.4.2 1776 | '@changesets/types': 6.1.0 1777 | fs-extra: 7.0.1 1778 | p-filter: 2.1.0 1779 | picocolors: 1.1.1 1780 | 1781 | '@changesets/should-skip-package@0.1.2': 1782 | dependencies: 1783 | '@changesets/types': 6.1.0 1784 | '@manypkg/get-packages': 1.1.3 1785 | 1786 | '@changesets/types@4.1.0': {} 1787 | 1788 | '@changesets/types@6.1.0': {} 1789 | 1790 | '@changesets/write@0.4.0': 1791 | dependencies: 1792 | '@changesets/types': 6.1.0 1793 | fs-extra: 7.0.1 1794 | human-id: 4.1.1 1795 | prettier: 2.8.8 1796 | 1797 | '@emnapi/core@1.7.1': 1798 | dependencies: 1799 | '@emnapi/wasi-threads': 1.1.0 1800 | tslib: 2.6.2 1801 | optional: true 1802 | 1803 | '@emnapi/runtime@1.7.1': 1804 | dependencies: 1805 | tslib: 2.6.2 1806 | optional: true 1807 | 1808 | '@emnapi/wasi-threads@1.1.0': 1809 | dependencies: 1810 | tslib: 2.6.2 1811 | optional: true 1812 | 1813 | '@esbuild/aix-ppc64@0.25.12': 1814 | optional: true 1815 | 1816 | '@esbuild/android-arm64@0.25.12': 1817 | optional: true 1818 | 1819 | '@esbuild/android-arm@0.25.12': 1820 | optional: true 1821 | 1822 | '@esbuild/android-x64@0.25.12': 1823 | optional: true 1824 | 1825 | '@esbuild/darwin-arm64@0.25.12': 1826 | optional: true 1827 | 1828 | '@esbuild/darwin-x64@0.25.12': 1829 | optional: true 1830 | 1831 | '@esbuild/freebsd-arm64@0.25.12': 1832 | optional: true 1833 | 1834 | '@esbuild/freebsd-x64@0.25.12': 1835 | optional: true 1836 | 1837 | '@esbuild/linux-arm64@0.25.12': 1838 | optional: true 1839 | 1840 | '@esbuild/linux-arm@0.25.12': 1841 | optional: true 1842 | 1843 | '@esbuild/linux-ia32@0.25.12': 1844 | optional: true 1845 | 1846 | '@esbuild/linux-loong64@0.25.12': 1847 | optional: true 1848 | 1849 | '@esbuild/linux-mips64el@0.25.12': 1850 | optional: true 1851 | 1852 | '@esbuild/linux-ppc64@0.25.12': 1853 | optional: true 1854 | 1855 | '@esbuild/linux-riscv64@0.25.12': 1856 | optional: true 1857 | 1858 | '@esbuild/linux-s390x@0.25.12': 1859 | optional: true 1860 | 1861 | '@esbuild/linux-x64@0.25.12': 1862 | optional: true 1863 | 1864 | '@esbuild/netbsd-arm64@0.25.12': 1865 | optional: true 1866 | 1867 | '@esbuild/netbsd-x64@0.25.12': 1868 | optional: true 1869 | 1870 | '@esbuild/openbsd-arm64@0.25.12': 1871 | optional: true 1872 | 1873 | '@esbuild/openbsd-x64@0.25.12': 1874 | optional: true 1875 | 1876 | '@esbuild/openharmony-arm64@0.25.12': 1877 | optional: true 1878 | 1879 | '@esbuild/sunos-x64@0.25.12': 1880 | optional: true 1881 | 1882 | '@esbuild/win32-arm64@0.25.12': 1883 | optional: true 1884 | 1885 | '@esbuild/win32-ia32@0.25.12': 1886 | optional: true 1887 | 1888 | '@esbuild/win32-x64@0.25.12': 1889 | optional: true 1890 | 1891 | '@gerrit0/mini-shiki@3.18.0': 1892 | dependencies: 1893 | '@shikijs/engine-oniguruma': 3.19.0 1894 | '@shikijs/langs': 3.19.0 1895 | '@shikijs/themes': 3.19.0 1896 | '@shikijs/types': 3.19.0 1897 | '@shikijs/vscode-textmate': 10.0.2 1898 | 1899 | '@inquirer/external-editor@1.0.3(@types/node@24.10.4)': 1900 | dependencies: 1901 | chardet: 2.1.1 1902 | iconv-lite: 0.7.0 1903 | optionalDependencies: 1904 | '@types/node': 24.10.4 1905 | 1906 | '@jridgewell/gen-mapping@0.3.13': 1907 | dependencies: 1908 | '@jridgewell/sourcemap-codec': 1.5.5 1909 | '@jridgewell/trace-mapping': 0.3.31 1910 | 1911 | '@jridgewell/resolve-uri@3.1.2': {} 1912 | 1913 | '@jridgewell/source-map@0.3.6': 1914 | dependencies: 1915 | '@jridgewell/gen-mapping': 0.3.13 1916 | '@jridgewell/trace-mapping': 0.3.31 1917 | optional: true 1918 | 1919 | '@jridgewell/sourcemap-codec@1.5.5': {} 1920 | 1921 | '@jridgewell/trace-mapping@0.3.31': 1922 | dependencies: 1923 | '@jridgewell/resolve-uri': 3.1.2 1924 | '@jridgewell/sourcemap-codec': 1.5.5 1925 | 1926 | '@manypkg/find-root@1.1.0': 1927 | dependencies: 1928 | '@babel/runtime': 7.28.3 1929 | '@types/node': 12.20.55 1930 | find-up: 4.1.0 1931 | fs-extra: 8.1.0 1932 | 1933 | '@manypkg/get-packages@1.1.3': 1934 | dependencies: 1935 | '@babel/runtime': 7.28.3 1936 | '@changesets/types': 4.1.0 1937 | '@manypkg/find-root': 1.1.0 1938 | fs-extra: 8.1.0 1939 | globby: 11.1.0 1940 | read-yaml-file: 1.1.0 1941 | 1942 | '@napi-rs/wasm-runtime@1.1.0': 1943 | dependencies: 1944 | '@emnapi/core': 1.7.1 1945 | '@emnapi/runtime': 1.7.1 1946 | '@tybys/wasm-util': 0.10.1 1947 | optional: true 1948 | 1949 | '@nodelib/fs.scandir@2.1.5': 1950 | dependencies: 1951 | '@nodelib/fs.stat': 2.0.5 1952 | run-parallel: 1.2.0 1953 | 1954 | '@nodelib/fs.stat@2.0.5': {} 1955 | 1956 | '@nodelib/fs.walk@1.2.8': 1957 | dependencies: 1958 | '@nodelib/fs.scandir': 2.1.5 1959 | fastq: 1.17.1 1960 | 1961 | '@oxc-project/types@0.101.0': {} 1962 | 1963 | '@oxfmt/darwin-arm64@0.18.0': 1964 | optional: true 1965 | 1966 | '@oxfmt/darwin-x64@0.18.0': 1967 | optional: true 1968 | 1969 | '@oxfmt/linux-arm64-gnu@0.18.0': 1970 | optional: true 1971 | 1972 | '@oxfmt/linux-arm64-musl@0.18.0': 1973 | optional: true 1974 | 1975 | '@oxfmt/linux-x64-gnu@0.18.0': 1976 | optional: true 1977 | 1978 | '@oxfmt/linux-x64-musl@0.18.0': 1979 | optional: true 1980 | 1981 | '@oxfmt/win32-arm64@0.18.0': 1982 | optional: true 1983 | 1984 | '@oxfmt/win32-x64@0.18.0': 1985 | optional: true 1986 | 1987 | '@oxlint-tsgolint/darwin-arm64@0.9.1': 1988 | optional: true 1989 | 1990 | '@oxlint-tsgolint/darwin-x64@0.9.1': 1991 | optional: true 1992 | 1993 | '@oxlint-tsgolint/linux-arm64@0.9.1': 1994 | optional: true 1995 | 1996 | '@oxlint-tsgolint/linux-x64@0.9.1': 1997 | optional: true 1998 | 1999 | '@oxlint-tsgolint/win32-arm64@0.9.1': 2000 | optional: true 2001 | 2002 | '@oxlint-tsgolint/win32-x64@0.9.1': 2003 | optional: true 2004 | 2005 | '@oxlint/darwin-arm64@1.33.0': 2006 | optional: true 2007 | 2008 | '@oxlint/darwin-x64@1.33.0': 2009 | optional: true 2010 | 2011 | '@oxlint/linux-arm64-gnu@1.33.0': 2012 | optional: true 2013 | 2014 | '@oxlint/linux-arm64-musl@1.33.0': 2015 | optional: true 2016 | 2017 | '@oxlint/linux-x64-gnu@1.33.0': 2018 | optional: true 2019 | 2020 | '@oxlint/linux-x64-musl@1.33.0': 2021 | optional: true 2022 | 2023 | '@oxlint/win32-arm64@1.33.0': 2024 | optional: true 2025 | 2026 | '@oxlint/win32-x64@1.33.0': 2027 | optional: true 2028 | 2029 | '@portabletext/types@4.0.0': {} 2030 | 2031 | '@publint/pack@0.1.2': {} 2032 | 2033 | '@quansync/fs@1.0.0': 2034 | dependencies: 2035 | quansync: 1.0.0 2036 | 2037 | '@rolldown/binding-android-arm64@1.0.0-beta.53': 2038 | optional: true 2039 | 2040 | '@rolldown/binding-darwin-arm64@1.0.0-beta.53': 2041 | optional: true 2042 | 2043 | '@rolldown/binding-darwin-x64@1.0.0-beta.53': 2044 | optional: true 2045 | 2046 | '@rolldown/binding-freebsd-x64@1.0.0-beta.53': 2047 | optional: true 2048 | 2049 | '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.53': 2050 | optional: true 2051 | 2052 | '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.53': 2053 | optional: true 2054 | 2055 | '@rolldown/binding-linux-arm64-musl@1.0.0-beta.53': 2056 | optional: true 2057 | 2058 | '@rolldown/binding-linux-x64-gnu@1.0.0-beta.53': 2059 | optional: true 2060 | 2061 | '@rolldown/binding-linux-x64-musl@1.0.0-beta.53': 2062 | optional: true 2063 | 2064 | '@rolldown/binding-openharmony-arm64@1.0.0-beta.53': 2065 | optional: true 2066 | 2067 | '@rolldown/binding-wasm32-wasi@1.0.0-beta.53': 2068 | dependencies: 2069 | '@napi-rs/wasm-runtime': 1.1.0 2070 | optional: true 2071 | 2072 | '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.53': 2073 | optional: true 2074 | 2075 | '@rolldown/binding-win32-x64-msvc@1.0.0-beta.53': 2076 | optional: true 2077 | 2078 | '@rolldown/pluginutils@1.0.0-beta.53': {} 2079 | 2080 | '@rollup/rollup-android-arm-eabi@4.53.3': 2081 | optional: true 2082 | 2083 | '@rollup/rollup-android-arm64@4.53.3': 2084 | optional: true 2085 | 2086 | '@rollup/rollup-darwin-arm64@4.53.3': 2087 | optional: true 2088 | 2089 | '@rollup/rollup-darwin-x64@4.53.3': 2090 | optional: true 2091 | 2092 | '@rollup/rollup-freebsd-arm64@4.53.3': 2093 | optional: true 2094 | 2095 | '@rollup/rollup-freebsd-x64@4.53.3': 2096 | optional: true 2097 | 2098 | '@rollup/rollup-linux-arm-gnueabihf@4.53.3': 2099 | optional: true 2100 | 2101 | '@rollup/rollup-linux-arm-musleabihf@4.53.3': 2102 | optional: true 2103 | 2104 | '@rollup/rollup-linux-arm64-gnu@4.53.3': 2105 | optional: true 2106 | 2107 | '@rollup/rollup-linux-arm64-musl@4.53.3': 2108 | optional: true 2109 | 2110 | '@rollup/rollup-linux-loong64-gnu@4.53.3': 2111 | optional: true 2112 | 2113 | '@rollup/rollup-linux-ppc64-gnu@4.53.3': 2114 | optional: true 2115 | 2116 | '@rollup/rollup-linux-riscv64-gnu@4.53.3': 2117 | optional: true 2118 | 2119 | '@rollup/rollup-linux-riscv64-musl@4.53.3': 2120 | optional: true 2121 | 2122 | '@rollup/rollup-linux-s390x-gnu@4.53.3': 2123 | optional: true 2124 | 2125 | '@rollup/rollup-linux-x64-gnu@4.53.3': 2126 | optional: true 2127 | 2128 | '@rollup/rollup-linux-x64-musl@4.53.3': 2129 | optional: true 2130 | 2131 | '@rollup/rollup-openharmony-arm64@4.53.3': 2132 | optional: true 2133 | 2134 | '@rollup/rollup-win32-arm64-msvc@4.53.3': 2135 | optional: true 2136 | 2137 | '@rollup/rollup-win32-ia32-msvc@4.53.3': 2138 | optional: true 2139 | 2140 | '@rollup/rollup-win32-x64-gnu@4.53.3': 2141 | optional: true 2142 | 2143 | '@rollup/rollup-win32-x64-msvc@4.53.3': 2144 | optional: true 2145 | 2146 | '@sanity/parse-package-json@2.0.0': 2147 | dependencies: 2148 | zod: 4.1.13 2149 | 2150 | '@sanity/tsconfig@2.1.0': {} 2151 | 2152 | '@sanity/tsdown-config@0.4.2(tsdown@0.17.2(publint@0.3.16)(typescript@5.9.3))(typescript@5.9.3)': 2153 | dependencies: 2154 | '@sanity/parse-package-json': 2.0.0 2155 | publint: 0.3.16 2156 | tsdown: 0.17.2(publint@0.3.16)(typescript@5.9.3) 2157 | typescript: 5.9.3 2158 | 2159 | '@shikijs/engine-oniguruma@3.19.0': 2160 | dependencies: 2161 | '@shikijs/types': 3.19.0 2162 | '@shikijs/vscode-textmate': 10.0.2 2163 | 2164 | '@shikijs/langs@3.19.0': 2165 | dependencies: 2166 | '@shikijs/types': 3.19.0 2167 | 2168 | '@shikijs/themes@3.19.0': 2169 | dependencies: 2170 | '@shikijs/types': 3.19.0 2171 | 2172 | '@shikijs/types@3.19.0': 2173 | dependencies: 2174 | '@shikijs/vscode-textmate': 10.0.2 2175 | '@types/hast': 3.0.4 2176 | 2177 | '@shikijs/vscode-textmate@10.0.2': {} 2178 | 2179 | '@standard-schema/spec@1.0.0': {} 2180 | 2181 | '@tybys/wasm-util@0.10.1': 2182 | dependencies: 2183 | tslib: 2.6.2 2184 | optional: true 2185 | 2186 | '@types/chai@5.2.2': 2187 | dependencies: 2188 | '@types/deep-eql': 4.0.2 2189 | 2190 | '@types/deep-eql@4.0.2': {} 2191 | 2192 | '@types/estree@1.0.8': {} 2193 | 2194 | '@types/hast@3.0.4': 2195 | dependencies: 2196 | '@types/unist': 3.0.3 2197 | 2198 | '@types/node@12.20.55': {} 2199 | 2200 | '@types/node@24.10.4': 2201 | dependencies: 2202 | undici-types: 7.16.0 2203 | 2204 | '@types/unist@3.0.3': {} 2205 | 2206 | '@vitest/coverage-v8@4.0.15(vitest@4.0.15(@types/node@24.10.4)(lightningcss@1.30.2)(terser@5.30.3)(tsx@4.20.6)(yaml@2.8.1))': 2207 | dependencies: 2208 | '@bcoe/v8-coverage': 1.0.2 2209 | '@vitest/utils': 4.0.15 2210 | ast-v8-to-istanbul: 0.3.8 2211 | istanbul-lib-coverage: 3.2.2 2212 | istanbul-lib-report: 3.0.1 2213 | istanbul-lib-source-maps: 5.0.6 2214 | istanbul-reports: 3.2.0 2215 | magicast: 0.5.1 2216 | obug: 2.1.1 2217 | std-env: 3.10.0 2218 | tinyrainbow: 3.0.3 2219 | vitest: 4.0.15(@types/node@24.10.4)(lightningcss@1.30.2)(terser@5.30.3)(tsx@4.20.6)(yaml@2.8.1) 2220 | transitivePeerDependencies: 2221 | - supports-color 2222 | 2223 | '@vitest/expect@4.0.15': 2224 | dependencies: 2225 | '@standard-schema/spec': 1.0.0 2226 | '@types/chai': 5.2.2 2227 | '@vitest/spy': 4.0.15 2228 | '@vitest/utils': 4.0.15 2229 | chai: 6.2.1 2230 | tinyrainbow: 3.0.3 2231 | 2232 | '@vitest/mocker@4.0.15(vite@7.1.12(@types/node@24.10.4)(lightningcss@1.30.2)(terser@5.30.3)(tsx@4.20.6)(yaml@2.8.1))': 2233 | dependencies: 2234 | '@vitest/spy': 4.0.15 2235 | estree-walker: 3.0.3 2236 | magic-string: 0.30.21 2237 | optionalDependencies: 2238 | vite: 7.1.12(@types/node@24.10.4)(lightningcss@1.30.2)(terser@5.30.3)(tsx@4.20.6)(yaml@2.8.1) 2239 | 2240 | '@vitest/pretty-format@4.0.15': 2241 | dependencies: 2242 | tinyrainbow: 3.0.3 2243 | 2244 | '@vitest/runner@4.0.15': 2245 | dependencies: 2246 | '@vitest/utils': 4.0.15 2247 | pathe: 2.0.3 2248 | 2249 | '@vitest/snapshot@4.0.15': 2250 | dependencies: 2251 | '@vitest/pretty-format': 4.0.15 2252 | magic-string: 0.30.21 2253 | pathe: 2.0.3 2254 | 2255 | '@vitest/spy@4.0.15': {} 2256 | 2257 | '@vitest/utils@4.0.15': 2258 | dependencies: 2259 | '@vitest/pretty-format': 4.0.15 2260 | tinyrainbow: 3.0.3 2261 | 2262 | acorn@8.11.3: 2263 | optional: true 2264 | 2265 | ansi-colors@4.1.3: {} 2266 | 2267 | ansi-regex@5.0.1: {} 2268 | 2269 | ansis@4.2.0: {} 2270 | 2271 | argparse@1.0.10: 2272 | dependencies: 2273 | sprintf-js: 1.0.3 2274 | 2275 | argparse@2.0.1: {} 2276 | 2277 | array-union@2.1.0: {} 2278 | 2279 | ast-kit@2.2.0: 2280 | dependencies: 2281 | '@babel/parser': 7.28.5 2282 | pathe: 2.0.3 2283 | 2284 | ast-v8-to-istanbul@0.3.8: 2285 | dependencies: 2286 | '@jridgewell/trace-mapping': 0.3.31 2287 | estree-walker: 3.0.3 2288 | js-tokens: 9.0.1 2289 | 2290 | balanced-match@1.0.2: {} 2291 | 2292 | better-path-resolve@1.0.0: 2293 | dependencies: 2294 | is-windows: 1.0.2 2295 | 2296 | birpc@3.0.0: {} 2297 | 2298 | brace-expansion@2.0.1: 2299 | dependencies: 2300 | balanced-match: 1.0.2 2301 | 2302 | braces@3.0.3: 2303 | dependencies: 2304 | fill-range: 7.1.1 2305 | 2306 | buffer-from@1.1.2: 2307 | optional: true 2308 | 2309 | cac@6.7.14: {} 2310 | 2311 | chai@6.2.1: {} 2312 | 2313 | chardet@2.1.1: {} 2314 | 2315 | ci-info@3.9.0: {} 2316 | 2317 | commander@2.20.3: 2318 | optional: true 2319 | 2320 | cross-spawn@7.0.6: 2321 | dependencies: 2322 | path-key: 3.1.1 2323 | shebang-command: 2.0.0 2324 | which: 2.0.2 2325 | 2326 | dataloader@1.4.0: {} 2327 | 2328 | debug@4.4.3: 2329 | dependencies: 2330 | ms: 2.1.3 2331 | 2332 | detect-indent@6.1.0: {} 2333 | 2334 | detect-libc@2.0.4: 2335 | optional: true 2336 | 2337 | dir-glob@3.0.1: 2338 | dependencies: 2339 | path-type: 4.0.0 2340 | 2341 | dotenv@8.6.0: {} 2342 | 2343 | dts-resolver@2.1.3: {} 2344 | 2345 | empathic@2.0.0: {} 2346 | 2347 | enquirer@2.4.1: 2348 | dependencies: 2349 | ansi-colors: 4.1.3 2350 | strip-ansi: 6.0.1 2351 | 2352 | entities@4.5.0: {} 2353 | 2354 | es-module-lexer@1.7.0: {} 2355 | 2356 | esbuild@0.25.12: 2357 | optionalDependencies: 2358 | '@esbuild/aix-ppc64': 0.25.12 2359 | '@esbuild/android-arm': 0.25.12 2360 | '@esbuild/android-arm64': 0.25.12 2361 | '@esbuild/android-x64': 0.25.12 2362 | '@esbuild/darwin-arm64': 0.25.12 2363 | '@esbuild/darwin-x64': 0.25.12 2364 | '@esbuild/freebsd-arm64': 0.25.12 2365 | '@esbuild/freebsd-x64': 0.25.12 2366 | '@esbuild/linux-arm': 0.25.12 2367 | '@esbuild/linux-arm64': 0.25.12 2368 | '@esbuild/linux-ia32': 0.25.12 2369 | '@esbuild/linux-loong64': 0.25.12 2370 | '@esbuild/linux-mips64el': 0.25.12 2371 | '@esbuild/linux-ppc64': 0.25.12 2372 | '@esbuild/linux-riscv64': 0.25.12 2373 | '@esbuild/linux-s390x': 0.25.12 2374 | '@esbuild/linux-x64': 0.25.12 2375 | '@esbuild/netbsd-arm64': 0.25.12 2376 | '@esbuild/netbsd-x64': 0.25.12 2377 | '@esbuild/openbsd-arm64': 0.25.12 2378 | '@esbuild/openbsd-x64': 0.25.12 2379 | '@esbuild/openharmony-arm64': 0.25.12 2380 | '@esbuild/sunos-x64': 0.25.12 2381 | '@esbuild/win32-arm64': 0.25.12 2382 | '@esbuild/win32-ia32': 0.25.12 2383 | '@esbuild/win32-x64': 0.25.12 2384 | 2385 | esprima@4.0.1: {} 2386 | 2387 | estree-walker@3.0.3: 2388 | dependencies: 2389 | '@types/estree': 1.0.8 2390 | 2391 | expect-type@1.2.2: {} 2392 | 2393 | extendable-error@0.1.7: {} 2394 | 2395 | fast-glob@3.3.3: 2396 | dependencies: 2397 | '@nodelib/fs.stat': 2.0.5 2398 | '@nodelib/fs.walk': 1.2.8 2399 | glob-parent: 5.1.2 2400 | merge2: 1.4.1 2401 | micromatch: 4.0.8 2402 | 2403 | fastq@1.17.1: 2404 | dependencies: 2405 | reusify: 1.0.4 2406 | 2407 | fdir@6.5.0(picomatch@4.0.3): 2408 | optionalDependencies: 2409 | picomatch: 4.0.3 2410 | 2411 | fill-range@7.1.1: 2412 | dependencies: 2413 | to-regex-range: 5.0.1 2414 | 2415 | find-up@4.1.0: 2416 | dependencies: 2417 | locate-path: 5.0.0 2418 | path-exists: 4.0.0 2419 | 2420 | fs-extra@7.0.1: 2421 | dependencies: 2422 | graceful-fs: 4.2.11 2423 | jsonfile: 4.0.0 2424 | universalify: 0.1.2 2425 | 2426 | fs-extra@8.1.0: 2427 | dependencies: 2428 | graceful-fs: 4.2.11 2429 | jsonfile: 4.0.0 2430 | universalify: 0.1.2 2431 | 2432 | fsevents@2.3.3: 2433 | optional: true 2434 | 2435 | get-tsconfig@4.13.0: 2436 | dependencies: 2437 | resolve-pkg-maps: 1.0.0 2438 | 2439 | glob-parent@5.1.2: 2440 | dependencies: 2441 | is-glob: 4.0.3 2442 | 2443 | globby@11.1.0: 2444 | dependencies: 2445 | array-union: 2.1.0 2446 | dir-glob: 3.0.1 2447 | fast-glob: 3.3.3 2448 | ignore: 5.3.1 2449 | merge2: 1.4.1 2450 | slash: 3.0.0 2451 | 2452 | graceful-fs@4.2.11: {} 2453 | 2454 | has-flag@4.0.0: {} 2455 | 2456 | hookable@5.5.3: {} 2457 | 2458 | html-escaper@2.0.2: {} 2459 | 2460 | human-id@4.1.1: {} 2461 | 2462 | iconv-lite@0.7.0: 2463 | dependencies: 2464 | safer-buffer: 2.1.2 2465 | 2466 | ignore@5.3.1: {} 2467 | 2468 | import-without-cache@0.2.2: {} 2469 | 2470 | is-extglob@2.1.1: {} 2471 | 2472 | is-glob@4.0.3: 2473 | dependencies: 2474 | is-extglob: 2.1.1 2475 | 2476 | is-number@7.0.0: {} 2477 | 2478 | is-subdir@1.2.0: 2479 | dependencies: 2480 | better-path-resolve: 1.0.0 2481 | 2482 | is-windows@1.0.2: {} 2483 | 2484 | isexe@2.0.0: {} 2485 | 2486 | istanbul-lib-coverage@3.2.2: {} 2487 | 2488 | istanbul-lib-report@3.0.1: 2489 | dependencies: 2490 | istanbul-lib-coverage: 3.2.2 2491 | make-dir: 4.0.0 2492 | supports-color: 7.2.0 2493 | 2494 | istanbul-lib-source-maps@5.0.6: 2495 | dependencies: 2496 | '@jridgewell/trace-mapping': 0.3.31 2497 | debug: 4.4.3 2498 | istanbul-lib-coverage: 3.2.2 2499 | transitivePeerDependencies: 2500 | - supports-color 2501 | 2502 | istanbul-reports@3.2.0: 2503 | dependencies: 2504 | html-escaper: 2.0.2 2505 | istanbul-lib-report: 3.0.1 2506 | 2507 | js-tokens@9.0.1: {} 2508 | 2509 | js-yaml@3.14.1: 2510 | dependencies: 2511 | argparse: 1.0.10 2512 | esprima: 4.0.1 2513 | 2514 | js-yaml@4.1.1: 2515 | dependencies: 2516 | argparse: 2.0.1 2517 | 2518 | jsesc@3.1.0: {} 2519 | 2520 | jsonfile@4.0.0: 2521 | optionalDependencies: 2522 | graceful-fs: 4.2.11 2523 | 2524 | lightningcss-android-arm64@1.30.2: 2525 | optional: true 2526 | 2527 | lightningcss-darwin-arm64@1.30.2: 2528 | optional: true 2529 | 2530 | lightningcss-darwin-x64@1.30.2: 2531 | optional: true 2532 | 2533 | lightningcss-freebsd-x64@1.30.2: 2534 | optional: true 2535 | 2536 | lightningcss-linux-arm-gnueabihf@1.30.2: 2537 | optional: true 2538 | 2539 | lightningcss-linux-arm64-gnu@1.30.2: 2540 | optional: true 2541 | 2542 | lightningcss-linux-arm64-musl@1.30.2: 2543 | optional: true 2544 | 2545 | lightningcss-linux-x64-gnu@1.30.2: 2546 | optional: true 2547 | 2548 | lightningcss-linux-x64-musl@1.30.2: 2549 | optional: true 2550 | 2551 | lightningcss-win32-arm64-msvc@1.30.2: 2552 | optional: true 2553 | 2554 | lightningcss-win32-x64-msvc@1.30.2: 2555 | optional: true 2556 | 2557 | lightningcss@1.30.2: 2558 | dependencies: 2559 | detect-libc: 2.0.4 2560 | optionalDependencies: 2561 | lightningcss-android-arm64: 1.30.2 2562 | lightningcss-darwin-arm64: 1.30.2 2563 | lightningcss-darwin-x64: 1.30.2 2564 | lightningcss-freebsd-x64: 1.30.2 2565 | lightningcss-linux-arm-gnueabihf: 1.30.2 2566 | lightningcss-linux-arm64-gnu: 1.30.2 2567 | lightningcss-linux-arm64-musl: 1.30.2 2568 | lightningcss-linux-x64-gnu: 1.30.2 2569 | lightningcss-linux-x64-musl: 1.30.2 2570 | lightningcss-win32-arm64-msvc: 1.30.2 2571 | lightningcss-win32-x64-msvc: 1.30.2 2572 | optional: true 2573 | 2574 | linkify-it@5.0.0: 2575 | dependencies: 2576 | uc.micro: 2.1.0 2577 | 2578 | locate-path@5.0.0: 2579 | dependencies: 2580 | p-locate: 4.1.0 2581 | 2582 | lodash.startcase@4.4.0: {} 2583 | 2584 | lunr@2.3.9: {} 2585 | 2586 | magic-string@0.30.21: 2587 | dependencies: 2588 | '@jridgewell/sourcemap-codec': 1.5.5 2589 | 2590 | magicast@0.5.1: 2591 | dependencies: 2592 | '@babel/parser': 7.28.5 2593 | '@babel/types': 7.28.5 2594 | source-map-js: 1.2.1 2595 | 2596 | make-dir@4.0.0: 2597 | dependencies: 2598 | semver: 7.7.3 2599 | 2600 | markdown-it@14.1.0: 2601 | dependencies: 2602 | argparse: 2.0.1 2603 | entities: 4.5.0 2604 | linkify-it: 5.0.0 2605 | mdurl: 2.0.0 2606 | punycode.js: 2.3.1 2607 | uc.micro: 2.1.0 2608 | 2609 | mdurl@2.0.0: {} 2610 | 2611 | merge2@1.4.1: {} 2612 | 2613 | micromatch@4.0.8: 2614 | dependencies: 2615 | braces: 3.0.3 2616 | picomatch: 2.3.1 2617 | 2618 | minimatch@9.0.5: 2619 | dependencies: 2620 | brace-expansion: 2.0.1 2621 | 2622 | mri@1.2.0: {} 2623 | 2624 | ms@2.1.3: {} 2625 | 2626 | nanoid@3.3.11: {} 2627 | 2628 | node-fetch@2.7.0: 2629 | dependencies: 2630 | whatwg-url: 5.0.0 2631 | 2632 | obug@2.1.1: {} 2633 | 2634 | outdent@0.5.0: {} 2635 | 2636 | oxfmt@0.18.0: 2637 | dependencies: 2638 | tinypool: 2.0.0 2639 | optionalDependencies: 2640 | '@oxfmt/darwin-arm64': 0.18.0 2641 | '@oxfmt/darwin-x64': 0.18.0 2642 | '@oxfmt/linux-arm64-gnu': 0.18.0 2643 | '@oxfmt/linux-arm64-musl': 0.18.0 2644 | '@oxfmt/linux-x64-gnu': 0.18.0 2645 | '@oxfmt/linux-x64-musl': 0.18.0 2646 | '@oxfmt/win32-arm64': 0.18.0 2647 | '@oxfmt/win32-x64': 0.18.0 2648 | 2649 | oxlint-tsgolint@0.9.1: 2650 | optionalDependencies: 2651 | '@oxlint-tsgolint/darwin-arm64': 0.9.1 2652 | '@oxlint-tsgolint/darwin-x64': 0.9.1 2653 | '@oxlint-tsgolint/linux-arm64': 0.9.1 2654 | '@oxlint-tsgolint/linux-x64': 0.9.1 2655 | '@oxlint-tsgolint/win32-arm64': 0.9.1 2656 | '@oxlint-tsgolint/win32-x64': 0.9.1 2657 | 2658 | oxlint@1.33.0(oxlint-tsgolint@0.9.1): 2659 | optionalDependencies: 2660 | '@oxlint/darwin-arm64': 1.33.0 2661 | '@oxlint/darwin-x64': 1.33.0 2662 | '@oxlint/linux-arm64-gnu': 1.33.0 2663 | '@oxlint/linux-arm64-musl': 1.33.0 2664 | '@oxlint/linux-x64-gnu': 1.33.0 2665 | '@oxlint/linux-x64-musl': 1.33.0 2666 | '@oxlint/win32-arm64': 1.33.0 2667 | '@oxlint/win32-x64': 1.33.0 2668 | oxlint-tsgolint: 0.9.1 2669 | 2670 | p-filter@2.1.0: 2671 | dependencies: 2672 | p-map: 2.1.0 2673 | 2674 | p-limit@2.3.0: 2675 | dependencies: 2676 | p-try: 2.2.0 2677 | 2678 | p-locate@4.1.0: 2679 | dependencies: 2680 | p-limit: 2.3.0 2681 | 2682 | p-map@2.1.0: {} 2683 | 2684 | p-try@2.2.0: {} 2685 | 2686 | package-manager-detector@0.2.11: 2687 | dependencies: 2688 | quansync: 0.2.11 2689 | 2690 | package-manager-detector@1.6.0: {} 2691 | 2692 | path-exists@4.0.0: {} 2693 | 2694 | path-key@3.1.1: {} 2695 | 2696 | path-type@4.0.0: {} 2697 | 2698 | pathe@2.0.3: {} 2699 | 2700 | picocolors@1.1.1: {} 2701 | 2702 | picomatch@2.3.1: {} 2703 | 2704 | picomatch@4.0.3: {} 2705 | 2706 | pify@4.0.1: {} 2707 | 2708 | postcss@8.5.6: 2709 | dependencies: 2710 | nanoid: 3.3.11 2711 | picocolors: 1.1.1 2712 | source-map-js: 1.2.1 2713 | 2714 | prettier@2.8.8: {} 2715 | 2716 | publint@0.3.16: 2717 | dependencies: 2718 | '@publint/pack': 0.1.2 2719 | package-manager-detector: 1.6.0 2720 | picocolors: 1.1.1 2721 | sade: 1.8.1 2722 | 2723 | punycode.js@2.3.1: {} 2724 | 2725 | quansync@0.2.11: {} 2726 | 2727 | quansync@1.0.0: {} 2728 | 2729 | queue-microtask@1.2.3: {} 2730 | 2731 | read-yaml-file@1.1.0: 2732 | dependencies: 2733 | graceful-fs: 4.2.11 2734 | js-yaml: 3.14.1 2735 | pify: 4.0.1 2736 | strip-bom: 3.0.0 2737 | 2738 | resolve-from@5.0.0: {} 2739 | 2740 | resolve-pkg-maps@1.0.0: {} 2741 | 2742 | reusify@1.0.4: {} 2743 | 2744 | rolldown-plugin-dts@0.18.3(rolldown@1.0.0-beta.53)(typescript@5.9.3): 2745 | dependencies: 2746 | '@babel/generator': 7.28.5 2747 | '@babel/parser': 7.28.5 2748 | '@babel/types': 7.28.5 2749 | ast-kit: 2.2.0 2750 | birpc: 3.0.0 2751 | dts-resolver: 2.1.3 2752 | get-tsconfig: 4.13.0 2753 | magic-string: 0.30.21 2754 | obug: 2.1.1 2755 | rolldown: 1.0.0-beta.53 2756 | optionalDependencies: 2757 | typescript: 5.9.3 2758 | transitivePeerDependencies: 2759 | - oxc-resolver 2760 | 2761 | rolldown@1.0.0-beta.53: 2762 | dependencies: 2763 | '@oxc-project/types': 0.101.0 2764 | '@rolldown/pluginutils': 1.0.0-beta.53 2765 | optionalDependencies: 2766 | '@rolldown/binding-android-arm64': 1.0.0-beta.53 2767 | '@rolldown/binding-darwin-arm64': 1.0.0-beta.53 2768 | '@rolldown/binding-darwin-x64': 1.0.0-beta.53 2769 | '@rolldown/binding-freebsd-x64': 1.0.0-beta.53 2770 | '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.53 2771 | '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.53 2772 | '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.53 2773 | '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.53 2774 | '@rolldown/binding-linux-x64-musl': 1.0.0-beta.53 2775 | '@rolldown/binding-openharmony-arm64': 1.0.0-beta.53 2776 | '@rolldown/binding-wasm32-wasi': 1.0.0-beta.53 2777 | '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.53 2778 | '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.53 2779 | 2780 | rollup@4.53.3: 2781 | dependencies: 2782 | '@types/estree': 1.0.8 2783 | optionalDependencies: 2784 | '@rollup/rollup-android-arm-eabi': 4.53.3 2785 | '@rollup/rollup-android-arm64': 4.53.3 2786 | '@rollup/rollup-darwin-arm64': 4.53.3 2787 | '@rollup/rollup-darwin-x64': 4.53.3 2788 | '@rollup/rollup-freebsd-arm64': 4.53.3 2789 | '@rollup/rollup-freebsd-x64': 4.53.3 2790 | '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 2791 | '@rollup/rollup-linux-arm-musleabihf': 4.53.3 2792 | '@rollup/rollup-linux-arm64-gnu': 4.53.3 2793 | '@rollup/rollup-linux-arm64-musl': 4.53.3 2794 | '@rollup/rollup-linux-loong64-gnu': 4.53.3 2795 | '@rollup/rollup-linux-ppc64-gnu': 4.53.3 2796 | '@rollup/rollup-linux-riscv64-gnu': 4.53.3 2797 | '@rollup/rollup-linux-riscv64-musl': 4.53.3 2798 | '@rollup/rollup-linux-s390x-gnu': 4.53.3 2799 | '@rollup/rollup-linux-x64-gnu': 4.53.3 2800 | '@rollup/rollup-linux-x64-musl': 4.53.3 2801 | '@rollup/rollup-openharmony-arm64': 4.53.3 2802 | '@rollup/rollup-win32-arm64-msvc': 4.53.3 2803 | '@rollup/rollup-win32-ia32-msvc': 4.53.3 2804 | '@rollup/rollup-win32-x64-gnu': 4.53.3 2805 | '@rollup/rollup-win32-x64-msvc': 4.53.3 2806 | fsevents: 2.3.3 2807 | 2808 | run-parallel@1.2.0: 2809 | dependencies: 2810 | queue-microtask: 1.2.3 2811 | 2812 | sade@1.8.1: 2813 | dependencies: 2814 | mri: 1.2.0 2815 | 2816 | safer-buffer@2.1.2: {} 2817 | 2818 | semver@7.7.3: {} 2819 | 2820 | shebang-command@2.0.0: 2821 | dependencies: 2822 | shebang-regex: 3.0.0 2823 | 2824 | shebang-regex@3.0.0: {} 2825 | 2826 | siginfo@2.0.0: {} 2827 | 2828 | signal-exit@4.1.0: {} 2829 | 2830 | slash@3.0.0: {} 2831 | 2832 | source-map-js@1.2.1: {} 2833 | 2834 | source-map-support@0.5.21: 2835 | dependencies: 2836 | buffer-from: 1.1.2 2837 | source-map: 0.6.1 2838 | optional: true 2839 | 2840 | source-map@0.6.1: 2841 | optional: true 2842 | 2843 | spawndamnit@3.0.1: 2844 | dependencies: 2845 | cross-spawn: 7.0.6 2846 | signal-exit: 4.1.0 2847 | 2848 | sprintf-js@1.0.3: {} 2849 | 2850 | stackback@0.0.2: {} 2851 | 2852 | std-env@3.10.0: {} 2853 | 2854 | strip-ansi@6.0.1: 2855 | dependencies: 2856 | ansi-regex: 5.0.1 2857 | 2858 | strip-bom@3.0.0: {} 2859 | 2860 | supports-color@7.2.0: 2861 | dependencies: 2862 | has-flag: 4.0.0 2863 | 2864 | term-size@2.2.1: {} 2865 | 2866 | terser@5.30.3: 2867 | dependencies: 2868 | '@jridgewell/source-map': 0.3.6 2869 | acorn: 8.11.3 2870 | commander: 2.20.3 2871 | source-map-support: 0.5.21 2872 | optional: true 2873 | 2874 | tinybench@2.9.0: {} 2875 | 2876 | tinyexec@1.0.2: {} 2877 | 2878 | tinyglobby@0.2.15: 2879 | dependencies: 2880 | fdir: 6.5.0(picomatch@4.0.3) 2881 | picomatch: 4.0.3 2882 | 2883 | tinypool@2.0.0: {} 2884 | 2885 | tinyrainbow@3.0.3: {} 2886 | 2887 | to-regex-range@5.0.1: 2888 | dependencies: 2889 | is-number: 7.0.0 2890 | 2891 | tr46@0.0.3: {} 2892 | 2893 | tree-kill@1.2.2: {} 2894 | 2895 | tsdown@0.17.2(publint@0.3.16)(typescript@5.9.3): 2896 | dependencies: 2897 | ansis: 4.2.0 2898 | cac: 6.7.14 2899 | empathic: 2.0.0 2900 | hookable: 5.5.3 2901 | import-without-cache: 0.2.2 2902 | obug: 2.1.1 2903 | rolldown: 1.0.0-beta.53 2904 | rolldown-plugin-dts: 0.18.3(rolldown@1.0.0-beta.53)(typescript@5.9.3) 2905 | semver: 7.7.3 2906 | tinyexec: 1.0.2 2907 | tinyglobby: 0.2.15 2908 | tree-kill: 1.2.2 2909 | unconfig-core: 7.4.2 2910 | unrun: 0.2.19 2911 | optionalDependencies: 2912 | publint: 0.3.16 2913 | typescript: 5.9.3 2914 | transitivePeerDependencies: 2915 | - '@ts-macro/tsc' 2916 | - '@typescript/native-preview' 2917 | - oxc-resolver 2918 | - synckit 2919 | - vue-tsc 2920 | 2921 | tslib@2.6.2: 2922 | optional: true 2923 | 2924 | tsx@4.20.6: 2925 | dependencies: 2926 | esbuild: 0.25.12 2927 | get-tsconfig: 4.13.0 2928 | optionalDependencies: 2929 | fsevents: 2.3.3 2930 | optional: true 2931 | 2932 | typedoc@0.28.15(typescript@5.9.3): 2933 | dependencies: 2934 | '@gerrit0/mini-shiki': 3.18.0 2935 | lunr: 2.3.9 2936 | markdown-it: 14.1.0 2937 | minimatch: 9.0.5 2938 | typescript: 5.9.3 2939 | yaml: 2.8.1 2940 | 2941 | typescript@5.9.3: {} 2942 | 2943 | uc.micro@2.1.0: {} 2944 | 2945 | unconfig-core@7.4.2: 2946 | dependencies: 2947 | '@quansync/fs': 1.0.0 2948 | quansync: 1.0.0 2949 | 2950 | undici-types@7.16.0: {} 2951 | 2952 | universalify@0.1.2: {} 2953 | 2954 | unrun@0.2.19: 2955 | dependencies: 2956 | rolldown: 1.0.0-beta.53 2957 | 2958 | vite@7.1.12(@types/node@24.10.4)(lightningcss@1.30.2)(terser@5.30.3)(tsx@4.20.6)(yaml@2.8.1): 2959 | dependencies: 2960 | esbuild: 0.25.12 2961 | fdir: 6.5.0(picomatch@4.0.3) 2962 | picomatch: 4.0.3 2963 | postcss: 8.5.6 2964 | rollup: 4.53.3 2965 | tinyglobby: 0.2.15 2966 | optionalDependencies: 2967 | '@types/node': 24.10.4 2968 | fsevents: 2.3.3 2969 | lightningcss: 1.30.2 2970 | terser: 5.30.3 2971 | tsx: 4.20.6 2972 | yaml: 2.8.1 2973 | 2974 | vitest@4.0.15(@types/node@24.10.4)(lightningcss@1.30.2)(terser@5.30.3)(tsx@4.20.6)(yaml@2.8.1): 2975 | dependencies: 2976 | '@vitest/expect': 4.0.15 2977 | '@vitest/mocker': 4.0.15(vite@7.1.12(@types/node@24.10.4)(lightningcss@1.30.2)(terser@5.30.3)(tsx@4.20.6)(yaml@2.8.1)) 2978 | '@vitest/pretty-format': 4.0.15 2979 | '@vitest/runner': 4.0.15 2980 | '@vitest/snapshot': 4.0.15 2981 | '@vitest/spy': 4.0.15 2982 | '@vitest/utils': 4.0.15 2983 | es-module-lexer: 1.7.0 2984 | expect-type: 1.2.2 2985 | magic-string: 0.30.21 2986 | obug: 2.1.1 2987 | pathe: 2.0.3 2988 | picomatch: 4.0.3 2989 | std-env: 3.10.0 2990 | tinybench: 2.9.0 2991 | tinyexec: 1.0.2 2992 | tinyglobby: 0.2.15 2993 | tinyrainbow: 3.0.3 2994 | vite: 7.1.12(@types/node@24.10.4)(lightningcss@1.30.2)(terser@5.30.3)(tsx@4.20.6)(yaml@2.8.1) 2995 | why-is-node-running: 2.3.0 2996 | optionalDependencies: 2997 | '@types/node': 24.10.4 2998 | transitivePeerDependencies: 2999 | - jiti 3000 | - less 3001 | - lightningcss 3002 | - msw 3003 | - sass 3004 | - sass-embedded 3005 | - stylus 3006 | - sugarss 3007 | - terser 3008 | - tsx 3009 | - yaml 3010 | 3011 | webidl-conversions@3.0.1: {} 3012 | 3013 | whatwg-url@5.0.0: 3014 | dependencies: 3015 | tr46: 0.0.3 3016 | webidl-conversions: 3.0.1 3017 | 3018 | which@2.0.2: 3019 | dependencies: 3020 | isexe: 2.0.0 3021 | 3022 | why-is-node-running@2.3.0: 3023 | dependencies: 3024 | siginfo: 2.0.0 3025 | stackback: 0.0.2 3026 | 3027 | yaml@2.8.1: {} 3028 | 3029 | zod@4.1.13: {} 3030 | --------------------------------------------------------------------------------