diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..dad1af0
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+* text eol=lf
+*.pdf binary
+*.png binary
\ No newline at end of file
diff --git a/.github/workflows/release-github.yaml b/.github/workflows/release-github.yaml
new file mode 100644
index 0000000..8030e41
--- /dev/null
+++ b/.github/workflows/release-github.yaml
@@ -0,0 +1,18 @@
+name: Release GitHub
+
+on:
+ push:
+ branches: [release/*]
+
+jobs:
+ create-github-release:
+ name: Create GitHub Release and Git tag
+ runs-on: ubuntu-latest
+ environment: Release
+ permissions:
+ contents: write
+ steps:
+ - uses: actions/checkout@v4
+ - uses: cucumber/action-create-github-release@v1.1.1
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/release-npm.yaml b/.github/workflows/release-npm.yaml
new file mode 100644
index 0000000..89a1f4f
--- /dev/null
+++ b/.github/workflows/release-npm.yaml
@@ -0,0 +1,24 @@
+name: Release NPM
+
+on:
+ push:
+ branches: [release/*]
+
+jobs:
+ publish-npm:
+ name: Publish NPM module
+ runs-on: ubuntu-latest
+ environment: Release
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: '22.x'
+ cache: 'npm'
+ cache-dependency-path: package-lock.json
+ - run: npm ci
+ - run: npm run build
+ - uses: cucumber/action-publish-npm@v1.1.1
+ with:
+ npm-token: ${{ secrets.NPM_TOKEN }}
+ npm-tag: 'latest'
diff --git a/.github/workflows/site.yaml b/.github/workflows/site.yaml
new file mode 100644
index 0000000..7f36cc7
--- /dev/null
+++ b/.github/workflows/site.yaml
@@ -0,0 +1,35 @@
+name: Site
+
+on:
+ push:
+ branches:
+ - main
+
+jobs:
+ upload-artifact:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 22.x
+ - run: npm ci
+ - run: npm run docs
+ - run: |
+ chmod -c -R +rX "_site/" | while read line; do
+ echo "::warning title=Invalid file permissions automatically fixed::$line"
+ done
+ - uses: actions/upload-pages-artifact@v3
+
+ deploy:
+ needs: upload-artifact
+ permissions:
+ pages: write
+ id-token: write
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ steps:
+ - id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
new file mode 100644
index 0000000..c53ab00
--- /dev/null
+++ b/.github/workflows/test.yaml
@@ -0,0 +1,56 @@
+name: Test
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+jobs:
+ test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os:
+ - ubuntu-latest
+ - macos-latest
+ - windows-latest
+ node-version: [20.x, 22.x, 24.x]
+ fail-fast: false
+
+ steps:
+ - uses: actions/checkout@v4
+ - name: with Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ matrix.node-version }}
+ - run: npm ci
+ - run: npm run lint
+ - run: npm run build
+ - run: npm test
+
+ coverage:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 24.x
+ - run: npm ci
+ - run: npm run build
+ - run: npm run coverage:check
+
+ exports:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 24.x
+ - run: npm ci
+ - run: npm run build
+ - run: npm run exports:check
diff --git a/.gitignore b/.gitignore
index 9a5aced..d343be5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,139 +1,6 @@
-# Logs
-logs
-*.log
-npm-debug.log*
-yarn-debug.log*
-yarn-error.log*
-lerna-debug.log*
-
-# Diagnostic reports (https://nodejs.org/api/report.html)
-report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
-
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
+_site
coverage
-*.lcov
-
-# nyc test coverage
-.nyc_output
-
-# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
-
-# Snowpack dependency directory (https://snowpack.dev/)
-web_modules/
-
-# TypeScript cache
-*.tsbuildinfo
-
-# Optional npm cache directory
-.npm
-
-# Optional eslint cache
-.eslintcache
-
-# Optional stylelint cache
-.stylelintcache
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variable files
-.env
-.env.*
-!.env.example
-
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-.parcel-cache
-
-# Next.js build output
-.next
-out
-
-# Nuxt.js build / generate output
-.nuxt
dist
-
-# Gatsby files
-.cache/
-# Comment in the public line in if your project uses Gatsby and not Next.js
-# https://nextjs.org/blog/next-9-1#public-directory-support
-# public
-
-# vuepress build output
-.vuepress/dist
-
-# vuepress v2.x temp and cache directory
-.temp
-.cache
-
-# Sveltekit cache directory
-.svelte-kit/
-
-# vitepress build output
-**/.vitepress/dist
-
-# vitepress cache directory
-**/.vitepress/cache
-
-# Docusaurus cache and generated files
-.docusaurus
-
-# Serverless directories
-.serverless/
-
-# FuseBox cache
-.fusebox/
-
-# DynamoDB Local files
-.dynamodb/
-
-# Firebase cache directory
-.firebase/
-
-# TernJS port file
-.tern-port
-
-# Stores VSCode versions used for testing VSCode extensions
-.vscode-test
-
-# yarn v3
-.pnp.*
-.yarn/*
-!.yarn/patches
-!.yarn/plugins
-!.yarn/releases
-!.yarn/sdks
-!.yarn/versions
-
-# Vite logs files
-vite.config.js.timestamp-*
-vite.config.ts.timestamp-*
+node_modules
+tmp
+tsdoc-metadata.json
\ No newline at end of file
diff --git a/.mocharc.json b/.mocharc.json
new file mode 100644
index 0000000..83480ac
--- /dev/null
+++ b/.mocharc.json
@@ -0,0 +1,5 @@
+{
+ "require": "ts-node/register",
+ "extension": ["ts"],
+ "recursive": true
+}
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 0000000..0e9e3a7
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1,6 @@
+{
+ "trailingComma": "es5",
+ "semi": false,
+ "singleQuote": true,
+ "printWidth": 100
+}
diff --git a/LICENSE b/LICENSE
index d45f3f3..8cb58fc 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2025 Cucumber
+Copyright (c) 2025 David Goss and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 14bfe54..2c139fe 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,15 @@
-# javascript-core
\ No newline at end of file
+
+
+
+ javascript-core
+
+
+ Core test case composition library for building a Cucumber implementation
+
+
+
+
+
+
+
+This library provides helpers for taking pickles and support code and turning them into executable test cases.
\ No newline at end of file
diff --git a/RELEASING.md b/RELEASING.md
new file mode 100644
index 0000000..71e0bb8
--- /dev/null
+++ b/RELEASING.md
@@ -0,0 +1 @@
+See [.github/RELEASING](https://github.com/cucumber/.github/blob/main/RELEASING.md).
diff --git a/api-extractor.json b/api-extractor.json
new file mode 100644
index 0000000..cd6d672
--- /dev/null
+++ b/api-extractor.json
@@ -0,0 +1,33 @@
+{
+ "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
+ "mainEntryPointFilePath": "/dist/index.d.ts",
+ "compiler": {},
+ "apiReport": {
+ "enabled": true,
+ "reportFolder": "",
+ "reportTempFolder": "/tmp",
+ "reportFileName": "cucumber-core"
+ },
+ "docModel": {
+ "enabled": false
+ },
+ "dtsRollup": {
+ "enabled": false
+ },
+ "messages": {
+ "extractorMessageReporting": {
+ "ae-forgotten-export": {
+ "logLevel": "warning",
+ "addToApiReportFile": false
+ }
+ },
+ "tsdocMessageReporting": {
+ "tsdoc-undefined-tag": {
+ "logLevel": "none"
+ },
+ "tsdoc-escape-greater-than": {
+ "logLevel": "none"
+ }
+ }
+ }
+}
diff --git a/cucumber-core.api.md b/cucumber-core.api.md
new file mode 100644
index 0000000..fa0f08b
--- /dev/null
+++ b/cucumber-core.api.md
@@ -0,0 +1,194 @@
+## API Report File for "@cucumber/core"
+
+> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
+
+```ts
+
+import { Argument } from '@cucumber/cucumber-expressions';
+import { CucumberExpression } from '@cucumber/cucumber-expressions';
+import { Envelope } from '@cucumber/messages';
+import { GherkinDocument } from '@cucumber/messages';
+import { Hook } from '@cucumber/messages';
+import { IdGenerator } from '@cucumber/messages';
+import { NamingStrategy } from '@cucumber/query';
+import parse from '@cucumber/tag-expressions';
+import { Pickle } from '@cucumber/messages';
+import { RegularExpression } from '@cucumber/cucumber-expressions';
+import { SourceReference } from '@cucumber/messages';
+import { StepDefinition } from '@cucumber/messages';
+import { TestCase } from '@cucumber/messages';
+import { TestStep } from '@cucumber/messages';
+
+// @public
+export class AmbiguousError extends Error {
+ constructor(text: string, references: ReadonlyArray);
+}
+
+// @public
+export interface AssembledStep {
+ always: boolean;
+ id: string;
+ name: {
+ prefix: string;
+ body: string;
+ };
+ prepare(thisArg?: unknown): PreparedFunction;
+ toMessage(): TestStep;
+}
+
+// @public
+export interface AssembledTestCase {
+ id: string;
+ name: string;
+ steps: ReadonlyArray;
+ toMessage(): TestCase;
+}
+
+// @public
+export interface AssembledTestPlan {
+ name?: string;
+ testCases: ReadonlyArray;
+ toEnvelopes(): ReadonlyArray;
+}
+
+// @public
+export function buildSupportCode(options?: SupportCodeOptions): SupportCodeBuilder;
+
+// @public
+export class DataTable {
+ constructor(cells: ReadonlyArray>);
+ hashes(): ReadonlyArray>;
+ list(): ReadonlyArray;
+ raw(): ReadonlyArray>;
+ rows(): ReadonlyArray>;
+ rowsHash(): Record;
+ transpose(): DataTable;
+}
+
+// @public
+export type DefinedHook = {
+ id: string;
+ name?: string;
+ tags?: {
+ raw: string;
+ compiled: ReturnType;
+ };
+ fn: SupportCodeFunction;
+ sourceReference: SourceReference;
+ toMessage(): Hook;
+};
+
+// @public
+export type DefinedParameterType = {
+ id: string;
+ name: string;
+ regularExpressions: ReadonlyArray;
+ preferForRegularExpressionMatch: boolean;
+ useForSnippets: boolean;
+ sourceReference: SourceReference;
+};
+
+// @public
+export type DefinedStep = {
+ id: string;
+ expression: {
+ raw: string | RegExp;
+ compiled: CucumberExpression | RegularExpression;
+ };
+ fn: SupportCodeFunction;
+ sourceReference: SourceReference;
+ toMessage(): StepDefinition;
+};
+
+// @public
+export function makeTestPlan(ingredients: TestPlanIngredients, options?: TestPlanOptions): AssembledTestPlan;
+
+// @public
+export type MatchedStep = {
+ def: DefinedStep;
+ args: ReadonlyArray;
+};
+
+// @public
+export interface NewHook {
+ fn: SupportCodeFunction;
+ name?: string;
+ sourceReference: SourceReference;
+ tags?: string;
+}
+
+// @public
+export interface NewParameterType {
+ name: string;
+ preferForRegexpMatch?: boolean;
+ regexp: RegExp | string | readonly RegExp[] | readonly string[];
+ sourceReference: SourceReference;
+ transformer?: (...match: string[]) => unknown;
+ useForSnippets?: boolean;
+}
+
+// @public
+export interface NewStep {
+ fn: SupportCodeFunction;
+ pattern: string | RegExp;
+ sourceReference: SourceReference;
+}
+
+// @public
+export type PreparedFunction = {
+ fn: SupportCodeFunction;
+ args: ReadonlyArray;
+};
+
+// @public
+export interface SupportCodeBuilder {
+ afterHook(options: NewHook): SupportCodeBuilder;
+ beforeHook(options: NewHook): SupportCodeBuilder;
+ build(): SupportCodeLibrary;
+ parameterType(options: NewParameterType): SupportCodeBuilder;
+ step(options: NewStep): SupportCodeBuilder;
+}
+
+// @public
+export type SupportCodeFunction = (...args: any[]) => any | Promise;
+
+// @public
+export interface SupportCodeLibrary {
+ findAllAfterHooksBy(tags: ReadonlyArray): ReadonlyArray;
+ findAllBeforeHooksBy(tags: ReadonlyArray): ReadonlyArray;
+ findAllStepsBy(text: string): ReadonlyArray;
+ toEnvelopes(): ReadonlyArray;
+}
+
+// @public
+export interface SupportCodeOptions {
+ newId?: IdGenerator.NewId;
+}
+
+// @public
+export interface TestPlanIngredients {
+ gherkinDocument: GherkinDocument;
+ pickles: ReadonlyArray;
+ supportCodeLibrary: SupportCodeLibrary;
+}
+
+// @public
+export interface TestPlanOptions {
+ newId?: IdGenerator.NewId;
+ strategy?: NamingStrategy;
+}
+
+// @public
+export class UndefinedError extends Error {
+ constructor(text: string);
+}
+
+// @public
+export type UndefinedParameterType = {
+ name: string;
+ expression: string;
+};
+
+// (No @packageDocumentation comment for this package)
+
+```
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000..34dc138
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,26 @@
+import js from "@eslint/js";
+import globals from "globals";
+import tseslint from "typescript-eslint";
+import simpleImportSort from "eslint-plugin-simple-import-sort";
+import {defineConfig} from "eslint/config";
+
+export default defineConfig([
+ {
+ files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
+ languageOptions: {globals: {...globals.browser, ...globals.node}},
+ plugins: {js, 'simple-import-sort': simpleImportSort,},
+ extends: ["js/recommended"],
+ rules: {
+ 'simple-import-sort/imports': 'error',
+ 'simple-import-sort/exports': 'error',
+ },
+ },
+ tseslint.configs.recommended,
+ {
+ files: ["**/*.spec.{ts,js}", "**/*.test.{ts,js}", "**/test/**/*.{ts,js}", "**/tests/**/*.{ts,js}"],
+ rules: {
+ '@typescript-eslint/no-explicit-any': 'off',
+ '@typescript-eslint/no-this-alias': 'off',
+ },
+ },
+]);
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..8ccdaa1
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,4044 @@
+{
+ "name": "@cucumber/core",
+ "version": "0.0.1",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@cucumber/core",
+ "version": "0.0.1",
+ "license": "MIT",
+ "devDependencies": {
+ "@cucumber/cucumber-expressions": "^18.0.1",
+ "@cucumber/gherkin": "^33.0.0",
+ "@cucumber/messages": "^28.0.0",
+ "@cucumber/query": "^13.5.0",
+ "@cucumber/tag-expressions": "^6.2.0",
+ "@eslint/js": "^9.31.0",
+ "@microsoft/api-extractor": "^7.52.8",
+ "@tsconfig/recommended": "^1.0.10",
+ "@types/chai": "^5.2.2",
+ "@types/mocha": "^10.0.10",
+ "@types/sinon": "^17.0.4",
+ "@types/sinon-chai": "^4.0.0",
+ "c8": "^10.1.3",
+ "chai": "^5.2.1",
+ "eslint": "^9.31.0",
+ "eslint-plugin-simple-import-sort": "^12.1.1",
+ "globals": "^16.3.0",
+ "mocha": "^11.7.1",
+ "prettier": "^3.6.2",
+ "sinon": "^21.0.0",
+ "sinon-chai": "^4.0.0",
+ "ts-node": "^10.9.2",
+ "typedoc": "^0.28.7",
+ "typescript": "^5.8.3",
+ "typescript-eslint": "^8.37.0"
+ },
+ "peerDependencies": {
+ "@cucumber/cucumber-expressions": "*",
+ "@cucumber/messages": "*",
+ "@cucumber/query": "*",
+ "@cucumber/tag-expressions": "*"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@cucumber/cucumber-expressions": {
+ "version": "18.0.1",
+ "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-18.0.1.tgz",
+ "integrity": "sha512-NSid6bI+7UlgMywl5octojY5NXnxR9uq+JisjOrO52VbFsQM6gTWuQFE8syI10KnIBEdPzuEUSVEeZ0VFzRnZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "regexp-match-indices": "1.0.2"
+ }
+ },
+ "node_modules/@cucumber/gherkin": {
+ "version": "33.0.0",
+ "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-33.0.0.tgz",
+ "integrity": "sha512-01+cAGttXsYIQ3xoEFJ8BsfxzppXKPxjz7/FzVv/+uKAVcVQtrcsxU8dAp5Cf+Qu31CWOa4SyB1nMz1ADLnApw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cucumber/messages": ">=19.1.4 <29"
+ }
+ },
+ "node_modules/@cucumber/messages": {
+ "version": "28.0.0",
+ "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-28.0.0.tgz",
+ "integrity": "sha512-y/DT0uWK1ODrN+PLPWL9/M/9kW9d4Rivw3P4w7QLsb8EGMXeQ84Cn3uH4/a3U/GOA37OvJwKof4KTjBZ+unxQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/uuid": "10.0.0",
+ "class-transformer": "0.5.1",
+ "reflect-metadata": "0.2.2",
+ "uuid": "11.1.0"
+ }
+ },
+ "node_modules/@cucumber/query": {
+ "version": "13.5.0",
+ "resolved": "https://registry.npmjs.org/@cucumber/query/-/query-13.5.0.tgz",
+ "integrity": "sha512-8L/7qMRixZZJl0S+ao4sq7IobLD1gAdr2H0KDVg81r4M063ZeWDNBSXAr2BXSAYL5I7cpNxpfbfU2VgXPaqapA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@teppeis/multimaps": "3.0.0",
+ "lodash.sortby": "^4.7.0"
+ },
+ "peerDependencies": {
+ "@cucumber/messages": "*"
+ }
+ },
+ "node_modules/@cucumber/tag-expressions": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-6.2.0.tgz",
+ "integrity": "sha512-KIF0eLcafHbWOuSDWFw0lMmgJOLdDRWjEL1kfXEWrqHmx2119HxVAr35WuEd9z542d3Yyg+XNqSr+81rIKqEdg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
+ "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
+ "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz",
+ "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.15.1",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz",
+ "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.31.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz",
+ "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.3.tgz",
+ "integrity": "sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.15.1",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@gerrit0/mini-shiki": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.8.1.tgz",
+ "integrity": "sha512-HVZW+8pxoOExr5ZMPK15U79jQAZTO/S6i5byQyyZGjtNj+qaYd82cizTncwFzTQgiLo8uUBym6vh+/1tfJklTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/engine-oniguruma": "^3.8.1",
+ "@shikijs/langs": "^3.8.1",
+ "@shikijs/themes": "^3.8.1",
+ "@shikijs/types": "^3.8.1",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.6",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
+ "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
+ "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz",
+ "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "node_modules/@microsoft/api-extractor": {
+ "version": "7.52.8",
+ "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.8.tgz",
+ "integrity": "sha512-cszYIcjiNscDoMB1CIKZ3My61+JOhpERGlGr54i6bocvGLrcL/wo9o+RNXMBrb7XgLtKaizZWUpqRduQuHQLdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@microsoft/api-extractor-model": "7.30.6",
+ "@microsoft/tsdoc": "~0.15.1",
+ "@microsoft/tsdoc-config": "~0.17.1",
+ "@rushstack/node-core-library": "5.13.1",
+ "@rushstack/rig-package": "0.5.3",
+ "@rushstack/terminal": "0.15.3",
+ "@rushstack/ts-command-line": "5.0.1",
+ "lodash": "~4.17.15",
+ "minimatch": "~3.0.3",
+ "resolve": "~1.22.1",
+ "semver": "~7.5.4",
+ "source-map": "~0.6.1",
+ "typescript": "5.8.2"
+ },
+ "bin": {
+ "api-extractor": "bin/api-extractor"
+ }
+ },
+ "node_modules/@microsoft/api-extractor-model": {
+ "version": "7.30.6",
+ "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.6.tgz",
+ "integrity": "sha512-znmFn69wf/AIrwHya3fxX6uB5etSIn6vg4Q4RB/tb5VDDs1rqREc+AvMC/p19MUN13CZ7+V/8pkYPTj7q8tftg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@microsoft/tsdoc": "~0.15.1",
+ "@microsoft/tsdoc-config": "~0.17.1",
+ "@rushstack/node-core-library": "5.13.1"
+ }
+ },
+ "node_modules/@microsoft/api-extractor/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@microsoft/api-extractor/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@microsoft/api-extractor/node_modules/minimatch": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
+ "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@microsoft/api-extractor/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@microsoft/api-extractor/node_modules/typescript": {
+ "version": "5.8.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
+ "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/@microsoft/tsdoc": {
+ "version": "0.15.1",
+ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz",
+ "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@microsoft/tsdoc-config": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz",
+ "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@microsoft/tsdoc": "0.15.1",
+ "ajv": "~8.12.0",
+ "jju": "~1.4.0",
+ "resolve": "~1.22.2"
+ }
+ },
+ "node_modules/@microsoft/tsdoc-config/node_modules/ajv": {
+ "version": "8.12.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
+ "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@microsoft/tsdoc-config/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@rushstack/node-core-library": {
+ "version": "5.13.1",
+ "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.13.1.tgz",
+ "integrity": "sha512-5yXhzPFGEkVc9Fu92wsNJ9jlvdwz4RNb2bMso+/+TH0nMm1jDDDsOIf4l8GAkPxGuwPw5DH24RliWVfSPhlW/Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "~8.13.0",
+ "ajv-draft-04": "~1.0.0",
+ "ajv-formats": "~3.0.1",
+ "fs-extra": "~11.3.0",
+ "import-lazy": "~4.0.0",
+ "jju": "~1.4.0",
+ "resolve": "~1.22.1",
+ "semver": "~7.5.4"
+ },
+ "peerDependencies": {
+ "@types/node": "*"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rushstack/node-core-library/node_modules/ajv": {
+ "version": "8.13.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz",
+ "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.4.1"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@rushstack/node-core-library/node_modules/ajv-draft-04": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz",
+ "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "ajv": "^8.5.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rushstack/node-core-library/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rushstack/node-core-library/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@rushstack/node-core-library/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@rushstack/rig-package": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz",
+ "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve": "~1.22.1",
+ "strip-json-comments": "~3.1.1"
+ }
+ },
+ "node_modules/@rushstack/terminal": {
+ "version": "0.15.3",
+ "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.3.tgz",
+ "integrity": "sha512-DGJ0B2Vm69468kZCJkPj3AH5nN+nR9SPmC0rFHtzsS4lBQ7/dgOwtwVxYP7W9JPDMuRBkJ4KHmWKr036eJsj9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rushstack/node-core-library": "5.13.1",
+ "supports-color": "~8.1.1"
+ },
+ "peerDependencies": {
+ "@types/node": "*"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@rushstack/ts-command-line": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.0.1.tgz",
+ "integrity": "sha512-bsbUucn41UXrQK7wgM8CNM/jagBytEyJqXw/umtI8d68vFm1Jwxh1OtLrlW7uGZgjCWiiPH6ooUNa1aVsuVr3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rushstack/terminal": "0.15.3",
+ "@types/argparse": "1.0.38",
+ "argparse": "~1.0.9",
+ "string-argv": "~0.3.1"
+ }
+ },
+ "node_modules/@rushstack/ts-command-line/node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/@shikijs/engine-oniguruma": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.8.1.tgz",
+ "integrity": "sha512-KGQJZHlNY7c656qPFEQpIoqOuC4LrxjyNndRdzk5WKB/Ie87+NJCF1xo9KkOUxwxylk7rT6nhlZyTGTC4fCe1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.8.1",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ }
+ },
+ "node_modules/@shikijs/langs": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.8.1.tgz",
+ "integrity": "sha512-TjOFg2Wp1w07oKnXjs0AUMb4kJvujML+fJ1C5cmEj45lhjbUXtziT1x2bPQb9Db6kmPhkG5NI2tgYW1/DzhUuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.8.1"
+ }
+ },
+ "node_modules/@shikijs/themes": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.8.1.tgz",
+ "integrity": "sha512-Vu3t3BBLifc0GB0UPg2Pox1naTemrrvyZv2lkiSw3QayVV60me1ujFQwPZGgUTmwXl1yhCPW8Lieesm0CYruLQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.8.1"
+ }
+ },
+ "node_modules/@shikijs/types": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.8.1.tgz",
+ "integrity": "sha512-5C39Q8/8r1I26suLh+5TPk1DTrbY/kn3IdWA5HdizR0FhlhD05zx5nKCqhzSfDHH3p4S0ZefxWd77DLV+8FhGg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@shikijs/vscode-textmate": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz",
+ "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "13.0.5",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz",
+ "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1"
+ }
+ },
+ "node_modules/@sinonjs/samsam": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz",
+ "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.1.0"
+ }
+ },
+ "node_modules/@sinonjs/samsam/node_modules/type-detect": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz",
+ "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@teppeis/multimaps": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@teppeis/multimaps/-/multimaps-3.0.0.tgz",
+ "integrity": "sha512-ID7fosbc50TbT0MK0EG12O+gAP3W3Aa/Pz4DaTtQtEvlc9Odaqi0de+xuZ7Li2GtK4HzEX7IuRWS/JmZLksR3Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
+ "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
+ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@tsconfig/recommended": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@tsconfig/recommended/-/recommended-1.0.10.tgz",
+ "integrity": "sha512-cGvydvg03lONp5Z9yaplW493Vw9/um7k588mvDkm+VFPF2PZUVPx0uswq4PFpeEySsLbQRETrDRhzh4Dmxaslw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/argparse": {
+ "version": "1.0.38",
+ "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz",
+ "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/chai": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
+ "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/deep-eql": "*"
+ }
+ },
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/hast": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/mocha": {
+ "version": "10.0.10",
+ "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz",
+ "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "24.0.14",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.14.tgz",
+ "integrity": "sha512-4zXMWD91vBLGRtHK3YbIoFMia+1nqEz72coM42C5ETjnNCa/heoj7NT1G67iAfOqMmcfhuCZ4uNpyz8EjlAejw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "undici-types": "~7.8.0"
+ }
+ },
+ "node_modules/@types/sinon": {
+ "version": "17.0.4",
+ "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.4.tgz",
+ "integrity": "sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/sinonjs__fake-timers": "*"
+ }
+ },
+ "node_modules/@types/sinon-chai": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-4.0.0.tgz",
+ "integrity": "sha512-Uar+qk3TmeFsUWCwtqRNqNUE7vf34+MCJiQJR5M2rd4nCbhtE8RgTiHwN/mVwbfCjhmO6DiOel/MgzHkRMJJFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "*",
+ "@types/sinon": "*"
+ }
+ },
+ "node_modules/@types/sinonjs__fake-timers": {
+ "version": "8.1.5",
+ "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz",
+ "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/uuid": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
+ "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.37.0.tgz",
+ "integrity": "sha512-jsuVWeIkb6ggzB+wPCsR4e6loj+rM72ohW6IBn2C+5NCvfUVY8s33iFPySSVXqtm5Hu29Ne/9bnA0JmyLmgenA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.37.0",
+ "@typescript-eslint/type-utils": "8.37.0",
+ "@typescript-eslint/utils": "8.37.0",
+ "@typescript-eslint/visitor-keys": "8.37.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^7.0.0",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.37.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.37.0.tgz",
+ "integrity": "sha512-kVIaQE9vrN9RLCQMQ3iyRlVJpTiDUY6woHGb30JDkfJErqrQEmtdWH3gV0PBAfGZgQXoqzXOO0T3K6ioApbbAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.37.0",
+ "@typescript-eslint/types": "8.37.0",
+ "@typescript-eslint/typescript-estree": "8.37.0",
+ "@typescript-eslint/visitor-keys": "8.37.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.37.0.tgz",
+ "integrity": "sha512-BIUXYsbkl5A1aJDdYJCBAo8rCEbAvdquQ8AnLb6z5Lp1u3x5PNgSSx9A/zqYc++Xnr/0DVpls8iQ2cJs/izTXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.37.0",
+ "@typescript-eslint/types": "^8.37.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.37.0.tgz",
+ "integrity": "sha512-0vGq0yiU1gbjKob2q691ybTg9JX6ShiVXAAfm2jGf3q0hdP6/BruaFjL/ManAR/lj05AvYCH+5bbVo0VtzmjOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.37.0",
+ "@typescript-eslint/visitor-keys": "8.37.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.37.0.tgz",
+ "integrity": "sha512-1/YHvAVTimMM9mmlPvTec9NP4bobA1RkDbMydxG8omqwJJLEW/Iy2C4adsAESIXU3WGLXFHSZUU+C9EoFWl4Zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.37.0.tgz",
+ "integrity": "sha512-SPkXWIkVZxhgwSwVq9rqj/4VFo7MnWwVaRNznfQDc/xPYHjXnPfLWn+4L6FF1cAz6e7dsqBeMawgl7QjUMj4Ow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.37.0",
+ "@typescript-eslint/typescript-estree": "8.37.0",
+ "@typescript-eslint/utils": "8.37.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.37.0.tgz",
+ "integrity": "sha512-ax0nv7PUF9NOVPs+lmQ7yIE7IQmAf8LGcXbMvHX5Gm+YJUYNAl340XkGnrimxZ0elXyoQJuN5sbg6C4evKA4SQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.37.0.tgz",
+ "integrity": "sha512-zuWDMDuzMRbQOM+bHyU4/slw27bAUEcKSKKs3hcv2aNnc/tvE/h7w60dwVw8vnal2Pub6RT1T7BI8tFZ1fE+yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.37.0",
+ "@typescript-eslint/tsconfig-utils": "8.37.0",
+ "@typescript-eslint/types": "8.37.0",
+ "@typescript-eslint/visitor-keys": "8.37.0",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.37.0.tgz",
+ "integrity": "sha512-TSFvkIW6gGjN2p6zbXo20FzCABbyUAuq6tBvNRGsKdsSQ6a7rnV6ADfZ7f4iI3lIiXc4F4WWvtUfDw9CJ9pO5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/scope-manager": "8.37.0",
+ "@typescript-eslint/types": "8.37.0",
+ "@typescript-eslint/typescript-estree": "8.37.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.37.0.tgz",
+ "integrity": "sha512-YzfhzcTnZVPiLfP/oeKtDp2evwvHLMe0LOy7oe+hb9KKIumLNohYS9Hgp1ifwpu42YWxhZE8yieggz6JpqO/1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.37.0",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-formats/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/c8": {
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz",
+ "integrity": "sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^1.0.1",
+ "@istanbuljs/schema": "^0.1.3",
+ "find-up": "^5.0.0",
+ "foreground-child": "^3.1.1",
+ "istanbul-lib-coverage": "^3.2.0",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-reports": "^3.1.6",
+ "test-exclude": "^7.0.1",
+ "v8-to-istanbul": "^9.0.0",
+ "yargs": "^17.7.2",
+ "yargs-parser": "^21.1.1"
+ },
+ "bin": {
+ "c8": "bin/c8.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "monocart-coverage-reports": "^2"
+ },
+ "peerDependenciesMeta": {
+ "monocart-coverage-reports": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/chai": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz",
+ "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
+ "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/class-transformer": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz",
+ "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decamelize": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
+ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/deep-eql": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/diff": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
+ "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.31.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.31.0.tgz",
+ "integrity": "sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.0",
+ "@eslint/core": "^0.15.0",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.31.0",
+ "@eslint/plugin-kit": "^0.3.1",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-plugin-simple-import-sort": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz",
+ "integrity": "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "eslint": ">=5.0.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
+ "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
+ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+ "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "16.3.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz",
+ "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-lazy": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
+ "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
+ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-report/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jju": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
+ "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "uc.micro": "^2.0.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
+ "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/loupe": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.4.tgz",
+ "integrity": "sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/lunr": {
+ "version": "2.3.9",
+ "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
+ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/markdown-it": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
+ "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "^4.4.0",
+ "linkify-it": "^5.0.0",
+ "mdurl": "^2.0.0",
+ "punycode.js": "^2.3.1",
+ "uc.micro": "^2.1.0"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.mjs"
+ }
+ },
+ "node_modules/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mocha": {
+ "version": "11.7.1",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.1.tgz",
+ "integrity": "sha512-5EK+Cty6KheMS/YLPPMJC64g5V61gIR25KsRItHw6x4hEKT6Njp1n9LOlH4gpevuwMVS66SXaBBpg+RWZkza4A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browser-stdout": "^1.3.1",
+ "chokidar": "^4.0.1",
+ "debug": "^4.3.5",
+ "diff": "^7.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-up": "^5.0.0",
+ "glob": "^10.4.5",
+ "he": "^1.2.0",
+ "js-yaml": "^4.1.0",
+ "log-symbols": "^4.1.0",
+ "minimatch": "^9.0.5",
+ "ms": "^2.1.3",
+ "picocolors": "^1.1.1",
+ "serialize-javascript": "^6.0.2",
+ "strip-json-comments": "^3.1.1",
+ "supports-color": "^8.1.1",
+ "workerpool": "^9.2.0",
+ "yargs": "^17.7.2",
+ "yargs-parser": "^21.1.1",
+ "yargs-unparser": "^2.0.0"
+ },
+ "bin": {
+ "_mocha": "bin/_mocha",
+ "mocha": "bin/mocha.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/pathval": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
+ "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.16"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
+ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/punycode.js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/reflect-metadata": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
+ "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/regexp-match-indices": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz",
+ "integrity": "sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "regexp-tree": "^0.1.11"
+ }
+ },
+ "node_modules/regexp-tree": {
+ "version": "0.1.27",
+ "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
+ "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "regexp-tree": "bin/regexp-tree"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.16.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/sinon": {
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.0.tgz",
+ "integrity": "sha512-TOgRcwFPbfGtpqvZw+hyqJDvqfapr1qUlOizROIk4bBLjlsjlB00Pg6wMFXNtJRpu+eCZuVOaLatG7M8105kAw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.1",
+ "@sinonjs/fake-timers": "^13.0.5",
+ "@sinonjs/samsam": "^8.0.1",
+ "diff": "^7.0.0",
+ "supports-color": "^7.2.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/sinon"
+ }
+ },
+ "node_modules/sinon-chai": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-4.0.0.tgz",
+ "integrity": "sha512-cWqO7O2I4XfJDWyWElAQ9D/dtdh5Mo0RHndsfiiYyjWnlPzBJdIvjCVURO4EjyYaC3BjV+ISNXCfTXPXTEIEWA==",
+ "dev": true,
+ "license": "(BSD-2-Clause OR WTFPL)",
+ "peerDependencies": {
+ "chai": "^5.0.0",
+ "sinon": ">=4.0.0"
+ }
+ },
+ "node_modules/sinon/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz",
+ "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^10.4.1",
+ "minimatch": "^9.0.4"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
+ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node/node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/typedoc": {
+ "version": "0.28.7",
+ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.7.tgz",
+ "integrity": "sha512-lpz0Oxl6aidFkmS90VQDQjk/Qf2iw0IUvFqirdONBdj7jPSN9mGXhy66BcGNDxx5ZMyKKiBVAREvPEzT6Uxipw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@gerrit0/mini-shiki": "^3.7.0",
+ "lunr": "^2.3.9",
+ "markdown-it": "^14.1.0",
+ "minimatch": "^9.0.5",
+ "yaml": "^2.8.0"
+ },
+ "bin": {
+ "typedoc": "bin/typedoc"
+ },
+ "engines": {
+ "node": ">= 18",
+ "pnpm": ">= 10"
+ },
+ "peerDependencies": {
+ "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"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.37.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.37.0.tgz",
+ "integrity": "sha512-TnbEjzkE9EmcO0Q2zM+GE8NQLItNAJpMmED1BdgoBMYNdqMhzlbqfdSwiRlAzEK2pA9UzVW0gzaaIzXWg2BjfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.37.0",
+ "@typescript-eslint/parser": "8.37.0",
+ "@typescript-eslint/typescript-estree": "8.37.0",
+ "@typescript-eslint/utils": "8.37.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/uc.micro": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/undici-types": {
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
+ "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
+ "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
+ "license": "MIT",
+ "bin": {
+ "uuid": "dist/esm/bin/uuid"
+ }
+ },
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.29",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz",
+ "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/workerpool": {
+ "version": "9.3.3",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.3.tgz",
+ "integrity": "sha512-slxCaKbYjEdFT/o2rH9xS1hf4uRDch1w7Uo+apxhZ+sf/1d9e0ZVkn42kPNGP2dgjIx6YFvSevj0zHvbWe2jdw==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yaml": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz",
+ "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-unparser": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
+ "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "camelcase": "^6.0.0",
+ "decamelize": "^4.0.0",
+ "flat": "^5.0.2",
+ "is-plain-obj": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yargs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yargs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..3141f4a
--- /dev/null
+++ b/package.json
@@ -0,0 +1,65 @@
+{
+ "name": "@cucumber/core",
+ "version": "0.0.1",
+ "description": "Core test case composition library for building a Cucumber implementation",
+ "type": "commonjs",
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build": "tsc --project tsconfig.build.json",
+ "coverage:check": "c8 --100 npm test",
+ "coverage:report": "c8 --reporter html npm test",
+ "docs": "typedoc",
+ "exports:check": "api-extractor run --verbose",
+ "exports:update": "api-extractor run --verbose --local",
+ "fix": "eslint --max-warnings 0 src --fix && prettier --write src",
+ "lint": "eslint --max-warnings 0 src && prettier --check src",
+ "test": "mocha \"src/**/*.spec.ts\""
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/cucumber/javascript-core.git"
+ },
+ "author": "David Goss",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/cucumber/javascript-core/issues"
+ },
+ "homepage": "https://github.com/cucumber/javascript-core#readme",
+ "peerDependencies": {
+ "@cucumber/cucumber-expressions": "*",
+ "@cucumber/messages": "*",
+ "@cucumber/query": "*",
+ "@cucumber/tag-expressions": "*"
+ },
+ "devDependencies": {
+ "@cucumber/cucumber-expressions": "^18.0.1",
+ "@cucumber/gherkin": "^33.0.0",
+ "@cucumber/messages": "^28.0.0",
+ "@cucumber/query": "^13.5.0",
+ "@cucumber/tag-expressions": "^6.2.0",
+ "@eslint/js": "^9.31.0",
+ "@microsoft/api-extractor": "^7.52.8",
+ "@tsconfig/recommended": "^1.0.10",
+ "@types/chai": "^5.2.2",
+ "@types/mocha": "^10.0.10",
+ "@types/sinon": "^17.0.4",
+ "@types/sinon-chai": "^4.0.0",
+ "c8": "^10.1.3",
+ "chai": "^5.2.1",
+ "eslint": "^9.31.0",
+ "eslint-plugin-simple-import-sort": "^12.1.1",
+ "globals": "^16.3.0",
+ "mocha": "^11.7.1",
+ "prettier": "^3.6.2",
+ "sinon": "^21.0.0",
+ "sinon-chai": "^4.0.0",
+ "ts-node": "^10.9.2",
+ "typedoc": "^0.28.7",
+ "typescript": "^5.8.3",
+ "typescript-eslint": "^8.37.0"
+ }
+}
diff --git a/src/AmbiguousError.spec.ts b/src/AmbiguousError.spec.ts
new file mode 100644
index 0000000..7fbe82f
--- /dev/null
+++ b/src/AmbiguousError.spec.ts
@@ -0,0 +1,21 @@
+import { SourceReference } from '@cucumber/messages'
+import { expect } from 'chai'
+
+import { AmbiguousError } from './AmbiguousError'
+
+describe('AmbiguousError', () => {
+ it('handles source references with and without locations', () => {
+ const references: ReadonlyArray = [
+ { uri: 'steps.js', location: { line: 1, column: 2 } },
+ { uri: 'steps.js', location: { line: 3, column: 4 } },
+ { uri: 'mysterious.js' },
+ ]
+ const error = new AmbiguousError('text', references)
+ expect(error.message).to.equal(
+ 'Multiple matching step definitions found for text "text":\n' +
+ '1) steps.js:1:2\n' +
+ '2) steps.js:3:4\n' +
+ '3) mysterious.js:?:?'
+ )
+ })
+})
diff --git a/src/AmbiguousError.ts b/src/AmbiguousError.ts
new file mode 100644
index 0000000..7e023c5
--- /dev/null
+++ b/src/AmbiguousError.ts
@@ -0,0 +1,20 @@
+import { SourceReference } from '@cucumber/messages'
+
+/**
+ * Represents an error that occurs when multiple step definitions are found matching the text of a step
+ * @public
+ */
+export class AmbiguousError extends Error {
+ constructor(text: string, references: ReadonlyArray) {
+ super(
+ `Multiple matching step definitions found for text "${text}":` +
+ '\n' +
+ references
+ .map(
+ (ref, index) =>
+ `${index + 1}) ${ref.uri}:${ref.location?.line ?? '?'}:${ref.location?.column ?? '?'}`
+ )
+ .join('\n')
+ )
+ }
+}
diff --git a/src/DataTable.spec.ts b/src/DataTable.spec.ts
new file mode 100644
index 0000000..a361c3f
--- /dev/null
+++ b/src/DataTable.spec.ts
@@ -0,0 +1,106 @@
+import { expect } from 'chai'
+import { describe, it } from 'mocha'
+
+import { DataTable } from './DataTable'
+
+describe('DataTable', () => {
+ describe('raw', () => {
+ it('should return a copy of the raw cells', () => {
+ const cells = [
+ ['a', 'b', 'c'],
+ ['1', '2', '3'],
+ ['4', '5', '6'],
+ ]
+ const dataTable = new DataTable(cells)
+ expect(dataTable.raw()).to.deep.eq(cells)
+ expect(dataTable.raw()).to.not.eq(cells)
+ })
+ })
+
+ describe('rows', () => {
+ it('returns a 2-D array without the header', () => {
+ expect(
+ new DataTable([
+ ['a', 'b', 'c'],
+ ['1', '2', '3'],
+ ['4', '5', '6'],
+ ]).rows()
+ ).to.deep.eq([
+ ['1', '2', '3'],
+ ['4', '5', '6'],
+ ])
+ })
+ })
+
+ describe('hashes', () => {
+ it('should produce an array of rows as objects, with keys from the first row', () => {
+ expect(
+ new DataTable([
+ ['a', 'b', 'c'],
+ ['1', '2', '3'],
+ ['4', '5', '6'],
+ ['7', '8', '9'],
+ ]).hashes()
+ ).to.deep.eq([
+ { a: '1', b: '2', c: '3' },
+ { a: '4', b: '5', c: '6' },
+ { a: '7', b: '8', c: '9' },
+ ])
+ })
+ })
+
+ describe('rowsHash', () => {
+ it('returns an object where the keys are the first column', () => {
+ expect(
+ new DataTable([
+ ['Tom', '1'],
+ ['Dick', '2'],
+ ['Sally', '3'],
+ ]).rowsHash()
+ ).to.eql({
+ Tom: '1',
+ Dick: '2',
+ Sally: '3',
+ })
+ })
+
+ it('should throw when not all rows have 1 column', () => {
+ expect(() => {
+ new DataTable([
+ ['Tom', '1'],
+ ['Dick', '2', 'whoops'],
+ ['Sally', '3'],
+ ]).rowsHash()
+ }).to.throw('All rows must have exactly 2 columns')
+ })
+ })
+
+ describe('list', () => {
+ it('should produce a list for a single column', () => {
+ expect(new DataTable([['foo'], ['bar'], ['baz']]).list()).to.deep.eq(['foo', 'bar', 'baz'])
+ })
+
+ it('should throw when not all rows have 1 column', () => {
+ expect(() => {
+ new DataTable([['foo', 'bar'], ['baz']]).list()
+ }).to.throw('All rows must have exactly 1 column')
+ })
+ })
+
+ describe('transpose', () => {
+ it('should transpose', () => {
+ expect(
+ new DataTable([
+ ['a', 'b', 'c'],
+ ['1', '2', '3'],
+ ])
+ .transpose()
+ .raw()
+ ).to.deep.eq([
+ ['a', '1'],
+ ['b', '2'],
+ ['c', '3'],
+ ])
+ })
+ })
+})
diff --git a/src/DataTable.ts b/src/DataTable.ts
new file mode 100644
index 0000000..6dce87e
--- /dev/null
+++ b/src/DataTable.ts
@@ -0,0 +1,154 @@
+/**
+ * Represents the cells of a Gherkin data table associated with a test step.
+ * @public
+ * @remarks
+ * For steps that include a data table, an instance of this will be injected as the last
+ * argument to your step function.
+ */
+export class DataTable {
+ constructor(private readonly cells: ReadonlyArray>) {}
+
+ /**
+ * Returns a copy of the raw cells, as a two-dimensional array.
+ *
+ * @example
+ * ```typescript
+ * const dataTable = new DataTable([
+ * ['a', 'b', 'c'],
+ * ['1', '2', '3'],
+ * ['4', '5', '6']
+ * ])
+ * console.log(dataTable.raw())
+ * // [['a', 'b', 'c'], ['1', '2', '3'], ['4', '5', '6']]
+ * ```
+ */
+ raw(): ReadonlyArray> {
+ return structuredClone(this.cells)
+ }
+
+ /**
+ * Returns a copy of the raw cells, as a two-dimensional array, with the first
+ * (header) row omitted.
+ *
+ * @example
+ * ```typescript
+ * const dataTable = new DataTable([
+ * ['a', 'b', 'c'],
+ * ['1', '2', '3'],
+ * ['4', '5', '6']
+ * ])
+ * console.log(dataTable.rows())
+ * // [['1', '2', '3'], ['4', '5', '6']]
+ * ```
+ */
+ rows(): ReadonlyArray> {
+ return this.raw().slice(1)
+ }
+
+ /**
+ * Returns an array, with each item representing a row of the table as key/value
+ * pairs using the header row for keys.
+ *
+ * @example
+ * ```typescript
+ * const dataTable = new DataTable([
+ * ['a', 'b', 'c'],
+ * ['1', '2', '3'],
+ * ['4', '5', '6'],
+ * ['7', '8', '9']
+ * ])
+ * console.log(dataTable.hashes())
+ * // [
+ * // { a: '1', b: '2', c: '3' },
+ * // { a: '4', b: '5', c: '6' },
+ * // { a: '7', b: '8', c: '9' }
+ * // ]
+ * ```
+ */
+ hashes(): ReadonlyArray> {
+ const [keys, ...rows] = this.raw()
+ return rows.map((row) => {
+ return row.reduce((acc, value, index) => {
+ return {
+ ...acc,
+ [keys[index]]: value,
+ }
+ }, {})
+ })
+ }
+
+ /**
+ * Returns key/value pairs with keys from the first column and values from the second.
+ * @remarks
+ * For use with two-column data tables that represent key/value pairs.
+ *
+ * @example
+ * ```typescript
+ * const dataTable = new DataTable([
+ * ['Tom', '1'],
+ * ['Dick', '2'],
+ * ['Sally', '3']
+ * ])
+ * console.log(dataTable.rowsHash())
+ * // { Tom: '1', Dick: '2', Sally: '3' }
+ * ```
+ *
+ * @throws When not all rows have exactly 2 columns
+ */
+ rowsHash(): Record {
+ const cells = this.raw()
+ if (!cells.every((row) => row.length === 2)) {
+ throw new Error('All rows must have exactly 2 columns')
+ }
+ return cells.reduce>(
+ (result, [key, value]) => ({
+ ...result,
+ [key]: value,
+ }),
+ {}
+ )
+ }
+
+ /**
+ * Returns an array, with each item being a cell value from the first/only column.
+ * @remarks
+ * For use with single-column data tables that represent a simple list.
+ *
+ * @example
+ * ```typescript
+ * const dataTable = new DataTable([
+ * ['foo'],
+ * ['bar'],
+ * ['baz']
+ * ])
+ * console.log(dataTable.list())
+ * // ['foo', 'bar', 'baz']
+ * ```
+ *
+ * @throws When not all rows have exactly 1 column
+ */
+ list(): ReadonlyArray {
+ const cells = this.raw()
+ if (!cells.every((row) => row.length === 1)) {
+ throw new Error('All rows must have exactly 1 column')
+ }
+ return cells.flat()
+ }
+
+ /**
+ * Returns a fresh data table instance based on the cells being transposed.
+ *
+ * @example
+ * ```typescript
+ * const dataTable = new DataTable([
+ * ['a', 'b', 'c'],
+ * ['1', '2', '3']
+ * ])
+ * console.log(dataTable.transpose().raw())
+ * // [['a', '1'], ['b', '2'], ['c', '3']]
+ * ```
+ */
+ transpose(): DataTable {
+ return new DataTable(this.cells[0].map((x, i) => this.cells.map((y) => y[i])))
+ }
+}
diff --git a/src/SupportCodeBuilderImpl.ts b/src/SupportCodeBuilderImpl.ts
new file mode 100644
index 0000000..86f8162
--- /dev/null
+++ b/src/SupportCodeBuilderImpl.ts
@@ -0,0 +1,219 @@
+import {
+ CucumberExpression,
+ ParameterType,
+ ParameterTypeRegistry,
+ RegularExpression,
+} from '@cucumber/cucumber-expressions'
+import { HookType, StepDefinitionPatternType } from '@cucumber/messages'
+import parse from '@cucumber/tag-expressions'
+
+import { SupportCodeLibraryImpl } from './SupportCodeLibraryImpl'
+import {
+ DefinedHook,
+ DefinedParameterType,
+ DefinedStep,
+ NewHook,
+ NewParameterType,
+ NewStep,
+ SupportCodeBuilder,
+ UndefinedParameterType,
+} from './types'
+
+type WithId = { id: string } & T
+
+/**
+ * @internal
+ */
+export class SupportCodeBuilderImpl implements SupportCodeBuilder {
+ private readonly parameterTypeRegistry = new ParameterTypeRegistry()
+ private readonly undefinedParameterTypes: Map> = new Map()
+ private readonly parameterTypes: Array> = []
+ private readonly steps: Array> = []
+ private readonly beforeHooks: Array> = []
+ private readonly afterHooks: Array> = []
+
+ constructor(private readonly newId: () => string) {}
+
+ parameterType(options: NewParameterType) {
+ this.parameterTypes.push({
+ id: this.newId(),
+ ...options,
+ })
+ return this
+ }
+
+ beforeHook(options: NewHook) {
+ this.beforeHooks.push({
+ id: this.newId(),
+ ...options,
+ })
+ return this
+ }
+
+ afterHook(options: NewHook) {
+ this.afterHooks.push({
+ id: this.newId(),
+ ...options,
+ })
+ return this
+ }
+
+ step(options: NewStep) {
+ this.steps.push({
+ id: this.newId(),
+ ...options,
+ })
+ return this
+ }
+
+ private buildParameterTypes(): ReadonlyArray {
+ return this.parameterTypes.map((registered) => {
+ const parameterType = new ParameterType(
+ registered.name,
+ registered.regexp,
+ null,
+ registered.transformer,
+ registered.useForSnippets ?? true,
+ registered.preferForRegexpMatch ?? false
+ )
+ this.parameterTypeRegistry.defineParameterType(parameterType)
+ return {
+ id: registered.id,
+ name: registered.name,
+ regularExpressions: [...parameterType.regexpStrings],
+ preferForRegularExpressionMatch: parameterType.preferForRegexpMatch as boolean,
+ useForSnippets: parameterType.useForSnippets as boolean,
+ sourceReference: registered.sourceReference,
+ }
+ })
+ }
+
+ private buildSteps(): ReadonlyArray {
+ return this.steps
+ .map(({ id, pattern, fn, sourceReference }) => {
+ const compiled = this.compileExpression(pattern)
+ if (!compiled) {
+ return undefined
+ }
+ return {
+ id,
+ expression: {
+ raw: pattern,
+ compiled,
+ },
+ fn,
+ sourceReference,
+ toMessage() {
+ return {
+ id,
+ pattern: {
+ type:
+ this.expression.compiled instanceof CucumberExpression
+ ? StepDefinitionPatternType.CUCUMBER_EXPRESSION
+ : StepDefinitionPatternType.REGULAR_EXPRESSION,
+ source: pattern.toString(),
+ },
+ sourceReference,
+ }
+ },
+ }
+ })
+ .filter((step) => !!step)
+ }
+
+ private compileExpression(
+ text: string | RegExp
+ ): CucumberExpression | RegularExpression | undefined {
+ if (typeof text === 'string') {
+ return this.compileCucumberExpression(text)
+ }
+ return new RegularExpression(text, this.parameterTypeRegistry)
+ }
+
+ private compileCucumberExpression(text: string): CucumberExpression | undefined {
+ try {
+ return new CucumberExpression(text, this.parameterTypeRegistry)
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ } catch (e: any) {
+ if ('undefinedParameterTypeName' in e) {
+ if (!this.undefinedParameterTypes.has(e.undefinedParameterTypeName)) {
+ this.undefinedParameterTypes.set(e.undefinedParameterTypeName, new Set())
+ }
+ this.undefinedParameterTypes.get(e.undefinedParameterTypeName)?.add(text.toString())
+ return undefined
+ } else {
+ throw e
+ }
+ }
+ }
+
+ private buildUndefinedParameterTypes(): ReadonlyArray {
+ return [...this.undefinedParameterTypes.entries()]
+ .map(([name, expressions]) => {
+ return [...expressions].map((expression) => ({ name, expression }))
+ })
+ .flat()
+ }
+
+ private buildBeforeHooks(): ReadonlyArray {
+ return this.beforeHooks.map(({ id, name, tags, fn, sourceReference }) => {
+ return {
+ id,
+ name,
+ tags: tags
+ ? {
+ raw: tags,
+ compiled: parse(tags),
+ }
+ : undefined,
+ fn,
+ sourceReference,
+ toMessage() {
+ return {
+ id,
+ type: HookType.BEFORE_TEST_CASE,
+ name,
+ tagExpression: this.tags?.raw,
+ sourceReference,
+ }
+ },
+ }
+ })
+ }
+
+ private buildAfterHooks(): ReadonlyArray {
+ return this.afterHooks.map(({ id, name, tags, fn, sourceReference }) => {
+ return {
+ id,
+ name,
+ tags: tags
+ ? {
+ raw: tags,
+ compiled: parse(tags),
+ }
+ : undefined,
+ fn,
+ sourceReference,
+ toMessage() {
+ return {
+ id,
+ type: HookType.AFTER_TEST_CASE,
+ name,
+ tagExpression: this.tags?.raw,
+ sourceReference,
+ }
+ },
+ }
+ })
+ }
+
+ build() {
+ return new SupportCodeLibraryImpl(
+ this.buildParameterTypes(),
+ this.buildSteps(),
+ this.buildUndefinedParameterTypes(),
+ this.buildBeforeHooks(),
+ this.buildAfterHooks()
+ )
+ }
+}
diff --git a/src/SupportCodeLibraryImpl.ts b/src/SupportCodeLibraryImpl.ts
new file mode 100644
index 0000000..0cf5592
--- /dev/null
+++ b/src/SupportCodeLibraryImpl.ts
@@ -0,0 +1,65 @@
+import {
+ DefinedHook,
+ DefinedParameterType,
+ DefinedStep,
+ MatchedStep,
+ SupportCodeLibrary,
+ UndefinedParameterType,
+} from './types'
+
+/**
+ * @internal
+ */
+export class SupportCodeLibraryImpl implements SupportCodeLibrary {
+ constructor(
+ private readonly parameterTypes: ReadonlyArray = [],
+ private readonly steps: ReadonlyArray = [],
+ private readonly undefinedParameterTypes: ReadonlyArray = [],
+ private readonly beforeHooks: ReadonlyArray = [],
+ private readonly afterHooks: ReadonlyArray = []
+ ) {}
+
+ findAllStepsBy(text: string) {
+ const results: Array = []
+ for (const def of this.steps) {
+ const args = def.expression.compiled.match(text)
+ if (args) {
+ results.push({
+ def,
+ args,
+ })
+ }
+ }
+ return results
+ }
+
+ findAllBeforeHooksBy(tags: ReadonlyArray) {
+ return this.beforeHooks.filter((def) => {
+ if (def.tags) {
+ return def.tags.compiled.evaluate(tags as string[])
+ }
+ return true
+ })
+ }
+
+ findAllAfterHooksBy(tags: ReadonlyArray) {
+ return this.afterHooks.filter((def) => {
+ if (def.tags) {
+ return def.tags.compiled.evaluate(tags as string[])
+ }
+ return true
+ })
+ }
+
+ toEnvelopes() {
+ return [
+ ...this.parameterTypes.map((parameterType) => ({ parameterType })),
+ ...this.steps
+ .map((definedStep) => definedStep.toMessage())
+ .map((stepDefinition) => ({ stepDefinition })),
+ ...this.undefinedParameterTypes.map((undefinedParameterType) => ({ undefinedParameterType })),
+ ...this.beforeHooks.map((definedHook) => definedHook.toMessage()).map((hook) => ({ hook })),
+ ...this.afterHooks.map((definedHook) => definedHook.toMessage()).map((hook) => ({ hook })),
+ ]
+ }
+}
diff --git a/src/UndefinedError.ts b/src/UndefinedError.ts
new file mode 100644
index 0000000..95b5464
--- /dev/null
+++ b/src/UndefinedError.ts
@@ -0,0 +1,9 @@
+/**
+ * Represents an error that occurs when no step definitions are found matching the text of a step
+ * @public
+ */
+export class UndefinedError extends Error {
+ constructor(text: string) {
+ super(`No matching step definitions found for text "${text}"`)
+ }
+}
diff --git a/src/buildSupportCode.spec.ts b/src/buildSupportCode.spec.ts
new file mode 100644
index 0000000..fd8c55d
--- /dev/null
+++ b/src/buildSupportCode.spec.ts
@@ -0,0 +1,304 @@
+import { CucumberExpression, RegularExpression } from '@cucumber/cucumber-expressions'
+import { IdGenerator, StepDefinitionPatternType } from '@cucumber/messages'
+import { expect } from 'chai'
+import sinon from 'sinon'
+
+import { buildSupportCode } from './buildSupportCode'
+import { SupportCodeLibrary } from './types'
+
+describe('buildSupportCode', () => {
+ let newId: () => string
+
+ beforeEach(() => {
+ newId = IdGenerator.incrementing()
+ })
+
+ describe('hooks', () => {
+ let library: SupportCodeLibrary
+ beforeEach(() => {
+ library = buildSupportCode({ newId: IdGenerator.incrementing() })
+ .beforeHook({
+ name: 'general setup',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 1, column: 1 } },
+ })
+ .beforeHook({
+ name: 'smoke setup',
+ tags: '@smoke',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 2, column: 1 } },
+ })
+ .beforeHook({
+ name: 'regression setup',
+ tags: '@regression',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 3, column: 1 } },
+ })
+ .afterHook({
+ name: 'general teardown',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 4, column: 1 } },
+ })
+ .afterHook({
+ name: 'smoke teardown',
+ tags: '@smoke',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 5, column: 1 } },
+ })
+ .afterHook({
+ name: 'regression teardown',
+ tags: '@regression',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 6, column: 1 } },
+ })
+ .build()
+ })
+
+ it('filters Before hooks correctly when no tags specified', () => {
+ const hooks = library.findAllBeforeHooksBy([])
+ expect(hooks).to.have.lengthOf(1)
+ expect(hooks[0].name).to.eq('general setup')
+ })
+
+ it('filters Before hooks correctly when tags specified', () => {
+ const hooks = library.findAllBeforeHooksBy(['@smoke'])
+ expect(hooks).to.have.lengthOf(2)
+ expect(hooks[0].name).to.eq('general setup')
+ expect(hooks[1].name).to.eq('smoke setup')
+ })
+
+ it('filters After hooks correctly when no tags specified', () => {
+ const hooks = library.findAllAfterHooksBy([])
+ expect(hooks).to.have.lengthOf(1)
+ expect(hooks[0].name).to.eq('general teardown')
+ })
+
+ it('filters After hooks correctly when tags specified', () => {
+ const hooks = library.findAllAfterHooksBy(['@smoke'])
+ expect(hooks).to.have.lengthOf(2)
+ expect(hooks[0].name).to.eq('general teardown')
+ expect(hooks[1].name).to.eq('smoke teardown')
+ })
+
+ it('produces correct envelopes', () => {
+ expect(library.toEnvelopes()).to.deep.eq([
+ {
+ hook: {
+ id: '0',
+ type: 'BEFORE_TEST_CASE',
+ name: 'general setup',
+ tagExpression: undefined,
+ sourceReference: { uri: 'hooks.js', location: { line: 1, column: 1 } },
+ },
+ },
+ {
+ hook: {
+ id: '1',
+ type: 'BEFORE_TEST_CASE',
+ name: 'smoke setup',
+ tagExpression: '@smoke',
+ sourceReference: { uri: 'hooks.js', location: { line: 2, column: 1 } },
+ },
+ },
+ {
+ hook: {
+ id: '2',
+ type: 'BEFORE_TEST_CASE',
+ name: 'regression setup',
+ tagExpression: '@regression',
+ sourceReference: { uri: 'hooks.js', location: { line: 3, column: 1 } },
+ },
+ },
+ {
+ hook: {
+ id: '3',
+ type: 'AFTER_TEST_CASE',
+ name: 'general teardown',
+ tagExpression: undefined,
+ sourceReference: { uri: 'hooks.js', location: { line: 4, column: 1 } },
+ },
+ },
+ {
+ hook: {
+ id: '4',
+ type: 'AFTER_TEST_CASE',
+ name: 'smoke teardown',
+ tagExpression: '@smoke',
+ sourceReference: { uri: 'hooks.js', location: { line: 5, column: 1 } },
+ },
+ },
+ {
+ hook: {
+ id: '5',
+ type: 'AFTER_TEST_CASE',
+ name: 'regression teardown',
+ tagExpression: '@regression',
+ sourceReference: { uri: 'hooks.js', location: { line: 6, column: 1 } },
+ },
+ },
+ ])
+ })
+ })
+
+ describe('steps', () => {
+ it('catches undefined parameter type errors and emits an appropriate message', () => {
+ expect(
+ buildSupportCode({ newId })
+ .step({
+ pattern: 'a {thing} happens',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+ .toEnvelopes()
+ ).to.deep.eq([
+ {
+ undefinedParameterType: {
+ expression: 'a {thing} happens',
+ name: 'thing',
+ },
+ },
+ ])
+ })
+
+ it('allows errors from expression compilation to bubble', () => {
+ expect(() =>
+ buildSupportCode({ newId })
+ .step({
+ pattern: '{{bad',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+ ).to.throw()
+ })
+
+ it('handles cucumber expressions', () => {
+ const library = buildSupportCode({ newId })
+ .step({
+ pattern: 'there are {int} widgets',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+ const matchedSteps = library.findAllStepsBy('there are 17 widgets')
+
+ expect(matchedSteps.length).to.eq(1)
+ expect(matchedSteps[0].def.expression.compiled).to.be.instanceof(CucumberExpression)
+ expect(matchedSteps[0].args.length).to.eq(1)
+ expect(matchedSteps[0].args[0].getValue(undefined)).to.eq(17)
+ expect(library.toEnvelopes()).to.deep.eq([
+ {
+ stepDefinition: {
+ id: '0',
+ pattern: {
+ source: 'there are {int} widgets',
+ type: StepDefinitionPatternType.CUCUMBER_EXPRESSION,
+ },
+ sourceReference: {
+ location: {
+ column: 1,
+ line: 1,
+ },
+ uri: 'steps.js',
+ },
+ },
+ },
+ ])
+ })
+
+ it('handles regular expressions', () => {
+ const library = buildSupportCode({ newId })
+ .step({
+ pattern: /there are (\d+) widgets/,
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+ const matchedSteps = library.findAllStepsBy('there are 17 widgets')
+
+ expect(matchedSteps.length).to.eq(1)
+ expect(matchedSteps[0].def.expression.compiled).to.be.instanceof(RegularExpression)
+ expect(matchedSteps[0].args.length).to.eq(1)
+ expect(matchedSteps[0].args[0].getValue(undefined)).to.eq(17)
+ expect(library.toEnvelopes()).to.deep.eq([
+ {
+ stepDefinition: {
+ id: '0',
+ pattern: {
+ source: '/there are (\\d+) widgets/',
+ type: StepDefinitionPatternType.REGULAR_EXPRESSION,
+ },
+ sourceReference: {
+ location: {
+ column: 1,
+ line: 1,
+ },
+ uri: 'steps.js',
+ },
+ },
+ },
+ ])
+ })
+ })
+
+ describe('parameter types', () => {
+ it('correctly handles user-defined parameter types', () => {
+ const library = buildSupportCode({ newId })
+ .parameterType({
+ name: 'flight',
+ regexp: /([A-Z]{3})-([A-Z]{3})/,
+ transformer(from: string, to: string) {
+ return [from, to]
+ },
+ sourceReference: { uri: 'support.js', location: { line: 1, column: 1 } },
+ })
+ .step({
+ pattern: '{flight} has been delayed',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const matchedSteps = library.findAllStepsBy('LHR-CDG has been delayed')
+ expect(matchedSteps.length).to.eq(1)
+ expect(matchedSteps[0].def.expression.compiled).to.be.instanceof(CucumberExpression)
+ expect(matchedSteps[0].args.length).to.eq(1)
+ expect(matchedSteps[0].args[0].getValue(undefined)).to.deep.eq(['LHR', 'CDG'])
+ expect(library.toEnvelopes()).to.deep.eq([
+ {
+ parameterType: {
+ id: '0',
+ name: 'flight',
+ preferForRegularExpressionMatch: false,
+ regularExpressions: ['([A-Z]{3})-([A-Z]{3})'],
+ sourceReference: {
+ location: {
+ column: 1,
+ line: 1,
+ },
+ uri: 'support.js',
+ },
+ useForSnippets: true,
+ },
+ },
+ {
+ stepDefinition: {
+ id: '1',
+ pattern: {
+ source: '{flight} has been delayed',
+ type: StepDefinitionPatternType.CUCUMBER_EXPRESSION,
+ },
+ sourceReference: {
+ location: {
+ column: 1,
+ line: 1,
+ },
+ uri: 'steps.js',
+ },
+ },
+ },
+ ])
+ })
+ })
+})
diff --git a/src/buildSupportCode.ts b/src/buildSupportCode.ts
new file mode 100644
index 0000000..c9fd590
--- /dev/null
+++ b/src/buildSupportCode.ts
@@ -0,0 +1,13 @@
+import { IdGenerator } from '@cucumber/messages'
+
+import { SupportCodeBuilderImpl } from './SupportCodeBuilderImpl'
+import { SupportCodeBuilder, SupportCodeOptions } from './types'
+
+/**
+ * Start building up a library user-defined support code
+ * @public
+ */
+export function buildSupportCode(options: SupportCodeOptions = {}): SupportCodeBuilder {
+ const { newId = IdGenerator.uuid() } = options
+ return new SupportCodeBuilderImpl(newId)
+}
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..fcf3c14
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,6 @@
+export * from './AmbiguousError'
+export * from './buildSupportCode'
+export * from './DataTable'
+export * from './makeTestPlan'
+export * from './types'
+export * from './UndefinedError'
diff --git a/src/makeTestPlan.spec.ts b/src/makeTestPlan.spec.ts
new file mode 100644
index 0000000..83e3085
--- /dev/null
+++ b/src/makeTestPlan.spec.ts
@@ -0,0 +1,665 @@
+import * as fs from 'node:fs'
+import * as path from 'node:path'
+
+import { AstBuilder, compile, GherkinClassicTokenMatcher, Parser } from '@cucumber/gherkin'
+import { GherkinDocument, IdGenerator, Pickle } from '@cucumber/messages'
+import { expect, use } from 'chai'
+import sinon from 'sinon'
+import sinonChai from 'sinon-chai'
+
+import { AmbiguousError } from './AmbiguousError'
+import { buildSupportCode } from './buildSupportCode'
+import { DataTable } from './DataTable'
+import { makeTestPlan } from './makeTestPlan'
+import { UndefinedError } from './UndefinedError'
+
+use(sinonChai)
+
+function parseGherkin(
+ file: string,
+ newId: () => string
+): { gherkinDocument: GherkinDocument; pickles: ReadonlyArray } {
+ const data = fs.readFileSync(path.join(__dirname, '..', 'testdata', file), { encoding: 'utf-8' })
+ const builder = new AstBuilder(newId)
+ const matcher = new GherkinClassicTokenMatcher()
+ const parser = new Parser(builder, matcher)
+ const uri = 'features/' + file
+ const gherkinDocument = {
+ uri,
+ ...parser.parse(data),
+ }
+ const pickles = compile(gherkinDocument, uri, newId)
+ return {
+ gherkinDocument,
+ pickles,
+ }
+}
+
+describe('makeTestPlan', () => {
+ class FakeWorld {}
+
+ let newId: () => string
+
+ beforeEach(() => {
+ newId = IdGenerator.incrementing()
+ })
+
+ describe('naming', () => {
+ it('uses the feature name for the plan name', () => {
+ const { gherkinDocument, pickles } = parseGherkin('minimal.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId }).build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ expect(result.name).to.eq('a feature')
+ })
+
+ it('falls back to the uri if the feature is unnamed', () => {
+ const { gherkinDocument, pickles } = parseGherkin('unnamed.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId }).build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ expect(result.name).to.eq('features/unnamed.feature')
+ })
+
+ it('includes rule names and numbers examples', () => {
+ const { gherkinDocument, pickles } = parseGherkin('naming.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId }).build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ expect(result.testCases.map((tc) => tc.name)).to.deep.eq([
+ 'a rule - a parameterised scenario - under 5 - #1.1',
+ 'a rule - a parameterised scenario - under 5 - #1.2',
+ 'a rule - a parameterised scenario - under 5 - #1.3',
+ 'a rule - a parameterised scenario - under 5 - #1.4',
+ 'a rule - a parameterised scenario - 5 and above - #2.1',
+ 'a rule - a parameterised scenario - 5 and above - #2.2',
+ ])
+ })
+
+ it('adheres to the supplied naming strategy', () => {
+ const { gherkinDocument, pickles } = parseGherkin('naming.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId }).build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ strategy: {
+ reduce(lineage, pickle) {
+ return `${pickle.id}: ${pickle.name}`
+ },
+ },
+ }
+ )
+
+ expect(result.testCases.map((tc) => tc.name)).to.deep.eq([
+ '14: a parameterised scenario',
+ '16: a parameterised scenario',
+ '18: a parameterised scenario',
+ '20: a parameterised scenario',
+ '22: a parameterised scenario',
+ '24: a parameterised scenario',
+ ])
+ })
+ })
+
+ describe('pickle steps', () => {
+ it('throws if a step is ambiguous', () => {
+ const { gherkinDocument, pickles } = parseGherkin('minimal.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .step({
+ pattern: 'a step',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .step({
+ pattern: 'a step',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 2, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ expect(() => result.testCases[0].steps[0].prepare(undefined)).to.throw(AmbiguousError)
+ })
+
+ it('throws if a step is undefined', () => {
+ const { gherkinDocument, pickles } = parseGherkin('minimal.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId }).build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ expect(() => result.testCases[0].steps[0].prepare(undefined)).to.throw(UndefinedError)
+ })
+
+ it('matches and prepares a step without parameters', () => {
+ let capturedThis: any
+ const fn = sinon.spy(function (this: any) {
+ capturedThis = this
+ })
+
+ const { gherkinDocument, pickles } = parseGherkin('minimal.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .step({
+ pattern: 'a step',
+ fn,
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ const fakeWorld = new FakeWorld()
+ const prepared = result.testCases[0].steps[0].prepare(fakeWorld)
+ expect(prepared.args).to.deep.eq([])
+ prepared.fn()
+ expect(fn).to.have.been.calledWithExactly()
+ expect(capturedThis).to.eq(fakeWorld)
+ })
+
+ it('matches and prepares a step with parameters', () => {
+ let capturedThis: any
+ const fn = sinon.spy(function (this: any) {
+ capturedThis = this
+ })
+
+ const { gherkinDocument, pickles } = parseGherkin('parameters.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .step({
+ pattern: 'we scored {int} out of {int}',
+ fn,
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ const fakeWorld = new FakeWorld()
+ const prepared = result.testCases[0].steps[0].prepare(fakeWorld)
+ expect(prepared.args).to.deep.eq([4, 5])
+ prepared.fn(...prepared.args)
+ expect(fn).to.have.been.calledWithExactly(...prepared.args)
+ expect(capturedThis).to.eq(fakeWorld)
+ })
+
+ it('matches and prepares a step with a data table', () => {
+ let capturedThis: any
+ const fn = sinon.spy(function (this: any) {
+ capturedThis = this
+ })
+
+ const { gherkinDocument, pickles } = parseGherkin('datatable.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .step({
+ pattern: 'a bunch of data:',
+ fn,
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ const fakeWorld = new FakeWorld()
+ const prepared = result.testCases[0].steps[0].prepare(fakeWorld)
+ expect(prepared.args).to.deep.eq([
+ new DataTable([
+ ['a', 'b', 'c'],
+ ['1', '2', '3'],
+ ]),
+ ])
+ prepared.fn(...prepared.args)
+ expect(fn).to.have.been.calledWithExactly(...prepared.args)
+ expect(capturedThis).to.eq(fakeWorld)
+ })
+
+ it('matches and prepares a step with a doc string', () => {
+ let capturedThis: any
+ const fn = sinon.spy(function (this: any) {
+ capturedThis = this
+ })
+
+ const { gherkinDocument, pickles } = parseGherkin('docstring.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .step({
+ pattern: 'a thing that says:',
+ fn,
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ const fakeWorld = new FakeWorld()
+ const prepared = result.testCases[0].steps[0].prepare(fakeWorld)
+ expect(prepared.args).to.deep.eq(['Hello world'])
+ prepared.fn(...prepared.args)
+ expect(fn).to.have.been.calledWithExactly(...prepared.args)
+ expect(capturedThis).to.eq(fakeWorld)
+ })
+ })
+
+ describe('hook steps', () => {
+ it('prepends Before and After hooks in correct order', () => {
+ const { gherkinDocument, pickles } = parseGherkin('minimal.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .beforeHook({
+ name: 'setup 1',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 1, column: 1 } },
+ })
+ .beforeHook({
+ name: 'setup 2',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 2, column: 1 } },
+ })
+ .afterHook({
+ name: 'teardown 1',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 3, column: 1 } },
+ })
+ .afterHook({
+ name: 'teardown 2',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 4, column: 1 } },
+ })
+ .step({
+ pattern: 'a step',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ expect(result.testCases[0].steps.map((step) => step.name)).to.deep.eq([
+ // Before hooks in definition order
+ { prefix: 'Before', body: 'setup 1' },
+ { prefix: 'Before', body: 'setup 2' },
+ // Pickle steps
+ { prefix: 'Given', body: 'a step' },
+ { prefix: 'When', body: 'a step' },
+ { prefix: 'Then', body: 'a step' },
+ // After hooks in reverse definition order
+ { prefix: 'After', body: 'teardown 2' },
+ { prefix: 'After', body: 'teardown 1' },
+ ])
+ })
+
+ it('marks After hooks to always be executed', () => {
+ const { gherkinDocument, pickles } = parseGherkin('minimal.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .beforeHook({
+ name: 'setup 1',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 1, column: 1 } },
+ })
+ .beforeHook({
+ name: 'setup 2',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 2, column: 1 } },
+ })
+ .afterHook({
+ name: 'teardown 1',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 3, column: 1 } },
+ })
+ .afterHook({
+ name: 'teardown 2',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 4, column: 1 } },
+ })
+ .step({
+ pattern: 'a step',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ expect(result.testCases[0].steps.map((step) => step.always)).to.deep.eq([
+ // Before hooks
+ false,
+ false,
+ // Pickle steps
+ false,
+ false,
+ false,
+ // After hooks
+ true,
+ true,
+ ])
+ })
+
+ it('filters hooks based on tags', () => {
+ const newId = IdGenerator.incrementing()
+ const { gherkinDocument, pickles } = parseGherkin('tags.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .beforeHook({
+ name: 'general setup',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 1, column: 1 } },
+ })
+ .beforeHook({
+ name: 'foo-only setup',
+ tags: '@foo',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 2, column: 1 } },
+ })
+ .beforeHook({
+ name: 'non-foo setup',
+ tags: 'not @foo',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 3, column: 1 } },
+ })
+ .afterHook({
+ name: 'general teardown',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 4, column: 1 } },
+ })
+ .afterHook({
+ name: 'foo-only teardown',
+ tags: '@foo',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 5, column: 1 } },
+ })
+ .afterHook({
+ name: 'non-foo teardown',
+ tags: 'not @foo',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 6, column: 1 } },
+ })
+ .step({
+ pattern: 'a step',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ expect(result.testCases[0].steps.map((step) => step.name)).to.deep.eq([
+ // Before hooks matched
+ { prefix: 'Before', body: 'general setup' },
+ { prefix: 'Before', body: 'foo-only setup' },
+ // Pickle steps
+ { prefix: 'Given', body: 'a step' },
+ { prefix: 'When', body: 'a step' },
+ { prefix: 'Then', body: 'a step' },
+ // Before hooks matched
+ { prefix: 'After', body: 'foo-only teardown' },
+ { prefix: 'After', body: 'general teardown' },
+ ])
+ })
+
+ it('prepares Before hooks for execution', () => {
+ let capturedThis: any
+ const fn = sinon.spy(function (this: any) {
+ capturedThis = this
+ })
+
+ const { gherkinDocument, pickles } = parseGherkin('minimal.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .beforeHook({
+ fn,
+ sourceReference: { uri: 'hooks.js', location: { line: 1, column: 1 } },
+ })
+ .step({
+ pattern: 'a step',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ const fakeWorld = new FakeWorld()
+ const prepared = result.testCases[0].steps[0].prepare(fakeWorld)
+ expect(prepared.args).to.deep.eq([])
+ prepared.fn()
+ expect(fn).to.have.been.calledWithExactly()
+ expect(capturedThis).to.eq(fakeWorld)
+ })
+
+ it('prepares After hooks for execution', () => {
+ let capturedThis: any
+ const fn = sinon.spy(function (this: any) {
+ capturedThis = this
+ })
+
+ const { gherkinDocument, pickles } = parseGherkin('minimal.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .afterHook({
+ fn,
+ sourceReference: { uri: 'hooks.js', location: { line: 1, column: 1 } },
+ })
+ .step({
+ pattern: 'a step',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ const fakeWorld = new FakeWorld()
+ const prepared = result.testCases[0].steps[3].prepare(fakeWorld)
+ expect(prepared.args).to.deep.eq([])
+ prepared.fn()
+ expect(fn).to.have.been.calledWithExactly()
+ expect(capturedThis).to.eq(fakeWorld)
+ })
+ })
+
+ describe('messages', () => {
+ it('produces the correct envelopes', () => {
+ const { gherkinDocument, pickles } = parseGherkin('parameters.feature', newId)
+ const supportCodeLibrary = buildSupportCode({ newId })
+ .beforeHook({
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 1, column: 1 } },
+ })
+ .afterHook({
+ fn: sinon.stub(),
+ sourceReference: { uri: 'hooks.js', location: { line: 2, column: 1 } },
+ })
+ .step({
+ pattern: 'we scored {int} out of {int}',
+ fn: sinon.stub(),
+ sourceReference: { uri: 'steps.js', location: { line: 1, column: 1 } },
+ })
+ .build()
+
+ const result = makeTestPlan(
+ {
+ gherkinDocument,
+ pickles,
+ supportCodeLibrary,
+ },
+ {
+ newId,
+ }
+ )
+
+ expect(result.toEnvelopes()).to.deep.eq([
+ {
+ testCase: {
+ id: '7',
+ pickleId: '3',
+ testSteps: [
+ {
+ hookId: '4',
+ id: '8',
+ },
+ {
+ id: '9',
+ pickleStepId: '2',
+ stepDefinitionIds: ['6'],
+ stepMatchArgumentsLists: [
+ {
+ stepMatchArguments: [
+ {
+ group: {
+ children: [],
+ start: 10,
+ value: '4',
+ },
+ parameterTypeName: 'int',
+ },
+ {
+ group: {
+ children: [],
+ start: 19,
+ value: '5',
+ },
+ parameterTypeName: 'int',
+ },
+ ],
+ },
+ ],
+ },
+ {
+ hookId: '5',
+ id: '10',
+ },
+ ],
+ },
+ },
+ ])
+ })
+ })
+})
diff --git a/src/makeTestPlan.ts b/src/makeTestPlan.ts
new file mode 100644
index 0000000..6a8fc9a
--- /dev/null
+++ b/src/makeTestPlan.ts
@@ -0,0 +1,214 @@
+import { Group as ExpressionsGroup } from '@cucumber/cucumber-expressions'
+import {
+ GherkinDocument,
+ Group as MessagesGroup,
+ IdGenerator,
+ Pickle,
+ Step,
+} from '@cucumber/messages'
+import {
+ Lineage,
+ namingStrategy,
+ NamingStrategyExampleName,
+ NamingStrategyFeatureName,
+ NamingStrategyLength,
+ Query,
+} from '@cucumber/query'
+
+import { AmbiguousError } from './AmbiguousError'
+import { DataTable } from './DataTable'
+import {
+ AssembledStep,
+ AssembledTestPlan,
+ SupportCodeLibrary,
+ TestPlanIngredients,
+ TestPlanOptions,
+} from './types'
+import { UndefinedError } from './UndefinedError'
+
+/**
+ * Make an executable test plan for a Gherkin document
+ * @public
+ */
+export function makeTestPlan(
+ ingredients: TestPlanIngredients,
+ options: TestPlanOptions = {}
+): AssembledTestPlan {
+ const { gherkinDocument, pickles, supportCodeLibrary } = ingredients
+ const {
+ newId = IdGenerator.uuid(),
+ strategy = namingStrategy(
+ NamingStrategyLength.LONG,
+ NamingStrategyFeatureName.EXCLUDE,
+ NamingStrategyExampleName.NUMBER
+ ),
+ } = options
+ const query = populateQuery(gherkinDocument, pickles)
+ return {
+ name: gherkinDocument.feature?.name || gherkinDocument.uri,
+ testCases: pickles.map((pickle) => {
+ const lineage = query.findLineageBy(pickle) as Lineage
+ return {
+ id: newId(),
+ name: strategy.reduce(lineage, pickle),
+ steps: [
+ ...fromBeforeHooks(pickle, supportCodeLibrary, newId),
+ ...fromPickleSteps(pickle, supportCodeLibrary, newId, query),
+ ...fromAfterHooks(pickle, supportCodeLibrary, newId),
+ ],
+ toMessage() {
+ return {
+ id: this.id,
+ pickleId: pickle.id,
+ testSteps: this.steps.map((step) => step.toMessage()),
+ }
+ },
+ }
+ }),
+ toEnvelopes() {
+ return this.testCases.map((tc) => ({ testCase: tc.toMessage() }))
+ },
+ }
+}
+
+function populateQuery(gherkinDocument: GherkinDocument, pickles: ReadonlyArray) {
+ const query = new Query()
+ query.update({ gherkinDocument })
+ pickles.forEach((pickle) => query.update({ pickle }))
+ return query
+}
+
+function fromBeforeHooks(
+ pickle: Pickle,
+ supportCodeLibrary: SupportCodeLibrary,
+ newId: () => string
+): ReadonlyArray {
+ return supportCodeLibrary.findAllBeforeHooksBy(pickle.tags.map((tag) => tag.name)).map((def) => {
+ return {
+ id: newId(),
+ name: {
+ prefix: 'Before',
+ body: def.name ?? '',
+ },
+ always: false,
+ prepare(thisArg) {
+ return {
+ fn: def.fn.bind(thisArg),
+ args: [],
+ }
+ },
+ toMessage() {
+ return {
+ id: this.id,
+ hookId: def.id,
+ }
+ },
+ }
+ })
+}
+
+function fromAfterHooks(
+ pickle: Pickle,
+ supportCodeLibrary: SupportCodeLibrary,
+ newId: () => string
+): ReadonlyArray {
+ return supportCodeLibrary
+ .findAllAfterHooksBy(pickle.tags.map((tag) => tag.name))
+ .toReversed()
+ .map((def) => {
+ return {
+ id: newId(),
+ name: {
+ prefix: 'After',
+ body: def.name ?? '',
+ },
+ always: true,
+ prepare(thisArg) {
+ return {
+ fn: def.fn.bind(thisArg),
+ args: [],
+ }
+ },
+ toMessage() {
+ return {
+ id: this.id,
+ hookId: def.id,
+ }
+ },
+ }
+ })
+}
+
+function fromPickleSteps(
+ pickle: Pickle,
+ supportCodeLibrary: SupportCodeLibrary,
+ newId: () => string,
+ query: Query
+): ReadonlyArray {
+ return pickle.steps.map((pickleStep) => {
+ const step = query.findStepBy(pickleStep) as Step
+ const matched = supportCodeLibrary.findAllStepsBy(pickleStep.text)
+ return {
+ id: newId(),
+ name: {
+ prefix: step.keyword.trim(),
+ body: pickleStep.text,
+ },
+ always: false,
+ prepare(thisArg) {
+ if (matched.length < 1) {
+ throw new UndefinedError(pickleStep.text)
+ } else if (matched.length > 1) {
+ throw new AmbiguousError(
+ pickleStep.text,
+ matched.map(({ def }) => def.sourceReference)
+ )
+ } else {
+ const { def, args } = matched[0]
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const allArgs: Array = args.map((arg) => arg.getValue(thisArg))
+ if (pickleStep.argument?.dataTable) {
+ allArgs.push(
+ new DataTable(
+ pickleStep.argument.dataTable.rows.map((row) => {
+ return row.cells.map((cell) => cell.value)
+ })
+ )
+ )
+ } else if (pickleStep.argument?.docString) {
+ allArgs.push(pickleStep.argument.docString.content)
+ }
+ return {
+ fn: def.fn.bind(thisArg),
+ args: allArgs,
+ }
+ }
+ },
+ toMessage() {
+ return {
+ id: this.id,
+ pickleStepId: pickleStep.id,
+ stepDefinitionIds: matched.map(({ def }) => def.id),
+ stepMatchArgumentsLists: matched.map(({ args }) => {
+ return {
+ stepMatchArguments: args.map((arg) => {
+ return {
+ group: mapArgumentGroup(arg.group),
+ parameterTypeName: arg.parameterType.name,
+ }
+ }),
+ }
+ }),
+ }
+ },
+ }
+ })
+}
+
+function mapArgumentGroup(group: ExpressionsGroup): MessagesGroup {
+ return {
+ start: group.start,
+ value: group.value,
+ children: group.children.map((child) => mapArgumentGroup(child)),
+ }
+}
diff --git a/src/types.ts b/src/types.ts
new file mode 100644
index 0000000..12e983f
--- /dev/null
+++ b/src/types.ts
@@ -0,0 +1,427 @@
+import { Argument, CucumberExpression, RegularExpression } from '@cucumber/cucumber-expressions'
+import {
+ Envelope,
+ GherkinDocument,
+ Hook,
+ IdGenerator,
+ Pickle,
+ SourceReference,
+ StepDefinition,
+ TestCase,
+ TestStep,
+} from '@cucumber/messages'
+import { NamingStrategy } from '@cucumber/query'
+import parse from '@cucumber/tag-expressions'
+
+/**
+ * A function defined by the end user for a step or hook
+ * @public
+ */
+export type SupportCodeFunction = (...args: any[]) => any | Promise // eslint-disable-line @typescript-eslint/no-explicit-any
+
+/**
+ * Options to modify how support code is built
+ * @public
+ */
+export interface SupportCodeOptions {
+ /**
+ * A function that will be used to generate unique identifiers
+ * @default crypto.randomUUID
+ */
+ newId?: IdGenerator.NewId
+}
+
+/**
+ * Attributes for creating a new parameter type
+ * @public
+ */
+export interface NewParameterType {
+ /**
+ * The name of the parameter type
+ */
+ name: string
+ /**
+ * One or more regular expressions which should be used to match the parameter type
+ */
+ regexp: RegExp | string | readonly RegExp[] | readonly string[]
+ /**
+ * A function for transforming the matched values to another object before passing to
+ * the step function
+ * @param match - matched values from the regular expression
+ * @remarks
+ * If not provided, the raw matched value(s) will be passed to the step function.
+ */
+ transformer?: (...match: string[]) => unknown
+ /**
+ * Whether the parameter type should be used when suggesting snippets for missing step
+ * definitions
+ * @default true
+ */
+ useForSnippets?: boolean
+ /**
+ * Whether the regular expression(s) for the parameter type should take precedence if used
+ * in conjunction with regular expressions for step definitions
+ * @default false
+ */
+ preferForRegexpMatch?: boolean
+ /**
+ * A reference to the source code of the user-defined parameter
+ */
+ sourceReference: SourceReference
+}
+
+/**
+ * Attributes for creating a new hook
+ * @public
+ */
+export interface NewHook {
+ /**
+ * Optional name for the hook
+ */
+ name?: string
+ /**
+ * Optional tag expression which, if not a match for a given scenario, will cause the hook
+ * to be omitted from the test
+ */
+ tags?: string
+ /**
+ * The user-defined function for the hook
+ */
+ fn: SupportCodeFunction
+ /**
+ * A reference to the source code of the user-defined function
+ */
+ sourceReference: SourceReference
+}
+
+/**
+ * Attributes for creating a new step definition
+ * @public
+ */
+export interface NewStep {
+ /**
+ * Either a Cucumber Expression or regular expression used to match the step with steps from Gherkin
+ */
+ pattern: string | RegExp
+ /**
+ * The user-defined function for the step
+ */
+ fn: SupportCodeFunction
+ /**
+ * A reference to the source code of the user-defined function
+ */
+ sourceReference: SourceReference
+}
+
+/**
+ * Represents a parameter type that was referenced but not defined
+ * @public
+ */
+export type UndefinedParameterType = {
+ /**
+ * The parameter type name being referenced
+ */
+ name: string
+ /**
+ * The expression in which the undefined parameter type was referenced
+ */
+ expression: string
+}
+
+/**
+ * A parameter type that has been defined and is available for use
+ * @public
+ */
+export type DefinedParameterType = {
+ /**
+ * A unique identifier for the parameter type
+ */
+ id: string
+ /**
+ * The name of the parameter type
+ */
+ name: string
+ /**
+ * One or more regular expressions that will be used to match the parameter type
+ */
+ regularExpressions: ReadonlyArray
+ /**
+ * Whether the regular expression(s) for this parameter type will take precedence if used
+ * in conjunction with regular expressions for step definitions
+ */
+ preferForRegularExpressionMatch: boolean
+ /**
+ * Whether this parameter type will be used when suggesting snippets for missing step
+ * definitions
+ */
+ useForSnippets: boolean
+ /**
+ * A reference to the source code of the user-defined parameter type
+ */
+ sourceReference: SourceReference
+}
+
+/**
+ * A hook that has been defined and is available for execution
+ * @public
+ */
+export type DefinedHook = {
+ /**
+ * A unique identifier for the hook
+ */
+ id: string
+ /**
+ * The name of the hook, if defined
+ */
+ name?: string
+ /**
+ * The tag expression for the hook, if defined, including both raw and compiled forms
+ */
+ tags?: {
+ raw: string
+ compiled: ReturnType
+ }
+ /**
+ * The user-defined function for the hook
+ */
+ fn: SupportCodeFunction
+ /**
+ * A reference to the source code of the user-defined function
+ */
+ sourceReference: SourceReference
+ /**
+ * Creates a Cucumber Message representing this hook
+ */
+ toMessage(): Hook
+}
+
+/**
+ * A step definition that has been defined and is available for matching
+ * @public
+ */
+export type DefinedStep = {
+ /**
+ * A unique identifier for the step
+ */
+ id: string
+ /**
+ * The text expression for the step, including both raw and compiled forms
+ * @remarks
+ * This may be a Cucumber Expression or a regular expression
+ */
+ expression: {
+ raw: string | RegExp
+ compiled: CucumberExpression | RegularExpression
+ }
+ /**
+ * The user-defined function for the step
+ */
+ fn: SupportCodeFunction
+ /**
+ * A reference to the source code of the user-defined function
+ */
+ sourceReference: SourceReference
+ /**
+ * Creates a Cucumber Message representing this step definition
+ */
+ toMessage(): StepDefinition
+}
+
+/**
+ * Builder for collecting user-defined support code
+ * @public
+ */
+export interface SupportCodeBuilder {
+ /**
+ * Define a new parameter type
+ */
+ parameterType(options: NewParameterType): SupportCodeBuilder
+ /**
+ * Define a new step
+ */
+ step(options: NewStep): SupportCodeBuilder
+ /**
+ * Define a new before hook
+ */
+ beforeHook(options: NewHook): SupportCodeBuilder
+ /**
+ * Define a new after hook
+ */
+ afterHook(options: NewHook): SupportCodeBuilder
+ /**
+ * Build and seal the support code library for use in {@link makeTestPlan}
+ * @remarks
+ * Includes validation of parameter types, step expressions, tag expressions, etc.
+ */
+ build(): SupportCodeLibrary
+}
+
+/**
+ * Sealed library of support code that provides hooks and step definitions
+ * @public
+ */
+export interface SupportCodeLibrary {
+ /**
+ * Find all Before hooks that match the given tags
+ */
+ findAllBeforeHooksBy(tags: ReadonlyArray): ReadonlyArray
+ /**
+ * Find all After hooks that match the given tags
+ * @remarks
+ * Hooks are returned in definition order. For execution, the order should be reversed.
+ */
+ findAllAfterHooksBy(tags: ReadonlyArray): ReadonlyArray
+ /**
+ * Find all step definitions whose expression is a match for the given text
+ */
+ findAllStepsBy(text: string): ReadonlyArray
+ /**
+ * Produces a list of Cucumber Messages envelopes for the support code
+ */
+ toEnvelopes(): ReadonlyArray
+}
+
+/**
+ * A step definition that has been matched to a pickle step
+ * @public
+ */
+export type MatchedStep = {
+ def: DefinedStep
+ args: ReadonlyArray
+}
+
+/**
+ * Elements required to assemble a test plan
+ * @public
+ */
+export interface TestPlanIngredients {
+ /**
+ * The Gherkin document that has been processed
+ */
+ gherkinDocument: GherkinDocument
+ /**
+ * The pickles that have been compiled from the document
+ */
+ pickles: ReadonlyArray
+ /**
+ * The support code library that has been built
+ */
+ supportCodeLibrary: SupportCodeLibrary
+}
+
+/**
+ * Options to modify how the test plan is assembled
+ * @public
+ */
+export interface TestPlanOptions {
+ /**
+ * A function that will be used to generate unique identifiers
+ * @default crypto.randomUUID
+ */
+ newId?: IdGenerator.NewId
+ /**
+ * The naming strategy to use when generating test case names
+ * @default namingStrategy(NamingStrategyLength.LONG, NamingStrategyFeatureName.EXCLUDE, NamingStrategyExampleName.NUMBER)
+ */
+ strategy?: NamingStrategy
+}
+
+/**
+ * A function that has been validated and prepared for execution
+ * @public
+ * @remarks
+ * Depending on the characteristics of the Cucumber implementation, additional
+ * arguments may be prepended or appended to the arguments when passed to the
+ * function.
+ */
+export type PreparedFunction = {
+ /**
+ * The function that is ready to execute
+ */
+ fn: SupportCodeFunction
+ /**
+ * The arguments to pass to the function
+ */
+ args: ReadonlyArray
+}
+
+/**
+ * A step that belongs to an {@link AssembledTestCase}
+ * @public
+ */
+export interface AssembledStep {
+ /**
+ * A unique identifier for this step
+ */
+ id: string
+ /**
+ * A non-unique name for this step
+ */
+ name: {
+ prefix: string
+ body: string
+ }
+ /**
+ * Whether this step should always be executed even if preceding steps fail
+ */
+ always: boolean
+ /**
+ * Prepare the step for execution and return the prepared function and arguments
+ * @param thisArg - the value to bound as `this` on the function
+ * @remarks
+ * For pickle steps, preparation includes finding matching step definitions from
+ * the support code library and throwing if there is not exactly one, plus resolving
+ * the correct arguments from across expressions, doc strings and data tables.
+ */
+ prepare(thisArg?: unknown): PreparedFunction
+ /**
+ * Converts the step to a TestStep message
+ */
+ toMessage(): TestStep
+}
+
+/**
+ * A test case that has been assembled from hook and pickle steps
+ * @public
+ */
+export interface AssembledTestCase {
+ /**
+ * A unique identifier for this test case
+ */
+ id: string
+ /**
+ * A non-unique name for this test case
+ * @remarks
+ * This could vary depending on the supplied naming strategy.
+ */
+ name: string
+ /**
+ * An ordered array of steps to be executed for this test case
+ */
+ steps: ReadonlyArray
+ /**
+ * Converts the test case to a TestCase message
+ */
+ toMessage(): TestCase
+}
+
+/**
+ * A test plan comprised of assembled test cases from a document
+ * @public
+ */
+export interface AssembledTestPlan {
+ /**
+ * A non-unique name for this test plan
+ * @remarks
+ * This will be the feature name, or else the URI of the document, or else omitted.
+ */
+ name?: string
+ /**
+ * An ordered array of test cases to be executed in this plan
+ */
+ testCases: ReadonlyArray
+ /**
+ * Produces a list of Cucumber Messages envelopes for the test plan
+ */
+ toEnvelopes(): ReadonlyArray
+}
diff --git a/testdata/datatable.feature b/testdata/datatable.feature
new file mode 100644
index 0000000..0bf52dc
--- /dev/null
+++ b/testdata/datatable.feature
@@ -0,0 +1,5 @@
+Feature: a feature
+ Scenario: a scenario
+ Given a bunch of data:
+ | a | b | c |
+ | 1 | 2 | 3 |
\ No newline at end of file
diff --git a/testdata/docstring.feature b/testdata/docstring.feature
new file mode 100644
index 0000000..e79f9ba
--- /dev/null
+++ b/testdata/docstring.feature
@@ -0,0 +1,6 @@
+Feature: a feature
+ Scenario: a scenario
+ Given a thing that says:
+ """
+ Hello world
+ """
\ No newline at end of file
diff --git a/testdata/minimal.feature b/testdata/minimal.feature
new file mode 100644
index 0000000..be358de
--- /dev/null
+++ b/testdata/minimal.feature
@@ -0,0 +1,5 @@
+Feature: a feature
+ Scenario: a scenario
+ Given a step
+ When a step
+ Then a step
\ No newline at end of file
diff --git a/testdata/naming.feature b/testdata/naming.feature
new file mode 100644
index 0000000..e813b70
--- /dev/null
+++ b/testdata/naming.feature
@@ -0,0 +1,14 @@
+Feature: a feature
+ Rule: a rule
+ Scenario Outline: a parameterised scenario
+ Given a widget with things
+ Examples: under 5
+ | count |
+ | 1 |
+ | 2 |
+ | 3 |
+ | 4 |
+ Examples: 5 and above
+ | count |
+ | 5 |
+ | 10 |
\ No newline at end of file
diff --git a/testdata/parameters.feature b/testdata/parameters.feature
new file mode 100644
index 0000000..9289c67
--- /dev/null
+++ b/testdata/parameters.feature
@@ -0,0 +1,3 @@
+Feature: a feature
+ Scenario: a scenario
+ Given we scored 4 out of 5
\ No newline at end of file
diff --git a/testdata/tags.feature b/testdata/tags.feature
new file mode 100644
index 0000000..b88a84f
--- /dev/null
+++ b/testdata/tags.feature
@@ -0,0 +1,7 @@
+@foo
+Feature: a feature
+ @bar
+ Scenario: a scenario
+ Given a step
+ When a step
+ Then a step
\ No newline at end of file
diff --git a/testdata/unnamed.feature b/testdata/unnamed.feature
new file mode 100644
index 0000000..51ce361
--- /dev/null
+++ b/testdata/unnamed.feature
@@ -0,0 +1,5 @@
+Feature:
+ Scenario:
+ Given a step
+ When a step
+ Then a step
\ No newline at end of file
diff --git a/tsconfig.build.json b/tsconfig.build.json
new file mode 100644
index 0000000..6ac0f96
--- /dev/null
+++ b/tsconfig.build.json
@@ -0,0 +1,9 @@
+{
+ "extends": "./tsconfig.json",
+ "include": [
+ "src"
+ ],
+ "exclude": [
+ "src/**/*.spec.*",
+ ]
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..7a12325
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "extends": "@tsconfig/recommended/tsconfig.json",
+ "include": [
+ "src"
+ ],
+ "compilerOptions": {
+ "lib": [
+ "dom",
+ "es2023"
+ ],
+ "target": "es2022",
+ "declaration": true,
+ "outDir": "dist",
+ "inlineSourceMap": true
+ }
+}
\ No newline at end of file
diff --git a/typedoc.json b/typedoc.json
new file mode 100644
index 0000000..0a41663
--- /dev/null
+++ b/typedoc.json
@@ -0,0 +1,8 @@
+{
+ "entryPoints": ["src/index.ts"],
+ "navigationLinks": {
+ "GitHub": "https://github.com/cucumber/javascript-core"
+ },
+ "out": "./_site",
+ "readme": "none"
+}