diff --git a/.eslintignore b/.eslintignore index cd7584c5..ccd22aec 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,7 +1,13 @@ -build -node_modules -.github -bundle.* -docs -dist -scripts \ No newline at end of file +*.config.js +*.config.ts +package*.json +.eslintrc.cjs +bundle*.js + +**/open_rpc/** +**/generated/** +**/dist/** +**/docs/** +typedoc.json +tsconfig.json +test \ No newline at end of file diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 5f6ee4a7..f7fbd4cb 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,11 +1,94 @@ +/* eslint-env node */ module.exports = { - extends: ["@massalabs","prettier"], - rules: { - "tsdoc/syntax": "warn", - "max-len": ["error", 200], - camelcase: "off", - "@typescript-eslint/no-unused-vars": "error", - 'no-console': 'warn', - "comma-dangle": "off" - }, -}; + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/strict', + 'plugin:@typescript-eslint/stylistic', + ], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + root: true, + rules: { + 'no-else-return': ['error', { allowElseIf: false }], + 'func-style': ['error', 'declaration', { 'allowArrowFunctions': false }], + 'no-magic-numbers': 'off', + '@typescript-eslint/no-magic-numbers': [ + 'error', + { + ignoreArrayIndexes: true, + enforceConst: true, + detectObjects: true, + ignoreEnums: true, + ignore: [0,1,-1,'0n','1n'], + }, + ], + '@typescript-eslint/ban-tslint-comment': 'off', + '@typescript-eslint/consistent-type-definitions': [ + 'error', + 'type' + ], + 'max-params': ['error', 4], + 'class-methods-use-this': ['error', { exceptMethods: [] }], + '@typescript-eslint/explicit-function-return-type': ['warn'], + '@typescript-eslint/explicit-module-boundary-types': ['error'], + '@typescript-eslint/naming-convention': [ + 'error', + { + selector: 'default', + format: ['camelCase'], + leadingUnderscore: 'forbid', + trailingUnderscore: 'forbid', + }, + { + selector: 'variable', + format: ['camelCase'], + leadingUnderscore: 'forbid', + trailingUnderscore: 'forbid', + }, + { + selector: 'variable', + modifiers: ['const'], + format: ['camelCase'], + leadingUnderscore: 'forbid', + trailingUnderscore: 'forbid', + }, + { + selector: 'variable', + modifiers: ['const', 'global'], + format: ['UPPER_CASE'], + leadingUnderscore: 'forbid', + trailingUnderscore: 'forbid', + }, + { + selector: 'parameter', + format: ['camelCase'], + leadingUnderscore: 'allow', + trailingUnderscore: 'forbid', + }, + { + selector: 'typeLike', + format: ['PascalCase'], + leadingUnderscore: 'forbid', + trailingUnderscore: 'forbid', + }, + { + selector: 'enumMember', + format: ['PascalCase'], + leadingUnderscore: 'forbid', + trailingUnderscore: 'forbid', + }, + { + selector: 'import', + format: ['camelCase', 'PascalCase'], + leadingUnderscore: 'forbid', + trailingUnderscore: 'forbid', + }, + ], + // Not working for now. To investigate at some point. + //'@typescript-eslint/prefer-nullish-coalescing': [ + // 'error', + // { ignoreConditionalTests: true, ignoreMixedLogicalExpressions: true }, + //], + }, + }; \ No newline at end of file diff --git a/.github/workflows/coverage-v2.yml b/.github/workflows/coverage-v2.yml new file mode 100644 index 00000000..4c1cf953 --- /dev/null +++ b/.github/workflows/coverage-v2.yml @@ -0,0 +1,21 @@ +name: coverage repport +on: + push: + +jobs: + test: + uses: ./.github/workflows/unit-tests.yml + coverage: + runs-on: ubuntu-latest + needs: test + steps: + - uses: actions/checkout@v3 + - uses: jwalton/gh-find-current-pr@v1 + id: findPr + + - uses: ArtiomTr/jest-coverage-report-action@v2 + with: + custom-title: Coverage report for experimental massa-web3 + prnumber: ${{ steps.findPr.outputs.number }} + working-directory: ./ + test-script: npm test \ No newline at end of file diff --git a/.github/workflows/workspace-gen-deploy-docs.yml b/.github/workflows/docs.yml similarity index 92% rename from .github/workflows/workspace-gen-deploy-docs.yml rename to .github/workflows/docs.yml index dc26143c..d660f328 100644 --- a/.github/workflows/workspace-gen-deploy-docs.yml +++ b/.github/workflows/docs.yml @@ -1,4 +1,4 @@ -name: (workspace) Deploy documentation +name: Deploy documentation on: push: @@ -26,3 +26,4 @@ jobs: key: ${{ secrets.MASSANET_SSHKEY }} source: "./massa-web3" target: "/var/www/type-doc" + port: 22000 diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml new file mode 100644 index 00000000..1a909396 --- /dev/null +++ b/.github/workflows/integration-tests.yml @@ -0,0 +1,29 @@ +name: Integration tests + +on: + workflow_call: + secrets: + PRIVATE_KEY: + required: true + +jobs: + test: + uses: ./.github/workflows/unit-tests.yml + integration-tests: + runs-on: ubuntu-latest + needs: test + + steps: + - uses: actions/checkout@v3 + - name: Use Node.js 18 + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: "npm" + - run: npm ci + - run: npm run build + + - name: Run integration tests + env: + PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} + run: npm run test:integration diff --git a/.github/workflows/massa-web3-code-snippets.yml b/.github/workflows/massa-web3-code-snippets.yml deleted file mode 100644 index 000ce950..00000000 --- a/.github/workflows/massa-web3-code-snippets.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Generate code snippets - -on: - push: - branches: [ main ] - - - -jobs: - generate-code-snippets: - runs-on: ubuntu-latest - - permissions: - # Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. - contents: write - - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - # Checkout code using massabot account - token: ${{ secrets.MASSABOTCLASSIC }} - - - name: Install node - uses: actions/setup-node@v3 - with: - node-version: 18 - registry-url: https://registry.npmjs.org - - - name: Install project dependencies - run: | - npm i - - - name: Generate code snippets - run: | - node scripts/transform-code-snippet-tests.mjs - - - name: Format code snippets - run: | - npm run prettier:fix - - - name: Commit Changes - uses: stefanzweifel/git-auto-commit-action@v4 - with: - token: - commit_message: "Generate code snippets" - file_pattern: "code-snippets/*" - # Commit code using massabot account that can bypass push and MR restriction - commit_author: massabot \ No newline at end of file diff --git a/.github/workflows/massa-web3-deploy-test-smartContract.yml b/.github/workflows/massa-web3-deploy-test-smartContract.yml deleted file mode 100644 index 705f4316..00000000 --- a/.github/workflows/massa-web3-deploy-test-smartContract.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: (massa-web3) Smart contract example Deploy - -on: - push: - branches: [main] - -jobs: - deploy-SC-example: - defaults: - run: - working-directory: ./packages/massa-web3/examples/smartContracts/ - - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Install node - uses: actions/setup-node@v3 - with: - node-version: "18" - cache: "npm" - cache-dependency-path: ./packages/massa-web3/examples/smartContracts/contracts/package-lock.json - - - name: Install dependencies - run: | - npm ci - working-directory: ./ - - - name: Build workspace - run: | - npm run build - working-directory: ./ - - - name: Deploy - run: | - echo ${{ secrets.JSON_RPC_URL_PUBLIC }} - if npm run test-smart-contract-example ; then - echo "Contracts successfully deployed!" - else - echo "Failed to deploy contracts ..." - exit 1 - fi - env: - JSON_RPC_URL_PUBLIC: https://buildnet.massa.net/api/v2 - - JSON_RPC_URL_PRIVATE: https://buildnet.massa.net/api/v2 - - DEPLOYER_PRIVATE_KEY: S12srNEAvZrTb9pktYeuePpuM4taW5dfmWAZYtdqyETWTBspkoT1 - RECEIVER_PRIVATE_KEY: S1ykLaxXyMnJoaWLYds8UntqKTamZ4vcxrZ1fdToR8WpWEpk3FC diff --git a/.github/workflows/workspace-npm-publish-dev.yml b/.github/workflows/npm-publish-dev.yml similarity index 66% rename from .github/workflows/workspace-npm-publish-dev.yml rename to .github/workflows/npm-publish-dev.yml index c9b93370..615bca1f 100644 --- a/.github/workflows/workspace-npm-publish-dev.yml +++ b/.github/workflows/npm-publish-dev.yml @@ -1,14 +1,17 @@ -name: (workspace) Npm nightly publish +name: Npm nightly publish on: push: branches: [main, buildnet] jobs: - test: - uses: ./.github/workflows/workspace-check-formatting-and-run-tests.yml + integration-tests: + uses: ./.github/workflows/integration-tests.yml + secrets: + PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} + publish-npm-dev: - needs: test + needs: integration-tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/workspace-npm-publish.yml b/.github/workflows/npm-publish.yml similarity index 74% rename from .github/workflows/workspace-npm-publish.yml rename to .github/workflows/npm-publish.yml index 667a0aed..4cf42894 100644 --- a/.github/workflows/workspace-npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -1,15 +1,17 @@ -name: (workspace) NPM Publish +name: NPM Publish latest on: release: types: [created] jobs: - test: - uses: ./.github/workflows/workspace-check-formatting-and-run-tests.yml + integration-tests: + uses: ./.github/workflows/integration-tests.yml + secrets: + PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} publish-npm: - needs: test + needs: integration-tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/publish-next.yml b/.github/workflows/publish-next.yml new file mode 100644 index 00000000..1771fa00 --- /dev/null +++ b/.github/workflows/publish-next.yml @@ -0,0 +1,24 @@ +name: Npm publish next + +on: + push: + branches: [next] + +jobs: + integration-tests: + uses: ./.github/workflows/integration-tests.yml + secrets: + PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} + + publish-npm-next: + needs: integration-tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + registry-url: https://registry.npmjs.org + - run: ./scripts/publish-next.sh + env: + NODE_AUTH_TOKEN: ${{ secrets.npm_token }} diff --git a/.github/workflows/workspace-check-formatting-and-run-tests.yml b/.github/workflows/unit-tests.yml similarity index 67% rename from .github/workflows/workspace-check-formatting-and-run-tests.yml rename to .github/workflows/unit-tests.yml index 7eaa0657..a063dace 100644 --- a/.github/workflows/workspace-check-formatting-and-run-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -1,7 +1,6 @@ -name: (workspace) Check Formatting and Run Tests +name: Check Formatting and Run unit tests on: - push: workflow_call: jobs: @@ -18,4 +17,7 @@ jobs: - run: npm ci - run: npm run build - run: npm run fmt:check - - run: npm test + - name: unit test + run: npm test + env: + PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} diff --git a/.github/workflows/workspace-coverage.yml b/.github/workflows/workspace-coverage.yml deleted file mode 100644 index cc631673..00000000 --- a/.github/workflows/workspace-coverage.yml +++ /dev/null @@ -1,76 +0,0 @@ -name: (workspace) Coverage - -on: - push: - branches: [paused] - -jobs: - build: - strategy: - matrix: - project: [massa-web3, web3-utils] - - runs-on: ubuntu-latest - - permissions: - # Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. - contents: write - - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - # https://github.com/actions/checkout/issues/298#issuecomment-664976337 - ref: ${{ github.head_ref }} - # Checkout code using massabot account - token: ${{ secrets.MASSABOTCLASSIC || github.token }} - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.x - cache: "npm" - - - name: Install Protoc - uses: arduino/setup-protoc@v1 - - - name: Install dependencies - run: | - npm ci - working-directory: ./ - - - name: Build workspace - run: | - npm run build - working-directory: ./ - - - name: allow access to coverage.sh - run: chmod +x ./scripts/coverage.sh - shell: bash - - - name: Extract coverage - id: coverage - run: | - value=$(npm run test:cov -w @massalabs/${{ matrix.project }} | awk '/All files/ {print $10}' | tr -d '%') - echo "coverage=$value" >> $GITHUB_OUTPUT - - - name: Add test coverage to README - run: ./scripts/coverage.sh - shell: bash - env: - COVERAGE: ${{ steps.coverage.outputs.coverage }} - PROJECT: ${{ matrix.project }} - - - name: Check if coverage changed - id: check_coverage_changed - run: | - echo "::set-output name=coverage_changed::$(git diff --name-only README.md | grep -E '^README.md$')" - - - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v4 - if: ${{ steps.check_coverage_changed.outputs.coverage_changed != '' }} - with: - commit_message: "Generate coverage badge" - file_pattern: "README.md" - # Commit code using massabot account that can bypass push and MR restriction - commit_author: massabot diff --git a/.github/workflows/workspace-powered-by.yml b/.github/workflows/workspace-powered-by.yml deleted file mode 100644 index 07de8b5a..00000000 --- a/.github/workflows/workspace-powered-by.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: (workspace) Generate Powered-By -on: - push: - -jobs: - generate-powered-by: - runs-on: ubuntu-latest - - permissions: - # Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. - contents: write - - steps: - - name: Checkout code - uses: actions/checkout@v3 - with: - # Checkout code using massabot account - token: ${{ secrets.MASSABOTCLASSIC }} - - - name: Install node - uses: actions/setup-node@v3 - with: - node-version: 18 - registry-url: https://registry.npmjs.org - - - name: Install license-report and jq - run: | - sudo apt-get update -y && sudo apt-get install -y jq - sudo npm install -g license-report - - - name: Install project dependencies - run: | - npm ci - - - name: Generate Powered-By - run: | - ./scripts/generate_powered-by.sh - - - name: Commit Changes - uses: stefanzweifel/git-auto-commit-action@v4 - with: - token: ${{ secrets.MASSABOTCLASSIC }} - commit_message: "Generate powered-by" - file_pattern: "powered-by.md" - # Commit code using massabot account that can bypass push and MR restriction - commit_author: massabot diff --git a/.gitignore b/.gitignore index 1a22401e..fef84211 100644 --- a/.gitignore +++ b/.gitignore @@ -75,3 +75,6 @@ docs # Misc .DS_Store +# temporary files +tmp + diff --git a/packages/massa-web3/.npmignore b/.npmignore similarity index 100% rename from packages/massa-web3/.npmignore rename to .npmignore diff --git a/.prettierignore b/.prettierignore index fc93c93e..fa658571 100644 --- a/.prettierignore +++ b/.prettierignore @@ -19,4 +19,5 @@ docs node_modules scripts README.md -LICENSE \ No newline at end of file +LICENSE +**/generated/* \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index cf1bd43b..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Massa - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index fbdf98a7..8d9948c9 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,34 @@ -# Massa Web3 Workspace +# massa-web3 ![Node CI](https://github.com/massalabs/massa-web3/workflows/Node.js%20CI/badge.svg) -Welcome to the Massa Web3 Workspace. This space houses a collection of projects designed to bolster interaction with the Massa blockchain through TypeScript. Below is an overview of each project with links to their respective READMEs for more in-depth information. +![check-code-coverage](https://img.shields.io/badge/coverage-95.25%25-green) -## Projects within the Workspace +> **PREREQUISITES:** +> +> - NodeJS 18+ +> - npm / yarn (see package.json) -### 1. **Massa-web3** -![check-code-coverage](https://img.shields.io/badge/coverage-94.69%25-green) +Massa-web3 is a TypeScript library that enables you to communicate with the Massa blockchain. It offers an interface to retrieve data directly from the blockchain, interact with smart contracts, acquire and monitor events, and perform additional actions. -**Description:** -Massa-web3 is a TypeScript library that facilitates communication with the Massa blockchain. It's your key to extracting data, interfacing with smart contracts, monitoring blockchain events, and much more. -- [๐Ÿ“– Read the full `Massa-web3` README](./packages/massa-web3/README.md) for detailed installation instructions, prerequisites, and additional resources. +## Installation -### 2. **Web3-Utils** +`Massa-web3` could be used as a library for frameworks or as a stand-alone bundled js file which can be easily loaded into the browser. -![check-code-coverage](https://img.shields.io/badge/coverage-93.15%25-green) +### Library (Node.js/React/Vue.js) usage -**Description:** -Web3-Utils is a toolkit crafted for the Massa TypeScript projects. Although it currently lacks a dedicated README, this utility provides an array of essential tools to streamline and enhance your blockchain interactions. +> npm install @massalabs/massa-web3 -- [๐Ÿ“– Read the full `Web3-utils` README](./packages/web3-utils/README.md) for detailed installation instructions, prerequisites, and additional resources. +## Documentation -## Contributing +- Read the [`Massa-web3 documentation`](https://docs.massa.net) to learn how to use Massa-web3. +- [`TypeDoc API`](https://web3.docs.massa.net) is available for all exported classes, interfaces and methods. +- dApp examples with associated frontend can be found at [massa-sc-examples](https://github.com/massalabs/massa-sc-examples) repository. +## Contributing We welcome contributions from the community! If you would like to contribute to `massa-web3`, please read the [CONTRIBUTING file](CONTRIBUTING.md). ## License - -All projects within the Massa Web3 Workspace are released under the [MIT License](LICENSE). +`massa-web3` is released under the [MIT License](LICENSE). diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..78c0f7f8 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,13 @@ +module.exports = { + presets: [ + [ + '@babel/preset-env', + { + targets: { + node: 'current', // Ensures compatibility with the version of Node.js you are running + }, + modules: 'commonjs', // Necessary for Node.js compatibility + }, + ], + ], +} diff --git a/jest-puppeteer.config.js b/jest-puppeteer.config.js new file mode 100644 index 00000000..77850b0b --- /dev/null +++ b/jest-puppeteer.config.js @@ -0,0 +1,5 @@ +module.exports = { + launch: { + headless: true, + }, +} diff --git a/jest.browser.config.js b/jest.browser.config.js new file mode 100644 index 00000000..1b7620a6 --- /dev/null +++ b/jest.browser.config.js @@ -0,0 +1,13 @@ +module.exports = { + preset: 'jest-puppeteer', + testMatch: ['**/test/unit/*.spec.ts'], + transform: { + '^.+\\.ts$': [ + 'ts-jest', + { + tsconfig: '/tsconfig.json', + }, + ], + '^.+\\.jsx?$': 'babel-jest', + }, +} diff --git a/jest.config.ts b/jest.config.ts index 5f8c94ed..3f8d99d3 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -1,23 +1,18 @@ import type { Config } from '@jest/types' const config: Config.InitialOptions = { + displayName: 'massa-web3', transform: { '^.+\\.ts$': [ 'ts-jest', { - tsconfig: '/tsconfig.base.json', + tsconfig: '/tsconfig.json', }, ], '^.+\\.jsx?$': 'babel-jest', }, - moduleNameMapper: { - '^@massalabs/massa-web3/(.*)$': '/packages/massa-web3/src/$1', - '^@massalabs/web3-utils/(.*)$': '/packages/web3-utils/src/$1', - }, - testPathIgnorePatterns: [ - '/node_modules/', - '/packages/*/dist/', - ], + testMatch: ['/test/**/*.(spec|test).ts?(x)'], + testPathIgnorePatterns: ['/node_modules/', '/dist/'], } export default config diff --git a/open_rpc/massa.api.json b/open_rpc/massa.api.json new file mode 100644 index 00000000..79f45110 --- /dev/null +++ b/open_rpc/massa.api.json @@ -0,0 +1,3748 @@ +{ + "openrpc": "1.2.4", + "info": { + "title": "Massa OpenRPC Specification", + "version": "MAIN.2.1", + "description": "Massa OpenRPC Specification document. Find more information on https://docs.massa.net/docs/build/api/jsonrpc", + "termsOfService": "https://open-rpc.org", + "contact": { + "name": "Massa Team", + "url": "https://massa.net", + "email": "info@massa.net" + } + }, + "servers": [ + { + "name": "Massa public buildnet API", + "url": "https://buildnet.massa.net/api/v2", + "description": "Massa public buildnet url" + }, + { + "name": "Massa public testnet API", + "url": "https://test.massa.net/api/v2", + "description": "Massa public testnet url" + }, + { + "name": "Massa public mainnet API", + "url": "https://mainnet.massa.net/api/v2", + "description": "Massa public mainnet url" + } + ], + "methods": [ + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "ReadOnlyBytecodeExecution", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadOnlyBytecodeExecution" + } + } + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExecuteReadOnlyResponse" + } + }, + "name": "ExecuteReadOnlyResponses" + }, + "name": "execute_read_only_bytecode", + "summary": "Execute a smart contract in a read only context", + "description": "Execute a smart contract in a read only context. The changes on the ledger will not be applied and directly drop after the context of the execution. All the events generated will be returned." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "ReadOnlyCall", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadOnlyCall" + } + } + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ExecuteReadOnlyResponse" + } + }, + "name": "ExecuteReadOnlyResponses" + }, + "name": "execute_read_only_call", + "summary": "Call a function of a contract in a read only context", + "description": "Call a function of a contract in a read only context. The changes on the ledger will not be applied and directly drop after the context of the execution. All the events generated will be returned." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "address", + "description": "Need to provide at least one valid address", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Address" + } + }, + "required": true + } + ], + "result": { + "name": "AddressInfo", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddressInfo" + } + } + }, + "name": "get_addresses", + "summary": "To check when your address is selected to stake.", + "description": "To check when your address is selected to stake, run this command and look at the โ€œnext drawsโ€ section.\nAlso check that your balance increases, for each block or endorsement that you create you should get a small reward." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "addressFilter", + "description": "Need to provide at least one valid address filter", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddressFilter" + } + }, + "required": true + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "type": "string", + "format": "byte" + } + }, + "name": "Addresses bytecode array" + }, + "name": "get_addresses_bytecode", + "summary": "Returns the bytecode of the given addresses.", + "description": "Returns the bytecode of the given addresses." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "blockId", + "description": "Need to provide at least one valid block id", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BlockId" + } + }, + "summary": "string", + "required": true + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BlockInfo" + } + }, + "name": "BlockInfo" + }, + "name": "get_blocks", + "summary": "Get blocks", + "description": "Get blocks." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "slot", + "description": "Slot of the block", + "schema": { + "type": "object", + "$ref": "#/components/schemas/Slot" + }, + "required": true + } + ], + "result": { + "schema": { + "$ref": "#/components/schemas/Block" + }, + "name": "Block" + }, + "name": "get_blockclique_block_by_slot", + "summary": "Get a block in the blockclique", + "description": "Get the block in the blockclique that is associated to the slot" + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Clique" + } + }, + "name": "Cliques" + }, + "name": "get_cliques", + "summary": "Get cliques", + "description": "Returns information about cliques." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "DatastoreEntryInputs", + "description": "Datastore entry input", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DatastoreEntryInput" + } + } + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataStoreEntryOutput" + } + }, + "name": "DataStoreEntryOutputs" + }, + "name": "get_datastore_entries", + "summary": "Get a data entry both at the latest final and active executed slots for the given addresses.", + "description": "Get a data entry both at the latest final and active executed slots for the given addresses.\n\nIf an existing final entry (final_value) is found in the active history, it will return its final value in active_value field. If it was deleted in the active history, it will return null in active_value field." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "slots", + "description": "Precise the slots you want to gather the transfers from", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Slot" + } + }, + "required": true + } + ], + "result": { + "name": "SlotsTransfers", + "schema": { + "type": "array", + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Transfer" + } + } + } + }, + "name": "get_slots_transfers", + "summary": "Get transfers for specified slots", + "description": "Get transfers for specified slots" + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "endorsementId", + "description": "Need to provide at least one valid endorsement id", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "required": true + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EndorsementInfo" + } + }, + "name": "EndorsementInfos" + }, + "name": "get_endorsements", + "summary": "Get endorsements", + "description": "Get endorsements." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "EventFilter", + "schema": { + "$ref": "#/components/schemas/EventFilter" + } + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SCOutputEvent" + } + }, + "name": "SCOutputEvents" + }, + "name": "get_filtered_sc_output_event", + "summary": "Returns events optionally filtered", + "description": "Returns events optionally filtered by: start slot, end slot, emitter address, original caller address, operation id." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "TimeInterval", + "schema": { + "type": "object", + "properties": { + "start": { + "type": "number" + }, + "end": { + "type": "number" + } + }, + "additionalProperties": false + } + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GraphInterval" + } + }, + "name": "GraphInterval" + }, + "name": "get_graph_interval", + "summary": "Get graph interval", + "description": "Get graph interval." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "operationId", + "description": "Need to provide at least one valid operation id", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "required": true + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OperationInfo" + } + }, + "name": "OperationInfos" + }, + "name": "get_operations", + "summary": "Get operations", + "description": "Get operations." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "schema": { + "$ref": "#/components/schemas/PageRequest" + }, + "name": "PageRequest" + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Staker" + } + }, + "name": "PagedStakers" + }, + "name": "get_stakers", + "summary": "Get stakers", + "description": "Returns the active stakers and their roll counts for the current cycle." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [], + "result": { + "name": "NodeStatus", + "description": "Node status", + "schema": { + "$ref": "#/components/schemas/NodeStatus" + } + }, + "name": "get_status", + "summary": "Summary of the current state", + "description": "Summary of the current state: time, last final blocks (hash, thread, slot, timestamp), clique count, connected nodes count." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "SecretKeys", + "description": "The strings must be secret(private) keys", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PrivateKey" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "add_staking_secret_keys", + "summary": "Add a vec of new secret(private) keys for the node to use to stake", + "description": "Add a vec of new secret keys(private) for the node to use to stake." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [], + "result": { + "schema": { + "type": "array", + "items": { + "description": "Address", + "$ref": "#/components/schemas/Address" + } + }, + "description": "The strings are addresses.", + "name": "Addresses" + }, + "name": "get_staking_addresses", + "summary": "Return hashset of staking addresses", + "description": "Return hashset of staking addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_add_to_bootstrap_blacklist", + "summary": "Add to bootstrap blacklist given IP addresses", + "description": "Add to bootstrap blacklist given IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_add_to_bootstrap_whitelist", + "summary": "Add to bootstrap whitelist given IP addresses", + "description": "Add to bootstrap whitelist given IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_add_to_peers_whitelist", + "summary": "Add to peers whitelist given IP addresses", + "description": "Add to peers whitelist given IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "id", + "description": "The strings are nodes ids.", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_ban_by_id", + "summary": "Ban given ids", + "description": "Ban given ids." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "ip", + "description": "The strings are IP addresses.", + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_ban_by_ip", + "summary": "Ban given IP addresses", + "description": "Ban given IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [], + "result": { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "$ref": "#/components/schemas/IpAddress" + } + } + }, + "name": "node_bootstrap_blacklist", + "summary": "Returns bootstrap blacklist IP addresses", + "description": "Returns bootstrap blacklist IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [], + "result": { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "$ref": "#/components/schemas/IpAddress" + } + } + }, + "name": "node_bootstrap_whitelist", + "summary": "Returns bootstrap whitelist IP addresses", + "description": "Returns bootstrap whitelist IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_bootstrap_whitelist_allow_all", + "summary": "Allow everyone to bootstrap from the node", + "description": "Allow everyone to bootstrap from the node. Remove bootstrap whitelist configuration file." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [], + "result": { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "$ref": "#/components/schemas/IpAddress" + } + } + }, + "name": "node_peers_whitelist", + "summary": "Returns peers whitelist IP addresses", + "description": "Returns peers whitelist IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_remove_from_bootstrap_blacklist", + "summary": "Remove from bootstrap blacklist given IP addresses", + "description": "Remove from bootstrap blacklist given IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_remove_from_bootstrap_whitelist", + "summary": "Remove from bootstrap whitelist given IP addresses", + "description": "Remove from bootstrap whitelist given IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_remove_from_peers_whitelist", + "summary": "Remove from peers whitelist given IP addresses", + "description": "Remove from peers whitelist given IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_remove_from_whitelist", + "summary": "Remove from whitelist given IP addresses", + "description": "Remove from whitelist given IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "addresses", + "description": "The strings must addresses", + "schema": { + "type": "array", + "items": { + "description": "Address", + "$ref": "#/components/schemas/Address" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "remove_staking_addresses", + "summary": "Remove a vec of addresses used to stake", + "description": "Remove a vec of addresses used to stake." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "message", + "description": "Message to be signed in byte array", + "schema": { + "format": "byte", + "type": "string" + }, + "required": true + } + ], + "result": { + "schema": { + "$ref": "#/components/schemas/PubkeySig" + }, + "name": "PubkeySig" + }, + "name": "node_sign_message", + "summary": "Sign message with nodeโ€™s key", + "description": "Sign message with nodeโ€™s key." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "stop_node", + "summary": "Gracefully stop the node", + "description": "Gracefully stop the node." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "id", + "description": "The strings are nodes ids.", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_unban_by_id", + "summary": "Unban given ids", + "description": "Unban given ids." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "ip", + "description": "The strings are IP addresses.", + "schema": { + "type": "array", + "items": { + "description": "Ip address", + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_unban_by_ip", + "summary": "Unban given IP addresses", + "description": "Unban given IP addresses." + }, + { + "tags": [ + { + "name": "private", + "description": "Massa private api" + } + ], + "params": [ + { + "name": "ip", + "description": "The strings must be IP addresses", + "schema": { + "type": "array", + "items": { + "description": "ip address", + "type": "string" + } + }, + "required": true + } + ], + "result": { + "name": "No return", + "description": "No return.", + "schema": false + }, + "name": "node_whitelist", + "summary": "Whitelist given IP addresses", + "description": "Whitelist given IP addresses." + }, + { + "tags": [ + { + "name": "public", + "description": "Massa public api" + } + ], + "params": [ + { + "name": "OperationInput", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OperationInput" + } + }, + "required": true + } + ], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OperationId" + } + }, + "name": "Operations" + }, + "name": "send_operations", + "summary": "Adds operations to pool", + "description": "Adds operations to pool. Returns operations that were ok and sent to pool." + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + } + ], + "params": [ + { + "schema": { + "$ref": "#/components/schemas/ApiRequest" + }, + "name": "ApiRequest", + "description": "Optional api request" + } + ], + "result": { + "schema": { + "$ref": "#/components/schemas/PagedVecStaker" + }, + "name": "PagedVecStaker" + }, + "name": "get_largest_stakers", + "summary": "Get largest stakers", + "description": "Returns the active stakers and their active roll counts for the current cycle sorted by largest roll counts." + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + } + ], + "params": [], + "result": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BlockParent" + } + }, + "name": "NextBlockBestParents" + }, + "name": "get_next_block_best_parents", + "summary": "Get next block best parents", + "description": "Returns the ids of best parents for the next block to be produced along with their period" + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + } + ], + "params": [], + "result": { + "schema": { + "$ref": "#/components/schemas/Version" + }, + "name": "Version", + "description": "Node version" + }, + "name": "get_version", + "summary": "Get Massa node version", + "description": "Get Massa node version." + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + }, + { + "name": "websocket", + "description": "WebSocket subscription" + } + ], + "params": [], + "result": { + "schema": { + "$ref": "#/components/schemas/BlockInfo" + }, + "name": "BlockInfo" + }, + "name": "subscribe_new_blocks", + "summary": "New produced blocks", + "description": "New produced blocks." + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + }, + { + "name": "websocket", + "description": "WebSocket subscription" + } + ], + "params": [], + "result": { + "schema": { + "$ref": "#/components/schemas/WrappedHeader" + }, + "name": "BlockHeader" + }, + "name": "subscribe_new_blocks_headers", + "summary": "New produced blocks headers", + "description": "New produced blocks headers." + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + }, + { + "name": "websocket", + "description": "WebSocket subscription" + } + ], + "params": [], + "result": { + "schema": { + "$ref": "#/components/schemas/FilledBlockInfo" + }, + "name": "FilledBlockInfo" + }, + "name": "subscribe_new_filled_blocks", + "summary": "New produced blocks with operations content", + "description": "New produced blocks with operations content." + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + }, + { + "name": "websocket", + "description": "WebSocket subscription" + } + ], + "params": [], + "result": { + "schema": { + "$ref": "#/components/schemas/Operation" + }, + "name": "Operation" + }, + "name": "subscribe_new_operations", + "summary": "Subscribe to new operations", + "description": "Subscribe to new operations." + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + }, + { + "name": "websocket", + "description": "WebSocket subscription" + } + ], + "params": [ + { + "name": "subscriptionId", + "description": "Subscription id", + "schema": { + "type": "integer" + }, + "required": true + } + ], + "result": { + "schema": { + "type": "boolean" + }, + "name": "unsubscribe result", + "description": "unsubscribe success message" + }, + "name": "unsubscribe_new_blocks", + "summary": "Unsubscribe from new produced blocks", + "description": "Unsubscribe from new produced blocks." + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + }, + { + "name": "websocket", + "description": "WebSocket subscription" + } + ], + "params": [ + { + "name": "subscriptionId", + "description": "Subscription id", + "schema": { + "type": "integer" + }, + "required": true + } + ], + "result": { + "schema": { + "type": "boolean" + }, + "name": "unsubscribe result", + "description": "unsubscribe success message" + }, + "name": "unsubscribe_new_blocks_headers", + "summary": "Unsubscribe from new produced blocks headers", + "description": "Unsubscribe from new produced blocks headers." + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + }, + { + "name": "websocket", + "description": "WebSocket subscription" + } + ], + "params": [ + { + "name": "subscriptionId", + "description": "Subscription id", + "schema": { + "type": "integer" + }, + "required": true + } + ], + "result": { + "schema": { + "type": "boolean" + }, + "name": "unsubscribe result", + "description": "unsubscribe success message" + }, + "name": "unsubscribe_new_filled_blocks", + "summary": "Unsubscribe from new produced filled blocks", + "description": "Unsubscribe from new produced filled blocks." + }, + { + "tags": [ + { + "name": "api", + "description": "Massa api V2" + }, + { + "name": "experimental", + "description": "Experimental APIs. They might disappear, and they will change" + }, + { + "name": "websocket", + "description": "WebSocket subscription" + } + ], + "params": [ + { + "name": "subscriptionId", + "description": "Subscription id", + "schema": { + "type": "integer" + }, + "required": true + } + ], + "result": { + "schema": { + "type": "boolean" + }, + "name": "unsubscribe result", + "description": "unsubscribe success message" + }, + "name": "unsubscribe_new_operations", + "summary": "Unsubscribe from new received operations", + "description": "Unsubscribe from new received operations." + } + ], + "components": { + "schemas": { + "Address": { + "title": "Address", + "description": "Address", + "type": "string" + }, + "AddressFilter": { + "title": "AddressFilter", + "description": "Address filter", + "type": "object", + "properties": { + "address": { + "$ref": "#/components/schemas/Address", + "description": "The address" + }, + "is_final": { + "type": "boolean", + "description": "true means final, false means candidate" + } + }, + "additionalProperties": false + }, + "AddressInfo": { + "title": "AddressInfo", + "required": [ + "address", + "thread", + "final_balance", + "final_roll_count", + "final_datastore_keys", + "candidate_balance", + "candidate_roll_count", + "candidate_datastore_keys", + "deferred_credits", + "next_block_draws", + "next_endorsement_draws", + "created_blocks", + "created_operations", + "created_endorsements", + "cycle_infos" + ], + "type": "object", + "properties": { + "address": { + "$ref": "#/components/schemas/Address", + "description": "The address" + }, + "thread": { + "description": "The thread the address belongs to", + "type": "number" + }, + "final_balance": { + "description": "The final balance", + "type": "string" + }, + "final_roll_count": { + "description": "The final roll count", + "type": "number" + }, + "final_datastore_keys": { + "description": "The final datastore keys", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + } + } + }, + "candidate_balance": { + "description": "The candidate balance", + "type": "string" + }, + "candidate_roll_count": { + "description": "The candidate roll count", + "type": "number" + }, + "candidate_datastore_keys": { + "description": "The candidate datastore keys", + "type": "array", + "items": { + "type": "array", + "items": { + "type": "number" + } + } + }, + "deferred_credits": { + "description": "The deferred credits", + "type": "array", + "items": { + "type": "object", + "properties": { + "slot": { + "$ref": "#/components/schemas/Slot", + "type": "object" + }, + "amount": { + "type": "string" + } + } + }, + "minItems": 0 + }, + "next_block_draws": { + "description": "The next block draws", + "type": "array", + "items": { + "$ref": "#/components/schemas/Slot", + "type": "object" + } + }, + "next_endorsement_draws": { + "description": "The next endorsement draws", + "type": "array", + "items": { + "type": "object", + "properties": { + "slot": { + "$ref": "#/components/schemas/Slot", + "type": "object" + }, + "index": { + "type": "number" + } + } + } + }, + "created_blocks": { + "description": "BlockIds of created blocks", + "type": "array", + "items": { + "$ref": "#/components/schemas/BlockId", + "type": "string" + }, + "minItems": 0 + }, + "created_operations": { + "description": "OperationIds of created operations", + "type": "array", + "items": { + "$ref": "#/components/schemas/OperationId", + "type": "string" + }, + "minItems": 0 + }, + "created_endorsements": { + "description": "EndorsementIds of created endorsements", + "type": "array", + "items": { + "$ref": "#/components/schemas/EndorsementId", + "type": "string" + }, + "minItems": 0 + }, + "cycle_infos": { + "description": "Cycle infos", + "type": "array", + "items": { + "$ref": "#/components/schemas/ExecutionAddressCycleInfo", + "type": "object" + } + } + }, + "additionalProperties": false + }, + "ApiRequest": { + "title": "ApiRequest", + "description": "ApiRequest for apiV2", + "type": "object", + "properties": { + "page_request": { + "$ref": "#/components/schemas/PageRequest", + "description": "Optional page request" + } + }, + "additionalProperties": false + }, + "Balance": { + "title": "Balance", + "required": [ + "candidate_balance", + "final_balance", + "locked_balance" + ], + "type": "object", + "properties": { + "candidate_balance": { + "description": "Represent an Amount in coins", + "type": "string" + }, + "final_balance": { + "description": "Represent an Amount in coins", + "type": "string" + }, + "locked_balance": { + "description": "Represent an Amount in coins", + "type": "string" + } + }, + "additionalProperties": false + }, + "Block": { + "title": "Block", + "required": [ + "header", + "operations" + ], + "type": "object", + "properties": { + "header": { + "$ref": "#/components/schemas/WrappedHeader", + "description": "signed header" + }, + "operations": { + "description": "Operations", + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "BlockId": { + "title": "BlockId", + "description": "Block identifier", + "type": "string" + }, + "BlockInfo": { + "title": "BlockInfo", + "required": [ + "id" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "content": { + "$ref": "#/components/schemas/BlockInfoContent" + } + }, + "additionalProperties": false + }, + "BlockInfoContent": { + "title": "BlockInfoContent", + "required": [ + "block", + "is_final", + "is_in_blockclique", + "is_candidate" + ], + "type": "object", + "properties": { + "is_final": { + "description": "true if final", + "type": "boolean" + }, + "is_candidate": { + "description": "true if candidate", + "type": "boolean" + }, + "is_discarded": { + "description": "true if discarded", + "type": "boolean" + }, + "is_in_blockclique": { + "description": "true if in the greatest clique", + "type": "boolean" + }, + "block": { + "$ref": "#/components/schemas/Block", + "description": "block" + } + }, + "additionalProperties": false + }, + "BlockParent": { + "title": "BlockParent", + "description": "A tuple which contains (BlockId, period)", + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "BlockId": { + "$ref": "#/components/schemas/BlockId" + }, + "period": { + "type": "number" + } + } + }, + "example": { + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1": "Number", + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2": "Number" + } + }, + "CallSC": { + "title": "CallSC", + "description": "Call Smart Contract", + "required": [ + "max_gas", + "param", + "coins", + "target_addr", + "target_func" + ], + "type": "object", + "properties": { + "target_addr": { + "$ref": "#/components/schemas/Address", + "description": "Address" + }, + "target_func": { + "description": "Function name", + "type": "string" + }, + "param": { + "description": "Parameter to pass to the function", + "type": "string" + }, + "max_gas": { + "type": "number" + }, + "coins": { + "description": "Amount", + "type": "number" + } + }, + "additionalProperties": false + }, + "Clique": { + "title": "Clique", + "description": "Clique", + "required": [ + "block_ids", + "is_blockclique", + "fitness" + ], + "type": "object", + "properties": { + "block_ids": { + "description": "The block ids of the blocks in that clique", + "type": "array", + "items": { + "$ref": "#/components/schemas/BlockId" + } + }, + "fitness": { + "description": "Depends on descendants and endorsement count", + "type": "number" + }, + "is_blockclique": { + "description": "True if it is the clique of higher fitness", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "CompactConfig": { + "title": "Config", + "description": "Compact configuration", + "required": [ + "block_reward", + "delta_f0", + "genesis_timestamp", + "operation_validity_periods", + "periods_per_cycle", + "roll_price", + "t0", + "thread_count", + "execution_stats" + ], + "type": "object", + "properties": { + "block_reward": { + "description": "Represent an Amount in coins", + "type": "string" + }, + "delta_f0": { + "description": "Used to compute finality threshold", + "type": "number" + }, + "end_timestamp": { + "description": "(Only in tesnets)\nTime in milliseconds when the blockclique started.", + "oneOf": [ + { + "type": "null" + }, + { + "type": "number" + } + ] + }, + "genesis_timestamp": { + "description": "Time in milliseconds when the blockclique started.", + "type": "number" + }, + "max_block_size": { + "description": "Maximum size (in bytes) of a block", + "type": "number" + }, + "operation_validity_periods": { + "description": "Maximum operation validity period count", + "type": "number" + }, + "periods_per_cycle": { + "description": "cycle duration in periods", + "type": "number" + }, + "roll_price": { + "description": "Represent an Amount in coins", + "type": "string" + }, + "t0": { + "description": "Time between the periods in the same thread.", + "type": "number" + }, + "thread_count": { + "description": "Number of threads", + "type": "number" + } + }, + "additionalProperties": false + }, + "ConnectedNodes": { + "title": "ConnectedNodes", + "description": "Connected nodes", + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "node_id": { + "type": "string" + }, + "ip_address": { + "type": "string" + } + } + }, + "example": { + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1": "String", + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2": "String" + } + }, + "ConsensusStats": { + "title": "ConsensusStats", + "description": "Consensus stats", + "required": [ + "clique_count", + "end_timespan", + "final_block_count", + "stale_block_count", + "start_timespan" + ], + "type": "object", + "properties": { + "clique_count": { + "type": "number" + }, + "end_timespan": { + "description": "Stats time interval, millis since 1970-01-01", + "type": "number" + }, + "final_block_count": { + "type": "number" + }, + "stale_block_count": { + "type": "number" + }, + "start_timespan": { + "description": "Stats time interval, millis since 1970-01-01", + "type": "number" + } + }, + "additionalProperties": false + }, + "DataStore": { + "title": "Datastore", + "description": "A tuple which contains (entry, bytes)", + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "entry": { + "type": "array", + "items": { + "type": "integer" + } + }, + "bytes": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, + "example": [ + [ + 1, + 2, + 3, + 4 + ], + [ + 5, + 6, + 7, + 9, + 10 + ] + ] + }, + "DataStoreEntry": { + "title": "DatastoreEntry", + "description": "Datastore entry", + "type": "object", + "properties": { + "candidate_value": { + "description": "", + "type": "string" + }, + "final_value": { + "description": "", + "type": "string" + } + }, + "additionalProperties": false + }, + "DatastoreEntryInput": { + "title": "DatastoreEntryInput", + "description": "", + "required": [ + "address", + "key" + ], + "type": "object", + "properties": { + "address": { + "$ref": "#/components/schemas/Address" + }, + "key": { + "description": "", + "type": "array", + "items": { + "type": "integer" + } + } + }, + "additionalProperties": false + }, + "DataStoreEntryOutput": { + "title": "DatastoreEntryOutput", + "description": "Datastore entry", + "type": "object", + "required": [ + "candidate_value", + "final_value" + ], + "properties": { + "candidate_value": { + "description": "The candidate datastore entry value bytes", + "oneOf": [ + { + "type": "array", + "items": { + "type": "integer" + } + }, + { + "type": "null" + } + ] + }, + "final_value": { + "description": "The final datastore entry value bytes", + "oneOf": [ + { + "type": "array", + "items": { + "type": "integer" + } + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Denunciation": { + "oneOf": [ + { + "$ref": "#/components/schemas/EndorsementDenunciation" + }, + { + "$ref": "#/components/schemas/BlockHeaderDenunciation" + } + ] + }, + "EndorsementDenunciation": { + "type": "object", + "properties": { + "public_key": { + "type": "string" + }, + "slot": { + "type": "integer" + }, + "index": { + "type": "integer" + }, + "hash_1": { + "type": "string" + }, + "hash_2": { + "type": "string" + }, + "signature_1": { + "type": "string" + }, + "signature_2": { + "type": "string" + } + } + }, + "BlockHeaderDenunciation": { + "type": "object", + "properties": { + "public_key": { + "type": "string" + }, + "slot": { + "type": "integer" + }, + "hash_1": { + "type": "string" + }, + "hash_2": { + "type": "string" + }, + "signature_1": { + "type": "string" + }, + "signature_2": { + "type": "string" + } + } + }, + "Endorsement": { + "title": "Endorsement", + "description": "Endorsement", + "required": [ + "content", + "content_creator_pub_key", + "signature" + ], + "type": "object", + "properties": { + "content": { + "$ref": "#/components/schemas/EndorsementContent" + }, + "content_creator_pub_key": { + "$ref": "#/components/schemas/PublicKey" + }, + "content_creator_address": { + "$ref": "#/components/schemas/Address" + }, + "id": { + "$ref": "#/components/schemas/EndorsementId" + }, + "signature": { + "type": "string" + } + }, + "additionalProperties": false + }, + "ExecutionStats": { + "title": "ExecutionStats", + "description": "Execution stats", + "required": [ + "time_window_start", + "time_window_end", + "final_block_count", + "final_executed_operations_count", + "active_cursor", + "final_cursor" + ], + "type": "object", + "properties": { + "time_window_start": { + "description": "Time window start", + "type": "number" + }, + "time_window_end": { + "description": "Time window end", + "type": "number" + }, + "final_block_count": { + "description": "number of final blocks in the time window", + "type": "number" + }, + "final_executed_operations_count": { + "description": "number of final executed operations in the time window", + "type": "number" + }, + "active_cursor": { + "descritpion": "active execution cursor slot", + "$ref": "#/components/schemas/Slot" + }, + "final_cursor": { + "description": "final execution cursor slot", + "$ref": "#/components/schemas/Slot" + } + }, + "additionalProperties": false + }, + "EndorsementContent": { + "title": "EndorsementContent", + "description": "Endorsement content", + "required": [ + "endorsed_block", + "index", + "slot" + ], + "type": "object", + "properties": { + "slot": { + "$ref": "#/components/schemas/Slot" + }, + "index": { + "type": "number" + }, + "endorsed_block": { + "$ref": "#/components/schemas/BlockId" + } + }, + "additionalProperties": false + }, + "EndorsementDraw": { + "title": "EndorsementDraw", + "required": [ + "index", + "slot" + ], + "type": "object", + "properties": { + "slot": { + "$ref": "#/components/schemas/Slot" + }, + "index": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "EndorsementId": { + "title": "EndorsementId", + "description": "Endorsement id", + "type": "string" + }, + "EndorsementInfo": { + "title": "EndorsementInfo", + "description": "Endorsement info", + "required": [ + "endorsement", + "id", + "in_blocks", + "in_pool", + "is_final" + ], + "type": "object", + "properties": { + "id": { + "$ref": "#/components/schemas/EndorsementId" + }, + "in_pool": { + "type": "boolean" + }, + "in_blocks": { + "description": "Block Id", + "type": "array", + "items": { + "$ref": "#/components/schemas/BlockId" + } + }, + "is_final": { + "type": "boolean" + }, + "endorsement": { + "$ref": "#/components/schemas/Endorsement", + "description": "Endorsement" + } + }, + "additionalProperties": false + }, + "ExecutedAt": { + "title": "ExecuteAt", + "required": [ + "period", + "thread" + ], + "type": "object", + "properties": { + "period": { + "type": "number" + }, + "thread": { + "type": "number" + } + }, + "additionalProperties": false + }, + "ExecuteReadOnlyResponse": { + "title": "ExecuteReadOnlyResponse", + "required": [ + "executed_at", + "output_events", + "result", + "gas_cost", + "state_changes" + ], + "type": "object", + "properties": { + "executed_at": { + "$ref": "#/components/schemas/ExecutedAt" + }, + "result": { + "$ref": "#/components/schemas/ReadOnlyResult" + }, + "output_events": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SCOutputEvent" + } + }, + "gas_cost": { + "description": "The gas cost for the execution", + "type": "number" + }, + "state_changes": { + "$ref": "#/components/schemas/StateChanges" + } + }, + "additionalProperties": false + }, + "ExecuteSC": { + "title": "ExecuteSC", + "description": "Execute Smart Contract", + "required": [ + "data", + "max_gas", + "datastore" + ], + "type": "object", + "properties": { + "data": { + "description": "Vec of bytes to execute", + "type": "array", + "items": { + "type": "number" + } + }, + "max_gas": { + "description": "Maximum amount of gas that the execution of the contract is allowed to cost.", + "type": "number" + }, + "datastore": { + "$ref": "#/components/schemas/DataStore", + "description": "A tuple which contains (key, value)" + } + }, + "additionalProperties": false + }, + "ExecutionAddressCycleInfo": { + "title": "ExecutionAddressCycleInfo", + "required": [ + "cycle", + "is_final", + "ok_count", + "nok_count" + ], + "type": "object", + "properties": { + "cycle": { + "type": "number" + }, + "is_final": { + "type": "boolean" + }, + "ok_count": { + "type": "number" + }, + "nok_count": { + "type": "number" + }, + "active_rolls": { + "oneOf": [ + { + "type": "null" + }, + { + "type": "number" + } + ] + } + }, + "additionalProperties": false + }, + "EventFilter": { + "title": "EventFilter", + "description": "Event filter", + "required": [], + "type": "object", + "properties": { + "start": { + "$ref": "#/components/schemas/Slot", + "description": "Optional start slot\nWill use by default Slot(0,0)" + }, + "end": { + "$ref": "#/components/schemas/Slot", + "description": "Optional end slot\nWill use by default Slot(0,0)" + }, + "emitter_address": { + "description": "Optional emitter address", + "type": "string" + }, + "original_caller_address": { + "description": "Optional caller address", + "type": "string" + }, + "original_operation_id": { + "description": "Optional operation id", + "type": "string" + }, + "is_final": { + "description": "Optional filter to filter only candidate or final events", + "type": "boolean" + }, + "is_error": { + "description": "Optional filter to retrieve events generated in a failed execution", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "EventId": { + "title": "EventId", + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "context": { + "$ref": "#/components/schemas/SCOEContext" + }, + "data": { + "type": "string" + } + } + } + }, + "EventExecutionContext": { + "title": "EventExecutionContext", + "description": "Context of the event (not generated by the user)", + "required": [ + "call_stack", + "index_in_slot", + "read_only", + "slot", + "is_final" + ], + "type": "object", + "properties": { + "slot": { + "$ref": "#/components/schemas/Slot", + "description": "When was it generated" + }, + "block": { + "$ref": "#/components/schemas/BlockId", + "description": "Block Id" + }, + "read_only": { + "description": "Wether the event was generated during read only call", + "type": "boolean" + }, + "call_stack": { + "description": "Addresses, most recent at the end", + "type": "array", + "items": { + "$ref": "#/components/schemas/Address" + } + }, + "index_in_slot": { + "description": "Index of the event in the slot", + "type": "number" + }, + "origin_operation_id": { + "$ref": "#/components/schemas/OperationId", + "description": "Origin operation id" + }, + "is_final": { + "description": "Whether the event is final", + "type": "boolean" + }, + "is_error": { + "description": "Whether the event was generated in a failed executed or not", + "type": "boolean" + } + }, + "additionalProperties": false + }, + "IpAddress": { + "title": "IpAddress", + "description": "Ipv4 or Ipv6 address", + "type": "string" + }, + "FilledBlock": { + "title": "FilledBlock", + "required": [ + "header", + "operations" + ], + "type": "object", + "properties": { + "header": { + "$ref": "#/components/schemas/WrappedHeader", + "description": "signed header" + }, + "operations": { + "description": "Operations", + "type": "array", + "items": { + "$ref": "#/components/schemas/OperationInfo" + } + } + }, + "additionalProperties": false + }, + "FilledBlockInfo": { + "title": "FilledBlockInfo", + "required": [ + "id" + ], + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "content": { + "$ref": "#/components/schemas/FilledBlockInfoContent" + } + }, + "additionalProperties": false + }, + "FilledBlockInfoContent": { + "title": "FilledBlockInfoContent", + "required": [ + "block", + "is_final", + "is_in_blockclique", + "is_stale" + ], + "type": "object", + "properties": { + "is_final": { + "description": "true if final", + "type": "boolean" + }, + "is_stale": { + "description": "true if incompatible with a final block", + "type": "boolean" + }, + "is_in_blockclique": { + "description": "true if in the greatest clique", + "type": "boolean" + }, + "block": { + "$ref": "#/components/schemas/FilledBlock", + "description": "filled block" + } + }, + "additionalProperties": false + }, + "GraphInterval": { + "title": "GraphInterval", + "required": [ + "creator", + "id", + "is_final", + "is_in_blockclique", + "is_stale", + "parents", + "slot" + ], + "type": "object", + "properties": { + "creator": { + "description": "Public key", + "type": "string" + }, + "id": { + "description": "Block Id", + "type": "string" + }, + "is_final": { + "type": "boolean" + }, + "is_in_blockclique": { + "type": "boolean" + }, + "is_stale": { + "type": "boolean" + }, + "parents": { + "description": "As many block Ids as there are threads", + "type": "array", + "items": { + "type": "string" + } + }, + "slot": { + "$ref": "#/components/schemas/Slot" + } + }, + "additionalProperties": false + }, + "Header": { + "title": "Header", + "required": [ + "operation_merkle_root", + "parents", + "slot" + ], + "type": "object", + "properties": { + "current_version": { + "description": "Current version", + "type": "number" + }, + "announced_version": { + "description": "Announced version", + "oneOf": [ + { + "type": "null" + }, + { + "type": "number" + } + ] + }, + "operation_merkle_root": { + "type": "string" + }, + "parents": { + "type": "array", + "items": { + "type": "string" + } + }, + "slot": { + "$ref": "#/components/schemas/Slot" + }, + "endorsements": { + "description": "Endorsements", + "type": "array", + "items": { + "type": "object", + "properties": { + "content": { + "$ref": "#/components/schemas/EndorsementContent" + }, + "signature": { + "type": "string" + }, + "content_creator_pub_key": { + "$ref": "#/components/schemas/PublicKey" + }, + "content_creator_address": { + "$ref": "#/components/schemas/Address" + }, + "id": { + "$ref": "#/components/schemas/EndorsementId" + } + } + } + }, + "denunciations": { + "description": "Denunciations", + "type": "array", + "items": { + "$ref": "#/components/schemas/Denunciation" + }, + "minItems": 0 + } + }, + "additionalProperties": false + }, + "LedgerInfo": { + "title": "SceLedgerInfo", + "required": [ + "balance", + "datastore" + ], + "type": "object", + "properties": { + "balance": { + "description": "Represent an amount", + "type": "string" + }, + "module": { + "description": "Stored bytecode", + "type": "array", + "items": { + "type": "integer" + } + }, + "datastore": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DataStore" + } + } + }, + "additionalProperties": false + }, + "NetworkStats": { + "title": "NetworkStats", + "description": "Network stats", + "required": [ + "active_node_count", + "banned_peer_count", + "in_connection_count", + "known_peer_count", + "out_connection_count" + ], + "type": "object", + "properties": { + "active_node_count": { + "description": "Active node count", + "type": "number" + }, + "banned_peer_count": { + "description": "Banned node count", + "type": "number" + }, + "in_connection_count": { + "description": "In connections count", + "type": "number" + }, + "known_peer_count": { + "description": "Total known peers count", + "type": "number" + }, + "out_connection_count": { + "description": "Out connections count", + "type": "number" + } + }, + "additionalProperties": false + }, + "NodeStatus": { + "title": "NodeStatus", + "description": "Node status", + "required": [ + "config", + "connected_nodes", + "consensus_stats", + "current_cycle", + "current_time", + "current_cycle_time", + "next_cycle_time", + "network_stats", + "last_slot", + "next_slot", + "node_id", + "pool_stats", + "version", + "execution_stats", + "chain_id" + ], + "type": "object", + "properties": { + "config": { + "$ref": "#/components/schemas/CompactConfig", + "description": "Compact configuration" + }, + "connected_nodes": { + "$ref": "#/components/schemas/ConnectedNodes", + "description": "Connected nodes (node id, ip address, true if the connection is outgoing, false if incoming)" + }, + "consensus_stats": { + "$ref": "#/components/schemas/ConsensusStats", + "description": "Consensus stats" + }, + "current_cycle": { + "description": "Current cycle", + "type": "number" + }, + "current_time": { + "description": "Time in milliseconds since 1970-01-01", + "type": "number" + }, + "current_cycle_time": { + "description": "current cycle starting time in milliseconds since 1970-01-01", + "type": "number" + }, + "next_cycle_time": { + "description": "next cycle starting time in milliseconds since 1970-01-01", + "type": "number" + }, + "last_slot": { + "$ref": "#/components/schemas/Slot", + "description": "Latest slot, none if now is before genesis timestamp" + }, + "network_stats": { + "$ref": "#/components/schemas/NetworkStats", + "description": "Network stats" + }, + "next_slot": { + "$ref": "#/components/schemas/Slot", + "description": "Next slot" + }, + "node_id": { + "description": "Our node id", + "type": "string" + }, + "node_ip": { + "description": "Optional node ip if provided", + "oneOf": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "pool_stats": { + "$ref": "#/components/schemas/PoolStats", + "description": "Pool stats" + }, + "version": { + "$ref": "#/components/schemas/Version", + "description": "Node Version" + }, + "execution_stats": { + "$ref": "#/components/schemas/ExecutionStats", + "description": "Execution stats" + }, + "chain_id": { + "description": "Chain id", + "type": "number" + }, + "minimal_fees": { + "description": "Minimal fee", + "type": "string" + } + }, + "additionalProperties": false + }, + "Operation": { + "title": "Operation", + "description": "Operation", + "required": [ + "fee", + "expire_period", + "op" + ], + "type": "object", + "properties": { + "fee": { + "description": "the fee they have decided for this operation", + "type": "string" + }, + "expire_period": { + "description": "after `expire_period` slot the operation won't be included in a block", + "type": "number" + }, + "op": { + "$ref": "#/components/schemas/OperationType", + "description": "the type specific operation part" + } + }, + "additionalProperties": false + }, + "OperationId": { + "title": "OperationId", + "description": "Operation id", + "type": "string" + }, + "OperationInfo": { + "title": "OperationInfo", + "description": "Operation info", + "required": [ + "id", + "in_blocks", + "in_pool", + "is_operation_final", + "thread", + "operation" + ], + "type": "object", + "properties": { + "id": { + "description": "Operation id", + "type": "string" + }, + "in_blocks": { + "description": "Block ids\nThe operation appears in `in_blocks`\nIf it appears in multiple blocks, these blocks are in different cliques", + "type": "array", + "items": { + "$ref": "#/components/schemas/BlockId" + } + }, + "in_pool": { + "description": "True if operation is still in pool", + "type": "boolean" + }, + "is_operation_final": { + "description": "True if the operation is final (for example in a final block)", + "oneOf": [ + { + "type": "null" + }, + { + "type": "boolean" + } + ] + }, + "thread": { + "description": "Thread in which the operation can be included", + "type": "number" + }, + "operation": { + "$ref": "#/components/schemas/WrappedOperation", + "description": "The operation itself" + }, + "op_exec_status": { + "description": "true if the operation execution succeeded, false if failed, None means unknown", + "oneOf": [ + { + "type": "null" + }, + { + "type": "boolean" + } + ] + } + }, + "additionalProperties": false + }, + "OperationInput": { + "title": "OperationInput", + "description": "Operation input", + "required": [ + "creator_public_key", + "signature", + "serialized_content" + ], + "type": "object", + "properties": { + "creator_public_key": { + "$ref": "#/components/schemas/PublicKey", + "description": "the content creator public key" + }, + "signature": { + "$ref": "#/components/schemas/Signature", + "description": "The signature of the operation" + }, + "serialized_content": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + "additionalProperties": false + }, + "OperationType": { + "title": "OperationType", + "description": "Type specific operation content.", + "type": "object", + "properties": { + "Transaction": { + "$ref": "#/components/schemas/Transaction", + "description": "transfer coins from sender to recipient" + }, + "ExecutSC": { + "$ref": "#/components/schemas/ExecuteSC", + "description": "Execute a smart contract." + }, + "CallSC": { + "$ref": "#/components/schemas/CallSC", + "description": "Calls an exported function from a stored smart contract" + }, + "RollBuy": { + "$ref": "#/components/schemas/RollBuy", + "description": "the sender buys `roll_count` rolls. Roll price is defined in configuration" + }, + "RollSell": { + "$ref": "#/components/schemas/RollSell", + "description": "the sender sells `roll_count` rolls. Roll price is defined in configuration" + } + }, + "additionalProperties": false + }, + "PageRequest": { + "title": "Pagination", + "description": "An PageRequest object, which contains limit (max elements par page) and a page offset.", + "type": "object", + "required": [ + "limit", + "offset" + ], + "properties": { + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + } + }, + "additionalProperties": false + }, + "PagedVecStaker": { + "title": "PagedVecStaker", + "description": "PagedVec of stakers for apiV2", + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Staker" + } + }, + "total_count": { + "type": "number" + } + }, + "additionalProperties": false + }, + "PoolStats": { + "title": "PoolStats", + "description": "Pool stats", + "type": "array", + "items": { + "type": "number" + } + }, + "PrivateKey": { + "title": "PrivateKey", + "description": "`PrivateKey` is used for signature and decryption", + "type": "string" + }, + "ProductionStat": { + "title": "ProductionStat", + "required": [ + "cycle", + "is_final", + "nok_count", + "ok_count" + ], + "type": "object", + "properties": { + "cycle": { + "type": "integer" + }, + "is_final": { + "type": "boolean" + }, + "nok_count": { + "type": "integer" + }, + "ok_count": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "PublicKey": { + "title": "PublicKey", + "description": "Public key used to check if a message was encoded by the corresponding `PublicKey`.\nGenerated from the `KeyPair` using `SignatureEngine`", + "type": "string" + }, + "PubkeySig": { + "title": "PubkeySig", + "description": "Public key and a signature it has produced used for serialization/deserialization purpose", + "required": [ + "public_key", + "signature" + ], + "type": "object", + "properties": { + "public_key": { + "description": "public key", + "type": "string" + }, + "signature": { + "description": "signature", + "type": "string" + } + }, + "additionalProperties": false + }, + "ReadOnlyBytecodeExecution": { + "title": "ReadOnlyBytecodeExecution", + "description": "Read only bytecode execution", + "required": [ + "max_gas", + "bytecode" + ], + "type": "object", + "properties": { + "max_gas": { + "description": "Max available gas", + "type": "number" + }, + "bytecode": { + "description": "Bytecode to execute", + "type": "array", + "items": { + "type": "integer" + } + }, + "address": { + "$ref": "#/components/schemas/Address", + "description": "caller's address" + }, + "operation_datastore": { + "description": "An operation datastore", + "type": "array", + "items": { + "type": "integer" + } + }, + "is_final": { + "description": "Whether to start execution from final or active state", + "type": "boolean" + }, + "coins": { + "description": "Amount in coins, optional", + "type": "number" + }, + "fee": { + "description": "Fee, optional", + "type": "number" + } + }, + "additionalProperties": false + }, + "ReadOnlyCall": { + "title": "ReadOnlyCall", + "description": "Read only call", + "required": [ + "max_gas", + "target_address", + "target_function", + "parameter", + "caller_address", + "coins", + "fee" + ], + "type": "object", + "properties": { + "max_gas": { + "description": "Max available gas", + "type": "number" + }, + "target_address": { + "description": "Target address", + "type": "string" + }, + "target_function": { + "description": "Target function", + "type": "string" + }, + "parameter": { + "description": "Function parameter", + "type": "array", + "items": { + "type": "integer" + } + }, + "caller_address": { + "description": "Caller's address, optional", + "oneOf": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "coins": { + "description": "Amount in coins, optional", + "oneOf": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + }, + "fee": { + "description": "Fee, optional", + "oneOf": [ + { + "type": "null" + }, + { + "type": "string" + } + ] + } + }, + "additionalProperties": false + }, + "ReadOnlyResult": { + "title": "ReadOnlyResult", + "description": "The result of a read-only execution", + "type": "object", + "properties": { + "Ok": { + "description": "Included in case of success. The result of the execution", + "type": "array", + "items": { + "format": "byte", + "type": "string" + } + }, + "Error": { + "description": "Included in case of error. The error message", + "type": "string" + } + }, + "additionalProperties": false + }, + "Roll": { + "title": "Roll", + "description": "Roll", + "required": [ + "roll_count" + ], + "type": "object", + "properties": { + "roll_count": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "RollBuy": { + "title": "RollBuy", + "description": "the sender buys `roll_count` rolls. Roll price is defined in configuration", + "required": [ + "roll_count" + ], + "type": "object", + "properties": { + "roll_count": { + "description": "roll count", + "type": "number" + } + }, + "additionalProperties": false + }, + "RollsInfo": { + "title": "RollsInfo", + "required": [ + "active_rolls", + "candidate_rolls", + "final_rolls" + ], + "type": "object", + "properties": { + "active_rolls": { + "type": "integer" + }, + "candidate_rolls": { + "type": "integer" + }, + "final_rolls": { + "type": "integer" + } + }, + "additionalProperties": false + }, + "RollSell": { + "title": "RollSell", + "description": "the sender sells `roll_count` rolls. Roll price is defined in configuration", + "required": [ + "roll_count" + ], + "type": "object", + "properties": { + "roll_count": { + "description": "roll count", + "type": "number" + } + }, + "additionalProperties": false + }, + "SCOEContext": { + "title": "SCOEContext", + "required": [ + "call_stack", + "index_in_slot", + "read_only", + "slot" + ], + "type": "object", + "properties": { + "slot": { + "$ref": "#/components/schemas/Slot" + }, + "block": { + "description": "Block Id", + "type": "string" + }, + "read_only": { + "description": "Wether the event was generated during read only call", + "type": "boolean" + }, + "call_stack": { + "description": "Addresses", + "type": "array", + "items": { + "type": "string" + } + }, + "index_in_slot": { + "type": "number" + }, + "origin_operation_id": { + "description": "Operation id", + "type": "string" + } + }, + "additionalProperties": false + }, + "SCOutputEvent": { + "title": "SCOutputEvent", + "required": [ + "context", + "data" + ], + "type": "object", + "properties": { + "data": { + "description": "String of the event you sended", + "type": "string" + }, + "context": { + "$ref": "#/components/schemas/EventExecutionContext", + "description": "Context generated by the execution context" + } + }, + "additionalProperties": false + }, + "Signature": { + "title": "Signature", + "description": "Signature generated from a message and a `KeyPair`.", + "type": "string" + }, + "Slot": { + "title": "Slot", + "description": "Slot", + "required": [ + "period", + "thread" + ], + "type": "object", + "properties": { + "period": { + "type": "number" + }, + "thread": { + "type": "number" + } + }, + "additionalProperties": false + }, + "Staker": { + "title": "Staker", + "description": "A tuple which contains (address, active_rolls)", + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "address": { + "$ref": "#/components/schemas/Address" + }, + "active_rolls": { + "type": "number" + } + } + }, + "example": { + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1": "Number", + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2": "Number" + } + }, + "StateChanges": { + "title": "StateChanges", + "required": [ + "async_pool_changes", + "executed_ops_changes", + "ledger_changes", + "pos_changes", + "executed_denunciations_changes", + "execution_trail_hash_change" + ], + "type": "object", + "properties": { + "ledger_changes": { + "description": "ledger changes", + "type": "object" + }, + "async_pool_changes": { + "description": "async pool changes", + "type": "array", + "items": { + "type": "object" + } + }, + "pos_changes": { + "description": "pos changes", + "type": "object" + }, + "executed_ops_changes": { + "description": "executed operations changes", + "type": "object" + }, + "executed_denunciations_changes": { + "description": "executed denunciation changes", + "type": "object" + }, + "execution_trail_hash_change": { + "description": "execution trail hash change", + "type": "string" + } + }, + "additionalProperties": false + }, + "Transaction": { + "title": "Transaction", + "description": "Transation", + "required": [ + "amount", + "recipient_address" + ], + "type": "object", + "properties": { + "amount": { + "description": "Represent an Amount in coins", + "type": "string" + }, + "recipient_address": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Transfer": { + "title": "Transfer", + "description": "Describe a transfer of MAS", + "required": [ + "from", + "to", + "amount", + "effective_amount_received", + "context", + "succeed", + "fee", + "block_id" + ], + "type": "object", + "properties": { + "from": { + "description": "Address of the sender", + "type": "string" + }, + "to": { + "description": "Address of the receiver", + "type": "string" + }, + "amount": { + "description": "Amount transferred", + "type": "integer" + }, + "effective_amount_received": { + "description": "Amount received by the receiver", + "type": "integer" + }, + "context": { + "description": "Context of the transfer : operation or asyncronous execution", + "type": "object" + }, + "succeed": { + "description": "True if the operation succeed otherwise false", + "type": "boolean" + }, + "fee": { + "description": "Fees passed to the operation", + "type": "number" + }, + "block_id": { + "description": "ID of the block in which the operation is included", + "type": "string" + } + }, + "additionalProperties": false + }, + "Version": { + "title": "Version", + "description": "Application version, checked during handshakes", + "type": "string" + }, + "WrappedHeader": { + "title": "WrappedHeader", + "description": "signed operation", + "required": [ + "content", + "signature", + "content_creator_pub_key", + "content_creator_address" + ], + "type": "object", + "properties": { + "content": { + "$ref": "#/components/schemas/Header", + "description": "header type" + }, + "signature": { + "$ref": "#/components/schemas/Signature", + "description": "signature" + }, + "content_creator_pub_key": { + "$ref": "#/components/schemas/PublicKey", + "description": "the content creator public key" + }, + "content_creator_address": { + "$ref": "#/components/schemas/Address", + "description": "the content creator address" + }, + "id": { + "$ref": "#/components/schemas/BlockId" + } + }, + "additionalProperties": false + }, + "WrappedOperation": { + "title": "WrappedOperation", + "description": "signed operation", + "required": [ + "content", + "signature", + "creator_public_key", + "creator_address" + ], + "type": "object", + "properties": { + "content": { + "$ref": "#/components/schemas/Operation" + }, + "signature": { + "$ref": "#/components/schemas/Signature", + "description": "signature" + }, + "content_creator_pub_key": { + "$ref": "#/components/schemas/PublicKey", + "description": "the content creator public key" + }, + "content_creator_address": { + "$ref": "#/components/schemas/Address", + "description": "the content creator address" + }, + "id": { + "$ref": "#/components/schemas/OperationId" + } + }, + "additionalProperties": false + } + }, + "contentDescriptors": { + "Address": { + "name": "Address", + "summary": "Address", + "description": "A Address object", + "schema": { + "$ref": "#/components/schemas/Address" + } + }, + "AddressFilter": { + "name": "AddressFilter", + "summary": "Address filter", + "description": "A AddressFilter object", + "schema": { + "$ref": "#/components/schemas/AddressFilter" + } + }, + "AddressInfo": { + "name": "AddressInfo", + "summary": "Address information", + "description": "A AddressInfo object", + "schema": { + "$ref": "#/components/schemas/AddressInfo" + } + }, + "BlockId": { + "name": "BlockId", + "summary": "BlockId", + "description": "A BlockId object", + "schema": { + "$ref": "#/components/schemas/BlockId" + } + }, + "BlockInfo": { + "name": "BlockInfo", + "summary": "BlockInfo", + "description": "A BlockInfo object", + "schema": { + "$ref": "#/components/schemas/BlockInfo" + } + }, + "BlockHeader": { + "name": "BlockHeader", + "summary": "BlockHeader", + "description": "A BlockHeader object", + "schema": { + "$ref": "#/components/schemas/WrappedHeader" + } + }, + "Clique": { + "name": "Clique", + "summary": "Clique", + "description": "A Clique object", + "schema": { + "$ref": "#/components/schemas/Clique" + } + }, + "DataStoreEntry": { + "name": "DataStoreEntry", + "summary": "DataStoreEntry", + "description": "A DataStoreEntry object", + "schema": { + "$ref": "#/components/schemas/DataStoreEntry" + } + }, + "DatastoreEntryInput": { + "name": "DatastoreEntryInput", + "summary": "DatastoreEntryInput", + "description": "A DatastoreEntryInput object", + "schema": { + "$ref": "#/components/schemas/DatastoreEntryInput" + } + }, + "DataStoreEntryOutput": { + "name": "DataStoreEntryOutput", + "summary": "DataStoreEntryOutput", + "description": "A DataStoreEntryOutput object", + "schema": { + "$ref": "#/components/schemas/DataStoreEntryOutput" + } + }, + "EndorsementInfo": { + "name": "EndorsementInfo", + "summary": "EndorsementInfo", + "description": "A EndorsementInfo object", + "schema": { + "$ref": "#/components/schemas/EndorsementInfo" + } + }, + "ExecuteReadOnlyResponse": { + "name": "ExecuteReadOnlyResponse", + "summary": "ExecuteReadOnlyResponse", + "description": "A ExecuteReadOnlyResponse object", + "schema": { + "$ref": "#/components/schemas/ExecuteReadOnlyResponse" + } + }, + "EventFilter": { + "name": "EventFilter", + "summary": "EventFilter", + "description": "A EventFilter object", + "schema": { + "$ref": "#/components/schemas/EventFilter" + } + }, + "FilledBlockInfo": { + "name": "FilledBlockInfo", + "summary": "FilledBlockInfo", + "description": "A FilledBlockInfo object", + "schema": { + "$ref": "#/components/schemas/FilledBlockInfo" + } + }, + "GraphInterval": { + "name": "GraphInterval", + "summary": "GraphInterval", + "description": "A GraphInterval object", + "schema": { + "$ref": "#/components/schemas/GraphInterval" + } + }, + "NodeStatus": { + "name": "NodeStatus", + "summary": "Node status", + "description": "A NodeStatus object", + "schema": { + "$ref": "#/components/schemas/NodeStatus" + } + }, + "Operation": { + "name": "Operation", + "summary": "Operation", + "description": "A Operation object", + "schema": { + "$ref": "#/components/schemas/Operation" + } + }, + "OperationId": { + "name": "OperationId", + "summary": "OperationId", + "description": "A OperationId object", + "schema": { + "$ref": "#/components/schemas/OperationId" + } + }, + "OperationInput": { + "name": "OperationInput", + "summary": "OperationInput", + "description": "A OperationInput object", + "schema": { + "$ref": "#/components/schemas/OperationInput" + } + }, + "OperationInfo": { + "name": "OperationInfo", + "summary": "OperationInfo", + "description": "A OperationInfo object", + "schema": { + "$ref": "#/components/schemas/OperationInfo" + } + }, + "OperationType": { + "name": "OperationType", + "summary": "OperationType", + "description": "A OperationType object", + "schema": { + "$ref": "#/components/schemas/OperationType" + } + }, + "PagedVecStaker": { + "name": "PagedVecStaker", + "summary": "PagedVecStaker", + "description": "A PagedVecStaker object", + "schema": { + "$ref": "#/components/schemas/PagedVecStaker" + } + }, + "PageRequest": { + "name": "PageRequest", + "summary": "PageRequest", + "description": "An Page request parameter, which contains limit and offset properties.", + "schema": { + "$ref": "#/components/schemas/PageRequest" + } + }, + "PubkeySig": { + "name": "PubkeySig", + "summary": "PubkeySig", + "description": "A PubkeySig object", + "schema": { + "$ref": "#/components/schemas/PubkeySig" + } + }, + "PrivateKey": { + "name": "PrivateKey", + "summary": "PrivateKey", + "description": "A PrivateKey object", + "schema": { + "$ref": "#/components/schemas/PrivateKey" + } + }, + "ReadOnlyCall": { + "name": "ReadOnlyCall", + "summary": "ReadOnlyCall", + "description": "A ReadOnlyCall object", + "schema": { + "$ref": "#/components/schemas/ReadOnlyCall" + } + }, + "SCOutputEvent": { + "name": "SCOutputEvent", + "summary": "SCOutputEvent", + "description": "A SCOutputEvent object", + "schema": { + "$ref": "#/components/schemas/SCOutputEvent" + } + }, + "Staker": { + "name": "Staker", + "summary": "Staker", + "description": "A Staker object. A tuple which contains (address, active_rolls)", + "schema": { + "$ref": "#/components/schemas/Staker" + } + }, + "Version": { + "name": "Version", + "summary": "Version", + "description": "A Version object", + "schema": { + "$ref": "#/components/schemas/Version" + } + } + } + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index f5eaccbb..a71c7eee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12309 +1,12433 @@ { - "name": "massa-web3-workspace", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "massa-web3-workspace", - "version": "1.0.0", - "workspaces": [ - "packages/web3-utils", - "packages/massa-web3" - ], - "devDependencies": { - "@massalabs/eslint-config": "^0.0.10", - "@types/jest": "^29.5.5", - "@typescript-eslint/eslint-plugin": "^6.20.0", - "bignumber.js": "^9.1.1", - "eslint": "^8.56.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-jsdoc": "^48.0.4", - "husky": "^8.0.0", - "lint-staged": "^15.0.1", - "prettier": "^3.2.4", - "typescript": "^4.9.5" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", - "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.7", - "@babel/parser": "^7.23.6", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-validator-option": "^7.23.5", - "browserslist": "^4.22.2", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.7.tgz", - "integrity": "sha512-xCoqR/8+BoNnXOY7RVSgv6X+o7pmT5q1d+gGcRlXYkI+9B31glE4jeejhKVpA04O1AtzOt7OSQ6VYKP5FcRl9g==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.4.tgz", - "integrity": "sha512-QcJMILQCu2jm5TFPGA3lCpJJTeEP+mqeXooG/NZbg/h5FTFi6V0+99ahlRsW8/kRLyb24LZVCCiclDedhLKcBA==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", - "dev": true, - "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", - "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.7", - "@babel/types": "^7.23.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", - "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.7.tgz", - "integrity": "sha512-PdxEpL71bJp1byMG0va5gwQcXHxuEYC/BgI/e88mGTtohbZN28O5Yit0Plkkm/dBzCF/BxmbNcses1RH1T+urA==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", - "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20", - "@babel/helper-split-export-declaration": "^7.22.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", - "dev": true, - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", - "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", - "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz", - "integrity": "sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==", - "dev": true, - "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", - "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", - "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.23.3", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.23.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.20" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", - "dev": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", - "dev": true, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.8.tgz", - "integrity": "sha512-lFlpmkApLkEP6woIKprO6DO60RImpatTQKtz4sUcDjVcK8M8mQ4sZsuxaTMNOZf0sqAq/ReYW1ZBHnOQwKpLWA==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.7", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.4", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.8", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.4", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.6", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.4", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.3", - "@babel/plugin-transform-modules-umd": "^7.23.3", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", - "@babel/plugin-transform-numeric-separator": "^7.23.4", - "@babel/plugin-transform-object-rest-spread": "^7.23.4", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.4", - "@babel/plugin-transform-optional-chaining": "^7.23.4", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.4", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.7", - "babel-plugin-polyfill-corejs3": "^0.8.7", - "babel-plugin-polyfill-regenerator": "^0.5.4", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, - "node_modules/@babel/runtime": { - "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz", - "integrity": "sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", - "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.6", - "@babel/types": "^7.23.6", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "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, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/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, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.37.1", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.37.1.tgz", - "integrity": "sha512-5vxWJ1gEkEF0yRd0O+uK6dHJf7adrxwQSX8PuRiPfFSAbNLnY0ZJfXaZucoz14Jj2N11xn2DnlEPwWRpYpvRjg==", - "dev": true, - "dependencies": { - "comment-parser": "1.3.1", - "esquery": "^1.5.0", - "jsdoc-type-pratt-parser": "~4.0.0" - }, - "engines": { - "node": "^14 || ^16 || ^17 || ^18 || ^19 || ^20" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/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 - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/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, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "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, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@hicaru/bearby.js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@hicaru/bearby.js/-/bearby.js-0.5.8.tgz", - "integrity": "sha512-K6mLazzHkDNF5Qmx5iQ4+UqmvBJxtuwg1ZHEDEvOKB1SV/QNuKJ54/HRlLMqJE0RHam2zP7s++RlnMZUIfWgGg==" - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/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, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "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, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", - "dev": true - }, - "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, - "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/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/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 - }, - "node_modules/@isaacs/cliui/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, - "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/@isaacs/cliui/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, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/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, - "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/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/console/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/console/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, - "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/@jest/console/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/console/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 - }, - "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/core/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/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, - "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/@jest/core/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/core/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 - }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", - "dev": true, - "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.6.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/reporters/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/reporters/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, - "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/@jest/reporters/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/reporters/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 - }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz", - "integrity": "sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/transform/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/transform/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, - "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/@jest/transform/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/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 - }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/types/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/types/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, - "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/@jest/types/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/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 - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@lukeed/csprng": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", - "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@massalabs/eslint-config": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/@massalabs/eslint-config/-/eslint-config-0.0.10.tgz", - "integrity": "sha512-9+ibJr9dEMMdb6q6S+9+1sPlA3jxip+OqP7An9GY40A2PwowJ71yVtVP/LFONOdsJj3pUmPwwD15ExbKZ1UYOg==", - "dev": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "^5.47.1", - "@typescript-eslint/parser": "^5.29.0", - "eslint": ">= 8", - "eslint-config-google": "^0.14.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jsdoc": "^41.1.1", - "eslint-plugin-json": "^3.1.0", - "eslint-plugin-tsdoc": "^0.2.17" - } - }, - "node_modules/@massalabs/eslint-config/node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@massalabs/eslint-config/node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@massalabs/eslint-config/node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@massalabs/eslint-config/node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@massalabs/eslint-config/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@massalabs/eslint-config/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@massalabs/eslint-config/node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@massalabs/eslint-config/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@massalabs/eslint-config/node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/@massalabs/eslint-config/node_modules/eslint-plugin-jsdoc": { - "version": "41.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-41.1.2.tgz", - "integrity": "sha512-MePJXdGiPW7AG06CU5GbKzYtKpoHwTq1lKijjq+RwL/cQkZtBZ59Zbv5Ep0RVxSMnq6242249/n+w4XrTZ1Afg==", - "dev": true, - "dependencies": { - "@es-joy/jsdoccomment": "~0.37.0", - "are-docs-informative": "^0.0.2", - "comment-parser": "1.3.1", - "debug": "^4.3.4", - "escape-string-regexp": "^4.0.0", - "esquery": "^1.5.0", - "semver": "^7.3.8", - "spdx-expression-parse": "^3.0.1" - }, - "engines": { - "node": "^14 || ^16 || ^17 || ^18 || ^19" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@massalabs/eslint-config/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@massalabs/eslint-config/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@massalabs/massa-web3": { - "resolved": "packages/massa-web3", - "link": true - }, - "node_modules/@massalabs/wallet-provider": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@massalabs/wallet-provider/-/wallet-provider-2.0.0.tgz", - "integrity": "sha512-3BKtYszSfKMOi85cxOB1q60uiMWYmdteV28stx2NjT42VtSyKOuWiTJq4KaWbf3ov+fkg+/HknXdl5bhDghbSQ==", - "dependencies": { - "@hicaru/bearby.js": "^0.5.7", - "@massalabs/web3-utils": "^1.4.9-dev", - "axios": "^0.28.0", - "bs58check": "^3.0.1", - "buffer": "^6.0.3", - "uid": "^2.0.1" - }, - "optionalDependencies": { - "bufferutil": "^4.0.7", - "utf-8-validate": "^6.0.2" - } - }, - "node_modules/@massalabs/wallet-provider/node_modules/axios": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.28.1.tgz", - "integrity": "sha512-iUcGA5a7p0mVb4Gm/sy+FSECNkPFT4y7wt6OM/CDpO/OnNCvSs3PoMG8ibrC9jRoGYU0gUK5pXVC4NPXq6lHRQ==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/@massalabs/web3-utils": { - "resolved": "packages/web3-utils", - "link": true - }, - "node_modules/@microsoft/tsdoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", - "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", - "dev": true - }, - "node_modules/@microsoft/tsdoc-config": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", - "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", - "dev": true, - "dependencies": { - "@microsoft/tsdoc": "0.14.2", - "ajv": "~6.12.6", - "jju": "~1.4.0", - "resolve": "~1.19.0" - } - }, - "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "dev": true, - "dependencies": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/@noble/ed25519": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.3.tgz", - "integrity": "sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] - }, - "node_modules/@noble/hashes": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz", - "integrity": "sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "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, - "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, - "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, - "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, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@rauschma/stringio": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@rauschma/stringio/-/stringio-1.4.0.tgz", - "integrity": "sha512-3uor2f/MXZkmX5RJf8r+OC3WvZVzpSme0yyL0rQDPEnatE02qRcqwEwnsgpgriEck0S/n4vWtUd6tTtrJwk45Q==", - "dev": true, - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/@rauschma/stringio/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "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 - }, - "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 - }, - "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 - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", - "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/bn.js": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.5.tgz", - "integrity": "sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "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 - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.5.11", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz", - "integrity": "sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==", - "dev": true, - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/jsdom": { - "version": "20.0.1", - "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", - "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/tough-cookie": "*", - "parse5": "^7.0.0" - } - }, - "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 - }, - "node_modules/@types/node": { - "version": "18.19.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.5.tgz", - "integrity": "sha512-22MG6T02Hos2JWfa1o5jsIByn+bc5iOt1IS4xyg6OG68Bu+wMonVZzdrgCw693++rpLE9RUT/Bx15BeDzO0j+g==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/secp256k1": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.6.tgz", - "integrity": "sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", - "dev": true - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true - }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "dev": true - }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.20.0.tgz", - "integrity": "sha512-fTwGQUnjhoYHeSF6m5pWNkzmDDdsKELYrOBxhjMrofPqCkoC2k3B2wvGHFxa1CTIqkEn88nlW1HVMztjo2K8Hg==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.20.0", - "@typescript-eslint/type-utils": "6.20.0", - "@typescript-eslint/utils": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, - "peer": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, - "peer": true, - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.20.0.tgz", - "integrity": "sha512-p4rvHQRDTI1tGGMDFQm+GtxP1ZHyAh64WANVoyEcNMpaTFn3ox/3CcgtIlELnRfKzSs/DwYlDccJEtr3O6qBvA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.20.0.tgz", - "integrity": "sha512-qnSobiJQb1F5JjN0YDRPHruQTrX7ICsmltXhkV536mp4idGAYrIyr47zF/JmkJtEcAVnIz4gUYJ7gOZa6SmN4g==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "6.20.0", - "@typescript-eslint/utils": "6.20.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.20.0.tgz", - "integrity": "sha512-MM9mfZMAhiN4cOEcUOEx+0HmuaW3WBfukBZPCfwSqFnQy0grXYtngKCqpQN339X3RrwtzspWJrpbrupKYUSBXQ==", - "dev": true, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.20.0.tgz", - "integrity": "sha512-RnRya9q5m6YYSpBN7IzKu9FmLcYtErkDkc8/dKv81I9QiLLtVBHrjz+Ev/crAqgMNW2FCsoZF4g2QUylMnJz+g==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/visitor-keys": "6.20.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.20.0.tgz", - "integrity": "sha512-/EKuw+kRu2vAqCoDwDCBtDRU6CTKbUmwwI7SH7AashZ+W+7o8eiyy6V2cdOqN49KsTcASWsC5QeghYuRDTyOOg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.20.0", - "@typescript-eslint/types": "6.20.0", - "@typescript-eslint/typescript-estree": "6.20.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.20.0.tgz", - "integrity": "sha512-E8Cp98kRe4gKHjJD4NExXKz/zOJ1A2hhZc+IMVD6i7w4yjIvh6VyuRI0gRtxAsXtoC35uGMaQ9rjI2zJaXDEAw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "6.20.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@web3pack/base-x": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@web3pack/base-x/-/base-x-1.0.2.tgz", - "integrity": "sha512-P3XgVnEQ1QFyUTmHzT1sXNprLyxE1aG8WAnk5/Fj+3j4AmsK4dRfMdV3t/aIdYP3i1KvjPRkQJhFXGpxUc+M8A==" - }, - "node_modules/@web3pack/base58-check": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@web3pack/base58-check/-/base58-check-1.0.3.tgz", - "integrity": "sha512-+s4HKOnJbIkj45jhGfSxgWkKsjBENuNbfqASPTLPy/yjGGv/jGCxzFCl0fb4gudV3x0gS50gLpJsC8qQ6cV1gw==", - "dependencies": { - "@web3pack/base-x": "^1.0.1", - "buffer": "^6.0.3", - "hash.js": "^1.1.7" - } - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead", - "dev": true - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", - "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", - "dev": true, - "dependencies": { - "acorn": "^8.1.0", - "acorn-walk": "^8.0.2" - } - }, - "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, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", - "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.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, - "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/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-sequence-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", - "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", - "dev": true - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/are-docs-informative": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", - "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "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, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", - "dependencies": { - "follow-redirects": "^1.14.8" - } - }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-jest/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/babel-jest/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, - "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/babel-jest/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/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 - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.7.tgz", - "integrity": "sha512-LidDk/tEGDfuHW2DWh/Hgo4rmnw3cduK6ZkOI1NPFceSK3n/yAGeOsNT7FLnSGHkXj3RHGSEVkN3FsCTY6w2CQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.4", - "semver": "^6.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.7.tgz", - "integrity": "sha512-KyDvZYxAzkC0Aj2dAPyDzi2Ym15e5JKZSK+maI7NAwSqofvuFglbSsxE7wUOvTg9oFVnHMzVzBKcqEb4PJgtOA==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.4", - "core-js-compat": "^3.33.1" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.4.tgz", - "integrity": "sha512-S/x2iOCvDaCASLYsOOgWOq4bCfKYVqvO/uxjkaYyZ3rVsVE3CeAI/c84NpyuBBymEgNvHgjEot3a9/Z/kXvqsg==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.4" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "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 - }, - "node_modules/base-x": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", - "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "engines": { - "node": "*" - } - }, - "node_modules/bip39": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", - "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", - "dependencies": { - "@noble/hashes": "^1.2.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "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" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bs58": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", - "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", - "dependencies": { - "base-x": "^4.0.0" - } - }, - "node_modules/bs58check": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz", - "integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==", - "dependencies": { - "@noble/hashes": "^1.2.0", - "bs58": "^5.0.0" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/bufferutil": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", - "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001576", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz", - "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", - "dev": true - }, - "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dev": true, - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", - "dev": true, - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true - }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", - "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", - "dev": true, - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate/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, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "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, - "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-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cliui/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/cliui/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 - }, - "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, - "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/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/comment-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", - "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", - "dev": true, - "engines": { - "node": ">= 12.0.0" - } - }, - "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 - }, - "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 - }, - "node_modules/core-js-compat": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.35.0.tgz", - "integrity": "sha512-5blwFAddknKeNgsjBzilkdQ0+YK8L1PfqPYq40NOYMYFSS38qj+hpTcLLWwpIwA2A5bje/x5jmVn2tzUMg9IVw==", - "dev": true, - "dependencies": { - "browserslist": "^4.22.2" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/create-jest/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/create-jest/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, - "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/create-jest/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/create-jest/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 - }, - "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 - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" - }, - "node_modules/cssom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", - "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz", - "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==", - "dev": true, - "dependencies": { - "rrweb-cssom": "^0.6.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/data-urls": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz", - "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==", - "dev": true, - "dependencies": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true - }, - "node_modules/dedent": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", - "integrity": "sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==", - "dev": true, - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "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 - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/domexception": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", - "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", - "deprecated": "Use your platform's native DOMException instead", - "dev": true, - "dependencies": { - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=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 - }, - "node_modules/electron-to-chromium": { - "version": "1.4.625", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.625.tgz", - "integrity": "sha512-DENMhh3MFgaPDoXWrVIqSPInQoLImywfCwrSmVl3cf9QHzoZSiutHwGaB/Ql3VkqcQV30rzgdM+BjKqBAJxo5Q==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "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 - }, - "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "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, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", - "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-google": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", - "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-jsdoc": { - "version": "48.0.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.0.4.tgz", - "integrity": "sha512-A0cH+5svWPXzGZszBjXA1t0aAqVGS+/x3i02KFmb73rU0iMLnadEcVWcD/dGBZHIfAMKr3YpWh58f6wn4N909w==", - "dev": true, - "dependencies": { - "@es-joy/jsdoccomment": "~0.41.0", - "are-docs-informative": "^0.0.2", - "comment-parser": "1.4.1", - "debug": "^4.3.4", - "escape-string-regexp": "^4.0.0", - "esquery": "^1.5.0", - "is-builtin-module": "^3.2.1", - "semver": "^7.5.4", - "spdx-expression-parse": "^4.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-jsdoc/node_modules/@es-joy/jsdoccomment": { - "version": "0.41.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.41.0.tgz", - "integrity": "sha512-aKUhyn1QI5Ksbqcr3fFJj16p99QdjUxXAEuFst1Z47DRyoiMwivIH9MV/ARcJOCXVjPfjITciej8ZD2O/6qUmw==", - "dev": true, - "dependencies": { - "comment-parser": "1.4.1", - "esquery": "^1.5.0", - "jsdoc-type-pratt-parser": "~4.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/eslint-plugin-jsdoc/node_modules/comment-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", - "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", - "dev": true, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/eslint-plugin-jsdoc/node_modules/spdx-expression-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", - "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/eslint-plugin-json": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-3.1.0.tgz", - "integrity": "sha512-MrlG2ynFEHe7wDGwbUuFPsaT2b1uhuEFhJ+W1f1u+1C2EkXmTYJp4B1aAdQQ8M+CC3t//N/oRKiIVw14L2HR1g==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21", - "vscode-json-languageservice": "^4.1.6" - }, - "engines": { - "node": ">=12.0" - } - }, - "node_modules/eslint-plugin-tsdoc": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/eslint-plugin-tsdoc/-/eslint-plugin-tsdoc-0.2.17.tgz", - "integrity": "sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==", - "dev": true, - "dependencies": { - "@microsoft/tsdoc": "0.14.2", - "@microsoft/tsdoc-config": "0.16.2" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "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, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/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 - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/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, - "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/eslint/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/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 - }, - "node_modules/eslint/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, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/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, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint/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, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "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, - "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, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.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 - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "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.4" - }, - "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, - "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 - }, - "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 - }, - "node_modules/fastq": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", - "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/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, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "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==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "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, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "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, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/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, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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 - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", - "dependencies": { - "get-intrinsic": "^1.2.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "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 - }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/husky": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", - "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", - "dev": true, - "bin": { - "husky": "lib/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/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, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/internal-slot": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", - "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.2", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "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, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", - "dev": true, - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", - "dev": true, - "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/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, - "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/jest-circus/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-circus/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 - }, - "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", - "dev": true, - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-cli/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-cli/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, - "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/jest-cli/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-cli/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 - }, - "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/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, - "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/jest-config/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-config/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 - }, - "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-diff/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/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, - "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/jest-diff/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/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 - }, - "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-each/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/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, - "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/jest-each/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-each/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 - }, - "node_modules/jest-environment-jsdom": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz", - "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/jsdom": "^20.0.0", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0", - "jsdom": "^20.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jest-environment-jsdom/node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "node_modules/jest-environment-jsdom/node_modules/data-urls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", - "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/jest-environment-jsdom/node_modules/jsdom": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", - "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.6", - "acorn": "^8.8.1", - "acorn-globals": "^7.0.0", - "cssom": "^0.5.0", - "cssstyle": "^2.3.0", - "data-urls": "^3.0.2", - "decimal.js": "^10.4.2", - "domexception": "^4.0.0", - "escodegen": "^2.0.0", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.2", - "parse5": "^7.1.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^4.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0", - "ws": "^8.11.0", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jest-environment-jsdom/node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "dev": true, - "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", - "dev": true, - "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-matcher-utils/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/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, - "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/jest-matcher-utils/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-matcher-utils/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 - }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-message-util/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/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, - "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/jest-message-util/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-message-util/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 - }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", - "dev": true, - "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-resolve/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-resolve/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, - "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/jest-resolve/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-resolve/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 - }, - "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runner/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runner/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, - "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/jest-runner/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runner/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 - }, - "node_modules/jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-runtime/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runtime/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, - "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/jest-runtime/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runtime/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 - }, - "node_modules/jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/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, - "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/jest-snapshot/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-snapshot/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 - }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-util/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, - "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/jest-util/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/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 - }, - "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, - "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-validate/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-validate/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, - "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/jest-validate/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-validate/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 - }, - "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", - "dev": true, - "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-watcher/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watcher/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, - "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/jest-watcher/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watcher/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 - }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-worker/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, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "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 - }, - "node_modules/js-base64": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.5.tgz", - "integrity": "sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdoc-type-pratt-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", - "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", - "dev": true, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/jsdom": { - "version": "21.1.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.2.tgz", - "integrity": "sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.6", - "acorn": "^8.8.2", - "acorn-globals": "^7.0.0", - "cssstyle": "^3.0.0", - "data-urls": "^4.0.0", - "decimal.js": "^10.4.3", - "domexception": "^4.0.0", - "escodegen": "^2.0.0", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.4", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.6.0", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^4.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^12.0.1", - "ws": "^8.13.0", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "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 - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "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 - }, - "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 - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, - "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, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/lint-staged": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.0.tgz", - "integrity": "sha512-TFZzUEV00f+2YLaVPWBWGAMq7So6yQx+GG8YRMDeOEIf95Zn5RyiLMsEiX4KTNl9vq/w+NqRJkLA1kPIo15ufQ==", - "dev": true, - "dependencies": { - "chalk": "5.3.0", - "commander": "11.1.0", - "debug": "4.3.4", - "execa": "8.0.1", - "lilconfig": "3.0.0", - "listr2": "8.0.0", - "micromatch": "4.0.5", - "pidtree": "0.6.0", - "string-argv": "0.3.2", - "yaml": "2.3.4" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "engines": { - "node": ">=18.12.0" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" - } - }, - "node_modules/lint-staged/node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/lint-staged/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/lint-staged/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/lint-staged/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/npm-run-path": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", - "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/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, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/lint-staged/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/listr2": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.0.tgz", - "integrity": "sha512-u8cusxAcyqAiQ2RhYvV7kRKNLgUvtObIbhOX2NCXqvp1UU32xIg5CT22ykS2TPKJXZWJwtK3IKLiqAGlGNE+Zg==", - "dev": true, - "dependencies": { - "cli-truncate": "^4.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^6.0.0", - "rfdc": "^1.3.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "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 - }, - "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, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/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, - "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/log-symbols/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/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 - }, - "node_modules/log-update": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", - "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", - "dev": true, - "dependencies": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/ansi-escapes": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", - "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", - "dev": true, - "dependencies": { - "type-fest": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/log-update/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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", - "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", - "dev": true, - "dependencies": { - "get-east-asian-width": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", - "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/log-update/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, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/log-update/node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "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 - }, - "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, - "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 - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true, - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "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, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "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 - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-gyp-build": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", - "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", - "optional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true - }, - "node_modules/node-ts": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/node-ts/-/node-ts-5.1.2.tgz", - "integrity": "sha512-ihRzS31ZbknFzXFkF4j9R3HJV1cRPTjyYzeRaEFyXv5DhWKGD+QNTJ+My5WiOc0kozEPjwRBsKh+g92hPyTNnQ==", - "dev": true, - "dependencies": { - "@rauschma/stringio": "^1.4.0", - "@types/node": "^16.4.13" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/node-ts/node_modules/@types/node": { - "version": "16.18.70", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.70.tgz", - "integrity": "sha512-8eIk20G5VVVQNZNouHjLA2b8utE2NvGybLjMaF4lyhA9uhGwnmXF8o+icdXKGSQSNANJewXva/sFUoZLwAaYAg==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - }, - "bin": { - "npm-run-all": "bin/npm-run-all/index.js", - "run-p": "bin/run-p/index.js", - "run-s": "bin/run-s/index.js" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/npm-run-all/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/npm-run-all/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/npm-run-all/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/npm-run-all/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/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, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/npm-run-all/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/pidtree": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", - "dev": true, - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/npm-run-all/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/npm-run-all/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-all/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-all/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", - "dev": true - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ora/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, - "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/ora/node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ora/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 - }, - "node_modules/ora/node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dev": true, - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "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 - }, - "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pidtree": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", - "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", - "dev": true, - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz", - "integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "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, - "engines": { - "node": ">=6" - } - }, - "node_modules/pure-rand": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", - "integrity": "sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ] - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "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" - } - ] - }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", - "dev": true, - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dev": true, - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dev": true, - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, - "node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dev": true, - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", - "dev": true - }, - "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" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=v12.22.7" - } - }, - "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, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/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, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/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 - }, - "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/shiki": { - "version": "0.14.7", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", - "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", - "dev": true, - "dependencies": { - "ansi-sequence-parser": "^1.1.0", - "jsonc-parser": "^3.2.0", - "vscode-oniguruma": "^1.7.0", - "vscode-textmate": "^8.0.0" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", - "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", - "dev": true - }, - "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 - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "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, - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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, - "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": { - "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, - "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/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.padend": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz", - "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/test-exclude/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, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "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, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", - "dev": true, - "dependencies": { - "punycode": "^2.3.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", - "dev": true, - "engines": { - "node": ">=16.13.0" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-jest": { - "version": "29.1.1", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz", - "integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "^7.5.3", - "yargs-parser": "^21.0.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-loader": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ts-loader/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, - "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/ts-loader/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ts-loader/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 - }, - "node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "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, - "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/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "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, - "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, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedoc": { - "version": "0.23.28", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.28.tgz", - "integrity": "sha512-9x1+hZWTHEQcGoP7qFmlo4unUoVJLB0H/8vfO/7wqTnZxg4kPuji9y3uRzEu0ZKez63OJAUmiGhUrtukC6Uj3w==", - "dev": true, - "dependencies": { - "lunr": "^2.3.9", - "marked": "^4.2.12", - "minimatch": "^7.1.3", - "shiki": "^0.14.1" - }, - "bin": { - "typedoc": "bin/typedoc" - }, - "engines": { - "node": ">= 14.14" - }, - "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x" - } - }, - "node_modules/typedoc/node_modules/minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/uid": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", - "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==", - "dependencies": { - "@lukeed/csprng": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.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, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/utf-8-validate": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-6.0.3.tgz", - "integrity": "sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "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 - }, - "node_modules/v8-to-istanbul": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", - "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", - "dev": true, - "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/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/varint": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", - "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" - }, - "node_modules/vscode-json-languageservice": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz", - "integrity": "sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA==", - "dev": true, - "dependencies": { - "jsonc-parser": "^3.0.0", - "vscode-languageserver-textdocument": "^1.0.3", - "vscode-languageserver-types": "^3.16.0", - "vscode-nls": "^5.0.0", - "vscode-uri": "^3.0.3" - } - }, - "node_modules/vscode-languageserver-textdocument": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz", - "integrity": "sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==", - "dev": true - }, - "node_modules/vscode-languageserver-types": { - "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", - "dev": true - }, - "node_modules/vscode-nls": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.2.0.tgz", - "integrity": "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==", - "dev": true - }, - "node_modules/vscode-oniguruma": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", - "dev": true - }, - "node_modules/vscode-textmate": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", - "dev": true - }, - "node_modules/vscode-uri": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", - "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", - "dev": true - }, - "node_modules/w3c-xmlserializer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", - "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", - "dev": true, - "dependencies": { - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "dev": true, - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-url": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", - "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", - "dev": true, - "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=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, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "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, - "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-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi-cjs/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 - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.0.0.tgz", - "integrity": "sha512-GPQHj7row82Hjo9hKZieKcHIhaAIKOJvFSIZXuCU9OASVZrMNUaZuz++SPVrBjnLsnk4k+z9f2EIypgxf2vNFw==", - "dev": true, - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrap-ansi/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, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "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, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", - "dev": true, - "engines": { - "node": ">= 14" - } - }, - "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, - "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, - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/massa-web3": { - "name": "@massalabs/massa-web3", - "version": "4.0.4", - "license": "MIT", - "dependencies": { - "@massalabs/wallet-provider": "^2.0.0", - "@massalabs/web3-utils": "^1.4.11", - "@noble/ed25519": "^1.7.3", - "@noble/hashes": "^1.2.0", - "@types/ws": "^8.5.4", - "@web3pack/base58-check": "^1.0.3", - "axios": "^0.26.1", - "bignumber.js": "^9.1.1", - "bip39": "^3.0.4", - "bs58check": "^3.0.1", - "buffer": "^6.0.3", - "crypto-js": "^4.1.1", - "dotenv": "^16.0.3", - "js-base64": "^3.7.5", - "string_decoder": "^1.3.0", - "tslib": "^2.5.2", - "util": "^0.12.5", - "varint": "^6.0.0" - }, - "devDependencies": { - "@babel/preset-env": "^7.22.15", - "@types/bn.js": "^5.1.1", - "@types/jest": "^29.5.5", - "@types/node": "^18.13.0", - "@types/secp256k1": "^4.0.3", - "@typescript-eslint/eslint-plugin": "^5.52.0", - "@typescript-eslint/parser": "^5.52.0", - "babel-jest": "^29.7.0", - "chalk": "^4.1.0", - "jest": "^29.5.0", - "jest-environment-jsdom": "^29.5.0", - "jsdom": "^21.1.1", - "node-ts": "^5.1.2", - "npm-run-all": "^4.1.5", - "ora": "^5.1.0", - "rimraf": "^5.0.1", - "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2", - "ts-node": "^10.9.1", - "typedoc": "^0.25.7", - "typescript": "^4.9.5" - }, - "optionalDependencies": { - "bufferutil": "^4.0.7", - "utf-8-validate": "^6.0.2" - } - }, - "packages/massa-web3/node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/massa-web3/node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/massa-web3/node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/massa-web3/node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/massa-web3/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/massa-web3/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/massa-web3/node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "packages/massa-web3/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/massa-web3/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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "packages/massa-web3/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, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "packages/massa-web3/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, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "packages/massa-web3/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 - }, - "packages/massa-web3/node_modules/eslint-scope": { - "version": "5.1.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "packages/massa-web3/node_modules/estraverse": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "packages/massa-web3/node_modules/typedoc": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.7.tgz", - "integrity": "sha512-m6A6JjQRg39p2ZVRIN3NKXgrN8vzlHhOS+r9ymUYtcUP/TIQPvWSq7YgE5ZjASfv5Vd5BW5xrir6Gm2XNNcOow==", - "dev": true, - "dependencies": { - "lunr": "^2.3.9", - "marked": "^4.3.0", - "minimatch": "^9.0.3", - "shiki": "^0.14.7" - }, - "bin": { - "typedoc": "bin/typedoc" - }, - "engines": { - "node": ">= 16" - }, - "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x" - } - }, - "packages/web3-utils": { - "name": "@massalabs/web3-utils", - "version": "1.4.11", - "license": "MIT", - "dependencies": { - "bignumber.js": "^9.1.2", - "buffer": "^6.0.3", - "events": "^3.3.0", - "string_decoder": "^1.3.0" - }, - "devDependencies": { - "@types/jest": "^29.5.5", - "@typescript-eslint/eslint-plugin": "^5.52.0", - "@typescript-eslint/parser": "^5.52.0", - "jest": "^29.5.0", - "jest-environment-jsdom": "^29.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^5.0.1", - "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2", - "ts-node": "^10.9.1", - "tslib": "^2.6.1", - "typedoc": "^0.23.25", - "typescript": "^4.9.5", - "util": "^0.12.5" - } - }, - "packages/web3-utils/node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/web3-utils/node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/web3-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/web3-utils/node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "packages/web3-utils/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/web3-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true + "name": "@massalabs/massa-web3", + "version": "5.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@massalabs/massa-web3", + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "@noble/ed25519": "^1.7.3", + "@noble/hashes": "^1.2.0", + "bs58check": "^4.0.0", + "decimal.js": "^10.4.3", + "dotenv": "^16.0.3", + "eventemitter3": "^5.0.1", + "lodash.isequal": "^4.5.0", + "secure-random": "^1.1.2", + "tslib": "^2.8.0", + "varint": "^6.0.0" + }, + "devDependencies": { + "@babel/preset-env": "^7.22.15", + "@open-rpc/typings": "^1.12.4", + "@types/jest": "^29.5.12", + "@types/node": "^20.12.13", + "@types/varint": "^6.0.3", + "@typescript-eslint/eslint-plugin": "^7.8.0", + "@typescript-eslint/parser": "^7.8.0", + "babel-jest": "^29.7.0", + "eslint": "^8.57.0", + "eslint-config-google": "^0.14.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-jsdoc": "^48.0.4", + "eslint-plugin-prettier": "^5.1.3", + "husky": "^9.0.11", + "is-ci": "^3.0.1", + "jest": "^29.5.0", + "jest-puppeteer": "^10.0.1", + "js-yaml": "^4.1.0", + "lint-staged": "^15.0.1", + "npm-run-all": "^4.1.5", + "prettier": "^3.2.4", + "puppeteer": "^22.6.3", + "rimraf": "^5.0.1", + "ts-interface-builder": "^0.3.3", + "ts-interface-checker": "^1.0.2", + "ts-jest": "^29.1.0", + "ts-node": "^10.9.1", + "typedoc": "^0.25.7", + "typescript": "^5.4.5", + "typescript-eslint": "^7.8.0", + "wait-for-expect": "^3.0.2" + }, + "optionalDependencies": { + "bufferutil": "^4.0.7", + "utf-8-validate": "^6.0.2" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.6.tgz", + "integrity": "sha512-ZJhac6FkEd1yhG2AHOmfcXG4ceoLltoCVJjN5XsWN9BifBQr+cHJbWi0h68HZuSORq+3WtJ2z0hwF2NG1b5kcA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.6", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.6.tgz", + "integrity": "sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.6.tgz", + "integrity": "sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.6", + "@babel/generator": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helpers": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/template": "^7.24.6", + "@babel/traverse": "^7.24.6", + "@babel/types": "^7.24.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.6.tgz", + "integrity": "sha512-S7m4eNa6YAPJRHmKsLHIDJhNAGNKoWNiWefz1MBbpnt8g9lvMDl1hir4P9bo/57bQEmuwEhnRU/AMWsD0G/Fbg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.6.tgz", + "integrity": "sha512-DitEzDfOMnd13kZnDqns1ccmftwJTS9DMkyn9pYTxulS7bZxUxpMly3Nf23QQ6NwA4UB8lAqjbqWtyvElEMAkg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.6.tgz", + "integrity": "sha512-+wnfqc5uHiMYtvRX7qu80Toef8BXeh4HHR1SPeonGb1SKPniNEd4a/nlaJJMv/OIEYvIVavvo0yR7u10Gqz0Iw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.6.tgz", + "integrity": "sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.6", + "@babel/helper-validator-option": "^7.24.6", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.6.tgz", + "integrity": "sha512-djsosdPJVZE6Vsw3kk7IPRWethP94WHGOhQTc67SNXE0ZzMhHgALw8iGmYS0TD1bbMM0VDROy43od7/hN6WYcA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-member-expression-to-functions": "^7.24.6", + "@babel/helper-optimise-call-expression": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.24.6.tgz", + "integrity": "sha512-C875lFBIWWwyv6MHZUG9HmRrlTDgOsLWZfYR0nW69gaKJNe0/Mpxx5r0EID2ZdHQkdUmQo2t0uNckTL08/1BgA==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.6.tgz", + "integrity": "sha512-Y50Cg3k0LKLMjxdPjIl40SdJgMB85iXn27Vk/qbHZCFx/o5XO3PSnpi675h1KEmmDb6OFArfd5SCQEQ5Q4H88g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.6.tgz", + "integrity": "sha512-xpeLqeeRkbxhnYimfr2PC+iA0Q7ljX/d1eZ9/inYbmfG2jpl8Lu3DyXvpOAnrS5kxkfOWJjioIMQsaMBXFI05w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.6.tgz", + "integrity": "sha512-SF/EMrC3OD7dSta1bLJIlrsVxwtd0UpjRJqLno6125epQMJ/kyFmpTT4pbvPbdQHzCHg+biQ7Syo8lnDtbR+uA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.6.tgz", + "integrity": "sha512-OTsCufZTxDUsv2/eDXanw/mUZHWOxSbEmC3pP8cgjcy5rgeVPWWMStnv274DV60JtHxTk0adT0QrCzC4M9NWGg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.6.tgz", + "integrity": "sha512-a26dmxFJBF62rRO9mmpgrfTLsAuyHk4e1hKTUkD/fcMfynt8gvEKwQPQDVxWhca8dHoDck+55DFt42zV0QMw5g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.6.tgz", + "integrity": "sha512-Y/YMPm83mV2HJTbX1Qh2sjgjqcacvOlhbzdCCsSlblOKjSYmQqEbO6rUniWQyRo9ncyfjT8hnUjlG06RXDEmcA==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-module-imports": "^7.24.6", + "@babel/helper-simple-access": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.6.tgz", + "integrity": "sha512-3SFDJRbx7KuPRl8XDUr8O7GAEB8iGyWPjLKJh/ywP/Iy9WOmEfMrsWbaZpvBu2HSYn4KQygIsz0O7m8y10ncMA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.6.tgz", + "integrity": "sha512-MZG/JcWfxybKwsA9N9PmtF2lOSFSEMVCpIRrbxccZFLJPrJciJdG/UhSh5W96GEteJI2ARqm5UAHxISwRDLSNg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.24.6.tgz", + "integrity": "sha512-1Qursq9ArRZPAMOZf/nuzVW8HgJLkTB9y9LfP4lW2MVp4e9WkLJDovfKBxoDcCk6VuzIxyqWHyBoaCtSRP10yg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-wrap-function": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.6.tgz", + "integrity": "sha512-mRhfPwDqDpba8o1F8ESxsEkJMQkUF8ZIWrAc0FtWhxnjfextxMWxr22RtFizxxSYLjVHDeMgVsRq8BBZR2ikJQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-member-expression-to-functions": "^7.24.6", + "@babel/helper-optimise-call-expression": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.6.tgz", + "integrity": "sha512-nZzcMMD4ZhmB35MOOzQuiGO5RzL6tJbsT37Zx8M5L/i9KSrukGXWTjLe1knIbb/RmxoJE9GON9soq0c0VEMM5g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.6.tgz", + "integrity": "sha512-jhbbkK3IUKc4T43WadP96a27oYti9gEf1LdyGSP2rHGH77kwLwfhO7TgwnWvxxQVmke0ImmCSS47vcuxEMGD3Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.6.tgz", + "integrity": "sha512-CvLSkwXGWnYlF9+J3iZUvwgAxKiYzK3BWuo+mLzD/MDGOZDj7Gq8+hqaOkMxmJwmlv0iu86uH5fdADd9Hxkymw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.6.tgz", + "integrity": "sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.6.tgz", + "integrity": "sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.6.tgz", + "integrity": "sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.6.tgz", + "integrity": "sha512-f1JLrlw/jbiNfxvdrfBgio/gRBk3yTAEJWirpAkiJG2Hb22E7cEYKHWo0dFPTv/niPovzIdPdEDetrv6tC6gPQ==", + "dev": true, + "dependencies": { + "@babel/helper-function-name": "^7.24.6", + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.6.tgz", + "integrity": "sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.6", + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.6.tgz", + "integrity": "sha512-2YnuOp4HAk2BsBrJJvYCbItHx0zWscI1C3zgWkz+wDyD9I7GIVrfnLyrR4Y1VR+7p+chAEcrgRQYZAGIKMV7vQ==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.6", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz", + "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.6.tgz", + "integrity": "sha512-bYndrJ6Ph6Ar+GaB5VAc0JPoP80bQCm4qon6JEzXfRl5QZyQ8Ur1K6k7htxWmPA5z+k7JQvaMUrtXlqclWYzKw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.6.tgz", + "integrity": "sha512-iVuhb6poq5ikqRq2XWU6OQ+R5o9wF+r/or9CeUyovgptz0UlnK4/seOQ1Istu/XybYjAhQv1FRSSfHHufIku5Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.6.tgz", + "integrity": "sha512-c8TER5xMDYzzFcGqOEp9l4hvB7dcbhcGjcLVwxWfe4P5DOafdwjsBJZKsmv+o3aXh7NhopvayQIovHrh2zSRUQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", + "@babel/plugin-transform-optional-chaining": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.6.tgz", + "integrity": "sha512-z8zEjYmwBUHN/pCF3NuWBhHQjJCrd33qAi8MgANfMrAvn72k2cImT8VjK9LJFu4ysOLJqhfkYYb3MvwANRUNZQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.6.tgz", + "integrity": "sha512-BE6o2BogJKJImTmGpkmOic4V0hlRRxVtzqxiSPa8TIFxyhi4EFjHm08nq1M4STK4RytuLMgnSz0/wfflvGFNOg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.6.tgz", + "integrity": "sha512-D+CfsVZousPXIdudSII7RGy52+dYRtbyKAZcvtQKq/NpsivyMVduepzcLqG5pMBugtMdedxdC8Ramdpcne9ZWQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.6.tgz", + "integrity": "sha512-lWfvAIFNWMlCsU0DRUun2GpFwZdGTukLaHJqRh1JRb80NdAP5Sb1HDHB5X9P9OtgZHQl089UzQkpYlBq2VTPRw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.6.tgz", + "integrity": "sha512-TzCtxGgVTEJWWwcYwQhCIQ6WaKlo80/B+Onsk4RRCcYqpYGFcG9etPW94VToGte5AAcxRrhjPUFvUS3Y2qKi4A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.6.tgz", + "integrity": "sha512-jSSSDt4ZidNMggcLx8SaKsbGNEfIl0PHx/4mFEulorE7bpYLbN0d3pDW3eJ7Y5Z3yPhy3L3NaPCYyTUY7TuugQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.6.tgz", + "integrity": "sha512-VEP2o4iR2DqQU6KPgizTW2mnMx6BG5b5O9iQdrW9HesLkv8GIA8x2daXBQxw1MrsIkFQGA/iJ204CKoQ8UcnAA==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-remap-async-to-generator": "^7.24.6", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.6.tgz", + "integrity": "sha512-NTBA2SioI3OsHeIn6sQmhvXleSl9T70YY/hostQLveWs0ic+qvbA3fa0kwAwQ0OA/XGaAerNZRQGJyRfhbJK4g==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-remap-async-to-generator": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.6.tgz", + "integrity": "sha512-XNW7jolYHW9CwORrZgA/97tL/k05qe/HL0z/qqJq1mdWhwwCM6D4BJBV7wAz9HgFziN5dTOG31znkVIzwxv+vw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.6.tgz", + "integrity": "sha512-S/t1Xh4ehW7sGA7c1j/hiOBLnEYCp/c2sEG4ZkL8kI1xX9tW2pqJTCHKtdhe/jHKt8nG0pFCrDHUXd4DvjHS9w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.6.tgz", + "integrity": "sha512-j6dZ0Z2Z2slWLR3kt9aOmSIrBvnntWjMDN/TVcMPxhXMLmJVqX605CBRlcGI4b32GMbfifTEsdEjGjiE+j/c3A==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.6.tgz", + "integrity": "sha512-1QSRfoPI9RoLRa8Mnakc6v3e0gJxiZQTYrMfLn+mD0sz5+ndSzwymp2hDcYJTyT0MOn0yuWzj8phlIvO72gTHA==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.6.tgz", + "integrity": "sha512-+fN+NO2gh8JtRmDSOB6gaCVo36ha8kfCW1nMq2Gc0DABln0VcHN4PrALDvF5/diLzIRKptC7z/d7Lp64zk92Fg==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.6.tgz", + "integrity": "sha512-cRzPobcfRP0ZtuIEkA8QzghoUpSB3X3qSH5W2+FzG+VjWbJXExtx0nbRqwumdBN1x/ot2SlTNQLfBCnPdzp6kg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/template": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.6.tgz", + "integrity": "sha512-YLW6AE5LQpk5npNXL7i/O+U9CE4XsBCuRPgyjl1EICZYKmcitV+ayuuUGMJm2lC1WWjXYszeTnIxF/dq/GhIZQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.6.tgz", + "integrity": "sha512-rCXPnSEKvkm/EjzOtLoGvKseK+dS4kZwx1HexO3BtRtgL0fQ34awHn34aeSHuXtZY2F8a1X8xqBBPRtOxDVmcA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.6.tgz", + "integrity": "sha512-/8Odwp/aVkZwPFJMllSbawhDAO3UJi65foB00HYnK/uXvvCPm0TAXSByjz1mpRmp0q6oX2SIxpkUOpPFHk7FLA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.6.tgz", + "integrity": "sha512-vpq8SSLRTBLOHUZHSnBqVo0AKX3PBaoPs2vVzYVWslXDTDIpwAcCDtfhUcHSQQoYoUvcFPTdC8TZYXu9ZnLT/w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.6.tgz", + "integrity": "sha512-EemYpHtmz0lHE7hxxxYEuTYOOBZ43WkDgZ4arQ4r+VX9QHuNZC+WH3wUWmRNvR8ECpTRne29aZV6XO22qpOtdA==", + "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.6.tgz", + "integrity": "sha512-inXaTM1SVrIxCkIJ5gqWiozHfFMStuGbGJAxZFBoHcRRdDP0ySLb3jH6JOwmfiinPwyMZqMBX+7NBDCO4z0NSA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.6.tgz", + "integrity": "sha512-n3Sf72TnqK4nw/jziSqEl1qaWPbCRw2CziHH+jdRYvw4J6yeCzsj4jdw8hIntOEeDGTmHVe2w4MVL44PN0GMzg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.6.tgz", + "integrity": "sha512-sOajCu6V0P1KPljWHKiDq6ymgqB+vfo3isUS4McqW1DZtvSVU2v/wuMhmRmkg3sFoq6GMaUUf8W4WtoSLkOV/Q==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.6.tgz", + "integrity": "sha512-Uvgd9p2gUnzYJxVdBLcU0KurF8aVhkmVyMKW4MIY1/BByvs3EBpv45q01o7pRTVmTvtQq5zDlytP3dcUgm7v9w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.6.tgz", + "integrity": "sha512-f2wHfR2HF6yMj+y+/y07+SLqnOSwRp8KYLpQKOzS58XLVlULhXbiYcygfXQxJlMbhII9+yXDwOUFLf60/TL5tw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.6.tgz", + "integrity": "sha512-EKaWvnezBCMkRIHxMJSIIylzhqK09YpiJtDbr2wsXTwnO0TxyjMUkaw4RlFIZMIS0iDj0KyIg7H7XCguHu/YDA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.6.tgz", + "integrity": "sha512-9g8iV146szUo5GWgXpRbq/GALTnY+WnNuRTuRHWWFfWGbP9ukRL0aO/jpu9dmOPikclkxnNsjY8/gsWl6bmZJQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.6.tgz", + "integrity": "sha512-eAGogjZgcwqAxhyFgqghvoHRr+EYRQPFjUXrTYKBRb5qPnAVxOOglaxc4/byHqjvq/bqO2F3/CGwTHsgKJYHhQ==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.6.tgz", + "integrity": "sha512-JEV8l3MHdmmdb7S7Cmx6rbNEjRCgTQMZxllveHO0mx6uiclB0NflCawlQQ6+o5ZrwjUBYPzHm2XoK4wqGVUFuw==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-simple-access": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.6.tgz", + "integrity": "sha512-xg1Z0J5JVYxtpX954XqaaAT6NpAY6LtZXvYFCJmGFJWwtlz2EmJoR8LycFRGNE8dBKizGWkGQZGegtkV8y8s+w==", + "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.24.6", + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.6.tgz", + "integrity": "sha512-esRCC/KsSEUvrSjv5rFYnjZI6qv4R1e/iHQrqwbZIoRJqk7xCvEUiN7L1XrmW5QSmQe3n1XD88wbgDTWLbVSyg==", + "dev": true, + "dependencies": { + "@babel/helper-module-transforms": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.6.tgz", + "integrity": "sha512-6DneiCiu91wm3YiNIGDWZsl6GfTTbspuj/toTEqLh9d4cx50UIzSdg+T96p8DuT7aJOBRhFyaE9ZvTHkXrXr6Q==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.6.tgz", + "integrity": "sha512-f8liz9JG2Va8A4J5ZBuaSdwfPqN6axfWRK+y66fjKYbwf9VBLuq4WxtinhJhvp1w6lamKUwLG0slK2RxqFgvHA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.6.tgz", + "integrity": "sha512-+QlAiZBMsBK5NqrBWFXCYeXyiU1y7BQ/OYaiPAcQJMomn5Tyg+r5WuVtyEuvTbpV7L25ZSLfE+2E9ywj4FD48A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.6.tgz", + "integrity": "sha512-6voawq8T25Jvvnc4/rXcWZQKKxUNZcKMS8ZNrjxQqoRFernJJKjE3s18Qo6VFaatG5aiX5JV1oPD7DbJhn0a4Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.6.tgz", + "integrity": "sha512-OKmi5wiMoRW5Smttne7BwHM8s/fb5JFs+bVGNSeHWzwZkWXWValR1M30jyXo1s/RaqgwwhEC62u4rFH/FBcBPg==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.6.tgz", + "integrity": "sha512-N/C76ihFKlZgKfdkEYKtaRUtXZAgK7sOY4h2qrbVbVTXPrKGIi8aww5WGe/+Wmg8onn8sr2ut6FXlsbu/j6JHg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-replace-supers": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.6.tgz", + "integrity": "sha512-L5pZ+b3O1mSzJ71HmxSCmTVd03VOT2GXOigug6vDYJzE5awLI7P1g0wFcdmGuwSDSrQ0L2rDOe/hHws8J1rv3w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.6.tgz", + "integrity": "sha512-cHbqF6l1QP11OkYTYQ+hhVx1E017O5ZcSPXk9oODpqhcAD1htsWG2NpHrrhthEO2qZomLK0FXS+u7NfrkF5aOQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.6.tgz", + "integrity": "sha512-ST7guE8vLV+vI70wmAxuZpIKzVjvFX9Qs8bl5w6tN/6gOypPWUmMQL2p7LJz5E63vEGrDhAiYetniJFyBH1RkA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.6.tgz", + "integrity": "sha512-T9LtDI0BgwXOzyXrvgLTT8DFjCC/XgWLjflczTLXyvxbnSR/gpv0hbmzlHE/kmh9nOvlygbamLKRo6Op4yB6aw==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.6.tgz", + "integrity": "sha512-Qu/ypFxCY5NkAnEhCF86Mvg3NSabKsh/TPpBVswEdkGl7+FbsYHy1ziRqJpwGH4thBdQHh8zx+z7vMYmcJ7iaQ==", + "dev": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.6", + "@babel/helper-create-class-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.6.tgz", + "integrity": "sha512-oARaglxhRsN18OYsnPTpb8TcKQWDYNsPNmTnx5++WOAsUJ0cSC/FZVlIJCKvPbU4yn/UXsS0551CFKJhN0CaMw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.6.tgz", + "integrity": "sha512-SMDxO95I8WXRtXhTAc8t/NFQUT7VYbIWwJCJgEli9ml4MhqUMh4S6hxgH6SmAC3eAQNWCDJFxcFeEt9w2sDdXg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.6.tgz", + "integrity": "sha512-DcrgFXRRlK64dGE0ZFBPD5egM2uM8mgfrvTMOSB2yKzOtjpGegVYkzh3s1zZg1bBck3nkXiaOamJUqK3Syk+4A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.6.tgz", + "integrity": "sha512-xnEUvHSMr9eOWS5Al2YPfc32ten7CXdH7Zwyyk7IqITg4nX61oHj+GxpNvl+y5JHjfN3KXE2IV55wAWowBYMVw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.6.tgz", + "integrity": "sha512-h/2j7oIUDjS+ULsIrNZ6/TKG97FgmEk1PXryk/HQq6op4XUUUwif2f69fJrzK0wza2zjCS1xhXmouACaWV5uPA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.6.tgz", + "integrity": "sha512-fN8OcTLfGmYv7FnDrsjodYBo1DhPL3Pze/9mIIE2MGCT1KgADYIOD7rEglpLHZj8PZlC/JFX5WcD+85FLAQusw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.6.tgz", + "integrity": "sha512-BJbEqJIcKwrqUP+KfUIkxz3q8VzXe2R8Wv8TaNgO1cx+nNavxn/2+H8kp9tgFSOL6wYPPEgFvU6IKS4qoGqhmg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.6.tgz", + "integrity": "sha512-IshCXQ+G9JIFJI7bUpxTE/oA2lgVLAIK8q1KdJNoPXOpvRaNjMySGuvLfBw/Xi2/1lLo953uE8hyYSDW3TSYig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.6.tgz", + "integrity": "sha512-bKl3xxcPbkQQo5eX9LjjDpU2xYHeEeNQbOhj0iPvetSzA+Tu9q/o5lujF4Sek60CM6MgYvOS/DJuwGbiEYAnLw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.6.tgz", + "integrity": "sha512-8EIgImzVUxy15cZiPii9GvLZwsy7Vxc+8meSlR3cXFmBIl5W5Tn9LGBf7CDKkHj4uVfNXCJB8RsVfnmY61iedA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.6.tgz", + "integrity": "sha512-pssN6ExsvxaKU638qcWb81RrvvgZom3jDgU/r5xFZ7TONkZGFf4MhI2ltMb8OcQWhHyxgIavEU+hgqtbKOmsPA==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.6.tgz", + "integrity": "sha512-quiMsb28oXWIDK0gXLALOJRXLgICLiulqdZGOaPPd0vRT7fQp74NtdADAVu+D8s00C+0Xs0MxVP0VKF/sZEUgw==", + "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.6.tgz", + "integrity": "sha512-CrxEAvN7VxfjOG8JNF2Y/eMqMJbZPZ185amwGUBp8D9USK90xQmv7dLdFSa+VbD7fdIqcy/Mfv7WtzG8+/qxKg==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.24.6", + "@babel/helper-compilation-targets": "^7.24.6", + "@babel/helper-plugin-utils": "^7.24.6", + "@babel/helper-validator-option": "^7.24.6", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.6", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.6", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.6", + "@babel/plugin-syntax-import-attributes": "^7.24.6", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.6", + "@babel/plugin-transform-async-generator-functions": "^7.24.6", + "@babel/plugin-transform-async-to-generator": "^7.24.6", + "@babel/plugin-transform-block-scoped-functions": "^7.24.6", + "@babel/plugin-transform-block-scoping": "^7.24.6", + "@babel/plugin-transform-class-properties": "^7.24.6", + "@babel/plugin-transform-class-static-block": "^7.24.6", + "@babel/plugin-transform-classes": "^7.24.6", + "@babel/plugin-transform-computed-properties": "^7.24.6", + "@babel/plugin-transform-destructuring": "^7.24.6", + "@babel/plugin-transform-dotall-regex": "^7.24.6", + "@babel/plugin-transform-duplicate-keys": "^7.24.6", + "@babel/plugin-transform-dynamic-import": "^7.24.6", + "@babel/plugin-transform-exponentiation-operator": "^7.24.6", + "@babel/plugin-transform-export-namespace-from": "^7.24.6", + "@babel/plugin-transform-for-of": "^7.24.6", + "@babel/plugin-transform-function-name": "^7.24.6", + "@babel/plugin-transform-json-strings": "^7.24.6", + "@babel/plugin-transform-literals": "^7.24.6", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.6", + "@babel/plugin-transform-member-expression-literals": "^7.24.6", + "@babel/plugin-transform-modules-amd": "^7.24.6", + "@babel/plugin-transform-modules-commonjs": "^7.24.6", + "@babel/plugin-transform-modules-systemjs": "^7.24.6", + "@babel/plugin-transform-modules-umd": "^7.24.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.6", + "@babel/plugin-transform-new-target": "^7.24.6", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.6", + "@babel/plugin-transform-numeric-separator": "^7.24.6", + "@babel/plugin-transform-object-rest-spread": "^7.24.6", + "@babel/plugin-transform-object-super": "^7.24.6", + "@babel/plugin-transform-optional-catch-binding": "^7.24.6", + "@babel/plugin-transform-optional-chaining": "^7.24.6", + "@babel/plugin-transform-parameters": "^7.24.6", + "@babel/plugin-transform-private-methods": "^7.24.6", + "@babel/plugin-transform-private-property-in-object": "^7.24.6", + "@babel/plugin-transform-property-literals": "^7.24.6", + "@babel/plugin-transform-regenerator": "^7.24.6", + "@babel/plugin-transform-reserved-words": "^7.24.6", + "@babel/plugin-transform-shorthand-properties": "^7.24.6", + "@babel/plugin-transform-spread": "^7.24.6", + "@babel/plugin-transform-sticky-regex": "^7.24.6", + "@babel/plugin-transform-template-literals": "^7.24.6", + "@babel/plugin-transform-typeof-symbol": "^7.24.6", + "@babel/plugin-transform-unicode-escapes": "^7.24.6", + "@babel/plugin-transform-unicode-property-regex": "^7.24.6", + "@babel/plugin-transform-unicode-regex": "^7.24.6", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.6", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true + }, + "node_modules/@babel/runtime": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.6.tgz", + "integrity": "sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.6.tgz", + "integrity": "sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/types": "^7.24.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.6.tgz", + "integrity": "sha512-OsNjaJwT9Zn8ozxcfoBc+RaHdj3gFmCmYoQLUII1o6ZrUwku0BMg80FoOTPx+Gi6XhcQxAYE4xyjPTo4SxEQqw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.24.6", + "@babel/generator": "^7.24.6", + "@babel/helper-environment-visitor": "^7.24.6", + "@babel/helper-function-name": "^7.24.6", + "@babel/helper-hoist-variables": "^7.24.6", + "@babel/helper-split-export-declaration": "^7.24.6", + "@babel/parser": "^7.24.6", + "@babel/types": "^7.24.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.6.tgz", + "integrity": "sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.24.6", + "@babel/helper-validator-identifier": "^7.24.6", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "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, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/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, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", + "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", + "dev": true, + "dependencies": { + "@types/eslint": "^8.56.5", + "@types/estree": "^1.0.5", + "@typescript-eslint/types": "^7.2.0", + "comment-parser": "1.4.1", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "dev": true + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dev": true, + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "dev": true + }, + "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, + "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/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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 + }, + "node_modules/@isaacs/cliui/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, + "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/@isaacs/cliui/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, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/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, + "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/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/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 + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/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, + "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/@jest/console/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/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 + }, + "node_modules/@jest/console/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/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, + "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/@jest/core/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/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 + }, + "node_modules/@jest/core/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/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, + "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/@jest/reporters/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/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 + }, + "node_modules/@jest/reporters/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", + "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/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, + "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/@jest/transform/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/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 + }, + "node_modules/@jest/transform/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/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, + "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/@jest/types/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/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 + }, + "node_modules/@jest/types/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@json-schema-spec/json-pointer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@json-schema-spec/json-pointer/-/json-pointer-0.1.2.tgz", + "integrity": "sha512-BYY7IavBjwsWWSmVcMz2A9mKiDD9RvacnsItgmy1xV8cmgbtxFfKmKMtkVpD7pYtkx4mIW4800yZBXueVFIWPw==", + "dev": true + }, + "node_modules/@json-schema-tools/dereferencer": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@json-schema-tools/dereferencer/-/dereferencer-1.6.3.tgz", + "integrity": "sha512-NoQkj6hx9Joqbd/GZAOHSGtE6R+OzlnOcDfyidmx8e/CUv1Q+Z6/fmZo2wwCQWiwP1pnGYc95iKwp8M7XlV7wQ==", + "dev": true, + "dependencies": { + "@json-schema-tools/reference-resolver": "^1.2.6", + "@json-schema-tools/traverse": "^1.10.4", + "fast-safe-stringify": "^2.1.1" + } + }, + "node_modules/@json-schema-tools/meta-schema": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@json-schema-tools/meta-schema/-/meta-schema-1.7.5.tgz", + "integrity": "sha512-8Hy6tuMC2BQdK7O4ilLovFB9t0j5o0L/sQTuWeg2CNYpITmPiFTRiG7Yb/jYd483D8784kxLFJ0dT+T4O2hNmw==", + "dev": true + }, + "node_modules/@json-schema-tools/reference-resolver": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@json-schema-tools/reference-resolver/-/reference-resolver-1.2.6.tgz", + "integrity": "sha512-4QZu5ROb5EpLSvV+buzk8WR30W+dffSNaKqD3VGFYJ3y0BLDi2OHoSz5e6NKcLYTyUYXV8IKxocNOszeVBJI4Q==", + "dev": true, + "dependencies": { + "@json-schema-spec/json-pointer": "^0.1.2", + "isomorphic-fetch": "^3.0.0" + } + }, + "node_modules/@json-schema-tools/referencer": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@json-schema-tools/referencer/-/referencer-1.1.3.tgz", + "integrity": "sha512-p2JU7GpHn1kMyP7gnB2Wnki+OnifsSi75Uj5PxqIg2pT4fqh+BM3rEEZKpaET4xv0ZszG46CCI9eEvs68v2rXg==", + "dev": true, + "dependencies": { + "@json-schema-tools/traverse": "^1.10.4" + } + }, + "node_modules/@json-schema-tools/titleizer": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@json-schema-tools/titleizer/-/titleizer-1.0.9.tgz", + "integrity": "sha512-Gwg3YTP5P+3Q+OnvEcthTnsup3AsEkxZCrRLXoWppdjtSzRnsWxtvmpKdGLbVcocPC7Sh3aqJ7Arp85Ii6q2GA==", + "dev": true, + "dependencies": { + "@json-schema-tools/traverse": "^1.10.4" + } + }, + "node_modules/@json-schema-tools/transpiler": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/@json-schema-tools/transpiler/-/transpiler-1.10.5.tgz", + "integrity": "sha512-uRm43U8wKWQV8czvvkJYwcUERpQC+azKmqbd7RhV1gWx7s1t0frLtrWqGbXh9xMcgdtF7+Tkiwex48nW5EnX1w==", + "dev": true, + "dependencies": { + "@json-schema-tools/referencer": "^1.1.3", + "@json-schema-tools/titleizer": "^1.0.9", + "@json-schema-tools/traverse": "^1.10.4", + "lodash.camelcase": "^4.3.0", + "lodash.deburr": "^4.1.0", + "lodash.snakecase": "^4.1.1", + "lodash.trim": "^4.5.1" + } + }, + "node_modules/@json-schema-tools/traverse": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@json-schema-tools/traverse/-/traverse-1.10.4.tgz", + "integrity": "sha512-9e42zjhLIxzBONroNC4SGsTqdB877tzwH2S6lqgTav9K24kWJR9vNieeMVSuyqnY8FlclH21D8wsm/tuD9WA9Q==", + "dev": true + }, + "node_modules/@noble/ed25519": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.3.tgz", + "integrity": "sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "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, + "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, + "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, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@open-rpc/meta-schema": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/@open-rpc/meta-schema/-/meta-schema-1.14.9.tgz", + "integrity": "sha512-2/CbDzOVpcaSnMs28TsRv8MKJwJi0TTYFlQ6q6qobAH26oIuhYgcZooKf4l71emgntU6MMcFQCA0h4mJ4dBCdA==", + "dev": true + }, + "node_modules/@open-rpc/typings": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/@open-rpc/typings/-/typings-1.12.4.tgz", + "integrity": "sha512-WadzXP6rXSQT51BgsmVT5OVxWS9+DWSsn8ebhtFBKb60Z3S8KA0wo5wiM7AQIrhNb4qfcQqk6HpYo6Fmpum4ew==", + "dev": true, + "dependencies": { + "@json-schema-tools/titleizer": "1.0.9", + "@json-schema-tools/transpiler": "^1.10.5", + "@open-rpc/schema-utils-js": "2.0.2", + "commander": "^6.0.0", + "fs-extra": "^10.0.0" + }, + "bin": { + "open-rpc-typings": "build/cli.js" + } + }, + "node_modules/@open-rpc/typings/node_modules/@open-rpc/schema-utils-js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@open-rpc/schema-utils-js/-/schema-utils-js-2.0.2.tgz", + "integrity": "sha512-0Fb8zx09Ijt8yZB5Cd1dXpjZmWjTlxzQP/B2x5CXpbs1z9Pu0E//GV0Ncp6uBMlovPvMc7ohWWyLKNwJzZMA8Q==", + "dev": true, + "dependencies": { + "@json-schema-tools/dereferencer": "^1.6.3", + "@json-schema-tools/meta-schema": "^1.7.5", + "@json-schema-tools/reference-resolver": "^1.2.6", + "@open-rpc/meta-schema": "^1.14.9", + "ajv": "^6.10.0", + "detect-node": "^2.0.4", + "fast-safe-stringify": "^2.0.7", + "fs-extra": "^10.1.0", + "is-url": "^1.2.4", + "isomorphic-fetch": "^3.0.0" + } + }, + "node_modules/@open-rpc/typings/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "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, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.3.tgz", + "integrity": "sha512-bJ0UBsk0ESOs6RFcLXOt99a3yTDcOKlzfjad+rhFwdaG1Lu/Wzq58GHYCDTlZ9z6mldf4g+NTb+TXEfe0PpnsQ==", + "dev": true, + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.4.0", + "semver": "7.6.0", + "tar-fs": "3.0.5", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@puppeteer/browsers/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, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@puppeteer/browsers/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@puppeteer/browsers/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 + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "dev": true, + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", + "dev": true + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "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, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true + }, + "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 + }, + "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 + }, + "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 + }, + "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 + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "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 + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", + "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "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 + }, + "node_modules/@types/node": { + "version": "20.12.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.13.tgz", + "integrity": "sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true + }, + "node_modules/@types/varint": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/varint/-/varint-6.0.3.tgz", + "integrity": "sha512-DHukoGWdJ2aYkveZJTB2rN2lp6m7APzVsoJQ7j/qy1fQxyamJTPD5xQzCMoJ2Qtgn0mE3wWeNOpbTyBFvF+dyA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz", + "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/type-utils": "7.11.0", + "@typescript-eslint/utils": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", + "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz", + "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/utils": "7.11.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", + "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", + "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz", + "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", + "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.11.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "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, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "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, + "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/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-sequence-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", + "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", + "dev": true + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "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 + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "dev": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", + "dev": true + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/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, + "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/babel-jest/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/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 + }, + "node_modules/babel-jest/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz", + "integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.1", + "core-js-compat": "^3.36.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "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 + }, + "node_modules/bare-events": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz", + "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==", + "dev": true, + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.0.tgz", + "integrity": "sha512-TNFqa1B4N99pds2a5NYHR15o0ZpdNKbAeKTE/+G6ED/UeOavv8RY3dr/Fu99HW3zU3pXpo2kDNO8Sjsm2esfOw==", + "dev": true, + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^1.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.3.0.tgz", + "integrity": "sha512-oPb8oMM1xZbhRQBngTgpcQ5gXw6kjOaRsSWsIeNyRxGed2w/ARyP7ScBYpWR1qfX2E5rS3gBw6OWcSQo+s+kUg==", + "dev": true, + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-1.0.0.tgz", + "integrity": "sha512-KhNUoDL40iP4gFaLSsoGE479t0jHijfYdIcxRn/XtezA2BaUD0NRf/JGRpsMq6dMNM+SrCrB0YSSo/5wBY4rOQ==", + "dev": true, + "optional": true, + "dependencies": { + "streamx": "^2.16.1" + } + }, + "node_modules/base-x": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.0.tgz", + "integrity": "sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "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" + } + ] + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "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, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bs58": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", + "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", + "dependencies": { + "base-x": "^5.0.0" + } + }, + "node_modules/bs58check": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-4.0.0.tgz", + "integrity": "sha512-FsGDOnFg9aVI9erdriULkd/JjEWONV/lQE5aYziB5PoBsXRind56lh8doIZIc9X4HoxT5x4bLjMWN1/NB8Zp5g==", + "dependencies": { + "@noble/hashes": "^1.2.0", + "bs58": "^6.0.0" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/bufferutil": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.8.tgz", + "integrity": "sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001625", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001625.tgz", + "integrity": "sha512-4KE9N2gcRH+HQhpeiRZXd+1niLB/XNLAhSy4z7fI8EzcbcPoAqjNInxVHTiTwWfTIV4w096XG8OtCOCQQKPv3w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chromium-bidi": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.19.tgz", + "integrity": "sha512-UA6zL77b7RYCjJkZBsZ0wlvCTD+jTjllZ8f6wdO4buevXgTZYjV+XLB9CiEa2OuuTGGTLnI7eN9I60YxuALGQg==", + "dev": true, + "dependencies": { + "mitt": "3.0.1", + "urlpattern-polyfill": "10.0.0", + "zod": "3.22.4" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "dev": true + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/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, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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, + "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-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/cliui/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 + }, + "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, + "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/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "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 + }, + "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 + }, + "node_modules/core-js-compat": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "dev": true, + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-jest/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/create-jest/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, + "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/create-jest/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/create-jest/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 + }, + "node_modules/create-jest/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/create-jest/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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 + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cwd": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/cwd/-/cwd-0.10.0.tgz", + "integrity": "sha512-YGZxdTTL9lmLkCUTpg4j0zQ7IhRB5ZmqNBbGCl3Tg6MP/d5/6sY7L5mmTjzbc6JKgVZYiqTQTNhPFsbXNGlRaA==", + "dev": true, + "dependencies": { + "find-pkg": "^0.1.2", + "fs-exists-sync": "^0.1.0" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, + "node_modules/dedent": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "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 + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "dev": true, + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/devtools-protocol": { + "version": "0.0.1286932", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1286932.tgz", + "integrity": "sha512-wu58HMQll9voDjR4NlPyoDEw1syfzaBNHymMMZ/QOXiHRNluOnDgu9hp1yHOKYoMlxCh4lSSiugLITe6Fvu1eA==", + "dev": true + }, + "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, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "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 + }, + "node_modules/electron-to-chromium": { + "version": "1.4.787", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.787.tgz", + "integrity": "sha512-d0EFmtLPjctczO3LogReyM2pbBiiZbnsKnGF+cdZhsYzHm/A0GV7W94kqzLD8SN4O3f3iHlgLUChqghgyznvCQ==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "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 + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-google": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "48.2.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.7.tgz", + "integrity": "sha512-fYj3roTnkFL9OFFTB129rico8lerC5G8Vp2ZW9SjO9RNWG0exVvI+i/Y8Bpm1ufjR0uvT38xtoab/U0Hp8Ybog==", + "dev": true, + "dependencies": { + "@es-joy/jsdoccomment": "~0.43.1", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.5.0", + "semver": "^7.6.2", + "spdx-expression-parse": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/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, + "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/eslint/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/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 + }, + "node_modules/eslint/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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/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, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/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, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "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, + "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, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/expect-puppeteer": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/expect-puppeteer/-/expect-puppeteer-10.0.0.tgz", + "integrity": "sha512-E7sE6nVdEbrnpDOBMmcLgyqLJKt876AlBg1A+gsu5R8cWx+SLafreOgJAgzXg5Qko7Tk0cW5oZdRbHQLU738dg==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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 + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "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.4" + }, + "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, + "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 + }, + "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 + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.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, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-file-up": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/find-file-up/-/find-file-up-0.1.3.tgz", + "integrity": "sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==", + "dev": true, + "dependencies": { + "fs-exists-sync": "^0.1.0", + "resolve-dir": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-pkg": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/find-pkg/-/find-pkg-0.1.2.tgz", + "integrity": "sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw==", + "dev": true, + "dependencies": { + "find-file-up": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-process": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.7.tgz", + "integrity": "sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "commander": "^5.1.0", + "debug": "^4.1.1" + }, + "bin": { + "find-process": "bin/find-process.js" + } + }, + "node_modules/find-process/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/find-process/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, + "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/find-process/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/find-process/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 + }, + "node_modules/find-process/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/find-process/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-process/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/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, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "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, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "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, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "dev": true, + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "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, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha512-JeXuCbvYzYXcwE6acL9V2bAOeSIGl4dD+iwLY9iUx2VBJJ80R18HCn+JCwHM9Oegdfya3lEkGCdaRkSyc10hDA==", + "dev": true, + "dependencies": { + "global-prefix": "^0.1.4", + "is-windows": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.0", + "ini": "^1.3.4", + "is-windows": "^0.2.0", + "which": "^1.2.12" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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 + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "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 + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/husky": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "dev": true, + "bin": { + "husky": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "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, + "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/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, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "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, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz", + "integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/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, + "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/jest-circus/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/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 + }, + "node_modules/jest-circus/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/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, + "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/jest-cli/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/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 + }, + "node_modules/jest-cli/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/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, + "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/jest-config/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/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 + }, + "node_modules/jest-config/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-dev-server": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/jest-dev-server/-/jest-dev-server-10.0.0.tgz", + "integrity": "sha512-FtyBBDxrAIfTX3hyKSOwj5KU6Z7fFLew5pQYOFpwyf+qpPpULL8aYxtsFkbkAwcs+Mb7qhcNbVLeiWsLOd7CKw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "cwd": "^0.10.0", + "find-process": "^1.4.7", + "prompts": "^2.4.2", + "spawnd": "^10.0.0", + "tree-kill": "^1.2.2", + "wait-on": "^7.2.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/jest-dev-server/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-dev-server/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, + "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/jest-dev-server/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-dev-server/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 + }, + "node_modules/jest-dev-server/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-dev-server/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/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, + "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/jest-diff/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/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 + }, + "node_modules/jest-diff/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/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, + "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/jest-each/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/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 + }, + "node_modules/jest-each/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-puppeteer": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-puppeteer/-/jest-environment-puppeteer-10.0.1.tgz", + "integrity": "sha512-FxMzVRyqieQqSy5CPWiwdK5t9dkRHid5eoRTVa8RtYeXLlpW6lU0dAmxEfPkdnDVCiPUhC2APeKOXq0J72bgag==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "cosmiconfig": "^8.3.6", + "deepmerge": "^4.3.1", + "jest-dev-server": "^10.0.0", + "jest-environment-node": "^29.7.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/jest-environment-puppeteer/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-environment-puppeteer/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, + "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/jest-environment-puppeteer/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-environment-puppeteer/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 + }, + "node_modules/jest-environment-puppeteer/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-puppeteer/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/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, + "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/jest-matcher-utils/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/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 + }, + "node_modules/jest-matcher-utils/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/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, + "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/jest-message-util/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/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 + }, + "node_modules/jest-message-util/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-puppeteer": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/jest-puppeteer/-/jest-puppeteer-10.0.1.tgz", + "integrity": "sha512-FzC35XbqeuQEt1smXh1EOqhJaRkWqJkyWDMfGkcZ8C59QHXeJ7F/iOmiNqYi6l/OsycUuOPCk+IkjfGfS9YbrQ==", + "dev": true, + "dependencies": { + "expect-puppeteer": "^10.0.0", + "jest-environment-puppeteer": "^10.0.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "puppeteer": ">=19" + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/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, + "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/jest-resolve/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/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 + }, + "node_modules/jest-resolve/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/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, + "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/jest-runner/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/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 + }, + "node_modules/jest-runner/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/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, + "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/jest-runtime/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/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 + }, + "node_modules/jest-runtime/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/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, + "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/jest-snapshot/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/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 + }, + "node_modules/jest-snapshot/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/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, + "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/jest-util/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/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 + }, + "node_modules/jest-util/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/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, + "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/jest-validate/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/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 + }, + "node_modules/jest-validate/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/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, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/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, + "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/jest-watcher/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/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 + }, + "node_modules/jest-watcher/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/joi": { + "version": "17.13.1", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.1.tgz", + "integrity": "sha512-vaBlIKCyo4FCUtCm7Eu4QZd/q02bWcxfUO6YSXAZOWF6gzcLBeba8kwotUdYJjDLW8Cz8RywsSOqiNJZW0mNvg==", + "dev": true, + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "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, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "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 + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "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 + }, + "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 + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true + }, + "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, + "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, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/lint-staged": { + "version": "15.2.5", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.5.tgz", + "integrity": "sha512-j+DfX7W9YUvdzEZl3Rk47FhDF6xwDBV5wwsCPw6BwWZVPYJemusQmvb9bRsW23Sqsaa+vRloAWogbK4BUuU2zA==", + "dev": true, + "dependencies": { + "chalk": "~5.3.0", + "commander": "~12.1.0", + "debug": "~4.3.4", + "execa": "~8.0.1", + "lilconfig": "~3.1.1", + "listr2": "~8.2.1", + "micromatch": "~4.0.7", + "pidtree": "~0.6.0", + "string-argv": "~0.3.2", + "yaml": "~2.4.2" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/lint-staged/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/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, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.1.tgz", + "integrity": "sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.3.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/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, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/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, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.deburr": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz", + "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==", + "dev": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "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 + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true + }, + "node_modules/lodash.trim": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.trim/-/lodash.trim-4.5.1.tgz", + "integrity": "sha512-nJAlRl/K+eiOehWKDzoBVrSMhK0K3A3YQsUNXHQa5yIrKBAhsZgSu3KoAFoFT+mEgiyBHddZ0pRk1ITpIp90Wg==", + "dev": true + }, + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/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, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/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, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "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 + }, + "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, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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 + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "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, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "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 + }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/npm-run-all/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/npm-run-all/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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/npm-run-all/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/npm-run-all/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/npm-run-all/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-all/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "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/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true, + "engines": { + "node": ">=0.10.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, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "dev": true, + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "dev": true, + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "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, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "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 + }, + "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, + "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/path-scurry/node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "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, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-agent": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", + "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.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, + "engines": { + "node": ">=6" + } + }, + "node_modules/puppeteer": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.10.0.tgz", + "integrity": "sha512-ZOkZd6a6t0BdKcWb0wAYHWQqCfdlN1PPnXOmg/XNrbo6gJhYWFX4qCNb6ahSn8TpAqBqLCoD4Q010F7GwOM7mA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@puppeteer/browsers": "2.2.3", + "cosmiconfig": "9.0.0", + "devtools-protocol": "0.0.1286932", + "puppeteer-core": "22.10.0" + }, + "bin": { + "puppeteer": "lib/esm/puppeteer/node/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer-core": { + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.10.0.tgz", + "integrity": "sha512-I54J4Vy4I07UHsgB1QSmuFoF7KNQjJWcvFBPhtY+ezMdBfwgGDr8dzYrJa11aPgP9kxIUHjhktcMmmfJkOAtTw==", + "dev": true, + "dependencies": { + "@puppeteer/browsers": "2.2.3", + "chromium-bidi": "0.5.19", + "debug": "4.3.4", + "devtools-protocol": "0.0.1286932", + "ws": "8.17.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/puppeteer/node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "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" + } + ] + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dev": true, + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA==", + "dev": true, + "dependencies": { + "expand-tilde": "^1.2.2", + "global-modules": "^0.2.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", + "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==", + "dev": true + }, + "node_modules/rimraf": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz", + "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", + "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/secure-random": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.2.tgz", + "integrity": "sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ==" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shiki": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.7.tgz", + "integrity": "sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==", + "dev": true, + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-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, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz", + "integrity": "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawnd": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/spawnd/-/spawnd-10.0.0.tgz", + "integrity": "sha512-6GKcakMTryb5b1SWCvdubCDHEsR2k+5VZUD5G19umZRarkvj1RyCGyizcqhjewI7cqZo8fTVD8HpnDZbVOLMtg==", + "dev": true, + "dependencies": { + "signal-exit": "^4.1.0", + "tree-kill": "^1.2.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/spawnd/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, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/streamx": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "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, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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, + "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": { + "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, + "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/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/tar-fs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", + "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", + "dev": true, + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/text-decoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", + "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-interface-builder": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/ts-interface-builder/-/ts-interface-builder-0.3.3.tgz", + "integrity": "sha512-WHQwVBy0+Sv/jcHhKlyFgTyEVTM0GEPEw+gLmOYlZiJC1/eh5ah2EHSw7o+RUrl2grjEAMU6MTOItCuQIVJvnQ==", + "dev": true, + "dependencies": { + "commander": "^2.12.2", + "fs-extra": "^4.0.3", + "glob": "^7.1.6", + "typescript": "^3.0.0" + }, + "bin": { + "ts-interface-builder": "bin/ts-interface-builder" + } + }, + "node_modules/ts-interface-builder/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/ts-interface-builder/node_modules/fs-extra": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", + "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "node_modules/ts-interface-builder/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/ts-interface-builder/node_modules/typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/ts-interface-builder/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-1.0.2.tgz", + "integrity": "sha512-4IKKvhZRXhvtYF/mtu+OCfBqJKV6LczUq4kQYcpT+iSB7++R9+giWnp2ecwWMIcnG16btVOkXFnoxLSYMN1Q1g==", + "dev": true + }, + "node_modules/ts-jest": { + "version": "29.1.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.4.tgz", + "integrity": "sha512-YiHwDhSvCiItoAgsKtoLFCuakDzDsJ1DLDnSouTaTmdOcOwIkSzbLXduaQ6M5DRVhuZC/NYaaZ/mtHbWMv/S6Q==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "^7.5.3", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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, + "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/tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" + }, + "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, + "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, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedoc": { + "version": "0.25.13", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.13.tgz", + "integrity": "sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ==", + "dev": true, + "dependencies": { + "lunr": "^2.3.9", + "marked": "^4.3.0", + "minimatch": "^9.0.3", + "shiki": "^0.14.7" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x" + } + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.11.0.tgz", + "integrity": "sha512-ZKe3yHF/IS/kCUE4CGE3UgtK+Q7yRk1e9kwEI0rqm9XxMTd9P1eHe0LVVtrZ3oFuIQ2unJ9Xn0vTsLApzJ3aPw==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "7.11.0", + "@typescript-eslint/parser": "7.11.0", + "@typescript-eslint/utils": "7.11.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.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, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", + "dev": true + }, + "node_modules/utf-8-validate": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-6.0.4.tgz", + "integrity": "sha512-xu9GQDeFp+eZ6LnCywXN/zBancWvOpUMzgjLPSjy4BRHSmTelvn2E0DG0o1sTiw5hkCKBHo8rwSKncfRfv2EEQ==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "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 + }, + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", + "dev": true, + "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/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" + }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, + "node_modules/wait-for-expect": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/wait-for-expect/-/wait-for-expect-3.0.2.tgz", + "integrity": "sha512-cfS1+DZxuav1aBYbaO/kE06EOS8yRw7qOFoD3XtjTkYvCvh3zUvNST8DXK/nPaeqIzIv3P3kL3lRJn8iwOiSag==", + "dev": true + }, + "node_modules/wait-on": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz", + "integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==", + "dev": true, + "dependencies": { + "axios": "^1.6.1", + "joi": "^17.11.0", + "lodash": "^4.17.21", + "minimist": "^1.2.8", + "rxjs": "^7.8.1" + }, + "bin": { + "wait-on": "bin/wait-on" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "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, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "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-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/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, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/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 + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/ws": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", + "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "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, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yaml": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", + "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "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, + "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, + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.22.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz", + "integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } - } - }, - "packages/web3-utils/node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "packages/web3-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "packages/web3-utils/node_modules/eslint-scope": { - "version": "5.1.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "packages/web3-utils/node_modules/estraverse": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } } - } } diff --git a/package.json b/package.json index 7db9bd49..9b8b6aac 100644 --- a/package.json +++ b/package.json @@ -1,42 +1,110 @@ { - "name": "massa-web3-workspace", - "version": "1.0.0", - "scripts": { - "prepare": "husky install", - "test": "jest --forceExit --detectOpenHandles", - "test:cov": "npm run test:cov --ws --if-present", - "test:all": "npm run test:all --ws --if-present", - "build": "npm run build --ws --if-present", - "lint": "eslint . && npm run check-types --ws", - "lint:fix": "eslint . --fix && npm run check-types --ws", - "prettier": "prettier --check .", - "prettier:fix": "prettier --write .", - "fmt": "npm run lint:fix && npm run prettier:fix", - "fmt:check": "npm run lint && npm run prettier" - }, - "devDependencies": { - "@massalabs/eslint-config": "^0.0.10", - "@types/jest": "^29.5.5", - "@typescript-eslint/eslint-plugin": "^6.20.0", - "bignumber.js": "^9.1.1", - "eslint": "^8.56.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-jsdoc": "^48.0.4", - "husky": "^8.0.0", - "lint-staged": "^15.0.1", - "prettier": "^3.2.4", - "typescript": "^4.9.5" - }, - "workspaces": [ - "packages/web3-utils", - "packages/massa-web3" - ], - "repository": { - "type": "git", - "url": "https://github.com/massalabs/massa-web3.git" - }, - "bugs": { - "url": "https://github.com/massalabs/massa-web3/issues" - }, - "homepage": "https://github.com/massalabs/massa-web3#readme" -} \ No newline at end of file + "name": "@massalabs/massa-web3", + "version": "5.0.0", + "description": "massa's web3 sdk client", + "main": "dist/cmd/index.js", + "module": "dist/esm/index.js", + "types": "dist/esm/index.d.ts", + "scripts": { + "prepare": "npx is-ci || husky install", + "lint": "eslint . && npm run check-types", + "lint:fix": "eslint . --fix && npm run check-types", + "prettier": "prettier --check .", + "prettier:fix": "prettier --write .", + "fmt": "npm run lint:fix && npm run prettier:fix", + "fmt:check": "npm run lint && npm run prettier", + "up": "npm update", + "check": "npm outdated", + "upgrade": "npm run up && npm run check && npm run build", + "clean-dist": "rimraf dist/*", + "build-esm": "tsc --project tsconfig.esm.json", + "build-commonjs": "tsc --project tsconfig.commonjs.json", + "build": "npm-run-all clean-dist build-*", + "generate:types": "npx open-rpc-typings --output-ts src/generated --name-ts client-types -d open_rpc/massa.api.json", + "generate:test": "ts-interface-builder -o test/generated src/generated/client-types.ts", + "generate:deployer": "ts-node scripts/deployerGeneration/generate-deployer.ts", + "generate": "npm-run-all generate:*", + "test": "jest --detectOpenHandles --forceExit ./test/unit", + "test:watch": "jest --watch ./test/unit", + "test:browser": "jest --config=jest.browser.config.js", + "test:cov": "jest --detectOpenHandles --coverage --forceExit", + "test:cov:watch": "jest --detectOpenHandles --coverage --watch", + "test:integration": "jest --forceExit --runInBand ./test/integration", + "test:all": "npm run test && npm run test:integration", + "test:watch:all": "jest --watchAll", + "check-types": "tsc --noEmit", + "doc": "typedoc src/index.ts --name massa-web3 --out docs/documentation/html --tsconfig tsconfig.json" + }, + "author": "Massa Labs ", + "contributors": [ + "Gregory Libert", + "Benjamin Reynes", + "Thomas Senechal " + ], + "license": "MIT", + "homepage": "https://github.com/massalabs/massa-web3", + "repository": { + "type": "git", + "url": "git+https://github.com/massalabs/massa-web3" + }, + "keywords": [ + "web3", + "ts", + "sdk", + "massa" + ], + "files": [ + "dist", + "bundle.js", + "bundle.min.js" + ], + "dependencies": { + "@noble/ed25519": "^1.7.3", + "@noble/hashes": "^1.2.0", + "bs58check": "^4.0.0", + "decimal.js": "^10.4.3", + "dotenv": "^16.0.3", + "eventemitter3": "^5.0.1", + "lodash.isequal": "^4.5.0", + "secure-random": "^1.1.2", + "tslib": "^2.8.0", + "varint": "^6.0.0" + }, + "devDependencies": { + "@babel/preset-env": "^7.22.15", + "@open-rpc/typings": "^1.12.4", + "@types/jest": "^29.5.12", + "@types/node": "^20.12.13", + "@types/varint": "^6.0.3", + "@typescript-eslint/eslint-plugin": "^7.8.0", + "@typescript-eslint/parser": "^7.8.0", + "babel-jest": "^29.7.0", + "eslint": "^8.57.0", + "eslint-config-google": "^0.14.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-jsdoc": "^48.0.4", + "eslint-plugin-prettier": "^5.1.3", + "husky": "^9.0.11", + "is-ci": "^3.0.1", + "jest": "^29.5.0", + "jest-puppeteer": "^10.0.1", + "js-yaml": "^4.1.0", + "lint-staged": "^15.0.1", + "npm-run-all": "^4.1.5", + "prettier": "^3.2.4", + "puppeteer": "^22.6.3", + "rimraf": "^5.0.1", + "ts-interface-builder": "^0.3.3", + "ts-interface-checker": "^1.0.2", + "ts-jest": "^29.1.0", + "ts-node": "^10.9.1", + "typedoc": "^0.25.7", + "typescript": "^5.4.5", + "typescript-eslint": "^7.8.0", + "wait-for-expect": "^3.0.2" + }, + "optionalDependencies": { + "bufferutil": "^4.0.7", + "utf-8-validate": "^6.0.2" + } +} diff --git a/packages/massa-web3/CONTRIBUTING.md b/packages/massa-web3/CONTRIBUTING.md deleted file mode 100644 index 0684a6c3..00000000 --- a/packages/massa-web3/CONTRIBUTING.md +++ /dev/null @@ -1,92 +0,0 @@ -# Contributing to massa-web3 - -Thank you for considering contributing to massa-web3! - -## Reporting Bugs - -If you discover a bug, please create a [new issue](https://github.com/massalabs/massa-web3/issues/new?assignees=&labels=issue) on our GitHub repository. - -In your issue, please include a clear and concise description of the bug, any relevant code snippets, error messages, and steps to reproduce the issue. - -## Installation - -To start developing with massa-web3, you must install all the necessary dev dependencies. You can do so by running the following command: - -```sh -npm install -``` - -This will install all the required packages listed in the package.json file, allowing you to update, fix, or improve massa-web3 in any way you see fit. - -## Contributing Code - -We welcome contributions in the form of bug fixes, enhancements, and new features. - -To contribute code, please follow these steps: - -1. Fork the massa-web3 repository to your own account. -2. Create a new branch from the `main` branch for your changes. -3. Make your changes and commit them to your branch. -4. Push your branch to your fork. -5. Create a pull request from your branch to the develop branch of the massa-web3 repository. - -> **NOTE:** When creating a pull request, please include a clear and concise title and description of your changes, as well as any relevant context or background information. - -## Contributing Namespaces - -Namespaces are used in massa-web3 to group related functions and objects together, making it easier for developers to find and use them in their contracts. All namespaces are located in the `src` directory, and each namespace is in its own subdirectory. - -### Using existing namespaces - -When contributing to massa-web3, make sure you add new features to the correct namespace. Before adding a new feature, it's a good idea to check if there's an existing namespace that contains related functions or objects. By adding to an existing namespace, you can help ensure that your code is well-organized and easy to find. - -### Creating new namespaces - -If you have an idea for a new feature or a collection of related functions and objects that doesn't fit into an existing namespace, you can create a new namespace. When creating a new namespace, make sure to choose a descriptive name that accurately reflects the purpose of the namespace. Additionally, make sure to keep the namespace focused and to only include related functions and objects. - -If an existing namespace is becoming too large or unwieldy, it may also be a good idea to create a new one. When doing so, make sure to document your namespace and its functions thoroughly to make it easy for other developers to understand and use. - -## Code Style - -Please ensure that your code follows the existing code style used in the project. - -We use the [MassaLabs Prettier configuration](https://github.com/massalabs/prettier-config-as) and [MassaLabs ESLint configuration](https://github.com/massalabs/eslint-config) for formatting and linting. - -You can run the following command to format your code before committing: - -```sh -npm run fmt -``` - -## Tests - -Please ensure that your changes include any necessary tests. - -We use [jest library](https://jestjs.io/fr/) for unit testing. - -You can run the following command to run the tests: - -```sh -npm run build -``` - -and then - -```sh -npm run test -``` - -## License - -By contributing to massa-web3, you agree that your contributions will be licensed under the MIT License. - -## Documentation - -massa-web3 provides complete documentation of all available functions and objects. - -To generate the documentation for a specific branch, run the following command: - -```sh -npm run doc -``` -The documentation will be generated inside each of the packages in the `./docs/documentation/html` directory. \ No newline at end of file diff --git a/packages/massa-web3/LICENSE b/packages/massa-web3/LICENSE deleted file mode 100644 index cf1bd43b..00000000 --- a/packages/massa-web3/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Massa - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/massa-web3/README.md b/packages/massa-web3/README.md deleted file mode 100644 index 86bda789..00000000 --- a/packages/massa-web3/README.md +++ /dev/null @@ -1,116 +0,0 @@ -# massa-web3 ![Node CI](https://github.com/massalabs/massa-web3/workflows/Node.js%20CI/badge.svg) ![check-code-coverage](https://img.shields.io/badge/coverage-95.25%25-green) - -> **PREREQUISITES:** -> -> - NodeJS 18+ -> - npm / yarn (see package.json) - -Massa-web3 is an exhaustive TypeScript library that enables you to communicate with the Massa blockchain. It offers an interface to retrieve data directly from the blockchain, interact with smart contracts, acquire and monitor events, and perform additional actions. The library can be used both in browser environments and Node.js runtime. - -## Installation - -`Massa-web3` can be used as a library for frameworks. - -### Library (Node.js/React/Vue.js) usage - -```shell -npm install @massalabs/massa-web3 -```` - -## Browser usage - -For maintenance reasons, a standalone version of the library is no longer provided. To use `massa-web3` in a vanilla JavaScript project, you will need to use a bundler like Vite. - -### Using Vite with npx - -1. **Create a Vite Project:** - - Use `npx` to create a new Vite project: - - ```shell - npx create-vite@latest my-massa-project --template vanilla - cd my-massa-project - ``` - - -2. **Install Massa-Web3:** - - Install the Massa-Web3 libraries: - - ```shell - npm install @massalabs/massa-web3 - npm install @massalabs/wallet-provider - ``` - -3. **Import Massa-Web3:** - - Import the libraries in your `index.html` file and make sure to have a wallet installed (here we use massa station as an example): - - ```html - - ``` - -#### Running the Vite Project - -Run the Vite project: - -```shell -npm run dev -``` - -## Documentation - -- Read the [`Massa-web3 documentation`](https://docs.massa.net) to learn how to use Massa-web3. -- [`TypeDoc API`](https://web3.docs.massa.net) is available for all exported classes, interfaces and methods. -- dApp examples with associated frontend can be found at [massa-sc-examples](https://github.com/massalabs/massa-sc-examples) repository. - -## Contributing -We welcome contributions from the community! - -If you would like to contribute to `massa-web3`, please read the [CONTRIBUTING file](CONTRIBUTING.md). - -## License -`massa-web3` is released under the [MIT License](LICENSE). - -## Powered By -`massa-web3` is developed with love by MassaLabs and powered by a variety of [open-source projects](powered-by.md). diff --git a/packages/massa-web3/babel.config.js b/packages/massa-web3/babel.config.js deleted file mode 100644 index d4f6648f..00000000 --- a/packages/massa-web3/babel.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { presets: ['@babel/preset-env'] } diff --git a/packages/massa-web3/code-snippets/README.md b/packages/massa-web3/code-snippets/README.md deleted file mode 100644 index 713c1c3b..00000000 --- a/packages/massa-web3/code-snippets/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Code Snippets - -**WARNING**: Do not manually edit files in this directory. They are automatically generated. \ No newline at end of file diff --git a/packages/massa-web3/code-snippets/walletGenerateNewAccount.ts b/packages/massa-web3/code-snippets/walletGenerateNewAccount.ts deleted file mode 100644 index fc1ad207..00000000 --- a/packages/massa-web3/code-snippets/walletGenerateNewAccount.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { WalletClient } from '@massalabs/massa-web3' -;(async () => { - const newAccount = await WalletClient.walletGenerateNewAccount() - // print the account address, public and private keys - console.log( - 'Address: ', - newAccount.address, - 'Public key', - newAccount.publicKey, - 'Private key', - newAccount.secretKey - ) -})() diff --git a/packages/massa-web3/examples/.env.example b/packages/massa-web3/examples/.env.example deleted file mode 100644 index 37cc7e50..00000000 --- a/packages/massa-web3/examples/.env.example +++ /dev/null @@ -1,10 +0,0 @@ -DEPLOYER_PRIVATE_KEY="S12srNEAvZrTb9pktYeuePpuM4taW5dfmWAZYtdqyETWTBspkoT1" -RECEIVER_PRIVATE_KEY="S1ykLaxXyMnJoaWLYds8UntqKTamZ4vcxrZ1fdToR8WpWEpk3FC" - -JSON_RPC_URL_PUBLIC=https://buildnet.massa.net/api/v2 -JSON_RPC_URL_PRIVATE=https://buildnet.massa.net/api/v2 - -CHAIN_ID=77658366 - -#JSON_RPC_URL_PUBLIC=http://127.0.0.1:33035 -#JSON_RPC_URL_PRIVATE=http://127.0.0.1:33034 diff --git a/packages/massa-web3/examples/smartContracts/contracts/deployer.wasm b/packages/massa-web3/examples/smartContracts/contracts/deployer.wasm deleted file mode 100644 index 32280eea..00000000 Binary files a/packages/massa-web3/examples/smartContracts/contracts/deployer.wasm and /dev/null differ diff --git a/packages/massa-web3/examples/smartContracts/contracts/deployer_code.ts b/packages/massa-web3/examples/smartContracts/contracts/deployer_code.ts deleted file mode 100644 index 0ca3ded8..00000000 --- a/packages/massa-web3/examples/smartContracts/contracts/deployer_code.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { - generateEvent, - createSC, - getOpData, - call, - functionExists, - hasOpKey, -} from '@massalabs/massa-as-sdk' -import { Args } from '@massalabs/as-types' - -const CONSTRUCTOR = 'constructor' - -/** - * This function deploys and calls the constructor function of the deployed smart contract. - * - * The data structure of the operation datastore must be like describe in - * packages/sc-deployer/src/index.ts - * - * @param _ - not used - */ -export function main(): StaticArray { - const masterKey = new StaticArray(1) - masterKey[0] = 0x00 - if (!hasOpKey(masterKey)) { - return [] - } - const nbSCSer = getOpData(masterKey) - const nbSC = new Args(nbSCSer).nextU64().unwrap() - for (let i: u64 = 0; i < nbSC; i++) { - const keyBaseArgs = new Args().add(i + 1) - const keyBaseCoins = new Args().add(i + 1) - const key = keyBaseArgs.serialize() - if (!hasOpKey(key)) { - return [] - } - const SCBytecode = getOpData(key) - const contractAddr = createSC(SCBytecode) - if (functionExists(contractAddr, CONSTRUCTOR)) { - const argsIdent = new Uint8Array(1) - argsIdent[0] = 0x00 - const keyArgs = keyBaseArgs.add(argsIdent).serialize() - const coinsIdent = new Uint8Array(1) - coinsIdent[0] = 0x01 - const keyCoins = keyBaseCoins.add(coinsIdent).serialize() - let args: Args - if (hasOpKey(keyArgs)) { - args = new Args(getOpData(keyArgs)) - } else { - args = new Args() - } - let coins: u64 - if (hasOpKey(keyCoins)) { - coins = new Args(getOpData(keyCoins)).nextU64().unwrap() - } else { - coins = 0 - } - call(contractAddr, CONSTRUCTOR, args, coins) - } - generateEvent(`Contract deployed at address: ${contractAddr.toString()}`) - } - return [] -} diff --git a/packages/massa-web3/examples/smartContracts/contracts/package-lock.json b/packages/massa-web3/examples/smartContracts/contracts/package-lock.json deleted file mode 100644 index 47c638a8..00000000 --- a/packages/massa-web3/examples/smartContracts/contracts/package-lock.json +++ /dev/null @@ -1,2309 +0,0 @@ -{ - "name": "contracts", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "devDependencies": { - "@massalabs/as-types": "^1.0.0", - "@massalabs/massa-as-sdk": "^2.1.0", - "assemblyscript": "^0.25.2", - "npm-run-all": "^4.1.5" - } - }, - "node_modules/@adraffy/ens-normalize": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", - "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==", - "dev": true - }, - "node_modules/@massalabs/as-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@massalabs/as-types/-/as-types-1.1.0.tgz", - "integrity": "sha512-wNc/CUFQxSeSGXpMP5jBccQji+JbbISWSM1K9FH71GtHBaIOrYOYxoG0+UjVex5YjcV2fmgeCYwn4wKpe92c9g==", - "dev": true, - "dependencies": { - "as-bignum": "^0.2.31", - "assemblyscript": "^0.25.2" - } - }, - "node_modules/@massalabs/massa-as-sdk": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/@massalabs/massa-as-sdk/-/massa-as-sdk-2.5.4.tgz", - "integrity": "sha512-rg+TECOiOxpGnDv4rj5yrNc1NeBZtcFtpCJZzyOAoQP0NrHUfPG4TmX4Nnu9l7PUGowald+goPJZDBeBT/1NrQ==", - "dev": true, - "dependencies": { - "ethers": "^6.8.1", - "js-sha3": "^0.9.2" - } - }, - "node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "dev": true, - "dependencies": { - "@noble/hashes": "1.3.2" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "dev": true, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@types/node": { - "version": "18.15.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", - "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", - "dev": true - }, - "node_modules/aes-js": { - "version": "4.0.0-beta.5", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", - "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", - "dev": true - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/as-bignum": { - "version": "0.2.40", - "resolved": "https://registry.npmjs.org/as-bignum/-/as-bignum-0.2.40.tgz", - "integrity": "sha512-fql9j63qUCmWwgWB3qW7+S8vp1DUrqSgFnpn/L3O2bjHMW52GZ0H/DfwLCQUAgQS15gsMsjwzMT14A2KCxu0cA==", - "dev": true - }, - "node_modules/assemblyscript": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.25.2.tgz", - "integrity": "sha512-67TQOMvKo23htvSK6lhOzsoQjnplNKkdwgq925uBvQZLDbg9pHfAWhg/R8i8tqKrtk6GH8haOJbQY4oNSQqehA==", - "dev": true, - "dependencies": { - "binaryen": "110.0.0-nightly.20221105", - "long": "^5.2.0" - }, - "bin": { - "asc": "bin/asc.js", - "asinit": "bin/asinit.js" - }, - "engines": { - "node": ">=16.0.0", - "npm": ">=7.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/assemblyscript" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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 - }, - "node_modules/binaryen": { - "version": "110.0.0-nightly.20221105", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-110.0.0-nightly.20221105.tgz", - "integrity": "sha512-OBESOc51q3SwgG8Uv8nMzGnSq7LJpSB/Fu8B3AjlZg6YtCEwRnlDWlnwNB6mdql+VdexfKmNcsrs4K7MYidmdQ==", - "dev": true, - "bin": { - "wasm-opt": "bin/wasm-opt", - "wasm2js": "bin/wasm2js" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "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 - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/ethers": { - "version": "6.9.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.9.2.tgz", - "integrity": "sha512-YpkrtILnMQz5jSEsJQRTpduaGT/CXuLnUIuOYzHA0v/7c8IX91m2J48wSKjzGL5L9J/Us3tLoUdb+OwE3U+FFQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/ethers-io/" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@adraffy/ens-normalize": "1.10.0", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.2", - "@types/node": "18.15.13", - "aes-js": "4.0.0-beta.5", - "tslib": "2.4.0", - "ws": "8.5.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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 - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-sha3": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.3.tgz", - "integrity": "sha512-BcJPCQeLg6WjEx3FE591wVAevlli8lxsxm9/FzV4HXkV49TmBH38Yvrpce6fjbADGMKFrBMGTqrVz3qPIZ88Gg==", - "dev": true - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/long": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", - "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==", - "dev": true - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "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, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - }, - "bin": { - "npm-run-all": "bin/npm-run-all/index.js", - "run-p": "bin/run-p/index.js", - "run-s": "bin/run-s/index.js" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "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 - }, - "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pidtree": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", - "dev": true, - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shell-quote": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.0.tgz", - "integrity": "sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", - "dev": true - }, - "node_modules/string.prototype.padend": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz", - "integrity": "sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - } - }, - "dependencies": { - "@adraffy/ens-normalize": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", - "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==", - "dev": true - }, - "@massalabs/as-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@massalabs/as-types/-/as-types-1.1.0.tgz", - "integrity": "sha512-wNc/CUFQxSeSGXpMP5jBccQji+JbbISWSM1K9FH71GtHBaIOrYOYxoG0+UjVex5YjcV2fmgeCYwn4wKpe92c9g==", - "dev": true, - "requires": { - "as-bignum": "^0.2.31", - "assemblyscript": "^0.25.2" - } - }, - "@massalabs/massa-as-sdk": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/@massalabs/massa-as-sdk/-/massa-as-sdk-2.5.4.tgz", - "integrity": "sha512-rg+TECOiOxpGnDv4rj5yrNc1NeBZtcFtpCJZzyOAoQP0NrHUfPG4TmX4Nnu9l7PUGowald+goPJZDBeBT/1NrQ==", - "dev": true, - "requires": { - "ethers": "^6.8.1", - "js-sha3": "^0.9.2" - } - }, - "@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "dev": true, - "requires": { - "@noble/hashes": "1.3.2" - } - }, - "@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "dev": true - }, - "@types/node": { - "version": "18.15.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", - "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", - "dev": true - }, - "aes-js": { - "version": "4.0.0-beta.5", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", - "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - } - }, - "as-bignum": { - "version": "0.2.40", - "resolved": "https://registry.npmjs.org/as-bignum/-/as-bignum-0.2.40.tgz", - "integrity": "sha512-fql9j63qUCmWwgWB3qW7+S8vp1DUrqSgFnpn/L3O2bjHMW52GZ0H/DfwLCQUAgQS15gsMsjwzMT14A2KCxu0cA==", - "dev": true - }, - "assemblyscript": { - "version": "0.25.2", - "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.25.2.tgz", - "integrity": "sha512-67TQOMvKo23htvSK6lhOzsoQjnplNKkdwgq925uBvQZLDbg9pHfAWhg/R8i8tqKrtk6GH8haOJbQY4oNSQqehA==", - "dev": true, - "requires": { - "binaryen": "110.0.0-nightly.20221105", - "long": "^5.2.0" - } - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, - "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 - }, - "binaryen": { - "version": "110.0.0-nightly.20221105", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-110.0.0-nightly.20221105.tgz", - "integrity": "sha512-OBESOc51q3SwgG8Uv8nMzGnSq7LJpSB/Fu8B3AjlZg6YtCEwRnlDWlnwNB6mdql+VdexfKmNcsrs4K7MYidmdQ==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" - } - }, - "es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "ethers": { - "version": "6.9.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.9.2.tgz", - "integrity": "sha512-YpkrtILnMQz5jSEsJQRTpduaGT/CXuLnUIuOYzHA0v/7c8IX91m2J48wSKjzGL5L9J/Us3tLoUdb+OwE3U+FFQ==", - "dev": true, - "requires": { - "@adraffy/ens-normalize": "1.10.0", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.2", - "@types/node": "18.15.13", - "aes-js": "4.0.0-beta.5", - "tslib": "2.4.0", - "ws": "8.5.0" - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "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 - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "js-sha3": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.3.tgz", - "integrity": "sha512-BcJPCQeLg6WjEx3FE591wVAevlli8lxsxm9/FzV4HXkV49TmBH38Yvrpce6fjbADGMKFrBMGTqrVz3qPIZ88Gg==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "long": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", - "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==", - "dev": true - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - } - }, - "object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "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 - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pidtree": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - } - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "shell-quote": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.0.tgz", - "integrity": "sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", - "dev": true - }, - "string.prototype.padend": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz", - "integrity": "sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "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 - }, - "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true - }, - "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - } - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - } - }, - "ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", - "dev": true, - "requires": {} - } - } -} diff --git a/packages/massa-web3/examples/smartContracts/contracts/package.json b/packages/massa-web3/examples/smartContracts/contracts/package.json deleted file mode 100644 index 393550a8..00000000 --- a/packages/massa-web3/examples/smartContracts/contracts/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "module", - "scripts": { - "build:1": "asc deployer_code.ts --target release --exportRuntime --runtime stub --outFile deployer.wasm", - "build:2": "asc sc_code.ts --target release --exportRuntime --runtime stub --outFile sc.wasm", - "build": "run-s build:1 build:2" - }, - "devDependencies": { - "@massalabs/as-types": "^1.0.0", - "@massalabs/massa-as-sdk": "^2.1.0", - "assemblyscript": "^0.25.2", - "npm-run-all": "^4.1.5" - } -} diff --git a/packages/massa-web3/examples/smartContracts/contracts/sc.wasm b/packages/massa-web3/examples/smartContracts/contracts/sc.wasm deleted file mode 100644 index 27a2be86..00000000 Binary files a/packages/massa-web3/examples/smartContracts/contracts/sc.wasm and /dev/null differ diff --git a/packages/massa-web3/examples/smartContracts/contracts/sc_code.ts b/packages/massa-web3/examples/smartContracts/contracts/sc_code.ts deleted file mode 100644 index 32d8cbd8..00000000 --- a/packages/massa-web3/examples/smartContracts/contracts/sc_code.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { - generateEvent, - Context, - callerHasWriteAccess, - Storage, -} from '@massalabs/massa-as-sdk' -import { Args, Result, Serializable, stringToBytes } from '@massalabs/as-types' - -const MUSIC_ALBUM_KEY = 'MUSIC_ALBUM_KEY' - -class MusicAlbum implements Serializable { - constructor( - public id: string = '', - public title: string = '', - public artist: string = '', - public album: string = '', - public year: u64 = 0 - ) {} - - public serialize(): StaticArray { - const args = new Args() - args.add(this.id) - args.add(this.title) - args.add(this.artist) - args.add(this.album) - args.add(this.year) - return args.serialize() - } - - public deserialize(data: StaticArray, offset: i32 = 0): Result { - const args = new Args(data, offset) - - const id = args.nextString() - if (id.isErr()) { - return new Result(0, "Can't deserialize the id") - } - this.id = id.unwrap() - - const title = args.nextString() - if (title.isErr()) { - return new Result(0, "Can't deserialize the title") - } - this.title = title.unwrap() - - const artist = args.nextString() - if (artist.isErr()) { - return new Result(0, "Can't deserialize the artist") - } - this.artist = artist.unwrap() - - const album = args.nextString() - if (album.isErr()) { - return new Result(0, "Can't deserialize the album") - } - this.album = album.unwrap() - - const year = args.nextU64() - if (year.isErr()) { - return new Result(0, "Can't deserialize the year") - } - this.year = year.unwrap() - - return new Result(args.offset) - } -} - -/** - * This function is meant to be called only one time: when the contract is deployed. - * - * @param _args - Arguments serialized with Args - */ -export function constructor(): StaticArray { - // This line is important. It ensure that this function can't be called in the future. - // If you remove this check someone could call your constructor function and reset your SC. - if (!callerHasWriteAccess()) { - return [] - } - generateEvent(`Constructor called on contract ${Context.callee().toString()}`) - createInitialMusicShop() - return [] -} - -function createInitialMusicShop(): void { - const musicAlbum = new MusicAlbum('1', 'CD', 'Nirvana', 'Nevermind', 1991) - Storage.set( - stringToBytes(`${MUSIC_ALBUM_KEY}_${musicAlbum.id}`), - musicAlbum.serialize() - ) -} - -export function addMusicAlbum(binaryArgs: StaticArray): void { - // convert the binary input to Args - const args: Args = new Args(binaryArgs) - - // safely unwrap the request data - const musicAlbum: MusicAlbum = args.nextSerializable().unwrap() - - // assemble the storage key - const storageKey = `${MUSIC_ALBUM_KEY}_${musicAlbum.id}` - - // check music album does not already exist - const musicAlbumExists = Storage.has(storageKey) - assert(!musicAlbumExists, 'Music Album already exists') - - // save music album to storage - Storage.set(stringToBytes(storageKey), musicAlbum.serialize()) -} - -export function getMusicAlbum(binaryArgs: StaticArray): StaticArray { - // convert the binary input to Args - const args = new Args(binaryArgs) - - // safely unwrap the request data - const musicAlbumId = args.nextString().unwrap() - - // assemble the storage key - const storageKey = `${MUSIC_ALBUM_KEY}_${musicAlbumId}` - - // check music album must already exist - const musicAlbumExists = Storage.has(storageKey) - assert(musicAlbumExists, 'Music Album does not exist') - - // get the serialized music album info - return Storage.get(stringToBytes(storageKey)) -} - -export function deleteMusicAlbum(binaryArgs: StaticArray): void { - // convert the binary input to Args - const args = new Args(binaryArgs) - - // safely unwrap the request data - const musicAlbumId = args.nextString().unwrap() - - // assemble the storage key - const storageKey = `${MUSIC_ALBUM_KEY}_${musicAlbumId}` - - // check music album must already exist - const musicAlbumExists = Storage.has(storageKey) - assert(musicAlbumExists, 'Music Album does not exist') - - // delete the serialized music album info - return Storage.del(stringToBytes(storageKey)) -} diff --git a/packages/massa-web3/examples/smartContracts/contracts/tsconfig.json b/packages/massa-web3/examples/smartContracts/contracts/tsconfig.json deleted file mode 100644 index 91cf15ab..00000000 --- a/packages/massa-web3/examples/smartContracts/contracts/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "assemblyscript/std/assembly.json", - "include": [ - "**/*.ts" - ], - "typedocOptions": { - "exclude": "assembly/**/__tests__", - "excludePrivate": true, - "excludeProtected": true, - "excludeExternals": true, - "includeVersion": true, - "skipErrorChecking": true - } -} \ No newline at end of file diff --git a/packages/massa-web3/examples/smartContracts/deployer.ts b/packages/massa-web3/examples/smartContracts/deployer.ts deleted file mode 100644 index c95e9fb3..00000000 --- a/packages/massa-web3/examples/smartContracts/deployer.ts +++ /dev/null @@ -1,195 +0,0 @@ -/* eslint-disable no-console */ -/* eslint-disable @typescript-eslint/no-var-requires */ -import { IContractData } from '../../src/interfaces/IContractData' -import { Client } from '../../src/web3/Client' -import { EOperationStatus } from '../../src/interfaces/EOperationStatus' - -import { readFileSync } from 'fs' - -import { - Args, - MAX_GAS_DEPLOYMENT, - fromMAS, - u64ToBytes, - u8toByte, -} from '../../src' -import { IBaseAccount } from '../../src/interfaces/IBaseAccount' -const path = require('path') -const chalk = require('chalk') - -interface ISCData { - data: Uint8Array - args?: Args - coins: bigint -} - -async function checkBalance( - web3Client: Client, - account: IBaseAccount, - requiredBalance: bigint -) { - const balance = await web3Client - .wallet() - .getAccountBalance(account.address() as string) - if (!balance?.final || balance.final < requiredBalance) { - throw new Error('Insufficient MAS balance.') - } -} - -export async function awaitTxConfirmation( - web3Client: Client, - deploymentOperationId: string -): Promise { - console.log(`Awaiting ${chalk.green('FINAL')} transaction status....`) - let status: EOperationStatus - try { - status = await web3Client - .smartContracts() - .awaitRequiredOperationStatus( - deploymentOperationId, - EOperationStatus.SPECULATIVE_SUCCESS - ) - console.log( - `Transaction with Operation ID ${chalk.yellow( - deploymentOperationId - )} has reached finality!` - ) - } catch (ex) { - const msg = chalk.red( - `Error getting finality of transaction ${chalk.yellow( - deploymentOperationId - )}` - ) - console.error(msg) - throw new Error(ex) - } - - if (status !== EOperationStatus.SPECULATIVE_SUCCESS) { - const msg = chalk.red( - `Transaction ${chalk.yellow( - deploymentOperationId - )} did not reach finality after considerable amount of time. Try redeploying anew` - ) - console.error(msg) - throw new Error(msg) - } -} - -export const deploySmartContracts = async ( - contractsToDeploy: ISCData[], - web3Client: Client, - deployerAccount: IBaseAccount, - fee = fromMAS(0.01), - maxGas = MAX_GAS_DEPLOYMENT, - maxCoins = fromMAS(0.1) -): Promise => { - let deploymentOperationId: string - try { - // do checks - if (!deployerAccount) { - const baseAccount = web3Client.wallet().getBaseAccount() - if (baseAccount === null) { - throw new Error('Failed to get base account') - } else { - deployerAccount = baseAccount - } - } - - // check deployer account balance - const coinsRequired = contractsToDeploy.reduce( - (acc, contract) => acc + contract.coins, - 0n - ) - await checkBalance(web3Client, deployerAccount, coinsRequired) - - // construct a new datastore - const datastore = new Map() - - // set the number of contracts - datastore.set( - new Uint8Array([0x00]), - u64ToBytes(BigInt(contractsToDeploy.length)) - ) - // loop through all contracts and fill datastore - for (let i = 0; i < contractsToDeploy.length; i++) { - const contract: ISCData = contractsToDeploy[i] - - datastore.set(u64ToBytes(BigInt(i + 1)), contract.data) - if (contract.args) { - datastore.set( - new Uint8Array( - new Args() - .addU64(BigInt(i + 1)) - .addUint8Array(u8toByte(0)) - .serialize() - ), - new Uint8Array(contract.args.serialize()) - ) - } - if (contract.coins > 0) { - datastore.set( - new Uint8Array( - new Args() - .addU64(BigInt(i + 1)) - .addUint8Array(u8toByte(1)) - .serialize() - ), - u64ToBytes(contract.coins) // scaled value to be provided here - ) - } - } - - // deploy deployer contract - console.log(`Running ${chalk.green('deployment')} of smart contract....`) - try { - const coins = contractsToDeploy.reduce( - // scaled value to be provided here - (acc, contract) => contract.coins + acc, - 0n - ) - console.log('Sending coins ... ', coins.toString()) - const baseAccount = web3Client.wallet().getBaseAccount() - - if (!baseAccount) { - throw new Error('Failed to get base account') - } - - deploymentOperationId = await web3Client - .smartContracts() - .deploySmartContract( - { - contractDataBinary: readFileSync( - path.join(__dirname, '.', 'contracts', '/deployer.wasm') - ), - datastore, - fee, - maxGas, - maxCoins, - } as IContractData, - baseAccount - ) - console.log( - `Smart Contract ${chalk.green( - 'successfully' - )} deployed to Massa Network. Operation ID ${chalk.yellow( - deploymentOperationId - )}` - ) - } catch (ex) { - const msg = chalk.red( - `Error deploying deployer smart contract to Massa Network` - ) - console.error(msg) - throw new Error(ex) - } - } catch (ex) { - const msg = chalk.red( - `Error deploying deployer smart contract to Massa Network` - ) - console.error(msg) - throw new Error(ex) - } - console.log(`Smart Contract Deployment finished!`) - - return deploymentOperationId -} diff --git a/packages/massa-web3/examples/smartContracts/index.ts b/packages/massa-web3/examples/smartContracts/index.ts deleted file mode 100644 index 0a0765e8..00000000 --- a/packages/massa-web3/examples/smartContracts/index.ts +++ /dev/null @@ -1,372 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -/* eslint-disable no-console */ -import { IAccount } from '../../src/interfaces/IAccount' -import { IEventFilter } from '../../src/interfaces/IEventFilter' -import { ClientFactory } from '../../src/web3/ClientFactory' -import { WalletClient } from '../../src/web3/WalletClient' -import { awaitTxConfirmation, deploySmartContracts } from './deployer' -import { readFileSync } from 'fs' -import { Client } from '../../src/web3/Client' -import { - EventPoller, - ON_MASSA_EVENT_DATA, - ON_MASSA_EVENT_ERROR, -} from '../../src/web3/EventPoller' -import { INodeStatus } from '../../src/interfaces/INodeStatus' -import { withTimeoutRejection } from '../../src/utils/time' -import { IDatastoreEntryInput } from '../../src/interfaces/IDatastoreEntryInput' -import { ICallData } from '../../src/interfaces/ICallData' -import * as dotenv from 'dotenv' -import { IProvider, ProviderType } from '../../src/interfaces/IProvider' -import { - Args, - CHAIN_ID, - IDeserializedResult, - IEvent, - ISerializable, - fromMAS, - strToBytes, - toMAS, -} from '../../src' -import { getEnvVariable } from '../utils' - -const path = require('path') -const chalk = require('chalk') -const ora = require('ora') - -class MusicAlbum implements ISerializable { - constructor( - public id: string = '', - public title: string = '', - public artist: string = '', - public album: string = '', - public year = 0 - ) {} - - public serialize(): Uint8Array { - const args = new Args() - args.addString(this.id) - args.addString(this.title) - args.addString(this.artist) - args.addString(this.album) - args.addU64(BigInt(this.year)) - return Uint8Array.from(args.serialize()) - } - - public deserialize( - data: Uint8Array, - offset: number - ): IDeserializedResult { - const args = new Args(data, offset) - - const id = args.nextString() - this.id = id - - const title = args.nextString() - this.title = title - - const artist = args.nextString() - this.artist = artist - - const album = args.nextString() - this.album = album - - const year = args.nextU64() - this.year = Number(year) - - return { - instance: this, - offset: args.getOffset(), - } as IDeserializedResult - } -} - -dotenv.config({ - path: path.resolve(__dirname, '..', '.env'), -}) - -const publicApi = getEnvVariable('JSON_RPC_URL_PUBLIC') -const privateApi = getEnvVariable('JSON_RPC_URL_PRIVATE') -const chainId = CHAIN_ID.BuildNet -const deployerPrivateKey = getEnvVariable('DEPLOYER_PRIVATE_KEY') -const MASSA_EXEC_ERROR = 'massa_execution_error' - -interface IEventPollerResult { - isError: boolean - eventPoller: EventPoller - events: IEvent[] -} - -const pollAsyncEvents = async ( - web3Client: Client, - opId: string -): Promise => { - // determine the last slot - let nodeStatusInfo: INodeStatus | null | undefined = await web3Client - .publicApi() - .getNodeStatus() - - // set the events filter - const eventsFilter = { - start: (nodeStatusInfo as INodeStatus).last_slot, - end: null, - original_caller_address: null, - original_operation_id: opId, - emitter_address: null, - is_final: false, - } as IEventFilter - - const eventPoller = EventPoller.startEventsPolling( - eventsFilter, - 1000, - web3Client - ) - - return new Promise((resolve, reject) => { - eventPoller.on(ON_MASSA_EVENT_DATA, (events: Array) => { - console.log('Event Data Received:', events) - let errorEvents: IEvent[] = events.filter((e) => - e.data.includes(MASSA_EXEC_ERROR) - ) - if (errorEvents.length > 0) { - return resolve({ - isError: true, - eventPoller, - events: errorEvents, - } as IEventPollerResult) - } - - if (events.length) { - return resolve({ - isError: false, - eventPoller, - events, - } as IEventPollerResult) - } else { - console.log('No events have been emitted during deployment') - } - }) - eventPoller.on(ON_MASSA_EVENT_ERROR, (error: Error) => { - console.log('Event Data Error:', error) - return reject(error) - }) - }) -} - -;(async () => { - const header = '='.repeat(process.stdout.columns - 1) - console.log(header) - console.log(`${chalk.green.bold('Massa Smart Contract Interaction Example')}`) - console.log(header) - - let spinner - try { - // init client - const deployerAccount: IAccount = - await WalletClient.getAccountFromSecretKey(deployerPrivateKey) - - const web3Client: Client = await ClientFactory.createCustomClient( - [ - { url: publicApi, type: ProviderType.PUBLIC } as IProvider, - { url: privateApi, type: ProviderType.PRIVATE } as IProvider, - ], - chainId, - true, - deployerAccount - ) - - const accountAddress = deployerAccount.address - - if (!accountAddress) { - throw new Error('Missing account address') - } - - const deployerAccountBalance = await web3Client - .wallet() - .getAccountBalance(accountAddress) - - console.log( - `Deployer Wallet Address: ${accountAddress} with balance (candidate, final) = (${toMAS( - deployerAccountBalance?.candidate.toString() as string - )}, ${toMAS(deployerAccountBalance?.final.toString() as string)})` - ) - - // deploy smart contract - spinner = ora( - `Running ${chalk.green('deployment')} of deployer smart contract....` - ).start() - - const baseAccount = web3Client.wallet().getBaseAccount() - - if (!baseAccount) { - throw new Error('Failed to get base account') - } - - const deploymentOperationId = await deploySmartContracts( - [ - { - data: readFileSync( - path.join(__dirname, '.', 'contracts', '/sc.wasm') - ), - args: undefined, - coins: fromMAS(0.1), - }, - ], - web3Client, - baseAccount, - fromMAS(0.01), - 3000_000_000n, - fromMAS(1.5) - ) - - spinner.succeed( - `Deployed Smart Contract ${chalk.green( - 'successfully' - )} with opId ${deploymentOperationId}` - ) - - // async poll events in the background for the given opId - const { isError, eventPoller, events }: IEventPollerResult = - await withTimeoutRejection( - pollAsyncEvents(web3Client, deploymentOperationId), - 20000 - ) - - // stop polling - eventPoller.stopPolling() - - // if errors, don't await finalization - if (isError) { - throw new Error( - `Massa Deployment Error: ${JSON.stringify(events, null, 4)}` - ) - } - - // await finalization - await awaitTxConfirmation(web3Client, deploymentOperationId) - - // find an event that contains the emitted sc address - spinner = ora(`Extracting deployed sc address from events....`).start() - const addressEvent: IEvent | undefined = events.find((event) => - event.data.includes('Contract deployed at address') - ) - if (!addressEvent) { - throw new Error( - 'No events were emitted from contract containing a message `SC created at:...`. Please make sure to include such a message in order to fetch the sc address' - ) - } - const scAddress: string = addressEvent.data.split(':')[1].trim() - spinner.succeed(`Smart Contract Address: ${chalk.yellow(scAddress)}`) - - // ========================================= - // get function return value: get the music album - spinner = ora( - `Getting a function return value from the deployed smart contract...` - ).start() - const args = new Args().addString('1') - const result = await web3Client.smartContracts().readSmartContract({ - maxGas: 2000_000_000n, - targetAddress: scAddress, - targetFunction: 'getMusicAlbum', - parameter: args.serialize(), - coins: 0n, - fee: fromMAS(0.01), - }) - - const res = new Args(result.returnValue, 0) - const musicAlbum = res.nextSerializable(MusicAlbum) - spinner.succeed( - `Function Return Value: ${JSON.stringify(musicAlbum, null, 4)}` - ) - - // ========================================= - // make a smart contract call: delete the music album - spinner = ora( - `Calling a set function on the deployed smart contract...` - ).start() - const deleteMusicAlbumArgs = new Args().addString('1') - const deleteMusicAlbumCallOperationId = await web3Client - .smartContracts() - .callSmartContract({ - fee: fromMAS(0.01), - coins: 0n, - targetAddress: scAddress, - targetFunction: 'deleteMusicAlbum', - parameter: deleteMusicAlbumArgs.serialize(), - } as ICallData) - spinner.succeed( - `Delete Music Album operation ID: ${deleteMusicAlbumCallOperationId}` - ) - - // await finalization - await awaitTxConfirmation(web3Client, deleteMusicAlbumCallOperationId) - - // ========================================= - // make a smart contract call: create a new music album - spinner = ora( - `Calling a set function on the deployed smart contract...` - ).start() - const newMusicAlbum = new MusicAlbum( - '1', - 'CD', - 'The Beatles', - 'Let It Be', - 1970 - ) - const createMusicAlbumCallArgs = new Args(newMusicAlbum.serialize()) - const createMusicAlbumCallOperationId = await web3Client - .smartContracts() - .callSmartContract({ - fee: fromMAS(0.01), - coins: 0n, - targetAddress: scAddress, - targetFunction: 'addMusicAlbum', - parameter: createMusicAlbumCallArgs.serialize(), - } as ICallData) - spinner.succeed( - `Create Music Album Operation ID: ${createMusicAlbumCallOperationId}` - ) - - // await finalization - await awaitTxConfirmation(web3Client, createMusicAlbumCallOperationId) - - // ========================================= - // read value from store: read music album content - spinner = ora( - `Reading Music Album from the deployed smart contract storage...` - ).start() - const scStorage = await web3Client.publicApi().getDatastoreEntries([ - { - address: scAddress, - key: strToBytes(`MUSIC_ALBUM_KEY_1`), - } as IDatastoreEntryInput, - ]) - if (!scStorage[0].final_value) { - spinner.fail(`Storage contains null for that key. Something is wrong`) - } else { - const res = new Args(scStorage[0].final_value, 0) - const musicAlbum = res.nextSerializable(MusicAlbum) - spinner.succeed( - `Music Album from Storage: ${JSON.stringify(musicAlbum, null, 4)}` - ) - } - - // ========================================= - // read contract balance - spinner = ora(`Getting deployed smart contract balance...`).start() - const contractBalance = await web3Client - .smartContracts() - .getContractBalance(scAddress) - spinner.succeed( - `Deployed smart contract balance (candidate, final) = $(${toMAS( - contractBalance?.candidate.toString() as string - )},${toMAS(contractBalance?.final.toString() as string)})` - ) - process.exit(0) - } catch (ex) { - console.error(ex) - const msg = chalk.red(`Error = ${ex}`) - if (spinner) spinner.fail(msg) - process.exit(-1) - } -})() diff --git a/packages/massa-web3/examples/smartContracts/nameResolver.ts b/packages/massa-web3/examples/smartContracts/nameResolver.ts deleted file mode 100644 index 3bda352a..00000000 --- a/packages/massa-web3/examples/smartContracts/nameResolver.ts +++ /dev/null @@ -1,161 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -/* eslint-disable no-console */ -import { IAccount } from '../../src/interfaces/IAccount' -import { ClientFactory } from '../../src/web3/ClientFactory' -import { WalletClient } from '../../src/web3/WalletClient' -import { Client } from '../../src/web3/Client' -import { ICallData } from '../../src/interfaces/ICallData' -import * as dotenv from 'dotenv' -import { IProvider, ProviderType } from '../../src/interfaces/IProvider' -import { - Args, - CHAIN_ID, - EOperationStatus, - ITransactionData, - fromMAS, -} from '../../src' -import { getEnvVariable } from '../utils' - -const path = require('path') -const chalk = require('chalk') -const ora = require('ora') - -dotenv.config({ - path: path.resolve(__dirname, '..', '.env'), -}) - -const publicApi = getEnvVariable('JSON_RPC_URL_PUBLIC') -const privateApi = getEnvVariable('JSON_RPC_URL_PRIVATE') -const chainId = CHAIN_ID.BuildNet -const privateKey = getEnvVariable('DEPLOYER_PRIVATE_KEY') - -;(async () => { - const header = '='.repeat(process.stdout.columns - 1) - console.log(header) - console.log(`${chalk.green.bold('Massa Name Service Resolver Example')}`) - console.log(header) - - let spinner - try { - // init client - const deployerAccount: IAccount = - await WalletClient.getAccountFromSecretKey(privateKey) - const web3Client: Client = await ClientFactory.createCustomClient( - [ - { url: publicApi, type: ProviderType.PUBLIC } as IProvider, - { url: privateApi, type: ProviderType.PRIVATE } as IProvider, - ], - chainId, - true, - deployerAccount - ) - - // Try to register a domain - const domain = 'example' - const address = deployerAccount.address as string - - spinner = ora('Trying to create the domain').start() - try { - const domainCreationOpId = await web3Client - .smartContracts() - .callSmartContract({ - fee: fromMAS(0.01), - coins: fromMAS(2), - targetAddress: web3Client.mnsResolver().getMnsResolverAddress(), - targetFunction: 'dnsAlloc', - parameter: new Args() - .addString(domain) - .addString(address) - .serialize(), - } as ICallData) - await web3Client - .smartContracts() - .awaitMultipleRequiredOperationStatus(domainCreationOpId, [ - EOperationStatus.SPECULATIVE_SUCCESS, - EOperationStatus.SPECULATIVE_ERROR, - ]) - spinner.succeed('Domain created successfully') - } catch (ex) { - spinner.succeed('Domain already exists') - } - - // Try to resolve the domain - spinner = ora('Trying to resolve the domain').start() - const resolvedAddress = await web3Client - .mnsResolver() - .resolve(domain + '.massa') - spinner.succeed(`Domain resolved to address ${resolvedAddress}`) - - // Try to send a transaction to the resolved address - spinner = ora( - 'Trying to send a transaction to the resolved address' - ).start() - const txData = { - amount: fromMAS(1), - recipientAddress: resolvedAddress, - fee: fromMAS(0.01), - } as ITransactionData - const txOpId = await web3Client.wallet().sendTransaction(txData) - await web3Client - .smartContracts() - .awaitMultipleRequiredOperationStatus(txOpId[0], [ - EOperationStatus.SPECULATIVE_SUCCESS, - ]) - spinner.succeed('Transaction sent successfully') - // Try to call a function on the resolved address - spinner = ora('Trying to call a function on the resolved address').start() - const callData = { - fee: fromMAS(0.01), - coins: fromMAS(1), - targetAddress: resolvedAddress, - targetFunction: 'getBalance', - parameter: new Args().serialize(), - } - - try { - await web3Client.smartContracts().callSmartContract(callData) - } catch (ex) { - if ( - ex.message.endsWith( - `The called address ${resolvedAddress} is not a smart contract address` - ) - ) { - spinner.succeed('Call smart contract resolved address successfully') - } else { - spinner.fail('Call smart contract resolved address failed') - throw ex - } - } - - // Try to call a read only function on the resolved address - spinner = ora( - 'Trying to call a read only function on the resolved address' - ).start() - const callReadOnlyData = { - fee: fromMAS(0.01), - targetAddress: resolvedAddress, - targetFunction: 'getBalance', - parameter: new Args().serialize(), - } - - try { - await web3Client.smartContracts().readSmartContract(callReadOnlyData) - } catch (ex) { - if ( - ex.message.endsWith( - `The called address ${resolvedAddress} is not a smart contract address` - ) - ) { - spinner.succeed('Read smart contract resolved address successfully') - } else { - spinner.fail('Read smart contract resolved address failed') - throw ex - } - } - } catch (ex) { - console.error(ex) - const msg = chalk.red(`Error = ${ex}`) - if (spinner) spinner.fail(msg) - process.exit(-1) - } -})() diff --git a/packages/massa-web3/examples/tsconfig.json b/packages/massa-web3/examples/tsconfig.json deleted file mode 100644 index 2d186fad..00000000 --- a/packages/massa-web3/examples/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "include": [ - "./smartContracts/**/*.ts", - "./wallet/**/*.ts" - ], - "exclude": [ - "./smartContracts/contract/**/*.ts" - ] -} \ No newline at end of file diff --git a/packages/massa-web3/examples/utils.ts b/packages/massa-web3/examples/utils.ts deleted file mode 100644 index ceeb156a..00000000 --- a/packages/massa-web3/examples/utils.ts +++ /dev/null @@ -1,7 +0,0 @@ -export function getEnvVariable(key: string): string { - const value = process.env[key] - if (!value) { - throw new Error(`Missing ${key} in .env file`) - } - return value -} diff --git a/packages/massa-web3/examples/wallet/index.ts b/packages/massa-web3/examples/wallet/index.ts deleted file mode 100644 index a6ef7d07..00000000 --- a/packages/massa-web3/examples/wallet/index.ts +++ /dev/null @@ -1,178 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -/* eslint-disable no-console */ -import { IAccount } from '../../src/interfaces/IAccount' -import { IEventFilter } from '../../src/interfaces/IEventFilter' -import { ClientFactory } from '../../src/web3/ClientFactory' -import { WalletClient } from '../../src/web3/WalletClient' -import { EventPoller } from '../../src/web3/EventPoller' -import { ITransactionData } from '../../src/interfaces/ITransactionData' -import { EOperationStatus } from '../../src/interfaces/EOperationStatus' -import { IRollsData } from '../../src/interfaces/IRollsData' -import * as dotenv from 'dotenv' -import { Client } from '../../src/web3/Client' -import { IProvider, ProviderType } from '../../src/interfaces/IProvider' -import { CHAIN_ID, fromMAS } from '../../src' -import { getEnvVariable } from '../utils' -const path = require('path') -const chalk = require('chalk') - -dotenv.config({ - path: path.resolve(__dirname, '..', '.env'), -}) - -const publicApi = getEnvVariable('JSON_RPC_URL_PUBLIC') -const privateApi = getEnvVariable('JSON_RPC_URL_PRIVATE') -const chainId = CHAIN_ID.BuildNet -const deployerPrivateKey = getEnvVariable('DEPLOYER_PRIVATE_KEY') -const receiverPrivateKey = getEnvVariable('RECEIVER_PRIVATE_KEY') - -;(async () => { - const header = '='.repeat(process.stdout.columns - 1) - console.log(header) - console.log(`${chalk.green.bold('Massa Smart Contract Interaction Example')}`) - console.log(header) - - try { - // init account - const deployerAccount: IAccount = - await WalletClient.getAccountFromSecretKey(deployerPrivateKey) - - console.log('Deployer Wallet ', deployerAccount) - - // init web3 client with base account - const web3Client: Client = await ClientFactory.createCustomClient( - [ - { url: publicApi, type: ProviderType.PUBLIC } as IProvider, - { url: privateApi, type: ProviderType.PRIVATE } as IProvider, - ], - chainId, - true, - deployerAccount - ) - - await web3Client.wallet().addAccountsToWallet([deployerAccount]) - - // get wallet balance - const deployerAccountBalance = await web3Client - .wallet() - .getAccountBalance(deployerAccount.address as string) - console.log( - `Deployer Wallet Address: ${ - deployerAccount.address - } with balance (candidate, final) = (${deployerAccountBalance?.candidate.toString()}, ${deployerAccountBalance?.final.toString()})` - ) - - // get wallet accounts - let walletAccounts = await web3Client.wallet().getWalletAccounts() - console.log('Wallet Accounts ', walletAccounts) - - // get wallet info - const walletInfo = await web3Client.wallet().walletInfo() - console.log('Wallet Info ', walletInfo) - - // add a new wallet - console.log('Adding a new Account ...') - await web3Client.wallet().addSecretKeysToWallet([receiverPrivateKey]) - - // get wallet accounts - walletAccounts = await web3Client.wallet().getWalletAccounts() - console.log('Wallet Accounts (UPDATED) ', walletAccounts) - - // get the second account (the receiver) - const senderAccount = walletAccounts[0] - const receiverAccount = walletAccounts[1] - - if (!receiverAccount?.address || !senderAccount?.address) { - throw new Error('Missing receiver account address') - } - - // get receiver's wallet balance - const receiverAccountBalanceBefore = await web3Client - .wallet() - .getAccountBalance(receiverAccount.address) - - console.log( - `Receiver Wallet Balance (Before): ${ - receiverAccount.address - } with balance (candidate, final) = (${receiverAccountBalanceBefore?.candidate.toString()}, ${receiverAccountBalanceBefore?.final.toString()})` - ) - - const message = 'hello world' - - // sign a random wallet message using account2 - const signedMessage = await web3Client - .wallet() - .signMessage(message, chainId, receiverAccount.address) - console.log('Wallet sender signing a message... ', signedMessage) - - if (!deployerAccount?.publicKey || !signedMessage) { - throw new Error('Missing publicKey or signed message') - } - - const isVerified = await web3Client - .wallet() - .verifySignature(message, signedMessage) - console.log('Signature verification: ', isVerified) - - // send from base account to receiver - const txId = await web3Client.wallet().sendTransaction({ - amount: fromMAS(1), - fee: fromMAS(0.01), - recipientAddress: receiverAccount.address, - } as ITransactionData) - console.log('Money Transfer:: TxId ', txId[0]) - - // await finalization - console.log('Awaiting Finalization ...') - await web3Client - .smartContracts() - .awaitRequiredOperationStatus(txId[0], EOperationStatus.FINAL_SUCCESS) - - console.log('Polling events ... ') - const events = await EventPoller.getEventsOnce( - { - start: null, - end: null, - original_operation_id: txId[0], - original_caller_address: null, - emitter_address: null, - } as IEventFilter, - web3Client - ) - console.log('Polled Events ', events) - - // get receiver's wallet after - const receiverAccountBalanceAfter = await web3Client - .wallet() - .getAccountBalance(receiverAccount.address) - console.log( - `Receiver Wallet Balance (After): ${ - receiverAccount.address - } with balance (candidate, final) = (${receiverAccountBalanceAfter?.candidate.toString()}, ${receiverAccountBalanceAfter?.final.toString()})` - ) - - // get sender's wallet after - const senderAccountBalanceAfter = await web3Client - .wallet() - .getAccountBalance(senderAccount.address) - console.log( - `Sender Wallet Balance (After): ${ - receiverAccount.address - } with balance (candidate, final) = (${senderAccountBalanceAfter?.candidate.toString()}, ${senderAccountBalanceAfter?.final.toString()})` - ) - - // sender buys some rolls - const buyRollsTxId = await web3Client.wallet().buyRolls({ - amount: 2n, - fee: fromMAS(0.01), - } as IRollsData) - console.log('Buy Rolls Tx Id ', buyRollsTxId) - - process.exit(0) - } catch (ex) { - console.error(ex) - const msg = chalk.red(`Error = ${ex}`) - console.error(msg) - process.exit(-1) - } -})() diff --git a/packages/massa-web3/jest.config.ts b/packages/massa-web3/jest.config.ts deleted file mode 100644 index 2095669e..00000000 --- a/packages/massa-web3/jest.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import baseConfig from '../../jest.config' -import type { Config } from '@jest/types' - -const config: Config.InitialOptions = { - ...baseConfig, - rootDir: '../..', - displayName: 'massa-web3', - testMatch: ['/packages/massa-web3/test/**/*.(spec|test).ts?(x)'], -} - -export default config diff --git a/packages/massa-web3/package.json b/packages/massa-web3/package.json deleted file mode 100644 index 50c881f7..00000000 --- a/packages/massa-web3/package.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "name": "@massalabs/massa-web3", - "version": "4.0.4", - "description": "massa's web3 sdk client", - "main": "dist/cmd/index.js", - "module": "dist/esm/index.js", - "types": "dist/esm/index.d.ts", - "scripts": { - "up": "npm update", - "check": "npm outdated", - "upgrade": "npm run up && npm run check && npm run build", - "clean-dist": "rimraf dist/*", - "build-esm": "tsc --project tsconfig.esm.json", - "build-commonjs": "tsc --project tsconfig.commonjs.json", - "build": "npm-run-all clean-dist build-*", - "test": "jest --detectOpenHandles --forceExit", - "test:all": "npm run test && npm run test-smart-contract-example && npm run test-mns && npm run test-wallet", - "test:watch": "jest --watch", - "test:watch:all": "jest --watchAll", - "test:cov": "jest --coverage --silent --detectOpenHandles --forceExit", - "test-smart-contract-example": "ts-node ./examples/smartContracts/index.ts", - "test-mns": "ts-node ./examples/smartContracts/nameResolver.ts", - "test-wallet": "ts-node ./examples/wallet/index.ts", - "test-name-service-resolver": "ts-node ./examples/smartContracts/nameResolver.ts", - "check-types": "tsc --noEmit", - "doc": "typedoc src/index.ts --name massa-web3 --out docs/documentation/html --tsconfig tsconfig.json" - }, - "author": "Massa Labs ", - "contributors": [ - "Evgeni Pirianov", - "Yvan Sraka" - ], - "license": "MIT", - "homepage": "https://github.com/massalabs/massa-web3", - "repository": { - "type": "git", - "url": "git+https://github.com/massalabs/massa-web3" - }, - "keywords": [ - "web3", - "ts", - "sdk", - "massa" - ], - "files": [ - "dist", - "bundle.js", - "bundle.min.js" - ], - "dependencies": { - "@massalabs/wallet-provider": "^2.0.0", - "@massalabs/web3-utils": "^1.4.11", - "@noble/ed25519": "^1.7.3", - "@noble/hashes": "^1.2.0", - "@types/ws": "^8.5.4", - "@web3pack/base58-check": "^1.0.3", - "axios": "^0.26.1", - "bignumber.js": "^9.1.1", - "bip39": "^3.0.4", - "bs58check": "^3.0.1", - "buffer": "^6.0.3", - "crypto-js": "^4.1.1", - "dotenv": "^16.0.3", - "js-base64": "^3.7.5", - "string_decoder": "^1.3.0", - "tslib": "^2.5.2", - "util": "^0.12.5", - "varint": "^6.0.0" - }, - "devDependencies": { - "@babel/preset-env": "^7.22.15", - "@types/bn.js": "^5.1.1", - "@types/jest": "^29.5.5", - "@types/node": "^18.13.0", - "@types/secp256k1": "^4.0.3", - "@typescript-eslint/eslint-plugin": "^5.52.0", - "@typescript-eslint/parser": "^5.52.0", - "babel-jest": "^29.7.0", - "chalk": "^4.1.0", - "jest": "^29.5.0", - "jest-environment-jsdom": "^29.5.0", - "jsdom": "^21.1.1", - "node-ts": "^5.1.2", - "npm-run-all": "^4.1.5", - "ora": "^5.1.0", - "rimraf": "^5.0.1", - "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2", - "ts-node": "^10.9.1", - "typedoc": "^0.25.7", - "typescript": "^4.9.5" - }, - "optionalDependencies": { - "bufferutil": "^4.0.7", - "utf-8-validate": "^6.0.2" - } -} diff --git a/packages/massa-web3/powered-by.md b/packages/massa-web3/powered-by.md deleted file mode 100644 index 392fa1d8..00000000 --- a/packages/massa-web3/powered-by.md +++ /dev/null @@ -1,435 +0,0 @@ -# Dependencies Report - -The following is a list of all the dependencies for this package: -## [@massalabs/wallet-provider](git+https://github.com/massalabs/massa-wallet-provider.git) - -**License:** (MIT AND Apache-2.0) - perpetual - -**Used version:** 1.4.1 - -**Many thanks to:** [Massa Labs](info@massa.net) - -## [@noble/ed25519](git+https://github.com/paulmillr/noble-ed25519.git) - -**License:** MIT - perpetual - -**Used version:** 1.7.3 - -**Many thanks to:** Paul Miller (https://paulmillr.com) - -## [@noble/hashes](git+https://github.com/paulmillr/noble-hashes.git) - -**License:** MIT - perpetual - -**Used version:** 1.3.2 - -**Many thanks to:** Paul Miller (https://paulmillr.com) - -## [@types/ws](https://github.com/DefinitelyTyped/DefinitelyTyped.git) - -**License:** MIT - perpetual - -**Used version:** 8.5.7 - -**Many thanks to:** n/a - -## [@web3pack/base58-check](git+https://github.com/Web3Pack/base58-check.git) - -**License:** MIT - perpetual - -**Used version:** 1.0.3 - -**Many thanks to:** Evren Ceyhan - -## [axios](git+https://github.com/axios/axios.git) - -**License:** MIT - perpetual - -**Used version:** 0.26.1 - -**Many thanks to:** Matt Zabriskie - -## [bignumber.js](git+https://github.com/MikeMcl/bignumber.js.git) - -**License:** MIT - perpetual - -**Used version:** 9.1.2 - -**Many thanks to:** Michael Mclaughlin M8ch88l@gmail.com - -## [bip39](git+https://github.com/bitcoinjs/bip39.git) - -**License:** ISC - perpetual - -**Used version:** 3.1.0 - -**Many thanks to:** Wei Lu - -## [bs58check](git+https://github.com/bitcoinjs/bs58check.git) - -**License:** MIT - perpetual - -**Used version:** 3.0.1 - -**Many thanks to:** Daniel Cousens - -## [buffer](git://github.com/feross/buffer.git) - -**License:** MIT - perpetual - -**Used version:** 6.0.3 - -**Many thanks to:** Feross Aboukhadijeh feross@feross.org https://feross.org - -## [crypto-js](git+ssh://git@github.com/brix/crypto-js.git) - -**License:** MIT - perpetual - -**Used version:** 4.1.1 - -**Many thanks to:** Evan Vosberg http://github.com/evanvosberg - -## [dotenv](git://github.com/motdotla/dotenv.git) - -**License:** BSD-2-Clause - perpetual - -**Used version:** 16.3.1 - -**Many thanks to:** n/a - -## [jest-environment-jsdom](git+https://github.com/jestjs/jest.git) - -**License:** MIT - perpetual - -**Used version:** 29.7.0 - -**Many thanks to:** n/a - -## [js-base64](git+https://github.com/dankogai/js-base64.git) - -**License:** BSD-3-Clause - perpetual - -**Used version:** 3.7.5 - -**Many thanks to:** Dan Kogai - -## [string_decoder](git://github.com/nodejs/string_decoder.git) - -**License:** MIT - perpetual - -**Used version:** 1.3.0 - -**Many thanks to:** n/a - -## [tslib](git+https://github.com/Microsoft/tslib.git) - -**License:** 0BSD - perpetual - -**Used version:** 2.6.2 - -**Many thanks to:** Microsoft Corp. - -## [util](git://github.com/browserify/node-util.git) - -**License:** MIT - perpetual - -**Used version:** 0.12.5 - -**Many thanks to:** Joyent http://www.joyent.com - -## [varint](git://github.com/chrisdickinson/varint.git) - -**License:** MIT - perpetual - -**Used version:** 6.0.0 - -**Many thanks to:** [Chris Dickinson](chris@neversaw.us) - -## [@babel/preset-env](https://github.com/babel/babel.git) - -**License:** MIT - perpetual - -**Used version:** 7.22.20 - -**Many thanks to:** The Babel Team (https://babel.dev/team) - -## [@massalabs/eslint-config](git+https://github.com/massalabs/eslint-config.git) - -**License:** ISC - perpetual - -**Used version:** 0.0.9 - -**Many thanks to:** MassaLabs - -## [@massalabs/prettier-config-as](git+https://github.com/massalabs/prettier-config-as.git) - -**License:** MIT - perpetual - -**Used version:** 0.0.2 - -**Many thanks to:** [Nathan SEVA](ns@massa.net) - -## [@massalabs/web3-utils](git+https://github.com/massalabs/web3-utils.git) - -**License:** ISC - perpetual - -**Used version:** 1.4.2 - -**Many thanks to:** - -## [@types/bn.js](https://github.com/DefinitelyTyped/DefinitelyTyped.git) - -**License:** MIT - perpetual - -**Used version:** 5.1.2 - -**Many thanks to:** n/a - -## [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped.git) - -**License:** MIT - perpetual - -**Used version:** 29.5.5 - -**Many thanks to:** n/a - -## [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped.git) - -**License:** MIT - perpetual - -**Used version:** 18.18.4 - -**Many thanks to:** n/a - -## [@types/secp256k1](https://github.com/DefinitelyTyped/DefinitelyTyped.git) - -**License:** MIT - perpetual - -**Used version:** 4.0.4 - -**Many thanks to:** n/a - -## [@typescript-eslint/eslint-plugin](git+https://github.com/typescript-eslint/typescript-eslint.git) - -**License:** MIT - perpetual - -**Used version:** 5.62.0 - -**Many thanks to:** n/a - -## [@typescript-eslint/parser](git+https://github.com/typescript-eslint/typescript-eslint.git) - -**License:** BSD-2-Clause - perpetual - -**Used version:** 5.62.0 - -**Many thanks to:** n/a - -## [babel-jest](git+https://github.com/jestjs/jest.git) - -**License:** MIT - perpetual - -**Used version:** 29.7.0 - -**Many thanks to:** n/a - -## [chalk](git+https://github.com/chalk/chalk.git) - -**License:** MIT - perpetual - -**Used version:** 4.1.2 - -**Many thanks to:** n/a - -## [eslint](git+https://github.com/eslint/eslint.git) - -**License:** MIT - perpetual - -**Used version:** 8.51.0 - -**Many thanks to:** [Nicholas C. Zakas](nicholas+npm@nczconsulting.com) - -## [eslint-config-airbnb-base](git+https://github.com/airbnb/javascript.git) - -**License:** MIT - perpetual - -**Used version:** 15.0.0 - -**Many thanks to:** Jake Teton-Landis (https://twitter.com/@jitl) - -## [eslint-config-standard](git://github.com/standard/eslint-config-standard.git) - -**License:** MIT - perpetual - -**Used version:** 17.1.0 - -**Many thanks to:** Feross Aboukhadijeh feross@feross.org https://feross.org - -## [eslint-plugin-import](git+https://github.com/import-js/eslint-plugin-import.git) - -**License:** MIT - perpetual - -**Used version:** 2.28.1 - -**Many thanks to:** [Ben Mosher](me@benmosher.com) - -## [eslint-plugin-jsdoc](git+https://github.com/gajus/eslint-plugin-jsdoc.git) - -**License:** BSD-3-Clause - perpetual - -**Used version:** 40.3.0 - -**Many thanks to:** Gajus Kuizinas gajus@gajus.com http://gajus.com - -## [eslint-plugin-node](git+https://github.com/mysticatea/eslint-plugin-node.git) - -**License:** MIT - perpetual - -**Used version:** 11.1.0 - -**Many thanks to:** Toru Nagashima - -## [eslint-plugin-promise](git+https://github.com/eslint-community/eslint-plugin-promise.git) - -**License:** ISC - perpetual - -**Used version:** 6.1.1 - -**Many thanks to:** [jden](jason@denizac.org) - -## [husky](git+https://github.com/typicode/husky.git) - -**License:** MIT - perpetual - -**Used version:** 8.0.3 - -**Many thanks to:** [Typicode](typicode@gmail.com) - -## [jest](git+https://github.com/jestjs/jest.git) - -**License:** MIT - perpetual - -**Used version:** 29.7.0 - -**Many thanks to:** n/a - -## [jsdom](git+https://github.com/jsdom/jsdom.git) - -**License:** MIT - perpetual - -**Used version:** 21.1.2 - -**Many thanks to:** n/a - -## [node-ts](git://github.com/nikeee/node-ts.git) - -**License:** LGPL-3.0 - perpetual - -**Used version:** 5.1.2 - -**Many thanks to:** [Niklas Mollenhauer](nikeee@outlook.com) - -## [npm-run-all](git+https://github.com/mysticatea/npm-run-all.git) - -**License:** MIT - perpetual - -**Used version:** 4.1.5 - -**Many thanks to:** Toru Nagashima - -## [ora](git+https://github.com/sindresorhus/ora.git) - -**License:** MIT - perpetual - -**Used version:** 5.4.1 - -**Many thanks to:** Sindre Sorhus sindresorhus@gmail.com https://sindresorhus.com - -## [prettier](git+https://github.com/prettier/prettier.git) - -**License:** MIT - perpetual - -**Used version:** 2.8.8 - -**Many thanks to:** James Long - -## [prettier-eslint](git+https://github.com/prettier/prettier-eslint.git) - -**License:** MIT - perpetual - -**Used version:** 15.0.1 - -**Many thanks to:** [Kent C. Dodds](kent@doddsfamily.us> (http://kentcdodds.com/) - -## [prettier-standard](git+https://github.com/sheerun/prettier-standard.git) - -**License:** MIT - perpetual - -**Used version:** 16.4.1 - -**Many thanks to:** [Adam Stankiewicz](sheerun@sher.pl) - -## [rimraf](git://github.com/isaacs/rimraf.git) - -**License:** ISC - perpetual - -**Used version:** 5.0.5 - -**Many thanks to:** [Isaac Z. Schlueter](i@izs.me> (http://blog.izs.me/) - -## [ts-jest](git+https://github.com/kulshekhar/ts-jest.git) - -**License:** MIT - perpetual - -**Used version:** 29.1.1 - -**Many thanks to:** [Kulshekhar Kabra](kulshekhar@users.noreply.github.com> (https://github.com/kulshekhar) - -## [ts-loader](git+https://github.com/TypeStrong/ts-loader.git) - -**License:** MIT - perpetual - -**Used version:** 9.5.0 - -**Many thanks to:** [John Reilly](johnny_reilly@hotmail.com> (https://johnnyreilly.com) - -## [ts-node](git://github.com/TypeStrong/ts-node.git) - -**License:** MIT - perpetual - -**Used version:** 10.9.1 - -**Many thanks to:** Blake Embrey hello@blakeembrey.com http://blakeembrey.me - -## [typedoc](git://github.com/TypeStrong/TypeDoc.git) - -**License:** Apache-2.0 - perpetual - -**Used version:** 0.23.28 - -**Many thanks to:** n/a - -## [typescript](git+https://github.com/Microsoft/TypeScript.git) - -**License:** Apache-2.0 - perpetual - -**Used version:** 4.9.5 - -**Many thanks to:** Microsoft Corp. - -## [bufferutil](git+https://github.com/websockets/bufferutil.git) - -**License:** MIT - perpetual - -**Used version:** 4.0.7 - -**Many thanks to:** [Einar Otto Stangvik](einaros@gmail.com> (http://2x.io) - -## [utf-8-validate](git+https://github.com/websockets/utf-8-validate.git) - -**License:** MIT - perpetual - -**Used version:** 6.0.3 - -**Many thanks to:** [Einar Otto Stangvik](einaros@gmail.com> (http://2x.io) - diff --git a/packages/massa-web3/src/index.ts b/packages/massa-web3/src/index.ts deleted file mode 100644 index 64ad8ff9..00000000 --- a/packages/massa-web3/src/index.ts +++ /dev/null @@ -1,96 +0,0 @@ -/** Polyfills */ -import { Buffer } from 'buffer' -import EventEmitter from 'events' - -declare global { - interface Window { - Buffer: typeof Buffer - EventEmitter: typeof EventEmitter - } -} - -// Check if we are on browser -if (typeof window !== 'undefined') { - window.Buffer = Buffer - window.EventEmitter = EventEmitter -} - -/** Exposed interfaces */ -export { IAccount } from './interfaces/IAccount' -export { IEventFilter } from './interfaces/IEventFilter' -export { IEventRegexFilter } from './interfaces/IEventRegexFilter' -export { IAddressInfo } from './interfaces/IAddressInfo' -export { IBlockInfo } from './interfaces/IBlockInfo' -export { IClientConfig } from './interfaces/IClientConfig' -export { IClique } from './interfaces/IClique' -export { IContractData } from './interfaces/IContractData' -export { ICallData } from './interfaces/ICallData' -export { IReadData } from './interfaces/IReadData' -export { IFullAddressInfo } from './interfaces/IFullAddressInfo' -export { IEndorsement } from './interfaces/IEndorsement' -export { INodeStatus } from './interfaces/INodeStatus' -export { IOperationData } from './interfaces/IOperationData' -export { IProvider, ProviderType } from './interfaces/IProvider' -export { IRollsData } from './interfaces/IRollsData' -export { ISignature } from './interfaces/ISignature' -export { ISignedMessage } from './interfaces/ISignedMessage' -export { IStakingAddresses } from './interfaces/IStakingAddresses' -export { ITransactionData } from './interfaces/ITransactionData' -export { IBalance } from './interfaces/IBalance' -export { IDatastoreEntry } from './interfaces/IDatastoreEntry' -export { IExecuteReadOnlyData } from './interfaces/IExecuteReadOnlyData' -export { IExecuteReadOnlyResponse } from './interfaces/IExecuteReadOnlyResponse' -export { JsonRpcResponseData } from './interfaces/JsonRpcResponseData' -export { EOperationStatus } from './interfaces/EOperationStatus' -export { - ITransactionOpType, - IRollBuyOpType, - IRollSellOpType, - IExecSmartContractOpType, - OperationTypeId, - OpType, -} from './interfaces/OperationTypes' -export { IClient } from './interfaces/IClient' -export { IPublicApiClient } from './interfaces/IPublicApiClient' -export { IPrivateApiClient } from './interfaces/IPrivateApiClient' -export { IWalletClient } from './interfaces/IWalletClient' -export { ISmartContractsClient } from './interfaces/ISmartContractsClient' -export { IDatastoreEntryInput } from './interfaces/IDatastoreEntryInput' -export { IGetGraphInterval } from './interfaces/IGetGraphInterval' -export { IGraphInterval } from './interfaces/IGraphInterval' -export { - IBlockcliqueBlockBySlot, - IBlockHeaderInfo, - IEndorsementInfo, -} from './interfaces/IBlockcliqueBlockBySlot' -export { ISubscribeNewBlocksMessage } from './interfaces/ISubscribeNewBlocksMessage' -export { ISubscribedFullBlocksMessage } from './interfaces/ISubscribedFullBlocksMessage' -export { IBaseAccount } from './interfaces/IBaseAccount' - -/** Exposed clients and factories */ -export { ClientFactory } from './web3/ClientFactory' -export { Client } from './web3/Client' -export { PublicApiClient } from './web3/PublicApiClient' -export { PrivateApiClient } from './web3/PrivateApiClient' -export { WalletClient } from './web3/WalletClient' -export { - EventPoller, - ON_MASSA_EVENT_DATA, - ON_MASSA_EVENT_ERROR, -} from './web3/EventPoller' -export { - SmartContractsClient, - MASSA_PROTOFILE_KEY, - PROTO_FILE_SEPARATOR, -} from './web3/SmartContractsClient' -export { withTimeoutRejection } from './utils/time' - -export { Web3Account } from './web3/accounts/Web3Account' -export { WalletProviderAccount } from './web3/accounts/WalletProviderAccount' - -/** - * This namespace provides utility functions, such as unit conversion, serialization, encoding, etc. - */ -export * as utils from './utils' -export * from './utils/keyAndAddresses' -export * from '@massalabs/web3-utils' diff --git a/packages/massa-web3/src/interfaces/EOperationStatus.ts b/packages/massa-web3/src/interfaces/EOperationStatus.ts deleted file mode 100644 index c34bab8c..00000000 --- a/packages/massa-web3/src/interfaces/EOperationStatus.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Represents the status of an operation on the Massa blockchain. - */ -export enum EOperationStatus { - INCLUDED_PENDING = 0, - AWAITING_INCLUSION = 1, - FINAL_SUCCESS = 2, - INCONSISTENT = 3, - NOT_FOUND = 4, - FINAL_ERROR = 5, - SPECULATIVE_SUCCESS = 6, - SPECULATIVE_ERROR = 7, - UNEXECUTED_OR_EXPIRED = 8, -} diff --git a/packages/massa-web3/src/interfaces/IAccount.ts b/packages/massa-web3/src/interfaces/IAccount.ts deleted file mode 100644 index fdc22a1d..00000000 --- a/packages/massa-web3/src/interfaces/IAccount.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Represents the structure of an account object. - * - * @see address - A string representing the address of the account. - * @see publicKey - A string representing the base58 encoded public key associated with the account. - * @see secretKey - A string representing the base58 encoded private key associated with the account. - */ -export interface IAccount { - address: string | null - publicKey: string | null - secretKey: string | null -} diff --git a/packages/massa-web3/src/interfaces/IAddressInfo.ts b/packages/massa-web3/src/interfaces/IAddressInfo.ts deleted file mode 100644 index 1b20d06c..00000000 --- a/packages/massa-web3/src/interfaces/IAddressInfo.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { ISlot } from '@massalabs/web3-utils' - -/** - * Represents the production statistics for a specific cycle. - * - * @remarks - * This interface is used to track the production statistics of a cycle, - * including the number of successful and unsuccessful production attempts. - */ -export interface IProductionStats { - cycle: number - is_final: boolean - nok_count: number - ok_count: number -} - -/** - * Represents the endorsement draws data for a slot and its index. - */ -export interface IEndorsementDraws { - slot: ISlot - index: number -} - -/** - * Represents a ledger datastore with a mapping of string keys to an array of numbers. - */ -export interface ILedgerDatastore { - [name: string]: number[] -} - -/** - * Represents the cycle information including active rolls, cycle number, and production statistics. - */ -export interface ICycleInfos { - active_rolls: number - cycle: number - is_final: boolean - nok_count: number - ok_count: number -} - -/** - * Represents the deferred credits for a specific slot and amount. - */ -export interface IDeferredCredits { - slot: ISlot - amount: number -} - -/** - * Represents the address information including balances, datastore keys, roll counts, - * and information about created blocks, endorsements, and operations. - */ -export interface IAddressInfo { - address: string - candidate_balance: string // Represents an amount in coins. - candidate_datastore_keys: Array> - candidate_roll_count: number - created_blocks: Array - created_endorsements: Array - created_operations: Array - cycle_infos: Array - deferred_credits: Array - final_balance: string // Represents an amount in coins. - final_datastore_keys: Array> - final_roll_count: number - next_block_draws: ISlot[] - next_endorsement_draws: Array - thread: number -} diff --git a/packages/massa-web3/src/interfaces/IBalance.ts b/packages/massa-web3/src/interfaces/IBalance.ts deleted file mode 100644 index 5b1d34fc..00000000 --- a/packages/massa-web3/src/interfaces/IBalance.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Represents the balance information for a given address. - * - * @remarks - * This interface is used to track both the final and candidate balances - * for an address, which are represented as BigInt. - */ -export interface IBalance { - final: bigint - candidate: bigint -} diff --git a/packages/massa-web3/src/interfaces/IBaseAccount.ts b/packages/massa-web3/src/interfaces/IBaseAccount.ts deleted file mode 100644 index 066190fd..00000000 --- a/packages/massa-web3/src/interfaces/IBaseAccount.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { ICallData } from './ICallData' -import { IContractData } from './IContractData' -import { IRollsData } from './IRollsData' -import { ISignature } from './ISignature' -import { ITransactionData } from './ITransactionData' - -/** - * Represents a BaseAccount object. - * - * @see sign - Sign an array of bytes. - * @see address - The address of the account. - * @see sellRolls - Sell rolls. - * @see buyRolls - Buy rolls. - * @see sendTransaction - Send a transaction. - * @see callSmartContract - Call a smart contract. - * @see deploySmartContract - Deploy a smart contract. - */ -export interface IBaseAccount { - /** - * Sign a message. - * - * @returns Signature of the message. - */ - sign(data: Buffer): Promise - - /** - * Verify integrity of the account. - * - * @throws - If the account is not valid. - */ - verify(): Promise - - /** - * The address of the account. - * - * @returns The address of the account. - */ - address(): string - - /** - * @param txData - The transaction data. - * - * @returns A promise that resolves to an array of operation ids as strings. - */ - sellRolls(txData: IRollsData): Promise - - /** - * @param txData - The transaction data. - * - * @returns A promise that resolves to an array of operation ids as strings. - */ - buyRolls(txData: IRollsData): Promise - - /** - * @param txData - The transaction data. - * - * @returns A promise that resolves to an array of operation ids as strings. - */ - sendTransaction(txData: ITransactionData): Promise - - /** - * @param callData - The call data. - * - * @returns A promise that resolves to the result of the call. - */ - callSmartContract(callData: ICallData): Promise - - /** - * @param contractData - The contract data. - * - * @returns A promise that resolves to the address of the deployed contract. - */ - deploySmartContract(contractData: IContractData): Promise -} diff --git a/packages/massa-web3/src/interfaces/IBlockInfo.ts b/packages/massa-web3/src/interfaces/IBlockInfo.ts deleted file mode 100644 index 0931ad36..00000000 --- a/packages/massa-web3/src/interfaces/IBlockInfo.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { ISlot } from '@massalabs/web3-utils' - -type Denunciation = { - public_key: string - slot: number - hash_1: string - hash_2: string - signature_1: string - signature_2: string -} - -export type BlockHeaderDenunciation = Denunciation -export type EndorsementDenunciation = Denunciation & { index: number } - -export type Endorsement = { - content: { - slot: ISlot - index: number - endorsed_block: string - } - signature: string - content_creator_pub_key: string - content_creator_address: string - id: string -} - -export type BlockHeaderContent = { - current_version: number - announced_version: number | null - operation_merkle_root: string - parents: string[] - slot: ISlot - endorsements: Endorsement[] - denunciations: BlockHeaderDenunciation | EndorsementDenunciation -} - -export type BlockHeader = { - content: BlockHeaderContent - signature: string - content_creator_pub_key: string - content_creator_address: string - id: string -} - -export type BlockInfoContent = { - is_final: boolean - is_in_blockclique: boolean - is_candidate: boolean - is_discarded: boolean - block: { - header: BlockHeader - operations: string[] - } -} - -/** - * Represents information about a block. - * - * @remarks - * This interface is used to track the block information, including the block - * ID, content, signature, operations, and status flags (final, stale, and in blockclique). - */ -export interface IBlockInfo { - id: string // BlockId - content: BlockInfoContent -} diff --git a/packages/massa-web3/src/interfaces/IBlockcliqueBlockBySlot.ts b/packages/massa-web3/src/interfaces/IBlockcliqueBlockBySlot.ts deleted file mode 100644 index 1fc78a57..00000000 --- a/packages/massa-web3/src/interfaces/IBlockcliqueBlockBySlot.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ISlot } from '@massalabs/web3-utils' - -/** - * Represents the information for a block header. - * - * @remarks - * This interface is used to track the block header information, including the - * slot, parent blocks, operation merkle root, and endorsements. - */ -export interface IBlockHeaderInfo { - slot: ISlot - parents: Array - operation_merkle_root: string - endorsements: Array -} - -/** - * Represents the endorsement information. - * - * @remarks - * This interface is used to track the endorsement information, including the - * slot, index, endorsed block ID, signature, creator's public key, creator's - * address, and endorsement ID. - */ -export interface IEndorsementInfo { - content: { - slot: ISlot - index: number - endorsed_block: string // Block ID - } - signature: string - creator_public_key: string - creator_address: string - id: string -} - -/** - * Represents a block in a blockclique by slot. - * - * @remarks - * This interface is used to track the block information in a blockclique, - * including the block header, signature, creator's public key, creator's - * address, block ID, and operations. - */ -export interface IBlockcliqueBlockBySlot { - header: { - content: IBlockHeaderInfo - signature: string - creator_public_key: string - creator_address: string - id: string // Block ID - } - operations: Array -} diff --git a/packages/massa-web3/src/interfaces/ICallData.ts b/packages/massa-web3/src/interfaces/ICallData.ts deleted file mode 100644 index 12eac441..00000000 --- a/packages/massa-web3/src/interfaces/ICallData.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Args } from '@massalabs/web3-utils' - -/** - * Represents the information for a smart contract call. - * - * @remarks - * This interface is used to track the calldata information, including the - * transaction fee, maximum gas, transferred coins, target smart contract address, - * target function name, and parameters for the function call. - * - * @see fee of type `bigint` represents the transaction fee. - * @see maxGas of type `bigint` represents the maximum amount of gas that the execution of the contract is allowed to cost. - * @see coins of type `bigint` represents the extra coins in `nanoMassa` that are spent from the caller's balance and transferred to the target. - * @see targetAddress of type `string` represents the target smart contract address or the MNS domain associated. - * @see targetFunction of type `string` represents the target function name. No function is called if empty. - * @see parameter of type `Array` or an Args represents the parameters to pass to the target function. - */ -export interface ICallData { - /** The fee amount in nanoMassa. */ - fee: bigint - maxGas?: bigint - /** The coin amount in nanoMassa. */ - coins?: bigint - targetAddress: string - targetFunction: string - parameter: Array | Args -} diff --git a/packages/massa-web3/src/interfaces/IClient.ts b/packages/massa-web3/src/interfaces/IClient.ts deleted file mode 100644 index 68e6bb3c..00000000 --- a/packages/massa-web3/src/interfaces/IClient.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { DefaultProviderUrls } from '@massalabs/web3-utils' -import { IPrivateApiClient } from './IPrivateApiClient' -import { IProvider } from './IProvider' -import { IPublicApiClient } from './IPublicApiClient' -import { ISmartContractsClient } from './ISmartContractsClient' -import { IWalletClient } from './IWalletClient' -import { MnsResolver } from '../web3/MnsResolver' - -/** - * Represents the client object. - * - * @remarks - * This interface is used to set private and public APIs. It also provides methods for setting - * custom and default providers. The default providers are the global connection URLs - * for Massa's MAINNET, TESTNET, LABNET, LOCALNET and BUILDNET. - * - * @see privateApi() - A function that returns an instance of the private API client. - * @see publicApi() - A function that returns an instance of the public API client. - * @see wallet() - A function that returns an instance of the wallet client. - * @see smartContracts() - A function that returns an instance of the smart contracts client. - * @see mnsResolver() - A function that returns an instance of the MNS resolver. - * @see setCustomProviders - A method for setting custom providers. - * @see setNewDefaultProvider - A method for setting a new default provider. - * @see setNewMnsResolver - A method for setting a new MNS resolver. - */ -export interface IClient { - privateApi(): IPrivateApiClient - publicApi(): IPublicApiClient - wallet(): IWalletClient - smartContracts(): ISmartContractsClient - mnsResolver(): MnsResolver - setCustomProviders(providers: Array): void - setNewDefaultProvider(provider: DefaultProviderUrls): void - setNewMnsResolver(contractAddress: string): void -} diff --git a/packages/massa-web3/src/interfaces/IClientConfig.ts b/packages/massa-web3/src/interfaces/IClientConfig.ts deleted file mode 100644 index d3ca0559..00000000 --- a/packages/massa-web3/src/interfaces/IClientConfig.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { IProvider } from './IProvider' - -/** - * This interface is used to configure the client. - * - * @see providers of type `Array` is an array of providers used for API requests. - * @see retryStrategyOn of type `boolean` (optional) is a flag to enable or disable the retry strategy. - * @see periodOffset of type `number | null` is the period offset in seconds for syncing with the blockchain. - * @see pingTimeoutMs of type `number` (optional) is the ping timeout in milliseconds for the provider. - */ -export interface IClientConfig { - providers: Array - retryStrategyOn?: boolean - periodOffset?: number | null - pingTimeoutMs?: number -} diff --git a/packages/massa-web3/src/interfaces/IClique.ts b/packages/massa-web3/src/interfaces/IClique.ts deleted file mode 100644 index beabd1fa..00000000 --- a/packages/massa-web3/src/interfaces/IClique.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Represents a clique of blocks in the blockchain. - * - * @remarks - * This interface is used to track a block clique, including the block IDs, - * the fitness of the clique, and whether it is a valid block clique. - * Fitness is a measure of the quality of a block clique, with a higher fitness value - * indicating a better block clique. - * - * @see block_ids - An array of strings representing the block IDs in the clique. - * @see fitness - A number representing the fitness value of the block clique. - * @see is_blockclique - A boolean indicating whether the clique is a valid block clique. - */ -export interface IClique { - block_ids: string[] - fitness: number - is_blockclique: boolean -} diff --git a/packages/massa-web3/src/interfaces/IContractData.ts b/packages/massa-web3/src/interfaces/IContractData.ts deleted file mode 100644 index 420fc452..00000000 --- a/packages/massa-web3/src/interfaces/IContractData.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Represents the information related to a smart contract. - * - * @remarks - * This interface is used to track the smart contract information, including the - * storage fee, maximum gas (that the execution of the contract is allowed to cost), - * contract data (as text or bytecode), contract address, - * and an optional datastore for the smart contract's operational storage data. - * - * @see fee of type `bigint` represents the storage fee for the smart contract. - * @see maxGas of type `bigint` represents the maximum gas that can be consumed by the smart contract. - * @see maxCoins of type `bigint` represents maximum amount of coins allowed to be spent by the execution - * @see contractDataText of type `string | undefined` represents the contract's data as string (optional). - * @see contractDataBinary of type `Uint8Array | undefined` represents the contract's data as bytecode (optional). - * @see address of type `string | undefined` represents the smart contract address (optional) or the MNS domain associated. - * @see datastore of type `Map | undefined` represents the smart contract's operational storage data (optional). - */ -export interface IContractData { - fee: bigint - maxGas: bigint - maxCoins: bigint - contractDataText?: string - contractDataBinary?: Uint8Array - address?: string - datastore?: Map -} diff --git a/packages/massa-web3/src/interfaces/IDatastoreEntry.ts b/packages/massa-web3/src/interfaces/IDatastoreEntry.ts deleted file mode 100644 index 5ba28bac..00000000 --- a/packages/massa-web3/src/interfaces/IDatastoreEntry.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Represents the data entry both at the latest final and active executed slots. - * - * @see final_value of type `Uint8Array | null` represents the value of the data entry at the latest final executed slot. - * @see candidate_value of type `Uint8Array | null` represents the value of the data entry at the latest active executed slot. - */ -export interface IDatastoreEntry { - final_value: Uint8Array | null - candidate_value: Uint8Array | null -} diff --git a/packages/massa-web3/src/interfaces/IDatastoreEntryInput.ts b/packages/massa-web3/src/interfaces/IDatastoreEntryInput.ts deleted file mode 100644 index cb96bf72..00000000 --- a/packages/massa-web3/src/interfaces/IDatastoreEntryInput.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Represents the inputs of a datastore entry. - * - * @see address of type `string` represents the address of the datastore entry. - * @see key of type `Uint8Array` represents the key of the datastore entry. - */ -export interface IDatastoreEntryInput { - address: string - key: Uint8Array -} diff --git a/packages/massa-web3/src/interfaces/IEndorsement.ts b/packages/massa-web3/src/interfaces/IEndorsement.ts deleted file mode 100644 index fafa07b4..00000000 --- a/packages/massa-web3/src/interfaces/IEndorsement.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { ISlot } from '@massalabs/web3-utils' - -/** - * Represents an endorsement. - * - * @see id of type `string` represents the ID of the endorsement. - * @see in_pool of type `boolean` represents whether the endorsement is in the mempool. - * @see in_blocks of type `Array` represents the IDs of the blocks that contain the endorsement. - * @see is_final of type `boolean` represents whether the endorsement is final. - * @see endorsement of type `object` represents the endorsement: - * @see endorsement.content of type `object` represents the content of the endorsement - * @see endorsement.content.sender_public_key of type `string` represents the public key of the sender of the endorsement. - * @see endorsement.content.slot of type `ISlot` represents the time slot when the endorsement was created. - * @see endorsement.content.index of type `number` represents the index of the endorsement inside the slot. - * @see endorsement.content.endorsed_block of type `string` represents the ID of the block that was endorsed. - * @see endorsement.signature of type `string` represents the signature of the endorsement by its sender public key. - */ -export interface IEndorsement { - id: string // EndorsementId, - in_pool: boolean - in_blocks: string[] // BlockId, - is_final: boolean - endorsement: { - content: { - sender_public_key: string - slot: ISlot - index: number - endorsed_block: string // BlockId, - } - signature: string - } -} diff --git a/packages/massa-web3/src/interfaces/IEventFilter.ts b/packages/massa-web3/src/interfaces/IEventFilter.ts deleted file mode 100644 index 22abacf1..00000000 --- a/packages/massa-web3/src/interfaces/IEventFilter.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ISlot } from '@massalabs/web3-utils' - -/** - * Allows you to filter events by their properties. - * - * @see start of type `ISlot` represents the start of the time interval (can be null). - * @see end of type `ISlot` represents the end of the time interval (can be null). - * @see emitter_address of type `string` represents the address that emitted the event (can be null) or the MNS domain associated. - * @see original_caller_address of type `string` represents the operation id that generated the event (can be null) or the MNS domain associated. - * @see is_final of type `boolean` to filter final events (true), candidate events (false) or both (null). - */ -export interface IEventFilter { - start: null | ISlot - end: null | ISlot - emitter_address: null | string // Address - original_caller_address: null | string // Address - original_operation_id: null | string // operation id - /// is_final value (true=resolves to only final events, false => resolves to only candidate events, null => resolves to final and candidate events) - is_final: boolean | null -} diff --git a/packages/massa-web3/src/interfaces/IEventRegexFilter.ts b/packages/massa-web3/src/interfaces/IEventRegexFilter.ts deleted file mode 100644 index 6c6c8b33..00000000 --- a/packages/massa-web3/src/interfaces/IEventRegexFilter.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { IEventFilter } from './IEventFilter' - -/** - * Allows you to filter events by their name using regular expressions. - * - * @see eventsNameRegex of type `string` represents the regular expression to match the event name. - */ -export interface IEventRegexFilter extends IEventFilter { - eventsNameRegex: null | string -} diff --git a/packages/massa-web3/src/interfaces/IExecuteReadOnlyData.ts b/packages/massa-web3/src/interfaces/IExecuteReadOnlyData.ts deleted file mode 100644 index 937127d5..00000000 --- a/packages/massa-web3/src/interfaces/IExecuteReadOnlyData.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ISlot, IReadOperationResult, IEvent } from '@massalabs/web3-utils' - -/** - * Represents the inputs of a read-only operation on a deployed contract. - * - * @see executed_at of type `ISlot` represents the slot when the read operation was executed. - * @see result of type `IReadOperationResult` represents the result of the read operation. - * @see output_events of type `Array` represents any events that were emitted during the execution of the read operation. - * @see gas_cost of type `number` represents the amount of gas that was consumed by the read operation. - */ -export interface IExecuteReadOnlyData { - executed_at: ISlot - result: IReadOperationResult - output_events: Array - gas_cost: number -} diff --git a/packages/massa-web3/src/interfaces/IExecuteReadOnlyResponse.ts b/packages/massa-web3/src/interfaces/IExecuteReadOnlyResponse.ts deleted file mode 100644 index 31d0b837..00000000 --- a/packages/massa-web3/src/interfaces/IExecuteReadOnlyResponse.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { IExecuteReadOnlyData } from './IExecuteReadOnlyData' - -/** - * Represents the response from a read-only operation on a deployed contract. - * - * @see returnValue of type `Uint8Array` represents the return value of the read operation. - * @see info of type `IExecuteReadOnlyData` represents the inputs of the read operation. - */ -export interface IExecuteReadOnlyResponse { - returnValue: Uint8Array - info: IExecuteReadOnlyData -} diff --git a/packages/massa-web3/src/interfaces/IFullAddressInfo.ts b/packages/massa-web3/src/interfaces/IFullAddressInfo.ts deleted file mode 100644 index 2e8ea1ef..00000000 --- a/packages/massa-web3/src/interfaces/IFullAddressInfo.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { IAddressInfo } from './IAddressInfo' - -/** - * Represents an address with its public and secret keys. - * - * @see publicKey of type `string` represents the public key of the address. - * @see secretKey of type `string` represents the secret key of the address. - */ -export interface IFullAddressInfo extends IAddressInfo { - publicKey: string - secretKey: string -} diff --git a/packages/massa-web3/src/interfaces/IGetGraphInterval.ts b/packages/massa-web3/src/interfaces/IGetGraphInterval.ts deleted file mode 100644 index ab53c2bc..00000000 --- a/packages/massa-web3/src/interfaces/IGetGraphInterval.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Interface for the getGraphInterval function - * - * @see start of type `number` represents the start of the time interval (Unix Timestamp in milliseconds). - * @see end of type `number` represents the end of the time interval (Unix Timestamp in milliseconds). - */ -export interface IGetGraphInterval { - start: number // Unix Timestamp (milliseconds) - end: number // Unix Timestamp (milliseconds) -} diff --git a/packages/massa-web3/src/interfaces/IGraphInterval.ts b/packages/massa-web3/src/interfaces/IGraphInterval.ts deleted file mode 100644 index 52dd9455..00000000 --- a/packages/massa-web3/src/interfaces/IGraphInterval.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ISlot } from '@massalabs/web3-utils' - -/** - * Represents a graph interval. - * - * @see id of type `string` represents the graph id. - * @see is_final of type `boolean` represents if the graph is final. - * @see is_stale of type `boolean` represents if the graph is stale. - * @see is_in_blockclique of type `boolean` represents if the graph has been added to the blockclique. - * @see slot of type `ISlot` represents the time slot when the graph was created. - * @see creator of type `string` represents the creator of the graph. - * @see parents of type `Array` represents the parents of the graph. - */ -export interface IGraphInterval { - id: string // graph id - is_final: boolean // is final ? - is_stale: boolean // is stale ? - is_in_blockclique: boolean // has it been added to the blockclique - slot: ISlot // slot ? - creator: string // creator - parents: Array // parents -} diff --git a/packages/massa-web3/src/interfaces/IMnsResolver.ts b/packages/massa-web3/src/interfaces/IMnsResolver.ts deleted file mode 100644 index 5117e16a..00000000 --- a/packages/massa-web3/src/interfaces/IMnsResolver.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Represents the MNS resolver object. - * - * @remarks - * This interface is used to resolve domain name to addresses. It also provides methods for setting - * custom mns resolver instead of the default one provided for MAINNET and BUILDNET. - * - * @see resolve - A function that returns the address of the domain if it exists or throws an error if it does not. - * @see setMnsResolver - A method for setting a custom mns resolver. - */ - -export interface IMnsResolver { - resolve(domain: string): Promise - getMnsResolverAddress(): string | undefined - setMnsResolver(contractAddress: string): void -} diff --git a/packages/massa-web3/src/interfaces/INodeStatus.ts b/packages/massa-web3/src/interfaces/INodeStatus.ts deleted file mode 100644 index a76d7f09..00000000 --- a/packages/massa-web3/src/interfaces/INodeStatus.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ISlot } from '@massalabs/web3-utils' - -/** - * - */ -export interface NodesMap { - [name: string]: string -} - -/** - * Represents the status of a node. - * - * @see config of type `object` represents the configuration of the node. - * @see config.block_reward of type `string` represents the block reward of the node. - * @see config.delta_f0 of type `number` represents the delta f0 of the node. - * @see config.end_timestamp of type `number` represents the end timestamp of the node (can be null). - * @see config.genesis_timestamp of type `number` represents the genesis timestamp of the node. - * @see config.max_block_size of type `number` represents the maximum block size of the node. - * @see config.operation_validity_periods of type `number` represents the operation validity periods of the node. - * @see config.periods_per_cycle of type `number` represents the periods per cycle of the node. - * @see config.pos_lock_cycles of type `number` represents the proof of stake lock cycles of the node. - * - * @see connected_nodes of type `NodesMap` represents its connected nodes. - * @see consensus_stats of type `object` represents the consensus statistics of the node. - * @see current_cycle of type `number` represents the current cycle of the node. - * @see current_time of type `number` represents the current time of the node. - * @see last_slot of type `ISlot` represents the last slot of the node. - * @see network_stats of type `object` represents the network statistics of the node. - * @see next_slot of type `ISlot` represents the next slot of the node. - * @see node_id of type `string` represents the ID of the node. - * @see pool_stats of type `object` represents the pool statistics of the node. - */ -export interface INodeStatus { - config: { - block_reward: string - delta_f0: number - end_timestamp: number | null - genesis_timestamp: number - max_block_size: number - operation_validity_periods: number - periods_per_cycle: number - pos_lock_cycles: number - pos_lookback_cycles: number - roll_price: string - t0: number - thread_count: number - } - connected_nodes: NodesMap - consensus_stats: { - clique_count: 1 - end_timestamp: number - final_block_count: number - final_operation_count: number - staker_count: number - stale_block_count: number - start_timestamp: number - } - current_cycle: number - current_time: number - last_slot: ISlot - network_stats: { - active_node_count: number - banned_peer_count: number - in_connection_count: number - known_peer_count: number - out_connection_count: number - } - next_slot: ISlot - node_id: string - node_ip: string | null - pool_stats: { endorsement_count: number; operation_count: number } - version: string - chain_id: bigint - minimal_fees?: string -} diff --git a/packages/massa-web3/src/interfaces/IOperationData.ts b/packages/massa-web3/src/interfaces/IOperationData.ts deleted file mode 100644 index 643c0b95..00000000 --- a/packages/massa-web3/src/interfaces/IOperationData.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { OpType } from './OperationTypes' - -/** - * Represents the information for an operation. - * - * @remarks - * This interface is used to track the details of an operation, including its ID, associated block IDs, - * presence in the transaction pool, finality status, thread, operation content, and execution status. - * - * @see id - A string representing the ID of the operation. - * @see in_blocks - An array of strings representing the associated block IDs. - * @see in_pool - A boolean indicating whether the operation is in the transaction pool or not. - * @see is_operation_final - A boolean indicating whether the operation is final or not. - * @see thread - A number indicating the thread in which the operation is located. - * @see operation - An object containing the content and signature of the operation. - * @see op_exec_status - A boolean or null representing the execution status of the operation. - */ -export interface IOperationData { - id: string - in_blocks: string[] - in_pool: boolean - is_operation_final: boolean - thread: number - operation: { - content: { - expire_period: number - fee: string - op: OpType - sender_public_key: string - } - signature: string - content_creator_pub_key: string - content_creator_address: string - id: string - } - op_exec_status: boolean | null -} diff --git a/packages/massa-web3/src/interfaces/IPrivateApiClient.ts b/packages/massa-web3/src/interfaces/IPrivateApiClient.ts deleted file mode 100644 index 595ab750..00000000 --- a/packages/massa-web3/src/interfaces/IPrivateApiClient.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { ISignedMessage } from './ISignedMessage' - -/** - * Private API client interface for creating an API to interact with a Massa Node. - */ -export interface IPrivateApiClient { - /** - * Method to ban a node by its ID. - * - * @param id - The ID of the node to ban. - * - * @returns - A promise so that the call can be asynchronous. - */ - nodeBanById(id: string): Promise - - /** - * Method to ban a node by its IP address. - * - * @param ipAddress - The IP address of the node to ban. - * - * @returns - A promise so that the call can be asynchronous. - */ - nodeBanByIpAddress(ipAddress: string): Promise - - /** - * Method to unban a node by its ID. - * - * @param nodeId - The ID of the node to unban. - * - * @returns - A promise so that the call can be asynchronous. - */ - nodeUnbanById(nodeId: string): Promise - - /** - * Method to unban a node by its IP address. - * - * @param ipAddress - The IP address of the node to unban. - * - * @returns - A promise so that the call can be asynchronous. - */ - nodeUnbanByIpAddress(ipAddress: string): Promise - - /** - * Method to remove a node from the whitelist. - * - * @param ipAddress - The IP address of the node to remove from the whitelist. - * - * @returns - A promise so that the call can be asynchronous. - */ - nodeRemoveFromWhitelist(ipAddress: string): Promise - - /** - * Method to add a node to the whitelist. - * - * @param ipAddress - The IP address of the node to add to the whitelist. - * - * @returns - A promise so that the call can be asynchronous. - */ - nodeAddToPeersWhitelist(ipAddress: string): Promise - - /** - * Method to stop the node. - * - * @returns - A promise so that the call can be asynchronous. - */ - nodeStop(): Promise - - /** - * Method to sign a message from the node sign feature. - * - * @param message - The message to sign as a byte array. - * - * @returns - The signed message. - */ - nodeSignMessage(message: Uint8Array): Promise - - /** - * Method to get the staking addresses of the node. - * - * @returns - Return an array of addresses that are stacking on the node. - */ - nodeGetStakingAddresses(): Promise> - - /** - * Method to remove staking addresses from the node. - * - * @param addresses - The array of addresses to remove from the node. - * - * @returns - A promise so that the call can be asynchronous. - */ - nodeRemoveStakingAddresses(addresses: Array): Promise - - /** - * Method to add staking addresses to the node. - * - * @param secretKeys - The array of the secret keys of addresses to add to the node. - * - * @returns - A promise so that the call can be asynchronous. - */ - nodeAddStakingSecretKeys(secretKeys: Array): Promise -} diff --git a/packages/massa-web3/src/interfaces/IProvider.ts b/packages/massa-web3/src/interfaces/IProvider.ts deleted file mode 100644 index 1e179bd8..00000000 --- a/packages/massa-web3/src/interfaces/IProvider.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Represents a provider. - * - * @see url - url of the provider - * @see type - type of the provider - */ -export interface IProvider { - url: string - type: ProviderType -} - -/** - * Represents a provider type. - * - * @see PRIVATE - private provider - * @see PUBLIC - public provider - */ -export enum ProviderType { - PRIVATE, - PUBLIC, -} diff --git a/packages/massa-web3/src/interfaces/IPublicApiClient.ts b/packages/massa-web3/src/interfaces/IPublicApiClient.ts deleted file mode 100644 index 2af9b974..00000000 --- a/packages/massa-web3/src/interfaces/IPublicApiClient.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { IAddressInfo } from './IAddressInfo' -import { IBlockInfo } from './IBlockInfo' -import { IClique } from './IClique' -import { IEndorsement } from './IEndorsement' -import { INodeStatus } from './INodeStatus' -import { IOperationData } from './IOperationData' -import { IStakingAddresses } from './IStakingAddresses' -import { IDatastoreEntryInput } from './IDatastoreEntryInput' -import { IDatastoreEntry } from './IDatastoreEntry' -import { IGetGraphInterval } from './IGetGraphInterval' -import { IBlockcliqueBlockBySlot } from './IBlockcliqueBlockBySlot' -import { IGraphInterval } from './IGraphInterval' -import { BaseClient } from '../web3/BaseClient' -import { ISlot } from '@massalabs/web3-utils' - -/** - * Represents a PublicApiClient object. - * - * @see getNodeStatus - Get the node status. - * @see getAddresses - Get addresses. - * @see getBlocks - Get blocks. - * @see getEndorsements - Get endorsements. - * @see getOperations - Get operations. - * @see getCliques - Get cliques. - * @see getStakers - Get stakers. - * @see getDatastoreEntries - Get datastore entries. - * @see getBlockcliqueBlockBySlot - Get blockclique block by slot. - * @see getGraphInterval - Get graph interval. - */ -export interface IPublicApiClient extends BaseClient { - /** - * Get the node status. - * - * @returns The node status. - */ - getNodeStatus(): Promise - - /** - * Get addresses. - * - * @param addresses - The addresses. - * - * @returns The addresses as IAddressInfo. - */ - getAddresses(addresses: Array): Promise> - - /** - * Get blocks. - * - * @param blockIds - The block ids. - * - * @returns The blocks as IBlockInfo. - */ - getBlocks(blockIds: Array): Promise> - - /** - * Get endorsements. - * - * @param endorsementIds - The endorsement ids. - * - * @returns The endorsements as IEndorsement. - */ - getEndorsements(endorsementIds: Array): Promise> - - /** - * Get operations. - * - * @param operationIds - The operation ids. - * - * @returns The operations as IOperationData. - */ - getOperations(operationIds: Array): Promise> - - /** - * Get cliques. - * - * @returns The cliques as IClique. - */ - getCliques(): Promise> - - /** - * Get stakers. - * - * @returns The stakers as IStakingAddresses. - */ - getStakers(): Promise> - - /** - * Get datastore entries. - * - * @param getDatastoreEntries - The datastore entries. - * - * @returns The datastore entries as IDatastoreEntry. (null if not found) - */ - getDatastoreEntries( - getDatastoreEntries: Array - ): Promise> - - /** - * Get blockclique block by slot. - * - * @param slot - The slot - * - * @returns The blockclique block by slot as IBlockcliqueBlockBySlot. - */ - getBlockcliqueBlockBySlot(slot: ISlot): Promise - - /** - * Get graph interval. - * - * @param graphInterval - The graph interval. - * - * @returns The graph interval as IGraphInterval. - */ - getGraphInterval( - graphInterval: IGetGraphInterval - ): Promise> - - /** - * Get the minimal fees required for your operation to be accepted by the API provider - * - * @returns The minimal fees as bigint (in nano-MAS). - */ - getMinimalFees(): Promise -} diff --git a/packages/massa-web3/src/interfaces/IReadData.ts b/packages/massa-web3/src/interfaces/IReadData.ts deleted file mode 100644 index c22496aa..00000000 --- a/packages/massa-web3/src/interfaces/IReadData.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Args } from '@massalabs/web3-utils' - -/** - * Represents the data of a read operation. - * - * @see maxGas - The maximum amount of gas that the execution of the contract is allowed to cost. - * @see targetAddress - Target smart contract address or the mns associated - * @see targetFunction - Target function name. No function is called if empty. - * @see parameter - Parameter to pass to the target function - * @see callerAddress - Caller address - * @see fee of type `bigint` represents the transaction fee. - * @see coins of type `bigint` represents the extra coins in `nanoMassa` that are spent from the caller's balance and transferred to the target. - */ -export interface IReadData { - maxGas?: bigint - targetAddress: string - targetFunction: string - parameter: Array | Args - callerAddress?: string - /** The coin amount in nanoMassa. */ - coins?: bigint - /** The fee amount in nanoMassa. */ - fee?: bigint -} diff --git a/packages/massa-web3/src/interfaces/IRollsData.ts b/packages/massa-web3/src/interfaces/IRollsData.ts deleted file mode 100644 index ea25b5cb..00000000 --- a/packages/massa-web3/src/interfaces/IRollsData.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Represents the data of a roll. - * - * @see fee - fees paid for the roll - * @see amount - amount of rolls - */ -export interface IRollsData { - fee: bigint - amount: bigint -} diff --git a/packages/massa-web3/src/interfaces/ISignature.ts b/packages/massa-web3/src/interfaces/ISignature.ts deleted file mode 100644 index c2d98809..00000000 --- a/packages/massa-web3/src/interfaces/ISignature.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Represents a signature. - * - * @see base58Encoded - The base58 encoded signature. - */ -export interface ISignature { - publicKey: string - base58Encoded: string -} diff --git a/packages/massa-web3/src/interfaces/ISignedMessage.ts b/packages/massa-web3/src/interfaces/ISignedMessage.ts deleted file mode 100644 index 511582eb..00000000 --- a/packages/massa-web3/src/interfaces/ISignedMessage.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Represents a signed message. - * - * @see public_key - The public key of the node. - * @see signature - The signature of the message. - */ -export interface ISignedMessage { - public_key: string - signature: string -} diff --git a/packages/massa-web3/src/interfaces/ISmartContractsClient.ts b/packages/massa-web3/src/interfaces/ISmartContractsClient.ts deleted file mode 100644 index 62d68210..00000000 --- a/packages/massa-web3/src/interfaces/ISmartContractsClient.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { IContractReadOperationResponse, IEvent } from '@massalabs/web3-utils' -import { EOperationStatus } from './EOperationStatus' -import { IBalance } from './IBalance' -import { IBaseAccount } from './IBaseAccount' -import { ICallData } from './ICallData' -import { IContractData } from './IContractData' -import { IEventFilter } from './IEventFilter' -import { IExecuteReadOnlyResponse } from './IExecuteReadOnlyResponse' -import { IReadData } from './IReadData' - -/** - * Represents a SmartContractClient object. - * - * @see deploySmartContract - deploy smart contract - * @see callSmartContract - call smart contract - * @see readSmartContract - read smart contract - * @see getContractBalance - get contract balance - * @see getFilteredScOutputEvents - get filtered smart contract output events - * @see executeReadOnlySmartContract - execute read only smart contract - * @see getOperationStatus - get operation status - * @see awaitRequiredOperationStatus - await required operation status - */ -export interface ISmartContractsClient { - /** - * Deploy a smart contract. - * - * @param contractData - The contract data - * @param executor - The account used to send the transaction (if not set, the base account is used) - * - * @returns The operation id - */ - deploySmartContract( - contractData: IContractData, - executor?: IBaseAccount - ): Promise - - /** - * Calls a smart contract. - * - * @param callData - The call data - * @param executor - The account used to send the transaction (if not set, the base account is used) - * - * @returns The operation id - */ - callSmartContract( - callData: ICallData, - executor?: IBaseAccount - ): Promise - - /** - * Read a smart contract. - * - * @param readData - The read data - * - * @returns The contract read operation response - */ - readSmartContract( - readData: IReadData - ): Promise - - /** - * Get contract balance. - * - * @param address - The contract address - * - * @returns The contract balance (null if not found) - */ - getContractBalance(address: string): Promise - - /** - * Get filtered smart contract output events. - * - * @param eventFilterData - The event filter data - * - * @returns The array of corresponding events - */ - getFilteredScOutputEvents( - eventFilterData: IEventFilter - ): Promise> - - /** - * Execute read only smart contract. - * - * @param contractData - The contract data - * - * @returns The execute read only response - */ - executeReadOnlySmartContract( - contractData: IContractData - ): Promise - - /** - * Get an operation status. - * - * @param opId - The operation id - * - * @returns The operation status - */ - getOperationStatus(opId: string): Promise - - /** - * Await required operation status. - * - * @param opId - The operation id - * @param requiredStatus - The required operation status - * - * @returns The operation status - */ - awaitRequiredOperationStatus( - opId: string, - requiredStatus: EOperationStatus - ): Promise -} diff --git a/packages/massa-web3/src/interfaces/IStakingAddresses.ts b/packages/massa-web3/src/interfaces/IStakingAddresses.ts deleted file mode 100644 index 027c4e7e..00000000 --- a/packages/massa-web3/src/interfaces/IStakingAddresses.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Interface for staking addresses - * - * @see name - name of the staking address with the number of rolls it has - */ -export interface IStakingAddresses { - [name: string]: number // address-rolls number -} diff --git a/packages/massa-web3/src/interfaces/ISubscribeNewBlocksMessage.ts b/packages/massa-web3/src/interfaces/ISubscribeNewBlocksMessage.ts deleted file mode 100644 index 1cd2da8b..00000000 --- a/packages/massa-web3/src/interfaces/ISubscribeNewBlocksMessage.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { IBlockHeaderInfo } from './IBlockcliqueBlockBySlot' - -/** - * Represents a subscribed new blocks message. - * - * @see header.content - block header info - * @see header.signature - block header signature - * @see header.creator_public_key - block header creator public key - * @see header.creator_address - block header creator address - * @see header.id - block header id - * @see operations - array of operations present in the block - */ -export interface ISubscribeNewBlocksMessage { - header: { - content: IBlockHeaderInfo - signature: string - creator_public_key: string - creator_address: string - id: string - } - operations: Array -} diff --git a/packages/massa-web3/src/interfaces/ISubscribedFullBlocksMessage.ts b/packages/massa-web3/src/interfaces/ISubscribedFullBlocksMessage.ts deleted file mode 100644 index 917217db..00000000 --- a/packages/massa-web3/src/interfaces/ISubscribedFullBlocksMessage.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { IBlockHeaderInfo } from './IBlockcliqueBlockBySlot' - -/** - * Represents a filled block info. - * - * @see content.fee - fee paid - * @see content.expire_period - expire period of the block - * @see content.op - operation object - * @see signature - block signature from the creator - * @see creator_public_key - block creator public key - * @see creator_address - block creator address - * @see id - block id - */ -export interface IFilledBlockInfo { - content: { fee: string; expire_period: number; op: object } - signature: string - creator_public_key: string - creator_address: string - id: string -} - -/** - * Represents a subscribed full blocks message. - * - * @see header.content - block header info - * @see header.signature - block header signature - * @see header.creator_public_key - block header creator public key - * @see header.creator_address - block header creator address - * @see header.id - block header id - * @see operations - array of operations present in the block - */ -export interface ISubscribedFullBlocksMessage { - header: { - content: IBlockHeaderInfo - signature: string - creator_public_key: string - creator_address: string - id: string - } - operations: Array<[string, [IFilledBlockInfo]]> -} diff --git a/packages/massa-web3/src/interfaces/ITransactionData.ts b/packages/massa-web3/src/interfaces/ITransactionData.ts deleted file mode 100644 index fda595e9..00000000 --- a/packages/massa-web3/src/interfaces/ITransactionData.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Interface for transaction data - * - * @see fee - fee paid for transaction - * @see amount - amount of tokens sent - * @see recipientAddress - recipient address - */ -export interface ITransactionData { - fee: bigint - amount: bigint - recipientAddress: string -} diff --git a/packages/massa-web3/src/interfaces/IWalletClient.ts b/packages/massa-web3/src/interfaces/IWalletClient.ts deleted file mode 100644 index bac36067..00000000 --- a/packages/massa-web3/src/interfaces/IWalletClient.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { IAccount } from './IAccount' -import { IFullAddressInfo } from './IFullAddressInfo' -import { IBalance } from './IBalance' -import { IRollsData } from './IRollsData' -import { ISignature } from './ISignature' -import { ITransactionData } from './ITransactionData' -import { BaseClient } from '../web3/BaseClient' -import { IBaseAccount } from './IBaseAccount' - -/** - * Interface for WalletClient objects - * - * @see setBaseAccount - set base account for wallet - * @see getBaseAccount - get base account for wallet - * @see getWalletAccounts - get all accounts in wallet - * @see cleanWallet - delete all accounts from wallet - * @see getWalletAccountByAddress - get account by address - * @see addSecretKeysToWallet - add accounts to wallet by secret keys - * @see addAccountsToWallet - add accounts to wallet - * @see removeAddressesFromWallet - remove accounts from wallet - * @see walletInfo - get all accounts info - * @see signMessage - sign message by account - * @see getAccountBalance - get account balance - * @see sendTransaction - send transaction - * @see buyRolls - buy rolls - * @see sellRolls - sell rolls - */ -export interface IWalletClient extends BaseClient { - /** - * Set the base account. - * - * @param baseAccount - The base account as an IAccount object. - */ - setBaseAccount(baseAccount: IBaseAccount): void - - /** - * Get the base account. - * - * @returns The base account (or null if the base account is not set). - */ - getBaseAccount(): IBaseAccount | null - - /** - * Get all accounts in the wallet. - * - * @returns An array of IAccount objects. - */ - getWalletAccounts(): Array - - /** - * Delete all accounts from the wallet. - */ - cleanWallet(): void - - /** - * Get an account by its address. - * - * @param address - The address of the account. - * - * @returns An IAccount object or undefined if not found. - */ - getWalletAccountByAddress(address: string): IAccount | undefined - - /** - * Add accounts to the wallet by secret keys. - * - * @param secretKeys - An array of secret keys. - * - * @returns A promise that resolves to an array of IAccount. - */ - addSecretKeysToWallet(secretKeys: Array): Promise> - - /** - * Add accounts to the wallet. - * - * @param accounts - An array of IAccount objects. - * - * @returns A promise that resolves to an array of IAccount objects. - */ - addAccountsToWallet(accounts: Array): Promise> - - /** - * Remove accounts from the wallet using their addresses. - * - * @param addresses - An array of addresses. - */ - removeAddressesFromWallet(addresses: Array): void - - /** - * Get all accounts info. - * - * @returns A promise that resolves to an array of IFullAddressInfo objects. - */ - walletInfo(): Promise> - - /** - * Sign a message using a specific account. - * - * @param data - The message to sign. - * @param accountSignerAddress - The address of the account used to sign the message. - * - * @returns A promise that resolves to the signed data as an ISignature object. - */ - signMessage( - data: string | Buffer, - chainId: bigint, - accountSignerAddress: string - ): Promise - - /** - * Verify a signature. - * - * @param data - The message to verify. - * @param signature - The signature to verify. - * @param signerPublicKey - The public key of the signer. - * - * @returns A promise that resolves to a boolean (true if the signature is valid, - * false otherwise). - */ - verifySignature( - data: string | Buffer, - signature: ISignature, - signerPublicKey: string - ): Promise - - /** - * Get the account balance. - * - * @param address - The address of the account. - * - * @returns A promise that resolves to an IBalance object or null if not found. - */ - getAccountBalance(address: string): Promise - - /** - * Send a transaction. - * - * @param txData - The transaction data. - * @param executor - The account used to send the transaction. - * - * @returns A promise that resolves to an array of operation ids as strings. - */ - sendTransaction( - txData: ITransactionData, - executor?: IBaseAccount - ): Promise> - - /** - * Buy rolls. - * - * @param txData - The transaction data. - * @param executor - The account used to send the transaction. - * - * @returns A promise that resolves to an array of operation ids as strings. - */ - buyRolls(txData: IRollsData, executor?: IBaseAccount): Promise> - - /** - * Sell rolls. - * - * @param txData - The transaction data. - * @param executor - The account used to send the transaction. - * - * @returns A promise that resolves to an array of operation ids as strings. - */ - sellRolls(txData: IRollsData, executor: IBaseAccount): Promise> -} diff --git a/packages/massa-web3/src/interfaces/JsonRpcMethods.ts b/packages/massa-web3/src/interfaces/JsonRpcMethods.ts deleted file mode 100644 index 47d19eae..00000000 --- a/packages/massa-web3/src/interfaces/JsonRpcMethods.ts +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Lists all JSON RPC Request Methods. - */ -export enum JSON_RPC_REQUEST_METHOD { - // public Api - GET_STATUS = 'get_status', - GET_ADDRESSES = 'get_addresses', - SEND_OPERATIONS = 'send_operations', - GET_BLOCKS = 'get_blocks', - GET_ENDORSEMENTS = 'get_endorsements', - GET_OPERATIONS = 'get_operations', - GET_CLIQUES = 'get_cliques', - GET_STAKERS = 'get_stakers', - GET_FILTERED_SC_OUTPUT_EVENT = 'get_filtered_sc_output_event', - EXECUTE_READ_ONLY_BYTECODE = 'execute_read_only_bytecode', - EXECUTE_READ_ONLY_CALL = 'execute_read_only_call', - GET_DATASTORE_ENTRIES = 'get_datastore_entries', - GET_BLOCKCLIQUE_BLOCK_BY_SLOT = 'get_blockclique_block_by_slot', - GET_GRAPH_INTERVAL = 'get_graph_interval', - - // private Api - STOP_NODE = 'stop_node', - NODE_BAN_BY_IP = 'node_ban_by_ip', - NODE_BAN_BY_ID = 'node_ban_by_id', - NODE_UNBAN_BY_IP = 'node_unban_by_ip', - NODE_UNBAN_BY_ID = 'node_unban_by_id', - GET_STAKING_ADDRESSES = 'get_staking_addresses', - REMOVE_STAKING_ADDRESSES = 'remove_staking_addresses', - ADD_STAKING_PRIVATE_KEYS = 'add_staking_private_keys', - NODE_SIGN_MESSAGE = 'node_sign_message', - NODE_REMOVE_FROM_WHITELIST = 'node_remove_from_whitelist', - NODE_ADD_TO_PEERS_WHITELIST = 'node_add_to_peers_whitelist', -} diff --git a/packages/massa-web3/src/interfaces/JsonRpcResponseData.ts b/packages/massa-web3/src/interfaces/JsonRpcResponseData.ts deleted file mode 100644 index 0b9edaf8..00000000 --- a/packages/massa-web3/src/interfaces/JsonRpcResponseData.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Interface for JSON RPC response data. - * - * @see isError - true if the response is an error, false otherwise - * @see result - the result of the response (can be null) - * @see error - the error of the response (can be null) - */ -export interface JsonRpcResponseData { - isError: boolean - result: T | null - error: Error | null -} diff --git a/packages/massa-web3/src/interfaces/OperationTypes.ts b/packages/massa-web3/src/interfaces/OperationTypes.ts deleted file mode 100644 index 992ebb29..00000000 --- a/packages/massa-web3/src/interfaces/OperationTypes.ts +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Represents an operation which transfers of coins from one account to another. - * - * @see Transaction.amount - represent an Amount in coins (string) - * @see Transaction.recipient_address - the address of the recipient - */ -export interface ITransactionOpType { - Transaction: { - amount: string // represent an Amount in coins - recipient_address: string - } -} - -/** - * Represents an operation which buys rolls. - * - * @see RollBuy.roll_count - the number of rolls to buy - */ -export interface IRollBuyOpType { - RollBuy: { - roll_count: number - } -} - -/** - * Represents an operation which sells rolls. - * - * @see RollSell.roll_count - the number of rolls to sell - */ -export interface IRollSellOpType { - RollSell: { - roll_count: number - } -} - -/** - * Represents an operation which executes a smart contract. - * - * @see ExecuteSC.data - vec of bytes to execute - * @see ExecuteSC.max_gas - maximum amount of gas that the execution of the contract is allowed to cost - * @see ExecuteSC.datastore - key-value pairs of data to be used by the smart contract - */ -export interface IExecSmartContractOpType { - ExecuteSC: { - data: number[] // vec of bytes to execute - max_gas: number // maximum amount of gas that the execution of the contract is allowed to cost - datastore: Map - } -} - -/** - * Represents an operation which calls a smart contract. - * - * @see CallSC.max_gas - maximum amount of gas that the execution of the contract is allowed to cost - * @see CallSC.param - parameter to pass to the target function - * @see CallSC.coins - coins to transfer - * @see CallSC.target_addr - target smart contract address - * @see CallSC.target_func - target function name. No function is called if empty. - * @see CallSC.caller_addr - caller address - */ -export interface ICallSmartContractOpType { - CallSC: { - max_gas: number - param: Array - coins: string - target_addr: string - target_func: string - } -} - -/** - * Associates an operation type with a number. - */ -export enum OperationTypeId { - Transaction = 0, - RollBuy = 1, - RollSell = 2, - ExecuteSC = 3, - CallSC = 4, -} - -export type OpType = - | ITransactionOpType - | IRollSellOpType - | IRollBuyOpType - | IExecSmartContractOpType - | ICallSmartContractOpType diff --git a/packages/massa-web3/src/utils/Xbqcrypto.ts b/packages/massa-web3/src/utils/Xbqcrypto.ts deleted file mode 100644 index afefb2af..00000000 --- a/packages/massa-web3/src/utils/Xbqcrypto.ts +++ /dev/null @@ -1,77 +0,0 @@ -import * as varint from 'varint' -import { blake3 } from '@noble/hashes/blake3' -/** - * A collection of utility functions for working with various data encoding and hashing formats. - * - * This module provides several functions for encoding and decoding data in various formats, including - * `base58`, `varint`, and `blake3 hashes`. - * - * @module Xbqcrypto.ts - */ - -import { unsignedBigIntUtils } from './encode_decode_int' -import { encode, decode } from 'bs58check' - -/** - * Hashes data with blake3 - * - * @param data - The data to hash - * - * @returns The hash of the data with blake3 - */ -export function hashBlake3(data: Uint8Array | string): Uint8Array { - return blake3(data) -} - -/** - * Encodes a buffer or an Uint8Array to base58 - * - * @param data - The data to encode - * - * @returns The base58 encoded data as a string - */ -export function base58Encode(data: Buffer | Uint8Array): string { - return encode(data) -} - -/** - * Decode a base58 encoded string to a buffer - * - * @param data - The base58 encoded string - * - * @returns The decoded buffer - */ -export function base58Decode(data: string): Buffer { - const decoded = decode(data) - return Buffer.from(decoded) -} - -/** - * Encodes a number or bigint to a varint encoded Uint8Array. - * - * @param data - The data to encode - * - * @returns The varint encoded data as a Uint8Array - */ -export function varintEncode(data: number | bigint): Uint8Array { - if (typeof data === 'bigint') { - return unsignedBigIntUtils.encode(data as bigint) - } - return varint.encode(data) -} - -/** - * Decodes a varint encoded Uint8Array to a number - * - * @param data - The varint encoded Uint8Array - * - * @returns The decoded number and the number of bytes read - */ -export function varintDecode(data: Uint8Array): { - value: number - bytes: number -} { - const value = varint.decode(data) - const bytes = varint.decode.bytes - return { value, bytes } -} diff --git a/packages/massa-web3/src/utils/bytes.ts b/packages/massa-web3/src/utils/bytes.ts deleted file mode 100644 index df8560e9..00000000 --- a/packages/massa-web3/src/utils/bytes.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { base58Decode } from './Xbqcrypto' - -/** - * Prefixes for secret and public keys. - * Prefixes are used as a convention to differentiate one key from another. - */ -const SECRET_KEY_PREFIX = 'S' -const PUBLIC_KEY_PREFIX = 'P' -const SECRET_KEY_PREFIX_LENGTH = 1 -const PUBLIC_KEY_PREFIX_LENGTH = 1 - -/** - * Get the byte representation of a given secret key. - * - * @param secretKey - The secret key to get the bytes from. - * - * @throws if the secret key is not valid. - * - * @returns a Uint8Array containing the bytes of the secret key. - */ -export function getBytesSecretKey(secretKey: string): Uint8Array { - const prefix = secretKey.slice(0, SECRET_KEY_PREFIX_LENGTH) - - if (!(prefix == SECRET_KEY_PREFIX)) { - throw new Error( - `Invalid secret key prefix: "${prefix}". The secret key should start with "${SECRET_KEY_PREFIX}". Please verify your secret key and try again.` - ) - } - const secretKeyBase58Decoded: Buffer = base58Decode( - secretKey.slice(SECRET_KEY_PREFIX_LENGTH) - ) - return secretKeyBase58Decoded -} - -/** - * Retrieves the byte representation of a given public key. - * - * @param publicKey - The public key to obtain the bytes from. - * - * @throws If the public key has an incorrect {@link PUBLIC_KEY_PREFIX}. - * - * @returns A Uint8Array containing the bytes of the public key. - */ -export function getBytesPublicKey(publicKey: string): Uint8Array { - const prefix = publicKey.slice(0, PUBLIC_KEY_PREFIX_LENGTH) - - if (!(prefix == PUBLIC_KEY_PREFIX)) { - throw new Error( - `Invalid public key prefix: ${prefix} should be ${PUBLIC_KEY_PREFIX}` - ) - } - const publicKeyBase58Decoded: Buffer = base58Decode( - publicKey.slice(PUBLIC_KEY_PREFIX_LENGTH) // Slice off the prefix - ) - return publicKeyBase58Decoded -} diff --git a/packages/massa-web3/src/utils/encode_decode_int/index.ts b/packages/massa-web3/src/utils/encode_decode_int/index.ts deleted file mode 100644 index 5c9badf6..00000000 --- a/packages/massa-web3/src/utils/encode_decode_int/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * This namespace is used to **serialize** and **deserialize** signed and unsigned numbers. - * - * @privateRemarks - * Please do not dump all your functions in this namespace. - * Try to organize them in different files. - * - * If any files becomes too big, or is starting to be too specific, - * don't hesitate to propose a new namespace. - * - * Here is the catalog of all functions organized by file: - * - * In the file **signed.ts** you can find functions to serialize and deserialize signed numbers such as: - * - encodingLength - * - encode - * - decode - * - * In the file **unsigned.ts** you can find functions to serialize and deserialize unsigned numbers such as: - * - encodingLength - * - encode - * - decode - * - */ -export * as signedBigIntUtils from './signed' -export * as unsignedBigIntUtils from './unsigned' diff --git a/packages/massa-web3/src/utils/encode_decode_int/signed.ts b/packages/massa-web3/src/utils/encode_decode_int/signed.ts deleted file mode 100644 index 4d4a9c60..00000000 --- a/packages/massa-web3/src/utils/encode_decode_int/signed.ts +++ /dev/null @@ -1,58 +0,0 @@ -import * as unsigned from './unsigned' - -/** - * @module Signed - * - * This module provides functions to encode and decode signed - * integers using Varint, which is a compact binary representation of integers. - */ -const oneBI = BigInt(1) -const twoBI = BigInt(2) - -/** - * Returns the number of bytes required to store the number. - * - * @privateRemarks - * If the `value` is positive, it will be encoded as a positive value by multiplying it by 2. - * If the `value` is negative, it will be encoded as a negative value by multiplying it by -2 and subtracting 1. - * - * @param value - The number to encode. - * - * @returns The number of bytes required to store the number. - */ -export function encodingLength(value: bigint): number { - return unsigned.encodingLength( - value >= 0 ? value * twoBI : value * -twoBI - oneBI - ) -} - -/** - * Encodes the given value into the given buffer at the given byteOffset. - * - * @param value - The value to encode. - * @param buffer - The buffer to encode into (optional). - * @param byteOffset - The byte offset to start encoding at (optional). - * - * @returns A buffer with the encoded value. - */ -export function encode( - value: bigint, - buffer?: ArrayBuffer, - byteOffset?: number -): ArrayBuffer { - value = value >= 0 ? value * twoBI : value * -twoBI - oneBI - return unsigned.encode(value, buffer, byteOffset) -} - -/** - * Decodes the given data at the given byteOffset. - * - * @param data - The data to decode. - * @param offset - The byte offset to start decoding at (Default: 0). - * - * @returns The decoded value. - */ -export function decode(data: Uint8Array, offset = 0): bigint { - const value = unsigned.decode(data, offset) - return value & oneBI ? (value + oneBI) / -twoBI : value / twoBI -} diff --git a/packages/massa-web3/src/utils/encode_decode_int/unsigned.ts b/packages/massa-web3/src/utils/encode_decode_int/unsigned.ts deleted file mode 100644 index bfe495aa..00000000 --- a/packages/massa-web3/src/utils/encode_decode_int/unsigned.ts +++ /dev/null @@ -1,88 +0,0 @@ -const LIMIT = BigInt(0x7f) - -const zeroBI = BigInt(0) -const sevenBI = BigInt(7) -/** - * @module unsigned.ts - * - * This module provides functions to encode and decode unsigned integers, - * using Varint which is a more compact binary representation of them. - */ - -/** - * Returns the number of bytes required to store the number in a varint. - * - * @param value - The number to encode. - * @returns The number of bytes required to store the number. - */ -export function encodingLength(value: bigint): number { - let i = 0 - - for (; value >= BigInt(0x80); i++) { - value >>= sevenBI - } - - return i + 1 -} - -/** - * Encodes a big number as a varint. - * - * @param i - The big number to encode. - * @param buffer - The buffer to write the varint to (optional). - * @param byteOffset - The offset in the buffer to start writing at (optional) (default: 0). - * @returns The buffer that was written to. - */ -export function encode( - i: bigint, - buffer?: ArrayBuffer, - byteOffset?: number -): Uint8Array { - if (i < zeroBI) { - throw new RangeError('value must be unsigned') - } - - const byteLength = encodingLength(i) - buffer = buffer || new ArrayBuffer(byteLength) - byteOffset = byteOffset || 0 - if (buffer.byteLength < byteOffset + byteLength) { - throw new RangeError( - 'the buffer is too small to encode the number at the offset' - ) - } - - const array = new Uint8Array(buffer, byteOffset) - - let offset = 0 - while (LIMIT < i) { - array[offset++] = Number(i & LIMIT) | 0x80 - i >>= sevenBI - } - - array[offset] = Number(i) - - return array -} - -/** - * Decodes a varint as a big number. - * - * @param data - The data to decode. - * @param offset - The offset in the data to start reading at (optional) (default: 0). - * @returns The decoded big number. - */ -export function decode(data: Uint8Array, offset = 0): bigint { - let i = zeroBI - let n = 0 - let b: number - do { - b = data[offset + n] - if (b === undefined) { - throw new RangeError('offset out of range') - } - - i += BigInt(b & 0x7f) << BigInt(n * 7) - n++ - } while (0x80 <= b) - return i -} diff --git a/packages/massa-web3/src/utils/index.ts b/packages/massa-web3/src/utils/index.ts deleted file mode 100644 index 38766dcd..00000000 --- a/packages/massa-web3/src/utils/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * as bytes from './bytes' - -export * as keyAndAddresses from './keyAndAddresses' - -export * as time from './time' - -export * as crypto from './Xbqcrypto' diff --git a/packages/massa-web3/src/utils/keyAndAddresses.ts b/packages/massa-web3/src/utils/keyAndAddresses.ts deleted file mode 100644 index 8126426c..00000000 --- a/packages/massa-web3/src/utils/keyAndAddresses.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { - base58Encode, - varintEncode, - varintDecode, - hashBlake3, - base58Decode, -} from './Xbqcrypto' - -import * as ed from '@noble/ed25519' -import { getBytesPublicKey, getBytesSecretKey } from './bytes' -import { - ADDRESS_CONTRACT_PREFIX, - ADDRESS_PREFIX_LENGTH, - ADDRESS_USER_PREFIX, - PUBLIC_KEY_PREFIX, -} from '@massalabs/web3-utils' - -/** - * A secret key. - * The secret key object is created from a base58 encoded string representing the secret key. - * - * @remarks - * - String representation is S + base58Check(version_bytes + secret_key_hash_bytes) - * - bytes attribute is the Uint8Array representation of the secret key. - */ -export class SecretKey { - version: number - bytes: Uint8Array - - constructor(secretKeyBase58Encoded: string) { - const versionAndKeyBytes = getBytesSecretKey(secretKeyBase58Encoded) - const { value, bytes } = varintDecode(versionAndKeyBytes) - this.version = value - this.bytes = versionAndKeyBytes.slice(bytes) - } - - /* Get the public key from the secret key */ - async getPublicKey(): Promise { - const publicKeyArray: Uint8Array = await ed.getPublicKey(this.bytes) - return new PublicKey(publicKeyArray, this.version) - } - - /* Sign a message hash digest with the secret key */ - async signDigest(messageHashDigest: Uint8Array): Promise { - return await ed.sign(messageHashDigest, this.bytes) - } -} - -/** - * The PublicKey class represents a cryptographic public key. - * - * @remarks - * - The public key is derived from the secret key and got the same version as the secret key. - * - String representation is P + base58Check(version_bytes + public_key_hash_bytes) - * - bytes attribute is the Uint8Array representation of the public key. - */ -export class PublicKey { - version: number - base58Encoded: string - bytes: Uint8Array - - constructor(bytes: Uint8Array, version: number) { - this.version = version - this.bytes = bytes - const versionBuffer = Buffer.from(varintEncode(this.version)) - - // Generate base58 encoded public key - this.base58Encoded = - PUBLIC_KEY_PREFIX + - base58Encode(Buffer.concat([versionBuffer, Buffer.from(this.bytes)])) - } - - // Create a new PublicKey object from a base58 encoded string - static fromString(base58Encoded: string): PublicKey { - const versionAndKeyBytes = getBytesPublicKey(base58Encoded) - - // Slice off the version byte - const { value, bytes } = varintDecode(versionAndKeyBytes) - const keyBytes = versionAndKeyBytes.slice(bytes) - - return new PublicKey(keyBytes, value) - } -} - -/** - * An address. - * - * @remarks when the address is created from a public key it got the same version as the public key. - * - * @remarks - * - String representation is A + U/S + base58Check(version_bytes + hashBlake3(version_bytes + public_key_bytes)) - * - The address bytes representation is `version + hashBlake3(version + publicKey)`. - * - bytes is not an attribute of the address object because it is not needed. - */ -export class Address { - base58Encoded = '' - version = 0 - isUser = false - - constructor(base58Encoded: string) { - this.base58Encoded = base58Encoded - this._initialize() - } - - _initialize() { - this.checkPrefixAndSetUserFlag() - this.decodeVersionAndAddressBytes() - } - - private checkPrefixAndSetUserFlag() { - const prefix = this.base58Encoded.slice(0, ADDRESS_PREFIX_LENGTH) - if (![ADDRESS_USER_PREFIX, ADDRESS_CONTRACT_PREFIX].includes(prefix)) { - throw new Error( - `Invalid address prefix '${prefix}'. Expected '${ADDRESS_USER_PREFIX}' for users or '${ADDRESS_CONTRACT_PREFIX}' for contracts.` - ) - } - this.isUser = prefix === ADDRESS_USER_PREFIX - } - - private decodeVersionAndAddressBytes(): void { - const versionAndAddress = this.base58Encoded.slice(ADDRESS_PREFIX_LENGTH) - const versionAndAddressBytes = new Uint8Array( - base58Decode(versionAndAddress) - ) - - this.version = varintDecode(versionAndAddressBytes).value - } - - toBytes() { - const addressCategory = Buffer.from([this.isUser ? 0 : 1]) - const addressContents = base58Decode( - this.base58Encoded.slice(ADDRESS_PREFIX_LENGTH) - ) - return Buffer.concat([addressCategory, addressContents]) - } - - static fromPublicKey(publicKey: PublicKey): Address { - const versionBuffer = Buffer.from(varintEncode(publicKey.version)) - const versionAndPublicKey = Buffer.concat([versionBuffer, publicKey.bytes]) - - const base58Encoded = - ADDRESS_USER_PREFIX + - base58Encode( - Buffer.concat([versionBuffer, hashBlake3(versionAndPublicKey)]) - ) - - return new Address(base58Encoded) - } -} diff --git a/packages/massa-web3/src/utils/retryExecuteFunction.ts b/packages/massa-web3/src/utils/retryExecuteFunction.ts deleted file mode 100644 index 0e1ae11e..00000000 --- a/packages/massa-web3/src/utils/retryExecuteFunction.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { JSON_RPC_REQUEST_METHOD } from '../interfaces/JsonRpcMethods' -import { wait } from './time' - -const MAX_NUMBER_RETRIALS = 5 -const RETRY_INTERVAL_MS = 300 - -type CallbackFunction = ( - resource: JSON_RPC_REQUEST_METHOD, - params: object -) => Promise - -/** - * Tries to execute a function and retries if it fails. - * - * @param func - The function to execute - * @param args - The arguments to pass to the function (optional) - * @param retryTimes - The number of times to retry (default: 5) - * - * @throws If the function is not defined or if it fails after the number of retries - * - * @returns The result of the function upon successful execution - */ -export const trySafeExecute = async ( - func: CallbackFunction, - args?: [JSON_RPC_REQUEST_METHOD, object], - retryTimes: number = MAX_NUMBER_RETRIALS -): Promise => { - args = args || [null, {}] - - if (!func) - throw new Error(`Function execution init conditions are erroneous: ${func}`) - - let failureCounter = 0 - let res: R = null - while (true) { - try { - res = await func(...args) - break - } catch (ex) { - ++failureCounter - const msg = `Failed to execute function ${func.name}. Retrying for ${failureCounter}th time in ${RETRY_INTERVAL_MS}ms.` - console.error(msg) - await wait(RETRY_INTERVAL_MS) - - if (failureCounter === retryTimes) { - throw ex - } - } - } - return res -} diff --git a/packages/massa-web3/src/utils/time.ts b/packages/massa-web3/src/utils/time.ts deleted file mode 100644 index c4fb97f4..00000000 --- a/packages/massa-web3/src/utils/time.ts +++ /dev/null @@ -1,109 +0,0 @@ -export function wait(ms: number) { - return new Promise((resolve) => setTimeout(resolve, ms)) -} - -/** - * A class representing a timeout that triggers a callback function after a specified time interval. - */ -export class Timeout { - /** - * Constructs a new Timeout instance with the given timeout duration and callback function. - * - * @param timeoutMil - The timeout duration in milliseconds. - * @param callback - The function to be called when the timeout is triggered. - */ - constructor(timeoutMil: number, callback: () => void) { - this.clear = this.clear.bind(this) - - const that = this - this.isCleared = false - this.isCalled = false - this.timeoutHook = setTimeout(() => { - if (!that.isCleared) { - this.isCalled = true - callback() - } - }, timeoutMil) - } - private isCleared: boolean - private isCalled: boolean - private timeoutHook: ReturnType - - /** - * Clears the timeout so that the callback function is not called. - */ - public clear(): void { - if (!this.isCleared) { - clearTimeout(this.timeoutHook) - this.isCleared = true - } - } -} - -/** - * A class representing an interval that triggers a callback function repeatedly - * at a specified time interval. - */ -export class Interval { - /** - * Constructs a new Interval instance with the given interval duration and callback function. - * - * @param timeoutMil - The interval duration in milliseconds. - * @param callback - The function to be called when the interval is triggered. - */ - constructor(timeoutMil: number, callback: () => void) { - this.clear = this.clear.bind(this) - - const that = this - this.isCleared = false - this.isCalled = false - this.intervalHook = setInterval(() => { - if (!that.isCleared) { - this.isCalled = true - callback() - } - }, timeoutMil) - } - private isCleared: boolean - private isCalled: boolean - private intervalHook: NodeJS.Timeout - - /** - * Clears the interval so that the callback function is not called anymore. - */ - public clear(): void { - if (!this.isCleared) { - clearInterval(this.intervalHook) - this.isCleared = true - } - } -} - -/** - * Returns a promise that resolves after the specified time interval and throws an error if the - * specified promise does not resolve before the timeout interval. - * - * @param promise - The promise to be resolved. - * @param timeoutMs - The time interval in milliseconds. - * - * @throws if the specified promise does not resolve before the timeout interval. - * - * @returns A promise that resolves after the specified time interval. - */ -export async function withTimeoutRejection( - promise: Promise, - timeoutMs: number -): Promise { - const sleep = new Promise((resolve, reject) => - setTimeout( - () => - reject( - new Error( - `Timeout of ${timeoutMs} has passed and promise did not resolve` - ) - ), - timeoutMs - ) - ) - return Promise.race([promise, sleep]) as Promise -} diff --git a/packages/massa-web3/src/utils/uint8ArrayToString.ts b/packages/massa-web3/src/utils/uint8ArrayToString.ts deleted file mode 100644 index 069791d8..00000000 --- a/packages/massa-web3/src/utils/uint8ArrayToString.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Converts any Uint8Array to string - * - * @param bytesArray - Uint8Array to convert - * - * @returns The string representation of the Uint8Array - */ -export function bytesArrayToString(bytesArray: Uint8Array): string { - let str = '' - // use a for-of loop - for (const byte of bytesArray) { - str += String.fromCharCode(byte) - } - return str -} diff --git a/packages/massa-web3/src/web3/BaseClient.ts b/packages/massa-web3/src/web3/BaseClient.ts deleted file mode 100755 index 187f535b..00000000 --- a/packages/massa-web3/src/web3/BaseClient.ts +++ /dev/null @@ -1,391 +0,0 @@ -import { IProvider, ProviderType } from '../interfaces/IProvider' -import { IClientConfig } from '../interfaces/IClientConfig' -import { Buffer } from 'buffer' -import { varintEncode } from '../utils/Xbqcrypto' -import { IContractData } from '../interfaces/IContractData' -import { JsonRpcResponseData } from '../interfaces/JsonRpcResponseData' -import { JSON_RPC_REQUEST_METHOD } from '../interfaces/JsonRpcMethods' -import { ITransactionData } from '../interfaces/ITransactionData' -import { OperationTypeId } from '../interfaces/OperationTypes' -import { IRollsData } from '../interfaces/IRollsData' -import { ICallData } from '../interfaces/ICallData' -import { Address } from '../utils/keyAndAddresses' - -export type DataType = IContractData | ITransactionData | IRollsData | ICallData - -export const fetchRequestHeaders = { - Accept: - 'application/json,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', - 'Content-Type': 'application/json', -} - -export const PERIOD_OFFSET = 5 - -/** - * The Base Client object is the main entry point for interacting with the massa blockchain. - * - * @remarks - * The `BaseClient` class should not be instantiated directly; instead, it should - * be extended by other client classes to provide additional functionality on top of the core - * methods provided by this class. - * - * @throws Will throw an error if no public providers are included in client configuration. - * @throws Will throw an error if no private providers are included in client configuration. - */ -export class BaseClient { - public clientConfig: IClientConfig - - /** - * Constructor of the BaseClient class - * - * @param clientConfig - The client configuration object as defined in {@link IClientConfig} - */ - public constructor(clientConfig: IClientConfig) { - this.clientConfig = clientConfig - this.clientConfig.periodOffset = - this.clientConfig.periodOffset | PERIOD_OFFSET - if (this.getPublicProviders().length === 0) { - throw new Error( - 'Cannot initialize web3 with no public providers. Need at least one' - ) - } - - // bind class methods - this.getPrivateProviders = this.getPrivateProviders.bind(this) - this.getProviderForRpcMethod = this.getProviderForRpcMethod.bind(this) - this.getPublicProviders = this.getPublicProviders.bind(this) - this.sendJsonRPCRequest = this.sendJsonRPCRequest.bind(this) - this.compactBytesForOperation = this.compactBytesForOperation.bind(this) - this.setProviders = this.setProviders.bind(this) - this.promisifyJsonRpcCall = this.promisifyJsonRpcCall.bind(this) - } - - /** - * Set new providers as {@link IProvider}. - * - * @privateRemarks - * This methods add the providers to the existing ones in the clientConfig object. - * - * @param providers - The new providers to set as an array of IProvider. - * - * @throws Will throw an error if no public providers are included in the given array of providers. - * @throws Will throw an error if no private providers are included in the given array of providers. - */ - public setProviders(providers: Array): void { - const hasPublicProvider = providers.some( - (provider) => provider.type === ProviderType.PUBLIC - ) - - if (!hasPublicProvider) { - throw new Error( - 'Cannot set providers with no public providers. Need at least one' - ) - } - - this.clientConfig.providers = providers - } - - /** - * Returns all the private providers. - * - * @returns An array of IProvider containing all the private providers. - */ - protected getPrivateProviders(): Array { - return this.clientConfig.providers.filter( - (provider) => provider.type === ProviderType.PRIVATE - ) - } - - /** - * Returns all the public providers. - * - * @returns An array of IProvider containing all the public providers. - */ - protected getPublicProviders(): Array { - return this.clientConfig.providers.filter( - (provider) => provider.type === ProviderType.PUBLIC - ) - } - - /** - * Find provider for a concrete rpc method - * - * @remarks - * This method chooses the provider to use for a given rpc method. - * - If the rpc method is about getting or sending data to the blockchain, - * it will choose a public provider. - * - If the rpc method is meant to be used by the node itself, it will choose a private provider. - * - An error is thrown if no provider is found for the rpc method. - * - * @param requestMethod - The rpc method to find the provider for. - * - * @returns The provider for the rpc method. - */ - private getProviderForRpcMethod( - requestMethod: JSON_RPC_REQUEST_METHOD - ): IProvider { - switch (requestMethod) { - case JSON_RPC_REQUEST_METHOD.GET_ADDRESSES: - case JSON_RPC_REQUEST_METHOD.GET_STATUS: - case JSON_RPC_REQUEST_METHOD.SEND_OPERATIONS: - case JSON_RPC_REQUEST_METHOD.GET_OPERATIONS: - case JSON_RPC_REQUEST_METHOD.GET_BLOCKS: - case JSON_RPC_REQUEST_METHOD.GET_ENDORSEMENTS: - case JSON_RPC_REQUEST_METHOD.GET_CLIQUES: - case JSON_RPC_REQUEST_METHOD.GET_STAKERS: - case JSON_RPC_REQUEST_METHOD.GET_FILTERED_SC_OUTPUT_EVENT: - case JSON_RPC_REQUEST_METHOD.EXECUTE_READ_ONLY_BYTECODE: - case JSON_RPC_REQUEST_METHOD.EXECUTE_READ_ONLY_CALL: - case JSON_RPC_REQUEST_METHOD.GET_DATASTORE_ENTRIES: - case JSON_RPC_REQUEST_METHOD.GET_BLOCKCLIQUE_BLOCK_BY_SLOT: - case JSON_RPC_REQUEST_METHOD.GET_GRAPH_INTERVAL: { - let providers = this.getPublicProviders() - let idx = Math.floor(Math.random() * providers.length) - return providers[idx] - } - case JSON_RPC_REQUEST_METHOD.STOP_NODE: - case JSON_RPC_REQUEST_METHOD.NODE_BAN_BY_ID: - case JSON_RPC_REQUEST_METHOD.NODE_BAN_BY_IP: - case JSON_RPC_REQUEST_METHOD.NODE_UNBAN_BY_ID: - case JSON_RPC_REQUEST_METHOD.NODE_UNBAN_BY_IP: - case JSON_RPC_REQUEST_METHOD.GET_STAKING_ADDRESSES: - case JSON_RPC_REQUEST_METHOD.REMOVE_STAKING_ADDRESSES: - case JSON_RPC_REQUEST_METHOD.ADD_STAKING_PRIVATE_KEYS: - case JSON_RPC_REQUEST_METHOD.NODE_SIGN_MESSAGE: - case JSON_RPC_REQUEST_METHOD.NODE_REMOVE_FROM_WHITELIST: { - let providers = this.getPrivateProviders() - let idx = Math.floor(Math.random() * providers.length) - return providers[idx] - } - default: - throw new Error(`Unknown Json rpc method: ${requestMethod}`) - } - } - - /** - * Converts a json rpc call to a promise that resolves as a JsonRpcResponseData - * - * @privateRemarks - * If there is an error while sending the request, the function catches the error, the isError - * property is set to true, the result property set to null, and the error property set to a - * new Error object with a message indicating that there was an error. - * - * @param resource - The rpc method to call. - * @param params - The parameters to pass to the rpc method. - * - * @returns A promise that resolves as a JsonRpcResponseData. - */ - private async promisifyJsonRpcCall( - resource: JSON_RPC_REQUEST_METHOD, - params: object - ): Promise> { - let resp: Response = null - - const bodyData = { - jsonrpc: '2.0', - method: resource, - params: params, - id: 0, - } - let body - try { - body = JSON.stringify(bodyData) - } catch (ex) { - return { - isError: true, - result: null, - error: new Error('JSON.stringify error: ' + String(ex)), - } as JsonRpcResponseData - } - try { - resp = await fetch(this.getProviderForRpcMethod(resource).url, { - headers: fetchRequestHeaders, - body: body, - method: 'POST', - }) - - const responseData: JsonRpcResponseData = await resp.json() - - return { - isError: !!responseData.error, - result: responseData.error ? null : (responseData.result as T), - error: responseData.error - ? new Error(responseData.error.message) - : null, - } as JsonRpcResponseData - } catch (ex) { - return { - isError: true, - result: null, - error: new Error('Fetch error: ' + String(ex)), - } as JsonRpcResponseData - } - } - - /** - * Sends a post JSON rpc request to the node. - * - * @param resource - The rpc method to call. - * @param params - The parameters to pass to the rpc method. - * - * @throws An error if the rpc method returns an error. - * - * @returns A promise that resolves as the result of the rpc method. - */ - protected async sendJsonRPCRequest( - resource: JSON_RPC_REQUEST_METHOD, - params: object - ): Promise { - let resp: JsonRpcResponseData = null - resp = await this.promisifyJsonRpcCall(resource, params) - - // in case of rpc error, rethrow the error. - if (resp.error) { - throw resp.error - } - - return resp.result - } - - /** - * Compacts bytes payload per operation. - * - * @param data - The operation data. - * @param opTypeId - The operation type id. - * @param account - The account used. - * @param expirePeriod - The expire period. - * - * @returns The compacted bytes payload. - */ - protected compactBytesForOperation( - data: DataType, - opTypeId: OperationTypeId, - expirePeriod: number - ): Buffer { - const feeEncoded = Buffer.from(varintEncode(data.fee)) - const expirePeriodEncoded = Buffer.from(varintEncode(expirePeriod)) - const typeIdEncoded = Buffer.from(varintEncode(opTypeId.valueOf())) - - switch (opTypeId) { - case OperationTypeId.ExecuteSC: { - const { contractDataBinary, maxGas, maxCoins, datastore } = - data as IContractData - const maxGasEncoded = Buffer.from(varintEncode(maxGas)) - const maxCoinEncoded = Buffer.from(varintEncode(maxCoins)) - - const contractDataEncoded = Buffer.from(contractDataBinary) - const dataLengthEncoded = Buffer.from( - varintEncode(contractDataEncoded.length) - ) - - // smart contract operation datastore - const datastoreKeyMap = datastore || new Map() - - let datastoreSerializedBuffer = Buffer.from(new Uint8Array()) - for (const [key, value] of datastoreKeyMap) { - const encodedKeyBytes = Buffer.from(key) - const encodedKeyLen = Buffer.from( - varintEncode(encodedKeyBytes.length) - ) - const encodedValueBytes = Buffer.from(value) - const encodedValueLen = Buffer.from( - varintEncode(encodedValueBytes.length) - ) - datastoreSerializedBuffer = Buffer.concat([ - datastoreSerializedBuffer, - encodedKeyLen, - encodedKeyBytes, - encodedValueLen, - encodedValueBytes, - ]) - } - const datastoreSerializedBufferLen = Buffer.from( - varintEncode(datastoreKeyMap.size) - ) - - let buffers = [ - feeEncoded, - expirePeriodEncoded, - typeIdEncoded, - maxGasEncoded, - maxCoinEncoded, - dataLengthEncoded, - contractDataEncoded, - datastoreSerializedBufferLen, - ] - - if (datastoreSerializedBuffer.length !== 0) { - buffers.push(datastoreSerializedBuffer) - } - - return Buffer.concat(buffers) - } - case OperationTypeId.CallSC: { - const { maxGas, coins, targetAddress, targetFunction, parameter } = - data as ICallData - - const maxGasEncoded = Buffer.from(varintEncode(maxGas)) - const coinsEncoded = Buffer.from(varintEncode(coins)) - const targetAddressEncoded = new Address(targetAddress).toBytes() - const targetFunctionEncoded = new Uint8Array( - Buffer.from(targetFunction, 'utf8') - ) - const targetFunctionLengthEncoded = Buffer.from( - varintEncode(targetFunctionEncoded.length) - ) - - let serializedParam: number[] - - if (parameter instanceof Array) { - serializedParam = parameter - } else { - serializedParam = parameter.serialize() - } - - const parametersEncoded = new Uint8Array(serializedParam) - const parametersLengthEncoded = Buffer.from( - varintEncode(parametersEncoded.length) - ) - - return Buffer.concat([ - feeEncoded, - expirePeriodEncoded, - typeIdEncoded, - maxGasEncoded, - coinsEncoded, - targetAddressEncoded, - targetFunctionLengthEncoded, - targetFunctionEncoded, - parametersLengthEncoded, - parametersEncoded, - ]) - } - case OperationTypeId.Transaction: { - const { amount, recipientAddress } = data as ITransactionData - - const transferAmountEncoded = Buffer.from(varintEncode(amount)) - const recipientAddressEncoded = new Address(recipientAddress).toBytes() - - return Buffer.concat([ - feeEncoded, - expirePeriodEncoded, - typeIdEncoded, - recipientAddressEncoded, - transferAmountEncoded, - ]) - } - case OperationTypeId.RollBuy: - case OperationTypeId.RollSell: { - const { amount } = data as IRollsData - const rollsAmountEncoded = Buffer.from(varintEncode(amount)) - - return Buffer.concat([ - feeEncoded, - expirePeriodEncoded, - typeIdEncoded, - rollsAmountEncoded, - ]) - } - } - } -} diff --git a/packages/massa-web3/src/web3/Client.ts b/packages/massa-web3/src/web3/Client.ts deleted file mode 100755 index 1b50e539..00000000 --- a/packages/massa-web3/src/web3/Client.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { IClientConfig } from '../interfaces/IClientConfig' -import { PrivateApiClient } from './PrivateApiClient' -import { PublicApiClient } from './PublicApiClient' -import { WalletClient } from './WalletClient' -import { SmartContractsClient } from './SmartContractsClient' -import { IProvider, ProviderType } from '../interfaces/IProvider' -import { IClient } from '../interfaces/IClient' -import { IBaseAccount } from '../interfaces/IBaseAccount' -import { DefaultProviderUrls } from '@massalabs/web3-utils' -import { MnsResolver } from './MnsResolver' - -/** - * Massa Web3 Client object wraps all public, private, wallet and smart-contracts-related functionalities. - */ -export class Client implements IClient { - private mnsResolverVar: MnsResolver - private publicApiClient: PublicApiClient - private privateApiClient: PrivateApiClient - private walletClient: WalletClient - private smartContractsClient: SmartContractsClient - - /** - * Constructor of the Client class. - * - * @param clientConfig - client configuration object. - * @param baseAccount - base account to use for signing transactions (optional). - * @param publicApiClient - public api client to use (optional). - * @param mnsResolverAddress - MNS resolver address to use (optional). - */ - public constructor( - private clientConfig: IClientConfig, - baseAccount?: IBaseAccount, - publicApiClient?: PublicApiClient, - mnsResolverAddress?: string - ) { - this.mnsResolverVar = new MnsResolver(clientConfig, mnsResolverAddress) - this.publicApiClient = publicApiClient || new PublicApiClient(clientConfig) - this.privateApiClient = new PrivateApiClient(clientConfig) - this.walletClient = new WalletClient( - clientConfig, - this.publicApiClient, - this.mnsResolverVar, - baseAccount - ) - this.smartContractsClient = new SmartContractsClient( - clientConfig, - this.publicApiClient, - this.walletClient, - this.mnsResolverVar - ) - - // subclients - this.privateApi = this.privateApi.bind(this) - this.publicApi = this.publicApi.bind(this) - this.wallet = this.wallet.bind(this) - this.smartContracts = this.smartContracts.bind(this) - this.mnsResolver = this.mnsResolver.bind(this) - // setters - this.setCustomProviders = this.setCustomProviders.bind(this) - this.setNewDefaultProvider = this.setNewDefaultProvider.bind(this) - // getters - this.getProviders = this.getProviders.bind(this) - this.getPrivateProviders = this.getPrivateProviders.bind(this) - this.getPublicProviders = this.getPublicProviders.bind(this) - } - - /** - * Get the private api related RPC methods. - * - * @returns PrivateApiClient object. - */ - public privateApi(): PrivateApiClient { - return this.privateApiClient - } - - /** - * Get the public api related RPC methods. - * - * @returns PublicApiClient object. - */ - public publicApi(): PublicApiClient { - return this.publicApiClient - } - - /** - * Get the Wallet related methods. - * - * @returns WalletClient object. - */ - public wallet(): WalletClient { - return this.walletClient - } - - /** - * Get the smart Contracts related methods. - * - * @returns SmartContractsClient object. - */ - public smartContracts(): SmartContractsClient { - return this.smartContractsClient - } - - /** - * Get the MNS resolver object. - * - * @returns MnsResolver object. - */ - public mnsResolver(): MnsResolver { - return this.mnsResolverVar - } - - /** - * Set new providers. - * - * @param providers - array of providers to set. - */ - public setCustomProviders(providers: Array): void { - this.publicApiClient.setProviders(providers) - this.privateApiClient.setProviders(providers) - this.walletClient.setProviders(providers) - this.smartContractsClient.setProviders(providers) - } - - /** - * Get the currently set providers. - * - * @returns array of the known providers. - */ - public getProviders(): Array { - return this.clientConfig.providers - } - - /** - * Get all private providers. - * - * @returns all private providers. - */ - public getPrivateProviders(): Array { - return this.clientConfig.providers.filter( - (provider) => provider.type === ProviderType.PRIVATE - ) - } - - /** - * Get all public providers - * - * @returns all public providers - */ - public getPublicProviders(): Array { - return this.clientConfig.providers.filter( - (provider) => provider.type === ProviderType.PUBLIC - ) - } - - /** - * Set a new default json rpc provider. - * - * @param provider - The new default provider to set. - */ - public setNewDefaultProvider(provider: DefaultProviderUrls): void { - const providers = [ - { - url: provider, - type: ProviderType.PUBLIC, - } as IProvider, - { - url: provider, - type: ProviderType.PRIVATE, - } as IProvider, - ] - this.publicApiClient.setProviders(providers) - this.privateApiClient.setProviders(providers) - this.walletClient.setProviders(providers) - this.smartContractsClient.setProviders(providers) - } - - /** - * Set a new MNS resolver address. - * - * @param contractAddress - The new MNS resolver contract address. - */ - public setNewMnsResolver(contractAddress: string): void { - this.mnsResolverVar.setMnsResolver(contractAddress) - } -} diff --git a/packages/massa-web3/src/web3/ClientFactory.ts b/packages/massa-web3/src/web3/ClientFactory.ts deleted file mode 100644 index fb5e7c51..00000000 --- a/packages/massa-web3/src/web3/ClientFactory.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { IProvider, ProviderType } from '../interfaces/IProvider' -import { IAccount } from '../interfaces/IAccount' -import { Client } from './Client' -import { IClientConfig } from '../interfaces/IClientConfig' -import { - IAccount as IAccountWalletProvider, - IProvider as IProviderWalletProvider, -} from '@massalabs/wallet-provider' -import { Web3Account } from './accounts/Web3Account' -import { PublicApiClient } from './PublicApiClient' -import { WalletProviderAccount } from './accounts/WalletProviderAccount' -import { - DefaultProviderUrls, - CHAIN_ID_DNS_ADDRESS_MAP, -} from '@massalabs/web3-utils' - -/** - * Massa Web3 ClientFactory class allows you to easily initialize a client to - * connect to the massa blockchain. - * - * @remarks - * The client can be initialized using a default provider (MAINNET, TESTNET, LABNET, LOCALNET and BUILDNET) - * or a custom set of providers. - */ -export class ClientFactory { - /** - * Creates a default client using a default provider (MAINNET, TESTNET, LABNET, LOCALNET and BUILDNET). - * - * @param provider - Default provider to be used by the client. - * @param chainId - Chain id matching the network used by the provider - * @param retryStrategyOn - Whether to retry failed requests. - * @param baseAccount - Base account to use with the client (optional). - * - * @returns A promise that resolves to a Client object. - */ - public static async createDefaultClient( - provider: DefaultProviderUrls, - chainId: bigint, - retryStrategyOn = true, - baseAccount?: IAccount - ): Promise { - let publicProviderUrl = provider.toString() - let privateProviderUrl = provider.toString() - switch (provider) { - // in the case of LocalNet append specific default ports to url. - case DefaultProviderUrls.LOCALNET: { - privateProviderUrl = `${privateProviderUrl}:33034` - publicProviderUrl = `${publicProviderUrl}:33035` - break - } - // all other networks should have public access only. - default: { - break - } - } - - const providers = [ - { - url: publicProviderUrl, - type: ProviderType.PUBLIC, - } as IProvider, - { - url: privateProviderUrl, - type: ProviderType.PRIVATE, - } as IProvider, - ] - - let clientConfig = { - retryStrategyOn, - providers, - } as IClientConfig - let publicApi = new PublicApiClient(clientConfig) - let account: Web3Account = null - if (baseAccount) { - account = new Web3Account(baseAccount, publicApi, chainId) - } - const client: Client = new Client( - { - retryStrategyOn, - providers, - } as IClientConfig, - account, - publicApi, - CHAIN_ID_DNS_ADDRESS_MAP[chainId.toString()] - ) - return client - } - - /** - * Initializes a new client using a custom set of private and public providers. - * - * @remarks - * Suitable for local node interactions. - * - * @param providers - Array of providers to be used by the client. - * @param chainId - Chain id matching the network used by the provider - * @param retryStrategyOn - Whether to retry failed requests. - * @param baseAccount - Base account to be used by the client (optional). - * - * @returns A promise that resolves to a Client object. - */ - public static async createCustomClient( - providers: Array, - chainId: bigint, - retryStrategyOn = true, - baseAccount?: IAccount - ): Promise { - let clientConfig = { - retryStrategyOn, - providers, - } as IClientConfig - let publicApi = new PublicApiClient(clientConfig) - let account: Web3Account = null - if (baseAccount) { - account = new Web3Account(baseAccount, publicApi, chainId) - } - const client: Client = new Client( - clientConfig, - account, - publicApi, - CHAIN_ID_DNS_ADDRESS_MAP[chainId.toString()] - ) - return client - } - - /** - * Initializes a new client using the wallet provider. - * - * @remarks - * Suitable for local node interactions. - * - * @param provider - Provider from wallet provider to be used by the client. - * @param baseAccount - Base account from the wallet provider to be used by the client. - * @param retryStrategyOn - Whether to retry failed requests. - * - * @returns A promise that resolves to a Client object. - */ - public static async fromWalletProvider( - provider: IProviderWalletProvider, - baseAccount: IAccountWalletProvider, - retryStrategyOn = true - ): Promise { - const providers = (await provider.getNodesUrls()).map((url) => { - return { - url, - type: ProviderType.PUBLIC, - } - }) - const client: Client = new Client( - { - retryStrategyOn, - providers, - }, - new WalletProviderAccount(baseAccount), - undefined, - CHAIN_ID_DNS_ADDRESS_MAP[provider.getChainId().toString()] - ) - - return client - } -} diff --git a/packages/massa-web3/src/web3/EventPoller.ts b/packages/massa-web3/src/web3/EventPoller.ts deleted file mode 100644 index 7046088a..00000000 --- a/packages/massa-web3/src/web3/EventPoller.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { EventEmitter } from 'events' -import { IEventFilter } from '../interfaces/IEventFilter' -import { IEventRegexFilter } from '../interfaces/IEventRegexFilter' -import { Timeout } from '../utils/time' -import { Client } from './Client' -import { ISlot, IEvent } from '@massalabs/web3-utils' - -/** Smart Contracts Event Poller */ -export const ON_MASSA_EVENT_DATA = 'ON_MASSA_EVENT' -export const ON_MASSA_EVENT_ERROR = 'ON_MASSA_ERROR' - -/** - * Compares two ISlot instances based on their `period` and `thread` properties. - * - * @remarks - * The comparison is primarily based on the 'period' property. If the 'period' values are the same, - * the comparison is then based on the 'thread' property. - * - * @param a - The first ISlot instance to be compared. - * @param b - The second ISlot instance to be compared. - * - * @returns A positive number if 'a' should come after 'b', a negative number if 'a' should come before 'b', - * or 0 if 'a' and 'b' are considered equal. - */ -const compareByThreadAndPeriod = (a: ISlot, b: ISlot): number => { - const periodOrder = a.period - b.period - if (periodOrder === 0) { - const threadOrder = a.thread - b.thread - return threadOrder - } - return periodOrder -} - -/** - * The EventPoller class provides a convenient way to poll events from the Massa network. - */ -export class EventPoller extends EventEmitter { - private timeoutId: Timeout | null = null - private lastSlot: ISlot - - /** - * Constructor of the EventPoller object. - * - * @param eventsFilter - The filter to use for the events. - * @param pollIntervalMillis - The interval in milliseconds to poll for events. - * @param web3Client - The web3 client to use for polling. - */ - public constructor( - private readonly eventsFilter: IEventFilter | IEventRegexFilter, - private readonly pollIntervalMillis: number, - private readonly web3Client: Client - ) { - super() - - // bind class methods. - this.callback = this.callback.bind(this) - this.stopPolling = this.stopPolling.bind(this) - this.startPolling = this.startPolling.bind(this) - } - - /** - * Polls for new events that match a specified filter and emits them. - * - * @remarks - * It uses the Web3 client to retrieve events from a smart contract and filters them further. - * based on regular expression and last scanned slot. - * If any matching events are found, it sorts them based on the highest period and thread and emits them. - */ - private async callback() { - try { - // get all events using the filter. - const events: Array = await this.web3Client - .smartContracts() - .getFilteredScOutputEvents(this.eventsFilter) - - // filter further using regex and last scanned slot. - const filteredEvents: Array = events.filter((event) => { - // check if regex condition is met. - let meetsRegex = true - if ((this.eventsFilter as IEventRegexFilter).eventsNameRegex) { - meetsRegex = event.data.includes( - (this.eventsFilter as IEventRegexFilter).eventsNameRegex - ) - } - - // check if after last slot. - let isAfterLastSlot = true - if (this.lastSlot) { - isAfterLastSlot = - compareByThreadAndPeriod(event.context.slot, this.lastSlot) > 0 - } - - return meetsRegex && isAfterLastSlot - }) - - // sort after highest period and thread. - const sortedByHighestThreadAndPeriod = filteredEvents.sort((a, b) => { - return compareByThreadAndPeriod(a.context.slot, b.context.slot) - }) - - if (sortedByHighestThreadAndPeriod.length > 0) { - // update slot to be the very last slot. - this.lastSlot = - sortedByHighestThreadAndPeriod[ - sortedByHighestThreadAndPeriod.length - 1 - ].context.slot - - // emit the filtered events. - this.emit(ON_MASSA_EVENT_DATA, sortedByHighestThreadAndPeriod) - } - } catch (ex) { - this.emit(ON_MASSA_EVENT_ERROR, ex) - } - - // reset the interval. - this.timeoutId = new Timeout(this.pollIntervalMillis, () => { - this.callback() - }) - } - - /** - * Stops polling for events. - */ - public stopPolling(): void { - if (this.timeoutId) this.timeoutId.clear() - } - - /** - * Starts polling for events. - */ - public startPolling(): void { - const that = this - if (this.timeoutId) { - return - } - this.timeoutId = new Timeout(this.pollIntervalMillis, () => { - that.callback() - }) - } - - /** - * Starts polling for events and returns the EventPoller object. - * - * @param eventsFilter - The filter to use for the events. - * @param pollIntervalMillis - The interval in milliseconds to poll for events. - * @param web3Client - The web3 client to use for polling. - * @param onData - The callback function to call when new events are found. - * @param onError - The callback function to call when an error occurs. - * - * @returns The EventPoller object created. - */ - public static startEventsPolling( - eventsFilter: IEventFilter | IEventRegexFilter, - pollIntervalMillis: number, - web3Client: Client, - onData?: (data: Array) => void, - onError?: (err: Error) => void - ): EventPoller { - const eventPoller = new EventPoller( - eventsFilter, - pollIntervalMillis, - web3Client - ) - eventPoller.startPolling() - if (onData) { - eventPoller.on(ON_MASSA_EVENT_DATA, (data: [IEvent]) => { - onData(data) - }) - } - if (onError) { - eventPoller.on(ON_MASSA_EVENT_ERROR, (e) => { - onError(e) - }) - } - return eventPoller - } - - /** - * Get only the events that match the filter once. - * - * @param eventsFilter - The filter to use for the events. - * @param web3Client - The web3 client to use for polling. - * - * @returns The events that match the filter as a promise. - */ - public static async getEventsOnce( - eventsFilter: IEventFilter | IEventRegexFilter, - web3Client: Client - ): Promise> { - const events: Array = await web3Client - .smartContracts() - .getFilteredScOutputEvents(eventsFilter) - return events - } -} diff --git a/packages/massa-web3/src/web3/MnsResolver.ts b/packages/massa-web3/src/web3/MnsResolver.ts deleted file mode 100644 index f50339c3..00000000 --- a/packages/massa-web3/src/web3/MnsResolver.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { - Args, - IContractReadOperationData, - MAX_GAS_CALL, - bytesToStr, -} from '@massalabs/web3-utils' -import { IClientConfig } from '../interfaces/IClientConfig' -import { IMnsResolver } from '../interfaces/IMnsResolver' -import { BaseClient } from './BaseClient' -import { JSON_RPC_REQUEST_METHOD } from '../interfaces/JsonRpcMethods' -import { trySafeExecute } from '../utils/retryExecuteFunction' - -export class MnsResolver extends BaseClient implements IMnsResolver { - private contractResolver?: string - - /** - * Constructor of the MnsResolver class. - * - * @param clientConfig - client configuration object. - * @param dnsAddress - DNS address to use for resolving MNS records. - */ - public constructor(clientConfig: IClientConfig, dnsAddress?: string) { - super(clientConfig) - this.contractResolver = dnsAddress - } - - /** - * Resolves the domain to an address. - * - * @param domain - Domain to resolve. - * - * @returns A promise that resolves to the address of the domain if it exists or throws an error if it does not. - */ - public async resolve(domain: string): Promise { - if (!this.contractResolver) { - throw new Error( - 'MNS resolver contract address is not set. Use setMnsResolver method to set the contract address.' - ) - } - if (!domain || !domain.endsWith('.massa')) { - throw new Error( - 'Invalid domain name. Domain name should end with ".massa"' - ) - } - - // remove .massa from domain - domain = domain.slice(0, -6) - const data = { - max_gas: Number(MAX_GAS_CALL), - target_address: this.contractResolver, - target_function: 'dnsResolve', - parameter: new Args().addString(domain).serialize(), - caller_address: this.contractResolver, - } - - // returns operation ids - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.EXECUTE_READ_ONLY_CALL - let jsonRpcCallResult: Array = [] - if (this.clientConfig.retryStrategyOn) { - jsonRpcCallResult = await trySafeExecute< - Array - >(this.sendJsonRPCRequest, [jsonRpcRequestMethod, [[data]]]) - } else { - jsonRpcCallResult = await this.sendJsonRPCRequest(jsonRpcRequestMethod, [ - [data], - ]) - } - - if (jsonRpcCallResult.length <= 0) { - throw new Error( - 'Read operation bad response. No results array in json rpc response. Inspect smart contract' - ) - } - if (jsonRpcCallResult[0].result.Error) { - throw new Error(jsonRpcCallResult[0].result.Error) - } - - return bytesToStr(jsonRpcCallResult[0].result.Ok) - } - - resolveOrFallback = async (domain?: string): Promise => { - try { - return await this.resolve(domain) - } catch (e) { - return domain - } - } - /** - * Sets the MNS resolver contract address. - * - * @param contractAddress - Contract address to use for resolving MNS records. - */ - public setMnsResolver(contractAddress: string): void { - this.contractResolver = contractAddress - } - - /** - * Get the MNS resolver contract address. - * - * @returns The MNS resolver contract address. - */ - public getMnsResolverAddress(): string { - return this.contractResolver - } -} diff --git a/packages/massa-web3/src/web3/PrivateApiClient.ts b/packages/massa-web3/src/web3/PrivateApiClient.ts deleted file mode 100755 index 5e92e29b..00000000 --- a/packages/massa-web3/src/web3/PrivateApiClient.ts +++ /dev/null @@ -1,266 +0,0 @@ -import { IClientConfig } from '../interfaces/IClientConfig' -import { trySafeExecute } from '../utils/retryExecuteFunction' -import { JSON_RPC_REQUEST_METHOD } from '../interfaces/JsonRpcMethods' -import { ISignedMessage } from '../interfaces/ISignedMessage' -import { BaseClient } from './BaseClient' -import { IPrivateApiClient } from '../interfaces/IPrivateApiClient' - -/** - * Private Api Client for interacting with a massa node. - */ -export class PrivateApiClient extends BaseClient implements IPrivateApiClient { - /** - * Constructor for the {@link PrivateApiClient} object. - * - * @param clientConfig - The client configuration. - */ - public constructor(clientConfig: IClientConfig) { - super(clientConfig) - - // ========== bind api methods ========= // - - // private api methods - this.nodeStop = this.nodeStop.bind(this) - this.nodeBanById = this.nodeBanById.bind(this) - this.nodeBanByIpAddress = this.nodeBanByIpAddress.bind(this) - this.nodeUnbanById = this.nodeUnbanById.bind(this) - this.nodeUnbanByIpAddress = this.nodeUnbanByIpAddress.bind(this) - this.nodeAddStakingSecretKeys = this.nodeAddStakingSecretKeys.bind(this) - this.nodeGetStakingAddresses = this.nodeGetStakingAddresses.bind(this) - this.nodeRemoveStakingAddresses = this.nodeRemoveStakingAddresses.bind(this) - this.nodeSignMessage = this.nodeSignMessage.bind(this) - this.nodeRemoveFromWhitelist = this.nodeRemoveFromWhitelist.bind(this) - this.nodeAddToPeersWhitelist = this.nodeAddToPeersWhitelist.bind(this) - } - - /** - * Add a given Node IP address from the whitelist. - * - * @param ipAddress - The IP address to add to the whitelist. - * - * @returns A promise that resolves when the request is complete. - */ - public async nodeAddToPeersWhitelist(ipAddress: string): Promise { - const jsonRpcRequestMethod = - JSON_RPC_REQUEST_METHOD.NODE_ADD_TO_PEERS_WHITELIST - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [[ipAddress]], - ]) - } else { - return await this.sendJsonRPCRequest(jsonRpcRequestMethod, [ - [ipAddress], - ]) - } - } - - /** - * Remove a given Node IP address from the whitelist. - * - * @param ipAddress - The IP address to remove from the whitelist. - * - * @returns A promise that resolves when the request is complete. - */ - public async nodeRemoveFromWhitelist(ipAddress: string): Promise { - const jsonRpcRequestMethod = - JSON_RPC_REQUEST_METHOD.NODE_REMOVE_FROM_WHITELIST - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [[ipAddress]], - ]) - } else { - return await this.sendJsonRPCRequest(jsonRpcRequestMethod, [ - [ipAddress], - ]) - } - } - - /** - * Unban a given IP address. - * - * @param ipAddress - The IP address to unban. - * - * @returns A promise that resolves when the request is complete. - */ - public async nodeUnbanByIpAddress(ipAddress: string): Promise { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.NODE_UNBAN_BY_IP - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [[ipAddress]], - ]) - } else { - return await this.sendJsonRPCRequest(jsonRpcRequestMethod, [ - [ipAddress], - ]) - } - } - - /** - * Unban a given node id. - * - * @param nodeId - The node id to unban. - * @returns A promise that resolves when the request is complete. - */ - public async nodeUnbanById(nodeId: string): Promise { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.NODE_UNBAN_BY_ID - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [[nodeId]], - ]) - } else { - return await this.sendJsonRPCRequest(jsonRpcRequestMethod, [ - [nodeId], - ]) - } - } - - /** - * Ban a given node IP address. - * - * @param ipAddress - The IP address to ban. - * @returns A promise that resolves when the request is complete. - */ - public async nodeBanByIpAddress(ipAddress: string): Promise { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.NODE_BAN_BY_IP - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [[ipAddress]], - ]) - } else { - return await this.sendJsonRPCRequest(jsonRpcRequestMethod, [ - [ipAddress], - ]) - } - } - - /** - * Ban a given node Id. - * - * @param id - The node id to ban. - * - * @returns A promise that resolves when the request is complete. - */ - public async nodeBanById(id: string): Promise { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.NODE_BAN_BY_ID - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [[id]], - ]) - } else { - return await this.sendJsonRPCRequest(jsonRpcRequestMethod, [[id]]) - } - } - - /** - * Stops the node. - * - * @returns A promise that resolves when the request is complete. - */ - public async nodeStop(): Promise { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.STOP_NODE - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [], - ]) - } else { - return await this.sendJsonRPCRequest(jsonRpcRequestMethod, []) - } - } - - /** - * Node signs a message. - * - * @param message - The message to sign. - * - * @returns A promise that resolves to an ISignedMessage object. - */ - public async nodeSignMessage(message: Uint8Array): Promise { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.NODE_SIGN_MESSAGE - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [message], - ]) - } else { - return await this.sendJsonRPCRequest( - jsonRpcRequestMethod, - [message] - ) - } - } - - /** - * Get staking addresses. - * - * @returns A promise that resolves to an array of addresses (strings). - */ - public async nodeGetStakingAddresses(): Promise> { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_STAKING_ADDRESSES - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute>(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [], - ]) - } else { - return await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [] - ) - } - } - - /** - * Remove staking addresses. - * - * @param addresses - The addresses to remove. - * - * @returns A promise that resolves when the request is complete. - */ - public async nodeRemoveStakingAddresses( - addresses: Array - ): Promise { - const jsonRpcRequestMethod = - JSON_RPC_REQUEST_METHOD.REMOVE_STAKING_ADDRESSES - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [addresses], - ]) - } else { - return await this.sendJsonRPCRequest(jsonRpcRequestMethod, [ - addresses, - ]) - } - } - - /** - * Add staking private keys. - * - * @param secretKeys - The secret keys to add. - * - * @returns A promise that resolves when the request is complete. - */ - public async nodeAddStakingSecretKeys( - secretKeys: Array - ): Promise { - const jsonRpcRequestMethod = - JSON_RPC_REQUEST_METHOD.ADD_STAKING_PRIVATE_KEYS - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [secretKeys], - ]) - } else { - return await this.sendJsonRPCRequest(jsonRpcRequestMethod, [ - secretKeys, - ]) - } - } -} diff --git a/packages/massa-web3/src/web3/PublicApiClient.ts b/packages/massa-web3/src/web3/PublicApiClient.ts deleted file mode 100755 index afa2320a..00000000 --- a/packages/massa-web3/src/web3/PublicApiClient.ts +++ /dev/null @@ -1,337 +0,0 @@ -import { IClientConfig } from '../interfaces/IClientConfig' -import { INodeStatus } from '../interfaces/INodeStatus' -import { IAddressInfo } from '../interfaces/IAddressInfo' -import { trySafeExecute } from '../utils/retryExecuteFunction' -import { JSON_RPC_REQUEST_METHOD } from '../interfaces/JsonRpcMethods' -import { IBlockInfo } from '../interfaces/IBlockInfo' -import { IEndorsement } from '../interfaces/IEndorsement' -import { IOperationData } from '../interfaces/IOperationData' -import { IClique } from '../interfaces/IClique' -import { IStakingAddresses } from '../interfaces/IStakingAddresses' -import { BaseClient } from './BaseClient' -import { IPublicApiClient } from '../interfaces/IPublicApiClient' -import { IDatastoreEntry } from '../interfaces/IDatastoreEntry' -import { IDatastoreEntryInput } from '../interfaces/IDatastoreEntryInput' -import { IGetGraphInterval } from '../interfaces/IGetGraphInterval' -import { IGraphInterval } from '../interfaces/IGraphInterval' -import { IBlockcliqueBlockBySlot } from '../interfaces/IBlockcliqueBlockBySlot' -import { ISlot, fromMAS } from '@massalabs/web3-utils' - -/** - * Public API client for interacting with a Massa node. - * - * This class provides an interface for interacting with the public API of a Massa node. - * It offers methods for querying various data structures used in the Massa blockchain, - * such as blocks, endorsements, operations, and stakers. - * - * @module PublicApiClient - */ -export class PublicApiClient extends BaseClient implements IPublicApiClient { - /** - * Constructor for the {@link PublicApiClient} object. - * - * @param clientConfig - The configuration settings for this client. - */ - public constructor(clientConfig: IClientConfig) { - super(clientConfig) - - // Bind all public API methods to the current context. - // This ensures that the methods can be called correctly even when their context is lost. - // For example, when passed as a callback function. - - // public api methods - this.getNodeStatus = this.getNodeStatus.bind(this) - this.getMinimalFees = this.getMinimalFees.bind(this) - this.getAddresses = this.getAddresses.bind(this) - this.getBlocks = this.getBlocks.bind(this) - this.getEndorsements = this.getEndorsements.bind(this) - this.getOperations = this.getOperations.bind(this) - this.getCliques = this.getCliques.bind(this) - this.getStakers = this.getStakers.bind(this) - this.getBlockcliqueBlockBySlot = this.getBlockcliqueBlockBySlot.bind(this) - this.getGraphInterval = this.getGraphInterval.bind(this) - } - - /** - * Get graph interval. - * - * @param graphInterval - The graph interval values in ms as an IGetGraphInterval. - * - * @returns A promise which resolves in the graph interval. - */ - public async getGraphInterval( - graphInterval: IGetGraphInterval - ): Promise> { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_GRAPH_INTERVAL - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute>( - this.sendJsonRPCRequest, - [jsonRpcRequestMethod, [graphInterval]] - ) - } else { - return await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [graphInterval] - ) - } - } - - /** - * Get blockclique details by period and thread. - * - * @param slot - The slot as an ISlot. - * - * @returns A promise which resolves in the blockclique details. - */ - public async getBlockcliqueBlockBySlot( - slot: ISlot - ): Promise { - const jsonRpcRequestMethod = - JSON_RPC_REQUEST_METHOD.GET_BLOCKCLIQUE_BLOCK_BY_SLOT - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute( - this.sendJsonRPCRequest, - [jsonRpcRequestMethod, [slot]] - ) - } else { - return await this.sendJsonRPCRequest( - jsonRpcRequestMethod, - [slot] - ) - } - } - - /** - * Retrieves the node's status. - * - * @remarks - * The returned information includes: - * - Whether the node is reachable - * - The number of connected peers - * - The node's version - * - The node's configuration parameters - * - * @returns A promise that resolves to the node's status information. - */ - public async getNodeStatus(): Promise { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_STATUS - let nodeStatus: INodeStatus - if (this.clientConfig.retryStrategyOn) { - nodeStatus = await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [], - ]) - } else { - nodeStatus = await this.sendJsonRPCRequest( - jsonRpcRequestMethod, - [] - ) - } - // convert chain_id to BigInt - return { ...nodeStatus, chain_id: BigInt(nodeStatus.chain_id) } - } - - /** - * Retrieves the minimal fees for operations to be accepted by the API provider. - * - * @returns The minimal fees as a bigint (in nano-MAS). - */ - public async getMinimalFees(): Promise { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_STATUS - let fees: string = '0' - if (this.clientConfig.retryStrategyOn) { - let result = await trySafeExecute(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [], - ]) - fees = result.minimal_fees || '0' - } else { - let result = await this.sendJsonRPCRequest( - jsonRpcRequestMethod, - [] - ) - fees = result.minimal_fees || '0' - } - return fromMAS(fees) - } - - /** - * Retrieves data about a list of addresses, such as their balances and block creation details. - * - * @param addresses - An array of addresses to query. - * - * @returns A promise that resolves to an array of address information. - */ - public async getAddresses( - addresses: Array - ): Promise> { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_ADDRESSES - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute>( - this.sendJsonRPCRequest, - [jsonRpcRequestMethod, [addresses]] - ) - } else { - return await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [addresses] - ) - } - } - - /** - * Show data about a block (content, finality ...). - * - * @remarks - * The blocks are stored in the node cache. After a certain time (depending of the network activity), - * the blocks are removed from the cache and the node will not be able to return the block data. - * The corresponding api parameter is 'max_discarded_blocks'. - * More information can be found here: https://docs.massa.net/en/latest/testnet/all-config.html - * - * @param blockIds - The block ids as an array of strings. - * - * @returns A promise which resolves in the block data. - */ - public async getBlocks(blockIds: Array): Promise> { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_BLOCKS - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute>(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [blockIds], - ]) - } else { - return await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [blockIds] - ) - } - } - - /** - * Show info about a list of endorsements. - * - * @param endorsementIds - The endorsement ids as an array of strings. - * - * @returns A promise which resolves in the endorsement data. - */ - public async getEndorsements( - endorsementIds: Array - ): Promise> { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_ENDORSEMENTS - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute>( - this.sendJsonRPCRequest, - [jsonRpcRequestMethod, [endorsementIds]] - ) - } else { - return await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [endorsementIds] - ) - } - } - - /** - * Retrieves data about a list of operations. - * - * @param operationIds - An array of operation IDs to query. - * - * @returns A promise that resolves to an array of operation data. - */ - public async getOperations( - operationIds: Array - ): Promise> { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_OPERATIONS - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute>( - this.sendJsonRPCRequest, - [jsonRpcRequestMethod, [operationIds]] - ) - } else { - return await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [operationIds] - ) - } - } - - /** - * Get cliques. - * - * @returns A promise which resolves to the cliques. - */ - public async getCliques(): Promise> { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_CLIQUES - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute>(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [], - ]) - } else { - return await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [] - ) - } - } - - /** - * Retrieves a list of active stakers and their roll counts for the current cycle. - * - * @returns A promise that resolves to an array of staking addresses and their roll counts. - */ - public async getStakers(): Promise> { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_STAKERS - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute>( - this.sendJsonRPCRequest, - [jsonRpcRequestMethod, []] - ) - } else { - return await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [] - ) - } - } - - /** - * Retrieves the data entries at both the latest final and active executed slots. - * - * @param addressesKeys - An array of objects containing address and key data. - * - * @returns A promise that resolves to an array of datastore entries. - * - * @remarks returned values could be easily converted into string if needed using e.g.: bytesToStr(scStorageValue[0].final_value) - */ - public async getDatastoreEntries( - addressesKeys: Array - ): Promise> { - const data = [] - for (const input of addressesKeys) { - data.push({ - address: input.address, - key: Array.prototype.slice.call(Buffer.from(input.key)), - }) - } - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_DATASTORE_ENTRIES - let datastoreEntries: Array = [] - if (this.clientConfig.retryStrategyOn) { - datastoreEntries = await trySafeExecute>( - this.sendJsonRPCRequest, - [jsonRpcRequestMethod, [data]] - ) - } else { - datastoreEntries = await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [data] - ) - } - return datastoreEntries.map((e) => { - return { - final_value: new Uint8Array(e.final_value), - candidate_value: new Uint8Array(e.candidate_value), - } - }) - } -} diff --git a/packages/massa-web3/src/web3/SmartContractsClient.ts b/packages/massa-web3/src/web3/SmartContractsClient.ts deleted file mode 100644 index 93ad8582..00000000 --- a/packages/massa-web3/src/web3/SmartContractsClient.ts +++ /dev/null @@ -1,563 +0,0 @@ -/** - * This file includes the implementation for the {@link SmartContractsClient} class. This class provides methods for interacting with smart contracts - * in the Massa blockchain. Such methods include {@link SmartContractsClient#deploySmartContract|deploying}, {@link SmartContractsClient#callSmartContract|calling}, - * and {@link SmartContractsClient#readSmartContract|reading} smart contracts, as well as retrieving smart contract {@link SmartContractsClient#getFilteredScOutputEvents|events} - * and {@link SmartContractsClient#getContractBalance|balances}. - * - * @module SmartContractsClient - */ -import { EOperationStatus } from '../interfaces/EOperationStatus' -import { IAddressInfo } from '../interfaces/IAddressInfo' -import { IBalance } from '../interfaces/IBalance' -import { ICallData } from '../interfaces/ICallData' -import { IClientConfig } from '../interfaces/IClientConfig' -import { IContractData } from '../interfaces/IContractData' - -import { IEventFilter } from '../interfaces/IEventFilter' -import { IExecuteReadOnlyData } from '../interfaces/IExecuteReadOnlyData' -import { IExecuteReadOnlyResponse } from '../interfaces/IExecuteReadOnlyResponse' -import { IReadData } from '../interfaces/IReadData' -import { ISmartContractsClient } from '../interfaces/ISmartContractsClient' -import { JSON_RPC_REQUEST_METHOD } from '../interfaces/JsonRpcMethods' -import { trySafeExecute } from '../utils/retryExecuteFunction' -import { BaseClient } from './BaseClient' -import { PublicApiClient } from './PublicApiClient' -import { IWalletClient } from '../interfaces/IWalletClient' -import { IBaseAccount } from '../interfaces/IBaseAccount' -import { - IContractReadOperationResponse, - IContractReadOperationData, - IEvent, - Args, - fromMAS, - MAX_GAS_CALL, - toMAS, - MASSA_SCALING_FACTOR, - MIN_GAS_CALL, -} from '@massalabs/web3-utils' -import { wait } from '../utils/time' -import { - isAwaitingInclusion, - isFinalError, - isFinalSuccess, - isIncludedPending, - isSpeculativeError, - isSpeculativeSuccess, - isUnexecutedOrExpired, -} from './helpers/operationStatus' -import { MnsResolver } from './MnsResolver' - -const WAIT_STATUS_TIMEOUT = 60000 -const WAIT_OPERATION_TIMEOUT = 160000 -const TX_POLL_INTERVAL_MS = 1000 - -/** - * The key name (as a string) to look for when we are retrieving the proto file from a contract - */ -export const MASSA_PROTOFILE_KEY = 'protoMassa' -/** - * The separator used to split the proto file content into separate proto files - */ -export const PROTO_FILE_SEPARATOR = '|||||' -/** - * Smart Contracts Client object enables smart contract deployment, calls and streaming of events. - */ -export class SmartContractsClient - extends BaseClient - implements ISmartContractsClient -{ - /** - * Constructor for {@link SmartContractsClient} objects. - */ - public constructor( - clientConfig: IClientConfig, - private readonly publicApiClient: PublicApiClient, - private readonly walletClient: IWalletClient, - private readonly mnsResolver: MnsResolver - ) { - super(clientConfig) - - // bind class methods - this.deploySmartContract = this.deploySmartContract.bind(this) - this.getFilteredScOutputEvents = this.getFilteredScOutputEvents.bind(this) - this.executeReadOnlySmartContract = - this.executeReadOnlySmartContract.bind(this) - this.awaitRequiredOperationStatus = - this.awaitRequiredOperationStatus.bind(this) - this.getOperationStatus = this.getOperationStatus.bind(this) - this.callSmartContract = this.callSmartContract.bind(this) - this.readSmartContract = this.readSmartContract.bind(this) - this.getContractBalance = this.getContractBalance.bind(this) - } - - /** - * Deploy a smart contract on the massa blockchain by creating and sending - * an operation containing byte code. - * - * @remarks - * If no executor is provided, the default wallet account from the provided {@link WalletClient} - * will be used. - * - * @param contractData - The deployment contract data. - * @param executor - The account to use for the deployment. - * - * @returns A promise that resolves to the operation ID of the deployment operation. - */ - public async deploySmartContract( - contractData: IContractData, - executor?: IBaseAccount - ): Promise { - const sender = executor || this.walletClient.getBaseAccount() - if (!sender) { - throw new Error('No tx sender available') - } - return await sender.deploySmartContract(contractData) - } - - /** - * Calls a smart contract method. - * - * @remarks - * If no executor is provided, the default wallet account will be used. - * - * @param callData - The data required for the smart contract call. - * @param executor - The account that will execute the call (default: the default - * wallet account from {@link WalletClient}). - * - * @returns A promise that resolves to the operation ID of the call operation as a string. - */ - public async callSmartContract( - callData: ICallData, - executor?: IBaseAccount - ): Promise { - const sender = executor || this.walletClient.getBaseAccount() - if (!sender) { - throw new Error('No tx sender available') - } - // check the max. allowed gas - if (callData.maxGas > MAX_GAS_CALL) { - throw new Error( - `The gas submitted ${callData.maxGas.toString()} exceeds the max. allowed block gas of ${MAX_GAS_CALL.toString()}` - ) - } - - callData.coins = callData.coins || BigInt(0) - - const senderBalance = await this.walletClient.getAccountBalance( - sender.address() - ) - - if (!senderBalance) { - throw new Error( - `Unable to retrieve the balance of the sender ${sender.address()}` - ) - } - - if (senderBalance.final < callData.coins) { - throw new Error( - `The sender ${sender.address()} does not have enough balance to pay for the coins` - ) - } - - if (callData.maxGas === null || callData.maxGas === undefined) { - try { - const response = await this.readSmartContract(callData) - callData.maxGas = BigInt(response.info.gas_cost) - if (callData.maxGas < MIN_GAS_CALL) { - callData.maxGas = MIN_GAS_CALL - } - } catch (error) { - throw new Error( - `Operation failed: Max gas unspecified and auto-estimation failed. Error details: ${error.message}` - ) - } - } - - callData.targetAddress = await this.mnsResolver.resolveOrFallback( - callData.targetAddress - ) - - return await sender.callSmartContract(callData) - } - - /** - * Execute a dry run Smart contract call and returns some data regarding its execution - * such as the changes of in the states that would have happen if the transaction was really executed on chain. - * - * @param readData - The data required for the a read operation of a smart contract. - * - * @returns A promise that resolves to an object which represents the result of the operation and contains data about its execution. - */ - public async readSmartContract( - readData: IReadData - ): Promise { - // check the max. allowed gas - if (readData.maxGas > MAX_GAS_CALL) { - throw new Error( - `The gas submitted ${readData.maxGas.toString()} exceeds the max. allowed block gas of ${MAX_GAS_CALL.toString()}` - ) - } - - readData.targetAddress = await this.mnsResolver.resolveOrFallback( - readData.targetAddress - ) - - const data = { - max_gas: - readData.maxGas === null || readData.maxGas === undefined - ? Number(MAX_GAS_CALL) - : Number(readData.maxGas), - target_address: readData.targetAddress, - target_function: readData.targetFunction, - parameter: - readData.parameter instanceof Args - ? readData.parameter.serialize() - : readData.parameter, - caller_address: readData.callerAddress - ? readData.callerAddress - : this.walletClient.getBaseAccount()?.address(), - coins: readData.coins - ? toMAS(readData.coins).toFixed(MASSA_SCALING_FACTOR) - : undefined, - fee: readData.fee - ? toMAS(readData.fee).toFixed(MASSA_SCALING_FACTOR) - : undefined, - } - - // returns operation ids - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.EXECUTE_READ_ONLY_CALL - let jsonRpcCallResult: Array = [] - if (this.clientConfig.retryStrategyOn) { - jsonRpcCallResult = await trySafeExecute< - Array - >(this.sendJsonRPCRequest, [jsonRpcRequestMethod, [[data]]]) - } else { - jsonRpcCallResult = await this.sendJsonRPCRequest(jsonRpcRequestMethod, [ - [data], - ]) - } - - if (jsonRpcCallResult.length <= 0) { - throw new Error( - 'Read operation bad response. No results array in json rpc response. Inspect smart contract' - ) - } - if (jsonRpcCallResult[0].result.Error) { - throw new Error(jsonRpcCallResult[0].result.Error) - } - - return { - returnValue: new Uint8Array(jsonRpcCallResult[0].result.Ok), - info: jsonRpcCallResult[0], - } - } - - /** - * Returns the balance of the smart contract. - * - * @param address - The address of the smart contract or the MNS domain associated. - * - * @returns A promise that resolves to the balance of the smart contract. - */ - public async getContractBalance(address: string): Promise { - address = await this.mnsResolver.resolveOrFallback(address) - - const addresses: Array = - await this.publicApiClient.getAddresses([address]) - if (addresses.length === 0) return null - const { candidate_balance, final_balance } = addresses[0] - - return { - candidate: fromMAS(candidate_balance), - final: fromMAS(final_balance), - } - } - - /** - * Get filtered smart contract output events. - * - * @param eventFilterData - The filter data for the events. - * - * @returns A promise that resolves to an array of IEvent objects containing the filtered events. - */ - public async getFilteredScOutputEvents( - eventFilterData: IEventFilter - ): Promise> { - eventFilterData.emitter_address = await this.mnsResolver.resolveOrFallback( - eventFilterData.emitter_address - ) - - eventFilterData.original_caller_address = - await this.mnsResolver.resolveOrFallback( - eventFilterData.original_caller_address - ) - - const data = { - start: eventFilterData.start, - end: eventFilterData.end, - emitter_address: eventFilterData.emitter_address, - original_caller_address: eventFilterData.original_caller_address, - original_operation_id: eventFilterData.original_operation_id, - is_final: eventFilterData.is_final, - } - - const jsonRpcRequestMethod = - JSON_RPC_REQUEST_METHOD.GET_FILTERED_SC_OUTPUT_EVENT - - // returns filtered events - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute>(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [data], - ]) - } else { - return await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [data] - ) - } - } - - /** - * Send a read-only smart contract execution request. - * - * @remarks - * This method is used to dry-run a smart contract execution and get the changes of the states that would - * have happen if the transaction was really executed on chain. - * This operation does not modify the blockchain state. - * - * @param contractData - The data required for the operation. - * - * @returns A promise which resolves to an object containing data about the operation. - * - * @throws - * - If the contract binary data is missing. - * - If the contract contract address is missing. - * - If the result is empty. - * - If the result contains an error. - */ - public async executeReadOnlySmartContract( - contractData: IContractData - ): Promise { - if (contractData.address) { - contractData.address = await this.mnsResolver.resolveOrFallback( - contractData.address - ) - } - - if (!contractData.contractDataBinary) { - throw new Error('Expected non-null contract bytecode, but received null.') - } - - if (!contractData.address) { - throw new Error('Expected contract address, but received null.') - } - - const data = { - max_gas: Number(contractData.maxGas), - bytecode: Array.from(contractData.contractDataBinary), - address: contractData.address, - } - - let jsonRpcCallResult: Array = [] - const jsonRpcRequestMethod = - JSON_RPC_REQUEST_METHOD.EXECUTE_READ_ONLY_BYTECODE - if (this.clientConfig.retryStrategyOn) { - jsonRpcCallResult = await trySafeExecute>( - this.sendJsonRPCRequest, - [jsonRpcRequestMethod, [[data]]] - ) - } else { - jsonRpcCallResult = await this.sendJsonRPCRequest< - Array - >(jsonRpcRequestMethod, [[data]]) - } - - if (jsonRpcCallResult.length <= 0) { - throw new Error( - `Read operation bad response. No results array in json rpc response. Inspect smart contract` - ) - } - if (jsonRpcCallResult[0].result.Error) { - throw new Error('Execute read-only smart contract error', { - cause: jsonRpcCallResult[0].result.Error, - }) - } - return { - returnValue: new Uint8Array(jsonRpcCallResult[0].result.Ok), - info: jsonRpcCallResult[0], - } - } - - /** - * Get the status of a specific operation. - * - * @param opId - The operation id. - * - * @returns A promise that resolves to the status of the operation. - */ - public async getOperationStatus(opId: string): Promise { - const operations = await this.publicApiClient.getOperations([opId]) - - if (!operations.length) { - return EOperationStatus.NOT_FOUND - } - - const operation = operations[0] - - if (isUnexecutedOrExpired(operation)) { - return EOperationStatus.UNEXECUTED_OR_EXPIRED - } - - if (isAwaitingInclusion(operation)) { - return EOperationStatus.AWAITING_INCLUSION - } - - if (isSpeculativeError(operation)) { - return EOperationStatus.SPECULATIVE_ERROR - } - - if (isSpeculativeSuccess(operation)) { - return EOperationStatus.SPECULATIVE_SUCCESS - } - - if (isFinalSuccess(operation)) { - return EOperationStatus.FINAL_SUCCESS - } - - if (isFinalError(operation)) { - return EOperationStatus.FINAL_ERROR - } - - if (isIncludedPending(operation)) { - return EOperationStatus.INCLUDED_PENDING - } - - return EOperationStatus.INCONSISTENT - } - - /** - * Get the status of a specific operation and wait until it reaches the required status. - * - * @param opId - The required operation id. - * @param requiredStatus - The required status. - * - * @returns A promise that resolves to the status of the operation. - */ - public async awaitRequiredOperationStatus( - opId: string, - requiredStatus: EOperationStatus, - timeout?: number - ): Promise { - return await this.awaitOperationStatusHelper( - opId, - timeout, - (currentStatus) => currentStatus === requiredStatus - ) - } - - /** - * Get the status of a specific operation and wait until it reaches one of the required statuses. - * - * @param opId - The required operation id. - * @param requiredStatuses - An array of required statuses. - * - * @returns A promise that resolves to the status of the operation. - */ - public async awaitMultipleRequiredOperationStatus( - opId: string, - requiredStatuses: EOperationStatus[], - timeout?: number - ): Promise { - return await this.awaitOperationStatusHelper( - opId, - timeout, - (currentStatus) => requiredStatuses.includes(currentStatus) - ) - } - - /** - * Watches the status of an operation and invokes a callback function when the status changes. - * - * @param opId - The ID of the operation to watch. - * @param callback - The function to call when the operation status changes. It receives the new status and a potential error as a parameter. - * @param timeInterval - The interval in milliseconds at which to check the operation status. Defaults to 1000 ms. - * @param timeout - The time at which to stop checking the operation status. Defaults is 16000 ms. - * - * @returns A Promise that resolves to a function that can be called to stop watching the operation status. - */ - public async watchOperationStatus( - opId: string, - callback: (status: EOperationStatus, error?: Error) => void, - timeInterval = TX_POLL_INTERVAL_MS, - timeout = WAIT_OPERATION_TIMEOUT - ): Promise<() => void> { - let lastStatus = await this.getOperationStatus(opId) - callback(lastStatus) - - const startTime = Date.now() - - const interval = setInterval(async () => { - if (Date.now() > startTime + timeout) { - callback(lastStatus, new Error('Operation timed out')) - clearInterval(interval) - return - } - - try { - const newStatus = await this.getOperationStatus(opId) - if (newStatus !== lastStatus) { - lastStatus = newStatus - callback(newStatus) - } - - if ( - newStatus === EOperationStatus.FINAL_SUCCESS || - newStatus === EOperationStatus.FINAL_ERROR - ) { - clearInterval(interval) - } - } catch (error) { - callback(lastStatus, error) - } - }, timeInterval) - - return () => clearInterval(interval) - } - - /** - * Helper method to wait for a specific condition on an operation's status. - * - * @param opId - The operation id to check. - * @param statusCheck - A callback function that defines the condition for the operation status. - * - * @returns A promise that resolves to the status of the operation. - * - */ - private async awaitOperationStatusHelper( - opId: string, - timeout = WAIT_STATUS_TIMEOUT, - statusCheck: (status: EOperationStatus) => boolean - ): Promise { - const startTime = Date.now() - - while (Date.now() - startTime < timeout) { - let currentStatus = EOperationStatus.NOT_FOUND - - try { - currentStatus = await this.getOperationStatus(opId) - - if (statusCheck(currentStatus)) { - return currentStatus - } - } catch (ex) { - console.warn(ex) - } - await wait(TX_POLL_INTERVAL_MS) - } - - throw new Error( - `Failed to retrieve status of operation id: ${opId}: Timeout reached.` - ) - } -} diff --git a/packages/massa-web3/src/web3/WalletClient.ts b/packages/massa-web3/src/web3/WalletClient.ts deleted file mode 100755 index f2ed8a24..00000000 --- a/packages/massa-web3/src/web3/WalletClient.ts +++ /dev/null @@ -1,583 +0,0 @@ -import { IClientConfig } from '../interfaces/IClientConfig' -import { IAccount } from '../interfaces/IAccount' -import { BaseClient } from './BaseClient' -import { IAddressInfo } from '../interfaces/IAddressInfo' -import { IFullAddressInfo } from '../interfaces/IFullAddressInfo' -import { ISignature } from '../interfaces/ISignature' -import { - base58Decode, - base58Encode, - varintEncode, - hashBlake3, -} from '../utils/Xbqcrypto' -import { JSON_RPC_REQUEST_METHOD } from '../interfaces/JsonRpcMethods' -import { trySafeExecute } from '../utils/retryExecuteFunction' -import { ITransactionData } from '../interfaces/ITransactionData' -import { PublicApiClient } from './PublicApiClient' -import { IRollsData } from '../interfaces/IRollsData' -import { IBalance } from '../interfaces/IBalance' -import * as ed from '@noble/ed25519' -import { IWalletClient } from '../interfaces/IWalletClient' -import { Address, SecretKey, PublicKey } from '../utils/keyAndAddresses' -import { IBaseAccount } from '../interfaces/IBaseAccount' -import { Web3Account } from './accounts/Web3Account' -import { - ADDRESS_USER_PREFIX, - KEYS_VERSION_NUMBER, - SECRET_KEY_PREFIX, - fromMAS, -} from '@massalabs/web3-utils' -import { MnsResolver } from './MnsResolver' - -const MAX_WALLET_ACCOUNTS = 256 - -/** - * A client class for interacting with wallets, which can seamlessly work with WebExtensions. - * - * @remarks - * The WalletClient manages multiple accounts and handles operations such as transaction signing, - * fetching account information, and interacting with the blockchain. It extends the BaseClient - * class and implements the IWalletClient interface. - */ -export class WalletClient extends BaseClient implements IWalletClient { - private wallet: Array = [] - private mnsResolver: MnsResolver - private baseAccount?: IBaseAccount - - /** - * Constructor of the {@link WalletClient} class. - * - * @param clientConfig - Configuration parameters for the client. - * @param publicApiClient - A {@link PublicApiClient} instance used for making API calls. - * @param baseAccount - (Optional) An {@link IAccount} to set as the base account for the wallet. - */ - public constructor( - clientConfig: IClientConfig, - private readonly publicApiClient: PublicApiClient, - mnsResolver: MnsResolver, - baseAccount?: IBaseAccount - ) { - super(clientConfig) - if (baseAccount) { - this.baseAccount = baseAccount - } - - this.mnsResolver = mnsResolver - - // ========== bind wallet methods ========= // - - // wallet methods - this.cleanWallet = this.cleanWallet.bind(this) - this.getWalletAccounts = this.getWalletAccounts.bind(this) - this.getWalletAccountByAddress = this.getWalletAccountByAddress.bind(this) - this.addSecretKeysToWallet = this.addSecretKeysToWallet.bind(this) - this.addAccountsToWallet = this.addAccountsToWallet.bind(this) - this.removeAddressesFromWallet = this.removeAddressesFromWallet.bind(this) - this.walletInfo = this.walletInfo.bind(this) - this.signMessage = this.signMessage.bind(this) - this.getWalletAddressesInfo = this.getWalletAddressesInfo.bind(this) - this.setBaseAccount = this.setBaseAccount.bind(this) - this.getBaseAccount = this.getBaseAccount.bind(this) - this.sendTransaction = this.sendTransaction.bind(this) - this.sellRolls = this.sellRolls.bind(this) - this.buyRolls = this.buyRolls.bind(this) - this.getAccountBalance = this.getAccountBalance.bind(this) - } - - /** - * Sets a provided account as the default (base) account for the wallet. - * - * @param baseAccount - An {@link IAccount} to be set as the base account. - * - * @returns A Promise that resolves to `void` when the base account has been set successfully. - */ - public async setBaseAccount(baseAccount: IBaseAccount): Promise { - if (!baseAccount.address()) { - throw new Error('Invalid base account address') - } - await baseAccount.verify() - this.baseAccount = baseAccount - } - - /** - * Retrieves the default (base) account of the wallet. - * - * @returns The default {@link IAccount} of the wallet. If no default account is set, it returns `null`. - */ - public getBaseAccount(): IBaseAccount | null { - return this.baseAccount - } - - /** - * Retrieves all accounts stored in the wallet. - * - * @returns An array of {@link IAccount} objects. - */ - public getWalletAccounts(): Array { - return this.wallet - } - - /** - * Removes all accounts from the wallet. - */ - public cleanWallet(): void { - this.wallet.length = 0 - this.baseAccount = null - } - - /** - * Retrieves a wallet account based on its address. - * - * @param address - The address of the account to retrieve. - * - * @returns The {@link IAccount} associated with the provided address - * or `undefined` if no account with the given address is found in the wallet. - */ - public getWalletAccountByAddress(address: string): IAccount | undefined { - return this.wallet.find( - (w) => w.address.toLowerCase() === address.toLowerCase() - ) // ignore case for flexibility - } - - /** - * Adds a set of private keys to the wallet. - * - * @param secretKeys - An array of base58 encoded private keys to be added to the wallet. - * - * @throws if the number of private keys exceeds the maximum limit. - * - * @returns A Promise that resolves to an array of {@link IAccount} objects. - */ - public async addSecretKeysToWallet( - secretKeys: Array - ): Promise> { - if (secretKeys.length > MAX_WALLET_ACCOUNTS) { - throw new Error( - `Maximum number of allowed wallet accounts exceeded ${MAX_WALLET_ACCOUNTS}. Submitted private keys: ${secretKeys.length}` - ) - } - const accountsToCreate: IAccount[] = [] - - const uniqueSecretKeys = secretKeys.filter( - (value, index, self) => self.indexOf(value) === index - ) - - for (const secretKeyBase58Encoded of uniqueSecretKeys) { - const secretKey = new SecretKey(secretKeyBase58Encoded) - const publicKey: PublicKey = await secretKey.getPublicKey() - const address: Address = Address.fromPublicKey(publicKey) - - if (!this.getWalletAccountByAddress(address.base58Encoded)) { - accountsToCreate.push({ - secretKey: secretKeyBase58Encoded, - publicKey: publicKey.base58Encoded, - address: address.base58Encoded, - } as IAccount) - } - } - - this.wallet.push(...accountsToCreate) - return accountsToCreate - } - - /** - * Adds a set of accounts to the wallet. - * - * @privateRemarks - * Each account must have a base58 encoded random entropy or private key. - * - * @param accounts - An array of accounts ({@link IAccount} objects) to be added to the wallet. - * - * @throws - * - If the number of accounts exceeds the {@link MAX_WALLET_ACCOUNTS} limit - * - If an account is missing a private key - * - If a submitted public key doesn't correspond to the associated private key - * - If an account address doesn't correspond to the private key-derived address - * - * @returns A Promise that resolves to an array of {@link IAccount} objects. - */ - public async addAccountsToWallet( - accounts: Array - ): Promise> { - if (accounts.length > MAX_WALLET_ACCOUNTS) { - throw new Error( - `Maximum number of allowed wallet accounts exceeded ${MAX_WALLET_ACCOUNTS}. Submitted accounts: ${accounts.length}` - ) - } - const accountsAdded: Array = [] - - for (const account of accounts) { - if (!account.secretKey) { - throw new Error('Missing account private key') - } - - // Create the secret key object - const secretKeyBase58Encoded: string = account.secretKey - const secretKey: SecretKey = new SecretKey(secretKeyBase58Encoded) - - // create the public key object - const publicKey: PublicKey = await secretKey.getPublicKey() - if (account.publicKey && account.publicKey !== publicKey.base58Encoded) { - throw new Error( - 'Public key does not correspond the the private key submitted' - ) - } - - // get wallet account address - const address: Address = Address.fromPublicKey(publicKey) - if (account.address && account.address !== address.base58Encoded) { - throw new Error( - 'Account address not correspond the the address submitted' - ) - } - - if (!this.getWalletAccountByAddress(address.base58Encoded)) { - accountsAdded.push({ - address: address.base58Encoded, - secretKey: secretKeyBase58Encoded, - publicKey: publicKey.base58Encoded, - } as IAccount) - } - } - - this.wallet.push(...accountsAdded) - return accountsAdded - } - - /** - * Remove a list of addresses from the wallet. - * - * @param addresses - An array of addresses to remove from the wallet. - */ - public removeAddressesFromWallet(addresses: Array): void { - for (const address of addresses) { - const index = this.wallet.findIndex((w) => w.address === address) - if (index > -1) { - this.wallet.splice(index, 1) - } - } - } - - /** - * Retrieves detailed information about the wallet. - * - * @throws Will throw an error if the number of retrieved wallets does not match the number of addresses in the wallet. - * - * @returns A Promise that resolves to an array of {@link IFullAddressInfo} objects. - */ - public async walletInfo(): Promise> { - if (this.wallet.length === 0) { - return [] - } - const addresses: Array = this.wallet.map( - (account) => account.address - ) - const addressesInfo: Array = - await this.getWalletAddressesInfo(addresses) - - if (addressesInfo.length !== this.wallet.length) { - throw new Error( - `Requested wallets not fully retrieved. Got ${addressesInfo.length}, expected: ${this.wallet.length}` - ) - } - - return addressesInfo.map((info, index) => { - return { - publicKey: this.wallet[index].publicKey, - secretKey: this.wallet[index].secretKey, - ...info, - } as IFullAddressInfo - }) - } - - /** - * Generates a new wallet account. - * @param KEYS_VERSION_NUMBER - The version number of the secret key to be generated, to create a new account. - * - * @returns A Promise that resolves to an {@link IAccount} object, which represents the newly created account. - */ - public static async walletGenerateNewAccount(): Promise { - // generate private key - const secretKeyArray: Uint8Array = ed.utils.randomPrivateKey() - - const version = Buffer.from(varintEncode(KEYS_VERSION_NUMBER)) - const secretKeyBase58Encoded: string = - SECRET_KEY_PREFIX + base58Encode(Buffer.concat([version, secretKeyArray])) - const secretKey: SecretKey = new SecretKey(secretKeyBase58Encoded) - - // get public key - const publicKey: PublicKey = await secretKey.getPublicKey() - - // get wallet account address - const address: Address = Address.fromPublicKey(publicKey) - - return { - address: address.base58Encoded, - secretKey: secretKeyBase58Encoded, - publicKey: publicKey.base58Encoded, - } as IAccount - } - - /** - * Generates an account from a given private key. - * - * @param secretKeyBase58 - A base58 encoded private key from which the account will be generated. - * - * @returns A Promise that resolves to an {@link IAccount} object. - */ - public static async getAccountFromSecretKey( - secretKeyBase58: string - ): Promise { - // get private key - const secretKey: SecretKey = new SecretKey(secretKeyBase58) - // get public key - const publicKey: PublicKey = await secretKey.getPublicKey() - - // get wallet account address - const address: Address = Address.fromPublicKey(publicKey) - - return { - address: address.base58Encoded, - secretKey: secretKeyBase58, - publicKey: publicKey.base58Encoded, - } as IAccount - } - - /** - * Signs a random message data using a wallet account that has already been added. - * - * @param data - The data to be signed. - * @param accountSignerAddress - The address of the wallet account that will sign the data. - * - * @throws Will throw an error if the account associated with the provided address is not found in the wallet. - * - * @returns A Promise that resolves to an {@link ISignature} object representing the signature. - */ - public async signMessage( - data: string | Buffer, - chainId: bigint, - accountSignerAddress: string - ): Promise { - let signerAccount = this.getWalletAccountByAddress(accountSignerAddress) - let account: IBaseAccount - if (!signerAccount) { - if (this.baseAccount.address() === accountSignerAddress) { - account = this.baseAccount - } else { - throw new Error( - `No signer account ${accountSignerAddress} found in wallet` - ) - } - } else { - account = new Web3Account(signerAccount, this.publicApiClient, chainId) - } - if (typeof data === 'string') { - data = Buffer.from(data) - } - return account.sign(data) - } - - /** - * Retrieves information about specified wallet addresses. - * - * @param addresses - An array of wallet addresses for which information is to be retrieved. - * - * @returns A Promise that resolves to an array of {@link IAddressInfo} objects, each containing - * information about a corresponding wallet address. - */ - private async getWalletAddressesInfo( - addresses: Array - ): Promise> { - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.GET_ADDRESSES - if (this.clientConfig.retryStrategyOn) { - return await trySafeExecute>( - this.sendJsonRPCRequest, - [jsonRpcRequestMethod, [addresses]] - ) - } else { - return await this.sendJsonRPCRequest>( - jsonRpcRequestMethod, - [addresses] - ) - } - } - - /** - * Signs the provided data with the given address. - * - * @remarks - * The address must be present in the wallet. - * - * @param data - The data to be signed. - * @param signer - The account that will be used to sign the data. - * - * @throws - * - if no private key is available for signing the message. - * - if no public key is available for verifying the signed message. - * - if the length of the generated signature is not valid. - * - if the signature could not be verified with the public key. - * - * @returns A Promise that resolves to an {@link ISignature} object representing the signature. - */ - public static async walletSignMessage( - data: string | Buffer, - signer: IBaseAccount - ): Promise { - return signer.sign(Buffer.from(data)) - } - - /** - * Verify a signature. - * - * @param data - The signed data to verify. - * @param signature - The signature to verify. - * @param signerPubKey - The public key of the signer. - * - * @returns A Promise that resolves to `true` if the signature is valid, `false` otherwise. - */ - public async verifySignature( - data: string | Buffer, - signature: ISignature - ): Promise { - // setup the public key. - const publicKey: PublicKey = PublicKey.fromString(signature.publicKey) - - // setup the message digest. - const bytesCompact: Buffer = Buffer.from(data) - const messageDigest: Uint8Array = hashBlake3(bytesCompact) - - try { - // setup the signature. - const versionAndSignatureBytes: Buffer = base58Decode( - signature.base58Encoded - ) - - // removing the version byte - const signatureBytes: Uint8Array = versionAndSignatureBytes.slice(1) - // check sig length - if (signatureBytes.length != 64) { - throw new Error( - `Invalid signature length. Expected 64, got ${signatureBytes.length}` - ) - } - if (publicKey.bytes.length != 32) { - throw new Error( - `Invalid public key length. Expected 32, got ${publicKey.bytes.length}` - ) - } - // verify signature. - const isVerified = await ed.verify( - signatureBytes, - messageDigest, - publicKey.bytes - ) - return isVerified - } catch (err) { - console.error('Failed to verify signature:', err) - return false - } - } - - /** - * Retrieves the balance of an account. - * - * @param address - The address to get the balance from. - * - * @returns A Promise that resolves to an {@link IBalance}. If the address is not found, - * it returns `null`. - */ - public async getAccountBalance(address: string): Promise { - try { - const addresses: Array = - await this.publicApiClient.getAddresses([address]) - if (addresses.length === 0) return null - - const addressInfo: IAddressInfo = addresses.at(0) - return { - candidate: fromMAS(addressInfo.candidate_balance), - final: fromMAS(addressInfo.final_balance), - } as IBalance - } catch (err) { - console.error('Failed to get account balance:', err) - return null - } - } - - /** - * Sends native MAS from a wallet address to another. - * - * @param txData - The transaction data. - * @param executor - (Optional) The account that will execute the transaction. If not - * provided, the base account is used. - * - * @throws if no sender account is available for the transaction. - * - * @returns a promise that resolves to an array of operations ids. - */ - public async sendTransaction( - txData: ITransactionData, - executor?: IBaseAccount - ): Promise> { - txData.recipientAddress = await this.mnsResolver.resolveOrFallback( - txData.recipientAddress - ) - - if (!new Address(txData.recipientAddress).isUser) { - throw new Error( - `Invalid recipient address: "${txData.recipientAddress}". The address must be a user address, starting with "${ADDRESS_USER_PREFIX}".` - ) - } - - const sender: IBaseAccount = executor || this.getBaseAccount() - if (!sender) { - throw new Error('No tx sender available') - } - return [await sender.sendTransaction(txData)] - } - - /** - * Buy rolls with wallet address. - * - * @param txData - The transaction data - * @param executor - (Optional) The account that will execute the transaction. - * If not specified, the base account is used by default. - * - * @throws if no sender account is available for the transaction. - * - * @returns a promise that resolves to an array of operations ids. - */ - public async buyRolls( - txData: IRollsData, - executor?: IBaseAccount - ): Promise> { - // check sender account - const sender: IBaseAccount = executor || this.getBaseAccount() - if (!sender) { - throw new Error('No tx sender available') - } - return [await sender.buyRolls(txData)] - } - - /** - * Sell rolls with wallet address. - * - * @param txData - The transaction data. - * @param executor - (Optional) The account that will execute the transaction. - * If not specified, the base account is used by default. - * - * @throws if no sender account is available for the transaction. - * - * @returns a promise that resolves to an array of operations ids. - */ - public async sellRolls( - txData: IRollsData, - executor?: IBaseAccount - ): Promise> { - // check sender account - const sender: IBaseAccount = executor || this.getBaseAccount() - if (!sender) { - throw new Error('No tx sender available') - } - return [await sender.sellRolls(txData)] - } -} diff --git a/packages/massa-web3/src/web3/accounts/WalletProviderAccount.ts b/packages/massa-web3/src/web3/accounts/WalletProviderAccount.ts deleted file mode 100644 index b5c63ea6..00000000 --- a/packages/massa-web3/src/web3/accounts/WalletProviderAccount.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { IBaseAccount } from '../../interfaces/IBaseAccount' -import { IAccount, ITransactionDetails } from '@massalabs/wallet-provider' -import { ISignature } from '../../interfaces/ISignature' -import { IRollsData } from '../../interfaces/IRollsData' -import { ITransactionData } from '../../interfaces/ITransactionData' -import { ICallData } from '../../interfaces/ICallData' -import { IContractData } from '../../interfaces/IContractData' -import { Args } from '@massalabs/web3-utils' - -export class WalletProviderAccount implements IBaseAccount { - private account: IAccount - constructor(account: IAccount) { - this.account = account - } - - public async sign(data: Buffer | Uint8Array | string): Promise { - if (data instanceof Uint8Array) { - data = Buffer.from(data) - } - - const signatureData = await this.account.sign(data) - - return { - publicKey: signatureData.publicKey, - base58Encoded: signatureData.base58Encoded, - } - } - - public address(): string { - return this.account.address() - } - - public async sellRolls(rollsData: IRollsData): Promise { - let res = await this.account.sellRolls(rollsData.amount, rollsData.fee) - return res.operationId - } - - public async buyRolls(rollsData: IRollsData): Promise { - let res = await this.account.buyRolls(rollsData.amount, rollsData.fee) - return res.operationId - } - - public async sendTransaction(txData: ITransactionData): Promise { - let res = await this.account.sendTransaction( - txData.amount, - txData.recipientAddress, - txData.fee - ) - return res.operationId - } - - public async callSmartContract(callData: ICallData): Promise { - let params: number[] | Args = callData.parameter - let paramToSend: Uint8Array | Args - - if (params instanceof Array) { - paramToSend = new Uint8Array(params) - } - if (params instanceof Args) { - paramToSend = params - } - - let res = (await this.account.callSC( - callData.targetAddress, - callData.targetFunction, - paramToSend, - callData.coins, - callData.fee, - callData.maxGas, - false - )) as ITransactionDetails - - return res.operationId - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - public async deploySmartContract(_: IContractData): Promise { - throw new Error( - 'deploySmartContract with an account from WalletProvider is not implemented yet.' - ) - } - - public async verify(): Promise { - return - } -} diff --git a/packages/massa-web3/src/web3/accounts/Web3Account.ts b/packages/massa-web3/src/web3/accounts/Web3Account.ts deleted file mode 100644 index 2c6e2060..00000000 --- a/packages/massa-web3/src/web3/accounts/Web3Account.ts +++ /dev/null @@ -1,266 +0,0 @@ -import { IAccount } from '../../interfaces/IAccount' -import { IBaseAccount } from '../../interfaces/IBaseAccount' -import { INodeStatus } from '../../interfaces/INodeStatus' -import { IPublicApiClient } from '../../interfaces/IPublicApiClient' -import { IRollsData } from '../../interfaces/IRollsData' -import { ISignature } from '../../interfaces/ISignature' -import { base58Encode, hashBlake3, varintEncode } from '../../utils/Xbqcrypto' -import { Address, PublicKey, SecretKey } from '../../utils/keyAndAddresses' -import * as ed from '@noble/ed25519' -import { BaseClient } from '../BaseClient' -import { OperationTypeId } from '../../interfaces/OperationTypes' -import { getBytesPublicKey } from '../../utils/bytes' -import { JSON_RPC_REQUEST_METHOD } from '../../interfaces/JsonRpcMethods' -import { ICallData } from '../../interfaces/ICallData' -import { IContractData } from '../../interfaces/IContractData' -import { trySafeExecute } from '../../utils/retryExecuteFunction' -import { ITransactionData } from '../../interfaces/ITransactionData' - -function getOperationBufferToSign( - chainId: bigint, - bytesPublicKey: Uint8Array, - bytesCompact: Buffer -): Buffer { - // Chain id is an 64-bit unsigned integer, convert to byte array (big endian) - const chainIdBuffer = new ArrayBuffer(8) - const view = new DataView(chainIdBuffer) - view.setBigUint64(0, chainId, false) - - return Buffer.concat([ - Buffer.from(chainIdBuffer), - bytesPublicKey, - bytesCompact, - ]) -} - -export class Web3Account extends BaseClient implements IBaseAccount { - private account: IAccount - private publicApiClient: IPublicApiClient - private chainId: bigint - - constructor( - account: IAccount, - publicApiClient: IPublicApiClient, - chainId: bigint - ) { - super(publicApiClient.clientConfig) - this.account = account - this.publicApiClient = publicApiClient - this.chainId = chainId - } - - /** - * Executes a blockchain operation - * - * @param txData - The transaction data for the operation. - * @param operationType - The type of operation to be executed. - * @param useRetry - Determines whether to use retry logic in case of failures. - * @param errorMessage - Custom error message to throw if operation fails. - * @param preExecutionCallback - An optional callback function to be executed before the operation, for any pre-execution logic or validation. - * @returns Returns a promise that resolves to the operation ID. - */ - private async executeOperation( - txData: IRollsData | ICallData | IContractData, - operationType: OperationTypeId, - useRetry: boolean = false, - errorMessage: string = 'Operation did not return a valid response', - preExecutionCallback?: ( - data: IRollsData | ICallData | IContractData - ) => Promise - ): Promise { - // Run pre-execution logic if provided - if (preExecutionCallback) { - await preExecutionCallback(txData) - } - - const nodeStatusInfo: INodeStatus = - await this.publicApiClient.getNodeStatus() - - const expiryPeriod: number = - nodeStatusInfo.next_slot.period + this.clientConfig.periodOffset - - const bytesCompact: Buffer = this.compactBytesForOperation( - txData, - operationType, - expiryPeriod - ) - - const signature: ISignature = await this.sign( - getOperationBufferToSign( - this.chainId, - getBytesPublicKey(this.account.publicKey), - bytesCompact - ) - ) - - const data = { - serialized_content: Array.prototype.slice.call(bytesCompact), - creator_public_key: this.account.publicKey, - signature: signature.base58Encoded, - } - - let opIds: Array - const jsonRpcRequestMethod = JSON_RPC_REQUEST_METHOD.SEND_OPERATIONS - - if (useRetry) { - opIds = await trySafeExecute>(this.sendJsonRPCRequest, [ - jsonRpcRequestMethod, - [[data]], - ]) - } else { - opIds = await this.sendJsonRPCRequest(jsonRpcRequestMethod, [[data]]) - } - - if (opIds.length <= 0) throw new Error(errorMessage) - - return opIds[0] - } - - public async verify(): Promise { - // Create the secret key object - const secretKeyBase58Encoded: string = this.account.secretKey - const secretKey: SecretKey = new SecretKey(secretKeyBase58Encoded) - - // create the public key object - const publicKey: PublicKey = await secretKey.getPublicKey() - if ( - this.account.publicKey && - this.account.publicKey !== publicKey.base58Encoded - ) { - throw new Error( - 'Public key does not correspond the the private key submitted' - ) - } - - // get wallet account address - const address: Address = Address.fromPublicKey(publicKey) - if ( - this.account.address && - this.account.address !== address.base58Encoded - ) { - throw new Error( - 'Account address not correspond the the address submitted' - ) - } - } - - public async sign(data: Buffer | Uint8Array | string): Promise { - // check private keys to sign the message with. - if (!this.account.secretKey) { - throw new Error('No private key to sign the message with') - } - - // check public key to verify the message with. - if (!this.account.publicKey) { - throw new Error('No public key to verify the signed message with') - } - - if (data instanceof Uint8Array) { - data = Buffer.from(data) - } - if (typeof data === 'string') { - data = Buffer.from(data, 'utf-8') - } - - // get private key - const secretKey: SecretKey = new SecretKey(this.account.secretKey) - - // bytes compaction - const bytesCompact: Buffer = Buffer.from(data) - // Hash byte compact - const messageHashDigest: Uint8Array = hashBlake3(bytesCompact) - - // sign the digest - const sig = await secretKey.signDigest(messageHashDigest) - - // check sig length - if (sig.length != 64) { - throw new Error( - `Invalid signature length. Expected 64, got ${sig.length}` - ) - } - - // verify signature - if (this.account.publicKey) { - const publicKey: PublicKey = await secretKey.getPublicKey() - - const isVerified = await ed.verify( - sig, - messageHashDigest, - publicKey.bytes - ) - - if (!isVerified) { - throw new Error( - `Signature could not be verified with public key. Please inspect` - ) - } - } - - // convert signature to base58 - const version = Buffer.from(varintEncode(secretKey.version)) - const base58Encoded = base58Encode(Buffer.concat([version, sig])) - - return { - publicKey: this.account.publicKey, - base58Encoded: base58Encoded, - } - } - - public address(): string { - return this.account.address - } - - public async sellRolls(txData: IRollsData): Promise { - return this.executeOperation(txData, OperationTypeId.RollSell) - } - public async buyRolls(txData: IRollsData): Promise { - return this.executeOperation(txData, OperationTypeId.RollBuy) - } - - public async sendTransaction(txData: ITransactionData): Promise { - return this.executeOperation(txData, OperationTypeId.Transaction) - } - - public async callSmartContract(callData: ICallData): Promise { - return this.executeOperation( - callData, - OperationTypeId.CallSC, - this.clientConfig.retryStrategyOn, - 'Call smart contract operation bad response. No results array in json rpc response. Inspect smart contract' - ) - } - - public async deploySmartContract( - contractData: IContractData - ): Promise { - const preExecutionLogic = async (data: IContractData) => { - // Check if SC data exists - if (!data.contractDataBinary) { - throw new Error( - 'Expected non-null contract bytecode, but received null.' - ) - } - - // Get the block size - const nodeStatusInfo: INodeStatus = - await this.publicApiClient.getNodeStatus() - if ( - data.contractDataBinary.length > - nodeStatusInfo.config.max_block_size / 2 - ) { - console.warn( - 'Bytecode size exceeded half of the maximum size of a block, operation will certainly be rejected' - ) - } - } - - return this.executeOperation( - contractData, - OperationTypeId.ExecuteSC, - false, - 'Deploy smart contract operation bad response. No results array in json rpc response. Inspect smart contract', - preExecutionLogic - ) - } -} diff --git a/packages/massa-web3/src/web3/helpers/operationStatus.ts b/packages/massa-web3/src/web3/helpers/operationStatus.ts deleted file mode 100644 index d21d06b7..00000000 --- a/packages/massa-web3/src/web3/helpers/operationStatus.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { IOperationData } from '../..' - -export function isUnexecutedOrExpired(operation: IOperationData): boolean { - return ( - operation.is_operation_final === null && operation.op_exec_status === null - ) -} - -export function isFinalSuccess(operation: IOperationData): boolean { - return operation.is_operation_final && operation.op_exec_status === true -} - -export function isFinalError(operation: IOperationData): boolean { - return operation.is_operation_final && operation.op_exec_status === false -} - -export function isSpeculativeSuccess(operation: IOperationData): boolean { - return !operation.is_operation_final && operation.op_exec_status === true -} - -export function isSpeculativeError(operation: IOperationData): boolean { - return !operation.is_operation_final && operation.op_exec_status === false -} - -export function isAwaitingInclusion(operation: IOperationData): boolean { - return operation.in_pool -} - -export function isIncludedPending(operation: IOperationData): boolean { - return operation.in_blocks.length > 0 -} diff --git a/packages/massa-web3/test/code-snippets/walletGenerateNewAccount.spec.ts b/packages/massa-web3/test/code-snippets/walletGenerateNewAccount.spec.ts deleted file mode 100644 index 8a1affa0..00000000 --- a/packages/massa-web3/test/code-snippets/walletGenerateNewAccount.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { WalletClient } from '@massalabs/massa-web3' - -it('should generate a new account with name and address', async () => { - const newAccount = await WalletClient.walletGenerateNewAccount() - - expect(newAccount).toHaveProperty('address') - expect(newAccount).toHaveProperty('publicKey') - expect(newAccount).toHaveProperty('secretKey') -}) diff --git a/packages/massa-web3/test/utils/conversion.spec.ts b/packages/massa-web3/test/utils/conversion.spec.ts deleted file mode 100644 index 18148b67..00000000 --- a/packages/massa-web3/test/utils/conversion.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { expect, it, describe } from '@jest/globals' -import BigNumber from 'bignumber.js' -import { fromMAS, toMAS } from '@massalabs/web3-utils' - -describe('conversion tests', () => { - it('test conversions to and from (all ranges and formats)', () => { - const nanoMassa1 = fromMAS('1.5234') - expect(nanoMassa1.toString()).toStrictEqual('1523400000') - const massa1 = toMAS(nanoMassa1) - expect(massa1.toString()).toStrictEqual('1.5234') - - const nanoMassa2 = fromMAS(1.5234) - expect(nanoMassa2.toString()).toStrictEqual('1523400000') - const massa2 = toMAS(nanoMassa2) - expect(massa2.toString()).toStrictEqual('1.5234') - - const nanoMassa3 = fromMAS(new BigNumber('1.5234')) - expect(nanoMassa3.toString()).toStrictEqual('1523400000') - const massa3 = toMAS(nanoMassa3) - expect(massa3.toString()).toStrictEqual('1.5234') - - const nanoMassa4 = fromMAS(BigInt(2)) - expect(nanoMassa4.toString()).toStrictEqual('2000000000') - const massa4 = toMAS(nanoMassa4) - expect(massa4.toString()).toStrictEqual('2') - - const nanoMassa5 = fromMAS('1.1234567899') - expect(nanoMassa5.toString()).toStrictEqual('1123456790') - const massa5 = toMAS(nanoMassa5) - expect(massa5.toString()).toStrictEqual('1.12345679') - }) -}) diff --git a/packages/massa-web3/test/utils/encode_decode.spec.ts b/packages/massa-web3/test/utils/encode_decode.spec.ts deleted file mode 100644 index 6fce964b..00000000 --- a/packages/massa-web3/test/utils/encode_decode.spec.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { expect, it, describe } from '@jest/globals' -import { - signedBigIntUtils, - unsignedBigIntUtils, -} from '../../src/utils/encode_decode_int/index' - -describe('BigInt Serializers Tests', () => { - beforeAll(() => { - const consoleSpy = jest.spyOn(console, 'error') - consoleSpy.mockImplementation(() => null) - }) - - afterAll(() => { - jest.restoreAllMocks() - }) - - describe('Unsigned BigInt Serializer Tests', () => { - it('should encode and decode positive unsigned BigInt', () => { - const values = [1n, 1111111n, 1111111111111111n] - - for (let value of values) { - const buffer = unsignedBigIntUtils.encode(value) - const decodedValue = unsignedBigIntUtils.decode(buffer) - expect(decodedValue).toEqual(value) - } - }) - - it('should calculate encoding length for unsigned BigInt', () => { - expect(unsignedBigIntUtils.encodingLength(1111111n)).toEqual(3) - }) - - it('should throw error when encoding negative unsigned BigInt', () => { - expect(() => unsignedBigIntUtils.encode(-1n)).toThrow( - 'value must be unsigned' - ) - }) - - it('should throw error when buffer is too small', () => { - const smallBuffer = new ArrayBuffer(1) - expect(() => unsignedBigIntUtils.encode(1111111n, smallBuffer)).toThrow( - 'the buffer is too small' - ) - }) - - it('should throw error when decoding with offset out of range', () => { - const encodedValue = unsignedBigIntUtils.encode(1111111n) - expect(() => unsignedBigIntUtils.decode(encodedValue, 100)).toThrow( - 'offset out of range' - ) - }) - }) - - describe('Signed BigInt Serializer Tests', () => { - it('should encode and decode positive signed BigInt', () => { - const values = [1n, 1111111n, BigInt(1) ** BigInt(11)] - - for (let value of values) { - const buffer = signedBigIntUtils.encode(value) - const uint8Array = new Uint8Array(buffer) - const decodedValue = signedBigIntUtils.decode(uint8Array) - expect(decodedValue).toEqual(value) - } - }) - - it('should encode and decode negative signed BigInt', () => { - const values = [-1n, -1111111n, -(BigInt(1) ** BigInt(11))] - - for (let value of values) { - const buffer = signedBigIntUtils.encode(value) - const uint8Array = new Uint8Array(buffer) - const decodedValue = signedBigIntUtils.decode(uint8Array) - expect(decodedValue).toEqual(value) - } - }) - - it('should calculate encoding length for positive signed BigInt', () => { - expect(signedBigIntUtils.encodingLength(1111111n)).toEqual(4) - }) - - it('should calculate encoding length for negative signed BigInt', () => { - expect(signedBigIntUtils.encodingLength(-1111111n)).toEqual(4) - }) - }) -}) diff --git a/packages/massa-web3/test/utils/keyAndAddresses.spec.ts b/packages/massa-web3/test/utils/keyAndAddresses.spec.ts deleted file mode 100644 index 53c73ab8..00000000 --- a/packages/massa-web3/test/utils/keyAndAddresses.spec.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { hashBlake3 } from '../../src/utils/Xbqcrypto' -import { - mockAddressResult, - mockPublicKeyObject, - mockSecretKeyOject, - mockSignatureResult, - mockAddressVersion, -} from '../web3/mockData' -import { SecretKey, PublicKey, Address } from '../../src/utils/keyAndAddresses' - -describe('SecretKey', () => { - it('should construct SecretKey correctly', async () => { - const secretKey = new SecretKey(mockSecretKeyOject.base58Encoded) - expect(secretKey.version).toEqual(mockSecretKeyOject.version) - expect(secretKey.bytes).toEqual(mockSecretKeyOject.bytes) - }) - - it('should get the public key correctly', async () => { - const secretKey: SecretKey = new SecretKey(mockSecretKeyOject.base58Encoded) - const publicKey: PublicKey = await secretKey.getPublicKey() - - expect(publicKey.version).toEqual(mockPublicKeyObject.version) - expect(publicKey.bytes).toEqual(mockPublicKeyObject.bytes) - expect(publicKey.base58Encoded).toEqual(mockPublicKeyObject.base58Encoded) - }) - - it('should sign the digest correctly', async () => { - const data = 'hello world' - - const bytesCompact: Buffer = Buffer.from(data) - - const messageHashDigest: Uint8Array = hashBlake3(bytesCompact) - - const secretKey: SecretKey = new SecretKey(mockSecretKeyOject.base58Encoded) - - const sig = await secretKey.signDigest(messageHashDigest) - - expect(sig).toEqual(mockSignatureResult.bytes) - }) -}) - -describe('PublicKey', () => { - it('should construct PublicKey correctly', async () => { - const bytes = mockPublicKeyObject.bytes - const version = mockPublicKeyObject.version - const expectedBase58Encode = mockPublicKeyObject.base58Encoded - - const publicKey = new PublicKey(bytes, version) - - expect(publicKey.bytes).toEqual(bytes) - expect(publicKey.version).toEqual(version) - expect(publicKey.base58Encoded).toEqual(expectedBase58Encode) - }) -}) - -describe('Address', () => { - it('should construct Address correctly', async () => { - const secretKeyObject: SecretKey = new SecretKey( - mockSecretKeyOject.base58Encoded - ) - const publicKeyObject: PublicKey = await secretKeyObject.getPublicKey() - - const addressObject: Address = Address.fromPublicKey(publicKeyObject) - - expect(addressObject.version).toEqual(mockAddressResult.version) - expect(addressObject.base58Encoded).toEqual(mockAddressResult.base58Encoded) - }) - - it('should construct Address correctly with version', async () => { - for (let addressObject of mockAddressVersion) { - const address = new Address(addressObject.base58Encoded) - expect(address.version).toEqual(addressObject.version) - } - }) - - it('should throw if the address is not valid', async () => { - const invalidAddress = 'A1' - expect(() => { - /* eslint-disable @typescript-eslint/no-unused-vars */ - const address = new Address(invalidAddress) - }).toThrow() - }) -}) diff --git a/packages/massa-web3/test/utils/retryExecuteFunction.spec.ts b/packages/massa-web3/test/utils/retryExecuteFunction.spec.ts deleted file mode 100644 index e0c8e191..00000000 --- a/packages/massa-web3/test/utils/retryExecuteFunction.spec.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { JSON_RPC_REQUEST_METHOD } from '../../src/interfaces/JsonRpcMethods' -import { trySafeExecute } from '../../src/utils/retryExecuteFunction' - -jest.mock('../../src/utils/time') - -describe('trySafeExecute function', () => { - beforeAll(() => { - const consoleSpy = jest.spyOn(console, 'error') - consoleSpy.mockImplementation(() => null) - }) - - beforeEach(() => { - jest.spyOn(global, 'setTimeout') - }) - - afterEach(() => { - jest.clearAllMocks() - }) - - afterAll(() => { - jest.restoreAllMocks() - }) - - it('should execute a function successfully on the first attempt', async () => { - const mockFunc = jest.fn().mockResolvedValue('success') - const result = await trySafeExecute(mockFunc, [ - JSON_RPC_REQUEST_METHOD.GET_STATUS, - {}, - ]) - expect(result).toEqual('success') - expect(mockFunc).toHaveBeenCalledTimes(1) - }) - - it('should retry the function upon failure and succeed', async () => { - const mockFunc = jest - .fn() - .mockRejectedValueOnce(new Error('failed')) - .mockResolvedValue('success') - const result = await trySafeExecute(mockFunc, [ - JSON_RPC_REQUEST_METHOD.GET_STATUS, - {}, - ]) - expect(result).toEqual('success') - expect(mockFunc).toHaveBeenCalledTimes(2) - }) - - it('should retry the function the correct number of times and then throw an error', async () => { - const mockFunc = jest.fn().mockRejectedValue(new Error('failed')) - await expect( - trySafeExecute(mockFunc, [JSON_RPC_REQUEST_METHOD.GET_STATUS, {}], 3) - ).rejects.toThrow('failed') - expect(mockFunc).toHaveBeenCalledTimes(3) - }) - - it('should throw an error when no function is provided', async () => { - await expect( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - trySafeExecute(null as any, [JSON_RPC_REQUEST_METHOD.GET_STATUS, {}]) - ).rejects.toThrow(`Function execution init conditions are erroneous: null`) - }) - - it('should handle missing args parameter', async () => { - const mockFunc = jest.fn().mockResolvedValue('success') - const result = await trySafeExecute(mockFunc) - expect(result).toEqual('success') - expect(mockFunc).toHaveBeenCalledWith(null, {}) - }) -}) diff --git a/packages/massa-web3/test/utils/time.spec.ts b/packages/massa-web3/test/utils/time.spec.ts deleted file mode 100644 index 4d7e05ca..00000000 --- a/packages/massa-web3/test/utils/time.spec.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Timeout, Interval, withTimeoutRejection } from '../../src/utils/time' - -describe('Timer utilities', () => { - jest.useFakeTimers() - - beforeAll(() => { - const consoleSpy = jest.spyOn(console, 'error') - consoleSpy.mockImplementation(() => null) - }) - - afterAll(() => { - jest.restoreAllMocks() - }) - - describe('Timeout class', () => { - it('should call the callback after the specified timeout', () => { - const callback = jest.fn() - void new Timeout(1000, callback) - - expect(callback).not.toBeCalled() - jest.advanceTimersByTime(1000) - expect(callback).toBeCalled() - }) - - it('should not call the callback if clear is called before the timeout', () => { - const callback = jest.fn() - const timeout = new Timeout(1000, callback) - jest.advanceTimersByTime(500) - timeout.clear() - - expect(callback).not.toBeCalled() - }) - }) - - describe('Interval class', () => { - it('should call the callback every interval', () => { - const callback = jest.fn() - void new Interval(1000, callback) - - jest.advanceTimersByTime(3000) - expect(callback).toBeCalledTimes(3) - }) - - it('should stop calling the callback if clear is called', () => { - const callback = jest.fn() - const interval = new Interval(1000, callback) - interval.clear() - - jest.advanceTimersByTime(3000) - expect(callback).not.toBeCalled() - }) - }) - - describe('withTimeoutRejection function', () => { - it('should resolve with the value of the promise if it resolves before the timeout', async () => { - const promise = Promise.resolve('success') - const result = withTimeoutRejection(promise, 1000) - jest.advanceTimersByTime(500) - - await expect(result).resolves.toBe('success') - }) - - it('should reject if the promise does not resolve before the timeout', async () => { - const promise = new Promise((resolve) => - setTimeout(resolve, 2000, 'success') - ) - const result = withTimeoutRejection(promise, 1000) - jest.advanceTimersByTime(1000) - - await expect(result).rejects.toThrow( - `Timeout of 1000 has passed and promise did not resolve` - ) - }) - }) - - afterEach(() => { - jest.clearAllTimers() - }) -}) diff --git a/packages/massa-web3/test/web3/Client.spec.ts b/packages/massa-web3/test/web3/Client.spec.ts deleted file mode 100644 index 3db23f90..00000000 --- a/packages/massa-web3/test/web3/Client.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { Client } from '../../src/web3/Client' -import { IClientConfig } from '../../src/interfaces/IClientConfig' -import { IProvider } from '../../src/interfaces/IProvider' -import { ProviderType } from '../../src/interfaces/IProvider' -import { DefaultProviderUrls } from '@massalabs/web3-utils' - -describe('Client Class', () => { - let clientConfig: IClientConfig - let client: Client - - beforeEach(() => { - clientConfig = { - providers: [ - { url: 'https://mock-public-api', type: ProviderType.PUBLIC }, - { url: 'https://mock-private-api', type: ProviderType.PRIVATE }, - ], - periodOffset: 0, - } - client = new Client(clientConfig) - }) - - test('should return the wallet client', () => { - const walletClient = client.wallet() - expect(walletClient).toBeTruthy() - }) - - test('should return the smart contracts client', () => { - const smartContractsClient = client.smartContracts() - expect(smartContractsClient).toBeTruthy() - }) - - test('should set custom providers', () => { - const newProviders: Array = [ - { url: 'https://mock-public-api', type: ProviderType.PUBLIC }, - { url: 'https://mock-private-api', type: ProviderType.PRIVATE }, - ] - client.setCustomProviders(newProviders) - - const currentProviders = client.getProviders() - expect(currentProviders).toEqual(newProviders) - }) - - test('should return public providers', () => { - const publicProviders = client.getPublicProviders() - expect(publicProviders).toHaveLength(1) - expect(publicProviders[0].type).toEqual(ProviderType.PUBLIC) - }) - - test('should return private providers', () => { - const privateProviders = client.getPrivateProviders() - expect(privateProviders).toHaveLength(1) - expect(privateProviders[0].type).toEqual(ProviderType.PRIVATE) - }) - - test('should set new default provider', () => { - const newDefaultProvider = 'https://new-default-provider.com' - client.setNewDefaultProvider(newDefaultProvider as DefaultProviderUrls) - - const currentProviders = client.getProviders() - expect(currentProviders).toHaveLength(2) - expect(currentProviders[0].url).toBe(newDefaultProvider) - expect(currentProviders[1].url).toBe(newDefaultProvider) - }) - - test('should return the private api client', () => { - const privateApiClient = client.privateApi() - expect(privateApiClient).toBeTruthy() - }) - - test('should return the public api client', () => { - const publicApiClient = client.publicApi() - expect(publicApiClient).toBeTruthy() - }) -}) diff --git a/packages/massa-web3/test/web3/baseClient.spec.ts b/packages/massa-web3/test/web3/baseClient.spec.ts deleted file mode 100644 index 80754cf5..00000000 --- a/packages/massa-web3/test/web3/baseClient.spec.ts +++ /dev/null @@ -1,384 +0,0 @@ -import { BaseClient } from '../../src/web3/BaseClient' -import { IProvider, ProviderType } from '../../src/interfaces/IProvider' -import { IClientConfig } from '../../src/interfaces/IClientConfig' -import { JSON_RPC_REQUEST_METHOD } from '../../src/interfaces/JsonRpcMethods' -import axios from 'axios' -import { fetchRequestHeaders } from '../../src/web3/BaseClient' - -jest.mock('axios') - -const publicApi = 'https://mock-public-api.com' -const privateApi = 'https://mock-private-api.com' - -export const PERIOD_OFFSET = 5 - -class TestBaseClient extends BaseClient { - constructor(config: IClientConfig) { - super(config) - } - - public getSendJsonRPCRequest( - method: JSON_RPC_REQUEST_METHOD, - params: object - ) { - return this.sendJsonRPCRequest(method, params) - } - - public getPrivateProviders() { - return super.getPrivateProviders() - } - - public getPublicProviders() { - return super.getPublicProviders() - } -} - -describe('BaseClient', () => { - describe('setProviders', () => { - test('setProviders should correctly set the new providers', () => { - const clientConfig: IClientConfig = { - providers: [ - { - url: 'https://oldRpcUrlPublic/api', - type: ProviderType.PUBLIC, - } as IProvider, - { - url: 'https://oldRpcUrlPrivate/api', - type: ProviderType.PRIVATE, - } as IProvider, - ], - periodOffset: PERIOD_OFFSET, - } - - const newProviders: Array = [ - { - url: publicApi, - type: ProviderType.PUBLIC, - } as IProvider, - { - url: privateApi, - type: ProviderType.PRIVATE, - } as IProvider, - ] - - const baseClient = new TestBaseClient(clientConfig) - const oldPrivateProviders = baseClient.getPrivateProviders() - const oldPublicProviders = baseClient.getPublicProviders() - - baseClient.setProviders(newProviders) - - const privateProviders = baseClient.getPrivateProviders() - const publicProviders = baseClient.getPublicProviders() - - expect(oldPrivateProviders).toHaveLength(1) - expect(oldPrivateProviders[0].url).toBe('https://oldRpcUrlPrivate/api') - expect(oldPrivateProviders[0].type).toBe(ProviderType.PRIVATE) - - expect(oldPublicProviders).toHaveLength(1) - expect(oldPublicProviders[0].url).toBe('https://oldRpcUrlPublic/api') - expect(oldPublicProviders[0].type).toBe(ProviderType.PUBLIC) - - expect(privateProviders).toHaveLength(1) - expect(privateProviders[0].url).toBe(privateApi) - expect(privateProviders[0].type).toBe(ProviderType.PRIVATE) - - expect(publicProviders).toHaveLength(1) - expect(publicProviders[0].url).toBe(publicApi) - expect(publicProviders[0].type).toBe(ProviderType.PUBLIC) - }) - - test('setProviders should throw an error when passed an empty array', () => { - const clientConfig: IClientConfig = { - providers: [ - { url: publicApi, type: ProviderType.PUBLIC } as IProvider, - { - url: privateApi, - type: ProviderType.PRIVATE, - } as IProvider, - ], - periodOffset: PERIOD_OFFSET, - } - - const baseClient = new BaseClient(clientConfig) - - expect(() => - baseClient.setProviders([ - { - url: privateApi, - type: ProviderType.PRIVATE, - } as IProvider, - ]) - ).toThrow( - 'Cannot set providers with no public providers. Need at least one' - ) - }) - - test('setProviders should correctly set multiple providers of the same type', () => { - const clientConfig: IClientConfig = { - providers: [ - { url: publicApi, type: ProviderType.PUBLIC } as IProvider, - { - url: privateApi, - type: ProviderType.PRIVATE, - } as IProvider, - ], - periodOffset: PERIOD_OFFSET, - } - - const newProviders: Array = [ - { - url: 'https://new-public-api-1.com', - type: ProviderType.PUBLIC, - } as IProvider, - { - url: 'https://new-public-api-2.com', - type: ProviderType.PUBLIC, - } as IProvider, - { - url: 'https://new-private-api-1.com', - type: ProviderType.PRIVATE, - } as IProvider, - { - url: 'https://new-private-api-2.com', - type: ProviderType.PRIVATE, - } as IProvider, - ] - - const baseClient = new TestBaseClient(clientConfig) - baseClient.setProviders(newProviders) - - const privateProviders = baseClient.getPrivateProviders() - const publicProviders = baseClient.getPublicProviders() - - expect(privateProviders).toHaveLength(2) - expect(privateProviders[0].url).toBe('https://new-private-api-1.com') - expect(privateProviders[1].url).toBe('https://new-private-api-2.com') - - expect(publicProviders).toHaveLength(2) - expect(publicProviders[0].url).toBe('https://new-public-api-1.com') - expect(publicProviders[1].url).toBe('https://new-public-api-2.com') - }) - }) - - describe('getPrivateProviders', () => { - test('getPrivateProviders should return an array of private providers', () => { - const clientConfig: IClientConfig = { - providers: [ - { url: publicApi, type: ProviderType.PUBLIC } as IProvider, - { - url: privateApi, - type: ProviderType.PRIVATE, - } as IProvider, - ], - periodOffset: PERIOD_OFFSET, - } - - const baseClient = new TestBaseClient(clientConfig) - const privateProviders = baseClient.getPrivateProviders() - - expect(privateProviders).toHaveLength(1) - expect(privateProviders[0].url).toBe(privateApi) - expect(privateProviders[0].type).toBe(ProviderType.PRIVATE) - }) - }) - - describe('getPublicProviders', () => { - test('getPublicProviders should return an array of public providers', () => { - const clientConfig: IClientConfig = { - providers: [ - { url: publicApi, type: ProviderType.PUBLIC } as IProvider, - { - url: privateApi, - type: ProviderType.PRIVATE, - } as IProvider, - ], - periodOffset: PERIOD_OFFSET, - } - - const baseClient = new TestBaseClient(clientConfig) - const publicProviders = baseClient.getPublicProviders() - - expect(publicProviders).toHaveLength(1) - expect(publicProviders[0].url).toBe(publicApi) - expect(publicProviders[0].type).toBe(ProviderType.PUBLIC) - }) - }) - - describe('sendJsonRPCRequest', () => { - let baseClient: TestBaseClient - const mockAxios = axios as jest.Mocked - - beforeEach(() => { - const clientConfig: IClientConfig = { - providers: [ - { url: publicApi, type: ProviderType.PUBLIC } as IProvider, - { - url: privateApi, - type: ProviderType.PRIVATE, - } as IProvider, - ], - periodOffset: PERIOD_OFFSET, - } - - baseClient = new TestBaseClient(clientConfig) - jest.resetAllMocks() - }) - - test('should use public provider for public RPC methods', async () => { - const mockResponse = { - ok: true, - status: 200, - json: () => - Promise.resolve({ - result: { - error: null, - isError: false, - result: 'some data returned from the API', - }, - error: null, - isError: false, - }), - } - - const mockFetch = jest - .spyOn(global, 'fetch') - .mockImplementation( - jest.fn(() => Promise.resolve(mockResponse)) as jest.Mock - ) - - const result = await baseClient.getSendJsonRPCRequest( - JSON_RPC_REQUEST_METHOD.GET_STATUS, // public method - {} - ) - - expect(mockFetch).toHaveBeenCalledTimes(1) - expect(mockFetch).toHaveBeenCalledWith( - publicApi, // <-- We check here that the public API is used - { - body: JSON.stringify({ - jsonrpc: '2.0', - method: JSON_RPC_REQUEST_METHOD.GET_STATUS, - params: {}, - id: 0, - }), - method: 'POST', - headers: fetchRequestHeaders, - } - ) - - expect(result).toEqual((await mockResponse.json()).result) - }) - - test('should use private provider for private RPC methods', async () => { - const mockResponse = { - json: () => - Promise.resolve({ - result: { - error: null, - isError: false, - result: 'some data returned from the API', - }, - error: null, - isError: false, - }), - } - - const mockFetch = jest - .spyOn(global, 'fetch') - .mockImplementation( - jest.fn(() => Promise.resolve(mockResponse)) as jest.Mock - ) - - const result = await baseClient.getSendJsonRPCRequest( - JSON_RPC_REQUEST_METHOD.STOP_NODE, // private method - {} - ) - - expect(mockFetch).toHaveBeenCalledTimes(1) - expect(mockFetch).toHaveBeenCalledWith( - privateApi, // <-- We check here that the private API is used - { - body: JSON.stringify({ - jsonrpc: '2.0', - method: JSON_RPC_REQUEST_METHOD.STOP_NODE, - params: {}, - id: 0, - }), - headers: fetchRequestHeaders, - method: 'POST', - } - ) - - expect(result).toEqual((await mockResponse.json()).result) - }) - - test('should throw an error for unknown RPC methods', async () => { - const mockResponse = { - data: { - result: { - error: null, - isError: false, - result: 'some data returned from the API', - }, - error: null, - isError: false, - }, - } - - mockAxios.post.mockResolvedValueOnce(mockResponse) - - const unknownMethod = 'unknownMethod' as JSON_RPC_REQUEST_METHOD - - await expect( - baseClient.getSendJsonRPCRequest(unknownMethod, {}) - ).rejects.toThrowError(`Unknown Json rpc method: ${unknownMethod}`) - }) - - test('should throw an error if no public providers are configured', async () => { - const clientConfig: IClientConfig = { - providers: [ - { - url: privateApi, - type: ProviderType.PRIVATE, - } as IProvider, - ], - periodOffset: PERIOD_OFFSET, - } - - const createClient = () => { - baseClient = new TestBaseClient(clientConfig) - } - - expect(createClient).toThrowError( - 'Cannot initialize web3 with no public providers. Need at least one' - ) - }) - - test('should handle JSON-RPC error responses', async () => { - const mockResponse = { - ok: true, - status: 200, - json: () => - Promise.resolve({ - result: null, - error: { - code: -32600, - message: 'Invalid Request', - }, - id: null, - jsonrpc: '2.0', - }), - } - - jest - .spyOn(global, 'fetch') - .mockImplementation( - jest.fn(() => Promise.resolve(mockResponse)) as jest.Mock - ) - - await expect( - baseClient.getSendJsonRPCRequest(JSON_RPC_REQUEST_METHOD.GET_STATUS, {}) - ).rejects.toThrowError('Invalid Request') - }) - }) -}) diff --git a/packages/massa-web3/test/web3/clientFactory.spec.ts b/packages/massa-web3/test/web3/clientFactory.spec.ts deleted file mode 100644 index 93972eae..00000000 --- a/packages/massa-web3/test/web3/clientFactory.spec.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { ClientFactory } from '../../src/web3/ClientFactory' -import { WalletClient } from '../../src/web3/WalletClient' -import { ProviderType } from '../../src/interfaces/IProvider' -import { Client } from '../../src/web3/Client' -import { IAccount } from '../../src/interfaces/IAccount' -import { BUILDNET_CHAIN_ID } from './mockData' -import { DefaultProviderUrls } from '@massalabs/web3-utils' - -const publicApi = 'https://mock-public-api.com' -const privateApi = 'https://mock-private-api.com' -const chainId = BUILDNET_CHAIN_ID - -describe('ClientFactory', () => { - describe('createDefaultClient', () => { - test('should create a default client with the specified provider', async () => { - const provider = DefaultProviderUrls.TESTNET - const baseAccount: IAccount = - await WalletClient.walletGenerateNewAccount() - - const client = await ClientFactory.createDefaultClient( - provider, - chainId, - true, - baseAccount - ) - - expect(client).toBeInstanceOf(Client) - expect(client.getProviders()).toHaveLength(2) - - const publicProvider = client.getPublicProviders()[0] - const privateProvider = client.getPrivateProviders()[0] - - expect(publicProvider?.url).toBe(provider) - expect(privateProvider?.url).toBe(provider) - }) - - test('should create a default client without a base account if not provided', async () => { - const provider = DefaultProviderUrls.MAINNET - - const client = await ClientFactory.createDefaultClient( - provider, - chainId, - true - ) - - expect(client).toBeInstanceOf(Client) - expect(client.getProviders()).toHaveLength(2) - expect(client.wallet().getBaseAccount()).toBeUndefined() - }) - }) - - describe('createCustomClient', () => { - test('should create a custom client with the specified providers', async () => { - const providers = [ - { url: publicApi, type: ProviderType.PUBLIC }, - { url: privateApi, type: ProviderType.PRIVATE }, - ] - const baseAccount: IAccount = - await WalletClient.walletGenerateNewAccount() - - const client = await ClientFactory.createCustomClient( - providers, - chainId, - true, - baseAccount - ) - - expect(client).toBeInstanceOf(Client) - expect(client.getProviders()).toHaveLength(2) - expect(client.getProviders()).toEqual(providers) - }) - - test('should create a custom client without a base account if not provided', async () => { - const providers = [ - { url: publicApi, type: ProviderType.PUBLIC }, - { url: privateApi, type: ProviderType.PRIVATE }, - ] - - const client = await ClientFactory.createCustomClient( - providers, - chainId, - true - ) - - expect(client).toBeInstanceOf(Client) - expect(client.getProviders()).toHaveLength(2) - expect(client.getProviders()).toEqual(providers) - expect(client.wallet().getBaseAccount()).toBeUndefined() - }) - }) -}) diff --git a/packages/massa-web3/test/web3/evenPoller.spec.ts b/packages/massa-web3/test/web3/evenPoller.spec.ts deleted file mode 100644 index a8df96a2..00000000 --- a/packages/massa-web3/test/web3/evenPoller.spec.ts +++ /dev/null @@ -1,243 +0,0 @@ -import { - EventPoller, - ON_MASSA_EVENT_DATA, - ON_MASSA_EVENT_ERROR, -} from '../../src/web3/EventPoller' -import { IEventFilter } from '../../src/interfaces/IEventFilter' -import { IEventRegexFilter } from '../../src/interfaces/IEventRegexFilter' -import { Client } from '../../src/web3/Client' -import { WalletClient } from '../../src/web3/WalletClient' -import { ClientFactory } from '../../src/web3/ClientFactory' -import { IAccount } from '../../src/interfaces/IAccount' -import { Timeout } from '../../src/utils/time' -import { IEvent, ISlot, DefaultProviderUrls } from '@massalabs/web3-utils' -import { BUILDNET_CHAIN_ID } from './mockData' - -// mock axios to intercept any axios POST request and resolve it immediately with an empty object, so -// no request is pending before Jest finishes the test -jest.mock('axios', () => ({ - post: jest.fn(() => Promise.resolve({ data: {} })), -})) - -jest.mock('../../src/utils/time', () => { - function Timeout(timeoutMil, callback) { - this.isCleared = false - this.isCalled = false - this.timeoutHook = setTimeout(() => { - if (!this.isCleared) { - this.isCalled = true - callback() - } - }, timeoutMil) - this.clear = function () { - if (!this.isCleared) { - clearTimeout(this.timeoutHook) - this.isCleared = true - } - } - } - return { - Timeout: jest.fn(Timeout), - } -}) - -// util function to create an event, only for that test file to avoid code duplication -function createEvent( - id: string, - data: string, - slot: ISlot, - callStack: string[] -): IEvent { - return { - id, - data: JSON.stringify(data), - context: { - slot, - block: null, - read_only: false, - call_stack: callStack, - index_in_slot: 0, - origin_operation_id: null, - is_final: true, - is_error: false, - }, - } -} - -describe('EventPoller', () => { - let eventPoller: EventPoller - let baseAccount: IAccount - let web3Client: Client - - const pollIntervalMillis = 1000 - const eventFilter: IEventFilter | IEventRegexFilter = { - start: { period: 2, thread: 1 }, - end: { period: 3, thread: 2 }, - emitter_address: 'address4', - original_caller_address: null, - original_operation_id: null, - is_final: null, - } - - beforeAll(async () => { - baseAccount = await WalletClient.walletGenerateNewAccount() - const provider = DefaultProviderUrls.TESTNET - web3Client = await ClientFactory.createDefaultClient( - provider, - BUILDNET_CHAIN_ID, - true, - baseAccount - ) - }) - - beforeEach(async () => { - eventPoller = new EventPoller(eventFilter, pollIntervalMillis, web3Client) - }) - - afterEach(() => { - eventPoller.stopPolling() - jest.clearAllMocks() - }) - - describe('compareByThreadAndPeriod', () => { - test('callback should sort events by thread and period correctly', async () => { - const mockedEvents: IEvent[] = [ - createEvent('event1', 'value1', { period: 1, thread: 1 }, ['address1']), // nยฐ1 - createEvent('event2', 'value2', { period: 2, thread: 1 }, ['address2']), // nยฐ3 - createEvent('event3', 'value3', { period: 1, thread: 2 }, ['address3']), // nยฐ2 - createEvent('event5', 'value5', { period: 2, thread: 2 }, ['address4']), // nยฐ4 - createEvent('event4', 'value4', { period: 1, thread: 2 }, ['address4']), // nยฐ2 - createEvent('event6', 'value6', { period: 3, thread: 2 }, ['address4']), // nยฐ5 - ] - jest - .spyOn(web3Client.smartContracts(), 'getFilteredScOutputEvents') - .mockResolvedValue(mockedEvents) - - jest.spyOn(eventPoller, 'emit') - - await eventPoller['callback']() - - // The ON_MASSA_EVENT_DATA event should have been emitted with the events sorted by period and thread - expect(eventPoller.emit).toHaveBeenCalledWith(ON_MASSA_EVENT_DATA, [ - mockedEvents[0], - mockedEvents[2], - mockedEvents[4], - mockedEvents[1], - mockedEvents[3], - mockedEvents[5], - ]) - }) - }) - - describe('startPolling', () => { - test('should create a new Timeout instance and call callback function after delay', () => { - jest.useFakeTimers() - jest.spyOn(web3Client.smartContracts(), 'getFilteredScOutputEvents') - - eventPoller.startPolling() - - expect((Timeout as jest.Mock).mock.calls.length).toBe(1) - expect((Timeout as jest.Mock).mock.calls[0][0]).toBe(pollIntervalMillis) - - // Fast-forward the timer and assert callback is called - jest.runOnlyPendingTimers() - expect( - web3Client.smartContracts().getFilteredScOutputEvents - ).toHaveBeenCalledTimes(1) - - jest.useRealTimers() - eventPoller.stopPolling() - }) - }) - - describe('startEventsPolling', () => { - const onData = jest.fn() - const onError = jest.fn() - - beforeEach(() => { - jest.restoreAllMocks() - }) - - test('should start events polling and set onData and onError when both are provided', () => { - const eventPoller = EventPoller.startEventsPolling( - eventFilter, - pollIntervalMillis, - web3Client, - onData, - onError - ) - - expect(eventPoller).toBeInstanceOf(EventPoller) - expect(eventPoller.listenerCount(ON_MASSA_EVENT_DATA)).toBe(1) - expect(eventPoller.listenerCount(ON_MASSA_EVENT_ERROR)).toBe(1) - eventPoller.stopPolling() - }) - - test('should start events polling and set onData only when onError is not provided', () => { - const eventPoller = EventPoller.startEventsPolling( - eventFilter, - pollIntervalMillis, - web3Client, - onData - ) - - expect(eventPoller).toBeInstanceOf(EventPoller) - expect(eventPoller.listenerCount(ON_MASSA_EVENT_DATA)).toBe(1) - expect(eventPoller.listenerCount(ON_MASSA_EVENT_ERROR)).toBe(0) - eventPoller.stopPolling() - }) - - test('should start events polling and set onError only when onData is not provided', () => { - const eventPoller = EventPoller.startEventsPolling( - eventFilter, - pollIntervalMillis, - web3Client, - undefined, - onError - ) - - expect(eventPoller).toBeInstanceOf(EventPoller) - expect(eventPoller.listenerCount(ON_MASSA_EVENT_DATA)).toBe(0) - expect(eventPoller.listenerCount(ON_MASSA_EVENT_ERROR)).toBe(1) - eventPoller.stopPolling() - }) - }) - - describe('getEventsOnce', () => { - let spygetFilteredEvents - - beforeEach(() => { - spygetFilteredEvents = jest.spyOn( - web3Client.smartContracts(), - 'getFilteredScOutputEvents' - ) - }) - - test('should return events when they match the filter', async () => { - const expectedEvents: Array = [ - createEvent('1', 'data1', { period: 2, thread: 1 }, ['address1']), - createEvent('2', 'data2', { period: 2, thread: 2 }, ['address2']), - createEvent('3', 'data3', { period: 3, thread: 2 }, ['address3']), - ] - - spygetFilteredEvents.mockResolvedValue(expectedEvents) - const events = await EventPoller.getEventsOnce(eventFilter, web3Client) - - expect( - web3Client.smartContracts().getFilteredScOutputEvents - ).toHaveBeenCalledWith(eventFilter) - expect(events).toEqual(expectedEvents) - }) - - test('should return empty array when no events match the filter', async () => { - spygetFilteredEvents.mockResolvedValue([]) - - const events = await EventPoller.getEventsOnce(eventFilter, web3Client) - - expect( - web3Client.smartContracts().getFilteredScOutputEvents - ).toHaveBeenCalledTimes(1) - expect(events).toEqual([]) - }) - }) -}) diff --git a/packages/massa-web3/test/web3/eventPoller.spec.ts b/packages/massa-web3/test/web3/eventPoller.spec.ts deleted file mode 100644 index cbff1042..00000000 --- a/packages/massa-web3/test/web3/eventPoller.spec.ts +++ /dev/null @@ -1,200 +0,0 @@ -import { - EventPoller, - ON_MASSA_EVENT_DATA, - ON_MASSA_EVENT_ERROR, -} from '../../src/web3/EventPoller' -import { IEventFilter } from '../../src/interfaces/IEventFilter' -import { IEventRegexFilter } from '../../src/interfaces/IEventRegexFilter' -import { Client } from '../../src/web3/Client' -import { WalletClient } from '../../src/web3/WalletClient' -import { ClientFactory } from '../../src/web3/ClientFactory' -import { IAccount } from '../../src/interfaces/IAccount' -import { Timeout } from '../../src/utils/time' -import { IEvent, ISlot, DefaultProviderUrls } from '@massalabs/web3-utils' -import { BUILDNET_CHAIN_ID } from './mockData' - -// Mock the Timeout class -jest.mock('../../src/utils/time', () => { - function Timeout(timeoutMil, callback) { - this.isCleared = false - this.isCalled = false - this.timeoutHook = setTimeout(() => { - if (!this.isCleared) { - this.isCalled = true - callback() - } - }, timeoutMil) - this.clear = function () { - if (!this.isCleared) { - clearTimeout(this.timeoutHook) - this.isCleared = true - } - } - } - - return { - Timeout: jest.fn(Timeout), - } -}) - -const mockedEvents: IEvent[] = [ - { - id: 'event1', - data: '{"key1": "value1"}', - context: { - slot: { - period: 1, - thread: 1, - }, - block: null, - read_only: false, - call_stack: ['address1'], - index_in_slot: 0, - origin_operation_id: null, - is_final: true, - is_error: false, - }, - }, - { - id: 'event2', - data: '{"key2": "value2"}', - context: { - slot: { - period: 2, - thread: 2, - }, - block: null, - read_only: false, - call_stack: ['address2'], - index_in_slot: 0, - origin_operation_id: null, - is_final: true, - is_error: false, - }, - }, - { - id: 'event3', - data: '{"key3": "value3"}', - context: { - slot: { - period: 3, - thread: 3, - }, - block: null, - read_only: false, - call_stack: ['address3'], - index_in_slot: 0, - origin_operation_id: null, - is_final: true, - is_error: false, - }, - }, -] - -describe('EventPoller', () => { - let eventPoller: EventPoller - let baseAccount: IAccount - let web3Client: Client - - const pollIntervalMillis = 1000 - const eventFilter: IEventFilter | IEventRegexFilter = { - start: null, - end: null, - emitter_address: null, - original_caller_address: null, - original_operation_id: null, - is_final: null, - } - - beforeAll(async () => { - baseAccount = await WalletClient.walletGenerateNewAccount() - const provider = DefaultProviderUrls.TESTNET - web3Client = await ClientFactory.createDefaultClient( - provider, - BUILDNET_CHAIN_ID, - true, - baseAccount - ) - }) - - beforeEach(async () => { - eventPoller = new EventPoller(eventFilter, pollIntervalMillis, web3Client) - }) - - afterEach(() => { - eventPoller.stopPolling() - jest.clearAllMocks() - }) - - test('should poll for events, filter them, sort them, and emit ON_MASSA_EVENT_DATA event', async () => { - // Mock the getFilteredScOutputEvents method to return the mocked events - jest - .spyOn(web3Client.smartContracts(), 'getFilteredScOutputEvents') - .mockResolvedValue(mockedEvents) - jest.spyOn(eventPoller, 'emit') - - // Set lastSlot to simulate an existing value - eventPoller['lastSlot'] = { period: 1, thread: 1 } as ISlot - - await eventPoller['callback']() - - // Verify the correct methods were called with the correct arguments - expect( - web3Client.smartContracts().getFilteredScOutputEvents - ).toHaveBeenCalledWith(eventFilter) - expect(eventPoller.emit).toHaveBeenCalledWith( - ON_MASSA_EVENT_DATA, - mockedEvents.slice(1) // The events with a slot after { period: 1, thread: 1 } - ) - expect(eventPoller['lastSlot']).toEqual( - mockedEvents[mockedEvents.length - 1].context.slot - ) - }) - - test('should emit ON_MASSA_EVENT_ERROR event if an error occurs', async () => { - const errorMessage = 'An error occurred' - // Mock the getFilteredScOutputEvents method to throw an error - jest - .spyOn(web3Client.smartContracts(), 'getFilteredScOutputEvents') - .mockRejectedValue(new Error(errorMessage)) - jest.spyOn(eventPoller, 'emit') - - await eventPoller['callback']() - // Verify the error event was emitted - expect(eventPoller.emit).toHaveBeenCalledWith( - ON_MASSA_EVENT_ERROR, - new Error(errorMessage) - ) - }) - - test('should reset the interval and call callback again after the specified poll interval', async () => { - const consoleSpy = jest.spyOn(console, 'error') - consoleSpy.mockImplementation(() => null) - - // Set lastSlot to simulate an existing value - eventPoller['lastSlot'] = { period: 1, thread: 1 } as ISlot - - // Replacing setTimeout with jest's fake timers - jest.useFakeTimers() - await eventPoller['callback']() - - // Assert that setTimeout was called once and with the correct arguments - expect(Timeout).toHaveBeenCalledTimes(1) - expect(Timeout).toHaveBeenCalledWith( - pollIntervalMillis, - expect.any(Function) - ) - - // Fast-forward the timer and assert callback is called again - jest.runOnlyPendingTimers() - - // Assert that getFilteredScOutputEvents was called twice - expect( - web3Client.smartContracts().getFilteredScOutputEvents - ).toHaveBeenCalledTimes(2) - - jest.useRealTimers() - - consoleSpy.mockRestore() - }) -}) diff --git a/packages/massa-web3/test/web3/mockData.ts b/packages/massa-web3/test/web3/mockData.ts deleted file mode 100644 index 2c5fd37f..00000000 --- a/packages/massa-web3/test/web3/mockData.ts +++ /dev/null @@ -1,781 +0,0 @@ -/* - This file contains mock data for testing purposes. -*/ - -import { IClientConfig } from '../../src/interfaces/IClientConfig' -import { ProviderType, IProvider } from '../../src/interfaces/IProvider' -import { PERIOD_OFFSET } from '../../src/web3/BaseClient' -import { IAccount } from '../../src/interfaces/IAccount' -import { IContractData } from '../../src/interfaces/IContractData' -import { ICallData } from '../../src/interfaces/ICallData' -import { IGetGraphInterval } from '../../src/interfaces/IGetGraphInterval' -import { IReadData } from '../../src/interfaces/IReadData' -import { IEventFilter } from '../../src/interfaces/IEventFilter' -import { IEventRegexFilter } from '../../src/interfaces/IEventRegexFilter' -import { IExecuteReadOnlyResponse } from '../../src/interfaces/IExecuteReadOnlyResponse' -import { ISignature } from '../../src/interfaces/ISignature' -import { IOperationData } from '../../src/interfaces/IOperationData' -import { INodeStatus } from '../../src/interfaces/INodeStatus' -import { IEndorsement } from '../../src/interfaces/IEndorsement' -import { - ISlot, - IEvent, - IContractReadOperationData, - IContractReadOperationResponse, -} from '@massalabs/web3-utils' -import { IBalance } from '../../src/interfaces/IBalance' - -export const BUILDNET_CHAIN_ID = BigInt(77658366) - -// util function to create an event, only for that test file to avoid code duplication -function createEvent( - id: string, - data: string, - slot: ISlot, - callStack: string[] -): IEvent { - return { - id, - data: JSON.stringify(data), - context: { - slot, - block: null, - read_only: false, - call_stack: callStack, - index_in_slot: 0, - origin_operation_id: null, - is_final: true, - is_error: false, - }, - } -} - -export const mockNodeStatusInfo: INodeStatus = { - node_id: 'N129tbNd4oVMRsnFvQcgSq4PUAZYYDA1pvqtef2ER6W7JqgY1Bfg', - node_ip: null, - version: 'SAND.23.0', - current_time: 1687275917301, - current_cycle: 6, - connected_nodes: {}, - last_slot: { period: 830, thread: 1 }, - next_slot: { period: 830, thread: 2 }, - consensus_stats: { - start_timestamp: 1687275857301, - end_timestamp: 1687275917301, - final_block_count: 120, - final_operation_count: 1296, - staker_count: 1, - stale_block_count: 0, - clique_count: 1, - }, - pool_stats: { endorsement_count: 0, operation_count: 1296 }, - network_stats: { - in_connection_count: 0, - out_connection_count: 0, - known_peer_count: 0, - banned_peer_count: 0, - active_node_count: 0, - }, - config: { - genesis_timestamp: 1687262636363, - end_timestamp: null, - thread_count: 32, - t0: 16000, - delta_f0: 1088, - operation_validity_periods: 10, - periods_per_cycle: 128, - block_reward: '0.30', - roll_price: '100', - max_block_size: 1000000, - pos_lock_cycles: 64, - pos_lookback_cycles: 64, - }, - chain_id: BUILDNET_CHAIN_ID, -} - -export const mockGraphInterval: IGetGraphInterval = { - start: 1624153200000, - end: 1624156800000, -} - -export const mockBlock = { - header: { - content: { - slot: { period: 830, thread: 1 }, - parents: ['0x000'], - operation_merkle_root: '0x000', - endorsements: [], - }, - signature: '0x000', - creator_public_key: '0x000', - creator_address: '0x000', - id: '0x000', - }, -} - -export const mockAddresses: string[] = [ - 'AU1qx8SWRBX3EaLLWmcviYiQqS7zb4jV4QykHt2TskjTPJbQAHF7', - 'AU1mTRrw6vVY2ehJTpL2PzHewP5iS1kGV2jhh3P9gNtLRxj4Z2fp', - 'AU12WVAJoH2giHAjSxk9R1XK3YhpCw2QxmkCbtXxcr4T3XCUG55nr', -] - -export const mockAddressesInfo = [ - { - address: 'AU1qx8SWRBX3EaLLWmcviYiQqS7zb4jV4QykHt2TskjTPJbQAHF7', - candidate_balance: '0', - final_balance: '0', - thread: 1, - }, - { - address: 'AU1mTRrw6vVY2ehJTpL2PzHewP5iS1kGV2jhh3P9gNtLRxj4Z2fp', - candidate_balance: '1', - final_balance: '1', - thread: 2, - }, - { - address: 'AU12WVAJoH2giHAjSxk9R1XK3YhpCw2QxmkCbtXxcr4T3XCUG55nr', - candidate_balance: '50', - final_balance: '50', - thread: 3, - }, -] - -export const mockBlockIds = ['0x000', '0x001'] - -export const mockBlockData = [ - { - id: mockBlockIds[0], - content: null, - is_final: false, - is_in_blockclique: false, - is_stale: false, - }, - { - id: mockBlockIds[1], - content: null, - is_final: true, - is_in_blockclique: false, - is_stale: false, - }, -] - -export const mockEndorsementIds = ['0x000', '0x001'] - -export const mockEndorsementData: Array = [ - { - id: mockEndorsementIds[0], - in_pool: false, - in_blocks: ['0x000'], - is_final: false, - endorsement: { - content: { - sender_public_key: '0x000', - slot: { period: 830, thread: 1 }, - index: 0, - endorsed_block: '0x000', - }, - signature: '0x000', - }, - }, - { - id: mockEndorsementIds[1], - in_pool: false, - in_blocks: ['0x001'], - is_final: true, - endorsement: { - content: { - sender_public_key: '0x000', - slot: { period: 830, thread: 1 }, - index: 0, - endorsed_block: '0x000', - }, - signature: '0x000', - }, - }, -] - -export const mockOpIds: Array = [ - 'O1z2xVtwFsKP3po3vkPmpEtZiJvwEd4v1hpK7iT8P3rk9zCEs9f', - 'O1s1xVtwFsKP3po3vkPmpELsiJvwEdk0yhpK7iT8P3rk9zCEs9g', - 'O1b4xVtwFsKP3po3vkPmpEjZiJvwEdk6yhpK7iT8P3rk9zCEs9h', - 'O1t2xVtwFsKP3po3vkPmpELZiJvwEd2vy3pK7iT8P3rk9zCEs9i', - 'O1t2xVtwFsKP3po3vkPmpELZiJvwEd2vy3pK7iT8P3rk9zCEs9j', - 'O1t2xVtwFsKP3po3vkPmpELZiJvwEd2vy3pK7iT8P3rk9zCEs9k', - 'O1t2xVtwFsKP3po3vkPmpELZiJvwEd2vy3pK7iT8P3rk9zCEs9l', -] - -export const mockOperationData = [ - { - id: mockOpIds[0], - in_blocks: ['0x000'], - in_pool: false, - is_operation_final: true, - thread: 1, - operation: {}, - }, - { - id: mockOpIds[1], - in_blocks: ['0x001'], - in_pool: false, - is_operation_final: true, - thread: 2, - operation: {}, - }, - { - id: mockOpIds[2], - in_blocks: ['0x002'], - in_pool: false, - is_operation_final: false, - thread: 3, - operation: {}, - }, - { - id: mockOpIds[3], - in_blocks: ['0x003'], - in_pool: false, - is_operation_final: false, - thread: 4, - operation: {}, - }, - { - id: mockOpIds[4], - in_blocks: ['0x004'], - in_pool: true, - is_operation_final: false, - thread: 4, - operation: {}, - }, - { - id: mockOpIds[5], - in_blocks: ['0x005'], - in_pool: false, - is_operation_final: null, - thread: 4, - operation: {}, - }, - { - id: mockOpIds[6], - in_blocks: ['0x006'], - in_pool: false, - is_operation_final: true, - thread: 4, - operation: {}, - }, - { - id: mockOpIds[7], - in_blocks: ['0x007'], - in_pool: false, - is_operation_final: false, - thread: 4, - operation: {}, - }, -] - -export const mockOperationDataDetailed: Array = [ - // EOperationStatus.FINAL_SUCCESS - { - id: mockOperationData[0].id, - in_blocks: ['0x000'], - in_pool: false, - is_operation_final: true, - thread: 1, - operation: { - content: { - expire_period: 0, - fee: '0', - op: { - Transaction: { - amount: '1000', - recipient_address: - 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - }, - }, - sender_public_key: 'public_key', - }, - signature: 'signature', - content_creator_pub_key: 'pub_key', - content_creator_address: - 'AU1fMUjzAR6Big9Woz3P3vTjAywLbb9KwSyC8btfK3KMDj8ffAHu', - id: 'id', - }, - op_exec_status: true, - }, - // EOperationStatus.FINAL_ERROR - { - id: mockOperationData[1].id, - in_blocks: ['0x000'], - in_pool: false, - is_operation_final: true, - thread: 1, - operation: { - content: { - expire_period: 0, - fee: '0', - op: { - Transaction: { - amount: '1000', - recipient_address: - 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - }, - }, - sender_public_key: 'public_key', - }, - signature: 'signature', - content_creator_pub_key: 'pub_key', - content_creator_address: - 'AU1fMUjzAR6Big9Woz3P3vTjAywLbb9KwSyC8btfK3KMDj8ffAHu', - id: 'id', - }, - op_exec_status: false, - }, - // EOperationStatus.SPECULATIVE_SUCCESS - { - id: mockOperationData[2].id, - in_blocks: ['0x000'], - in_pool: false, - is_operation_final: false, - thread: 1, - operation: { - content: { - expire_period: 0, - fee: '0', - op: { - Transaction: { - amount: '1000', - recipient_address: - 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - }, - }, - sender_public_key: 'public_key', - }, - signature: 'signature', - content_creator_pub_key: 'pub_key', - content_creator_address: - 'AU1fMUjzAR6Big9Woz3P3vTjAywLbb9KwSyC8btfK3KMDj8ffAHu', - id: 'id', - }, - op_exec_status: true, - }, - // EOperationStatus.SPECULATIVE_ERROR - { - id: mockOperationData[3].id, - in_blocks: ['0x000'], - in_pool: false, - is_operation_final: false, - thread: 1, - operation: { - content: { - expire_period: 0, - fee: '0', - op: { - Transaction: { - amount: '1000', - recipient_address: - 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - }, - }, - sender_public_key: 'public_key', - }, - signature: 'signature', - content_creator_pub_key: 'pub_key', - content_creator_address: - 'AU1fMUjzAR6Big9Woz3P3vTjAywLbb9KwSyC8btfK3KMDj8ffAHu', - id: 'id', - }, - op_exec_status: false, - }, - // EOperationStatus.AWAITING_INCLUSION - { - id: mockOperationData[4].id, - in_blocks: ['0x000'], - in_pool: true, - is_operation_final: false, - thread: 1, - operation: { - content: { - expire_period: 0, - fee: '0', - op: { - Transaction: { - amount: '1000', - recipient_address: - 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - }, - }, - sender_public_key: 'public_key', - }, - signature: 'signature', - content_creator_pub_key: 'pub_key', - content_creator_address: - 'AU1fMUjzAR6Big9Woz3P3vTjAywLbb9KwSyC8btfK3KMDj8ffAHu', - id: 'id', - }, - op_exec_status: false, - }, - // EOperationStatus.UNEXECUTED_OR_EXPIRED - { - id: mockOperationData[5].id, - in_blocks: ['0x000'], - in_pool: false, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - is_operation_final: null as any, - thread: 1, - operation: { - content: { - expire_period: 0, - fee: '0', - op: { - Transaction: { - amount: '1000', - recipient_address: - 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - }, - }, - sender_public_key: 'public_key', - }, - signature: 'signature', - content_creator_pub_key: 'pub_key', - content_creator_address: - 'AU1fMUjzAR6Big9Woz3P3vTjAywLbb9KwSyC8btfK3KMDj8ffAHu', - id: 'id', - }, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - op_exec_status: null as any, - }, - // EOperationStatus.INCONSISTENT - { - id: mockOperationData[6].id, - in_blocks: [], // empty array - in_pool: false, // not in pool - is_operation_final: true, // for the sake of inconsistency - thread: 1, - operation: { - content: { - expire_period: 0, - fee: '0', - op: { - Transaction: { - amount: '1000', - recipient_address: - 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - }, - }, - sender_public_key: 'public_key', - }, - signature: 'signature', - content_creator_pub_key: 'pub_key', - content_creator_address: - 'AU1fMUjzAR6Big9Woz3P3vTjAywLbb9KwSyC8btfK3KMDj8ffAHu', - id: 'id', - }, - op_exec_status: null, // this is explicitly set to null to avoid matching other conditions - }, - // EOperationStatus.INCLUDED_PENDING - { - id: mockOperationData[7].id, - in_blocks: ['0x000'], - in_pool: false, - is_operation_final: false, - thread: 1, - operation: { - content: { - expire_period: 0, - fee: '0', - op: { - Transaction: { - amount: '1000', - recipient_address: - 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - }, - }, - sender_public_key: 'public_key', - }, - signature: 'signature', - content_creator_pub_key: 'pub_key', - content_creator_address: - 'AU1fMUjzAR6Big9Woz3P3vTjAywLbb9KwSyC8btfK3KMDj8ffAHu', - id: 'id', - }, - op_exec_status: true, - }, -] - -export const mockStackersData = [ - { - AU1qx8SWRBX3EaLLWmcviYiQqS7zb4jV4QykHt2TskjTPJbQAHF7: 1, - AU1mTRrw6vVY2ehJTpL2PzHewP5iS1kGV2jhh3P9gNtLRxj4Z2fp: 2, - AU12WVAJoH2giHAjSxk9R1XK3YhpCw2QxmkCbtXxcr4T3XCUG55nr: 3, - }, -] - -export const mockDatastoreEntryInput = [ - { - address: 'AU1qx8SWRBX3EaLLWmcviYiQqS7zb4jV4QykHt2TskjTPJbQAHF7', - key: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]), - }, - { - address: 'AU1mTRrw6vVY2ehJTpL2PzHewP5iS1kGV2jhh3P9gNtLRxj4Z2fp', - key: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1]), - }, -] - -export const mockDatastoreEntries = [ - { - final_value: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]), - candidate_value: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]), - }, - { - final_value: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1]), - candidate_value: new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1]), - }, -] - -export const mockClientConfig: IClientConfig = { - providers: [ - { - url: 'https://mock-public-api.com', - type: ProviderType.PUBLIC, - } as IProvider, - { - url: 'https://mock-private-api.com', - type: ProviderType.PRIVATE, - } as IProvider, - ], - periodOffset: PERIOD_OFFSET, -} - -export const mockDeployerAccount: IAccount = { - address: 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - publicKey: 'P129tbNd4oVMRsnFvQcgSq4PUAZYYDA1pvqtef2ER6W7JqgY1Bfg', - secretKey: 'S12XuWmm5jULpJGXBnkeBsuiNmsGi2F4rMiTvriCzENxBR4Ev7vd', -} - -export const mockBalance: IBalance = { - final: 50n, - candidate: 50n, -} - -export const mockContractData: IContractData = { - fee: 1n, - maxGas: 10n, - maxCoins: 0n, - address: 'AU1fMUjzAR6Big9Woz3P3vTjAywLbb9KwSyC8btfK3KMDj8ffAHu', - contractDataText: 'Hello World!', - contractDataBinary: new Uint8Array([0x00, 0x01, 0x02, 0x03]), - datastore: new Map([ - [ - new Uint8Array([0x00, 0x01, 0x02, 0x03]), - new Uint8Array([0x00, 0x01, 0x02, 0x03]), - ], - [ - new Uint8Array([0x04, 0x05, 0x06, 0x07]), - new Uint8Array([0x04, 0x05, 0x06, 0x07]), - ], - [ - new Uint8Array([0x08, 0x09, 0x0a, 0x0b]), - new Uint8Array([0x08, 0x09, 0x0a, 0x0b]), - ], - [ - new Uint8Array([0x0c, 0x0d, 0x0e, 0x0f]), - new Uint8Array([0x0c, 0x0d, 0x0e, 0x0f]), - ], - ]), -} - -export const mockCallData: ICallData = { - fee: 1n, - maxGas: 10n, - coins: 1n, - targetAddress: 'AS12sRd6E6zKdBx3PGeZpCUUM8sE5oSA5mTa3VV4AoDCoqpoxwkmu', - targetFunction: 'test', - parameter: [1, 2, 3, 4], -} - -export const mockedEvents: IEvent[] = [ - createEvent('event1', 'value1', { period: 1, thread: 1 }, ['address1']), // nยฐ1 - createEvent('event2', 'value2', { period: 2, thread: 1 }, ['address2']), // nยฐ3 - createEvent('event3', 'value3', { period: 1, thread: 2 }, ['address3']), // nยฐ2 - createEvent('event5', 'value5', { period: 2, thread: 2 }, ['address4']), // nยฐ4 - createEvent('event4', 'value4', { period: 1, thread: 2 }, ['address4']), // nยฐ2 - createEvent('event6', 'value6', { period: 3, thread: 2 }, ['address4']), // nยฐ5 -] - -export const mockEventFilter: IEventFilter | IEventRegexFilter = { - start: { period: 2, thread: 1 }, - end: { period: 3, thread: 2 }, - emitter_address: 'address4', - original_caller_address: null, - original_operation_id: null, - is_final: null, -} -export const mockReadData: IReadData = { - maxGas: 10n, - targetAddress: 'AS12sRd6E6zKdBx3PGeZpCUUM8sE5oSA5mTa3VV4AoDCoqpoxwkmu', - targetFunction: 'test', - parameter: [1, 2, 3, 4], - callerAddress: 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - coins: 1n, - fee: 1n, -} - -export const mockContractReadOperationData: Array = - [ - { - executed_at: { - period: 1, - thread: 0, - }, - result: { - Ok: new Uint8Array([0x00, 0x01, 0x02, 0x03]), - }, - output_events: [ - { - id: 'O1z2xVtwFsKP3po3vkPmpELZiJvwEdkvyhpK7iT8P3rk9zCEs9f', - data: 'Hello World!', - context: { - slot: { - period: 1, - thread: 0, - }, - block: null, - read_only: true, - call_stack: [], - index_in_slot: 0, - origin_operation_id: null, - is_final: true, - is_error: false, - }, - }, - ], - gas_cost: 12345678, - }, - ] - -export const mockContractReadOperationResponse: IContractReadOperationResponse = - { - returnValue: new Uint8Array([0x00, 0x01, 0x02, 0x03]), - info: mockContractReadOperationData[0], - } - -export const mockContractReadOnlyOperationResponse: IExecuteReadOnlyResponse = { - returnValue: new Uint8Array([0x00, 0x01, 0x02, 0x03]), - info: mockContractReadOperationData[0], -} - -export const validSignature: ISignature = { - publicKey: 'P129tbNd4oVMRsnFvQcgSq4PUAZYYDA1pvqtef2ER6W7JqgY1Bfg', - base58Encoded: - '1TXucC8nai7BYpAnMPYrotVcKCZ5oxkfWHb2ykKj2tXmaGMDL1XTU5AbC6Z13RH3q59F8QtbzKq4gzBphGPWpiDonownxE', -} - -export const mockContractReadOperationDataWithError = [ - { - result: { - Error: 'Some error message. Inspect smart contract for more details', - }, - }, -] - -export const mockSecretKeyOject = { - base58Encoded: 'S1eK3SEXGDAWN6pZhdr4Q7WJv6UHss55EB14hPy4XqBpiktfPu6', - bytes: Buffer.from( - '54b8270c454be4dd5adb9f75eea6492c0d9a61d23d839c9924100622110f5a2f', - 'hex' - ), - version: 0, -} - -export const mockAddressVersion = [ - { - base58Encoded: 'AU12Set6aygzt1k7ZkDwrkStYovVBzeGs8VgaZogy11s7fQzaytv3', - version: 0, - }, - { - base58Encoded: 'AU4RyMrF2r7b85PJWgFtyk4WS2GNh6Mh9ecAnow8fGMi6PVi6i2x', - version: 1, - }, - { - base58Encoded: 'AUdyXW15XYA6LSfyJiBMVG89twMSEUVymMF7aXasr5YYrczaaEXo', - version: 19, - }, - { - base58Encoded: 'AUQXH9ootnQAUgdWHi7eK4DoJukbx7buKWT1NB8iTpMeRhjGQV6Ven', - version: 287, - }, -] - -export const mockPublicKeyObject = { - base58Encoded: 'P121uDTpo58d3SxQTENXKqSJTpB21ueSAy8RqQ2virGVeWs339ub', - bytes: Uint8Array.from([ - 133, 189, 128, 53, 164, 216, 224, 156, 184, 1, 149, 251, 189, 7, 11, 151, - 51, 176, 124, 204, 229, 184, 245, 144, 208, 126, 241, 70, 210, 29, 122, 105, - ]), - version: 0, -} - -export const mockSignatureResult = { - bytes: Uint8Array.from([ - 226, 197, 65, 223, 9, 206, 158, 120, 130, 222, 17, 217, 123, 27, 195, 26, - 237, 44, 219, 157, 85, 238, 191, 144, 250, 133, 142, 70, 170, 207, 92, 157, - 211, 42, 128, 159, 61, 214, 186, 133, 154, 100, 82, 251, 44, 56, 232, 24, - 203, 7, 121, 84, 78, 50, 205, 62, 146, 193, 4, 221, 73, 223, 226, 0, - ]), -} - -export const mockAddressResult = { - version: 0, - base58Encoded: 'AU12Set6aygzt1k7ZkDwrkStYovVBzeGs8VgaZogy11s7fQzaytv3', -} - -export const mockResultSendJsonRPCRequestWalletInfo = [ - { - address: 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - thread: 6, - final_balance: '500', - final_roll_count: 0, - final_datastore_keys: [], - candidate_balance: '500', - candidate_roll_count: 0, - candidate_datastore_keys: [], - deferred_credits: [], - next_block_draws: [], - next_endorsement_draws: [], - created_blocks: [], - created_operations: [], - created_endorsements: [], - cycle_infos: [ - [Object], - [Object], - [Object], - [Object], - [Object], - [Object], - [Object], - ], - }, - { - address: 'AU12eqpwwPeVxt2riAZZv2QMyFJ7qnZwBmATFRU3JKjkXvtupLHDS', - thread: 27, - final_balance: '0', - final_roll_count: 0, - final_datastore_keys: [], - candidate_balance: '0', - candidate_roll_count: 0, - candidate_datastore_keys: [], - deferred_credits: [], - next_block_draws: [], - next_endorsement_draws: [], - created_blocks: [], - created_operations: [], - created_endorsements: [], - cycle_infos: [ - [Object], - [Object], - [Object], - [Object], - [Object], - [Object], - [Object], - ], - }, -] diff --git a/packages/massa-web3/test/web3/privateApiClient.spec.ts b/packages/massa-web3/test/web3/privateApiClient.spec.ts deleted file mode 100644 index e9102399..00000000 --- a/packages/massa-web3/test/web3/privateApiClient.spec.ts +++ /dev/null @@ -1,205 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { JSON_RPC_REQUEST_METHOD } from '../../src/interfaces/JsonRpcMethods' -import { IClientConfig } from '../../src/interfaces/IClientConfig' -import { ProviderType, IProvider } from '../../src/interfaces/IProvider' -import { PrivateApiClient } from '../../src' - -export const PERIOD_OFFSET = 5 - -describe('PrivateApiClient', () => { - let client: PrivateApiClient - let mockSendJsonRPCRequest: jest.SpyInstance - let ipAddress = '192.168.0.1' - - const getRpcArgs = (wrapArgsInArray, mockData) => { - const argsInArray = Array.isArray(mockData) ? mockData : [mockData] - const rpcArgs = wrapArgsInArray ? [argsInArray] : argsInArray - return rpcArgs - } - - // Function to generate tests for a set of similar operations to avoid code duplication - function generateAPITests( - operation: string, - mockData: any, - mockResponse: any, - jsonRpcRequestMethod: JSON_RPC_REQUEST_METHOD, - wrapArgsInArray = true - ) { - test(`should call sendJsonRPCRequest with correct arguments`, async () => { - mockSendJsonRPCRequest.mockResolvedValue(Promise.resolve(mockResponse)) - - await (client as any)[operation](mockData) - - const rpcArgs = getRpcArgs(wrapArgsInArray, mockData) - - expect(mockSendJsonRPCRequest).toHaveBeenCalledWith( - jsonRpcRequestMethod, - rpcArgs - ) - }) - - test(`should return the correct result`, async () => { - mockSendJsonRPCRequest.mockResolvedValue(Promise.resolve(mockResponse)) - - const result = await (client as any)[operation](mockData) - - expect(result).toEqual(mockResponse) - }) - - test(`should handle errors correctly`, async () => { - const mockError = new Error('Error message') - mockSendJsonRPCRequest.mockRejectedValue(mockError) - - await expect((client as any)[operation](mockData)).rejects.toThrow( - mockError - ) - }) - - test(`should call trySafeExecute if retryStrategyOn is true`, async () => { - // Enable retry strategy - const originalRetryStrategy = (client as any).clientConfig.retryStrategyOn - ;(client as any).clientConfig.retryStrategyOn = true - - mockSendJsonRPCRequest.mockResolvedValue(Promise.resolve(mockResponse)) - - const result = await (client as any)[operation](mockData) - - const rpcArgs = getRpcArgs(wrapArgsInArray, mockData) - - expect(mockSendJsonRPCRequest).toHaveBeenCalledWith( - jsonRpcRequestMethod, - rpcArgs - ) - - expect(result).toEqual(mockResponse) - - // Restore retry strategy - ;(client as any).clientConfig.retryStrategyOn = originalRetryStrategy - }) - } - - beforeEach(() => { - const clientConfig: IClientConfig = { - providers: [ - { - url: 'https://mock-public-api.com', - type: ProviderType.PUBLIC, - } as IProvider, - { - url: 'https://mock-private-api.com', - type: ProviderType.PRIVATE, - } as IProvider, - ], - periodOffset: PERIOD_OFFSET, - } - client = new PrivateApiClient(clientConfig) - mockSendJsonRPCRequest = jest.spyOn(client as any, 'sendJsonRPCRequest') - }) - - describe('nodeAddToPeersWhitelist', () => { - generateAPITests( - 'nodeAddToPeersWhitelist', - ipAddress, - undefined, - JSON_RPC_REQUEST_METHOD.NODE_ADD_TO_PEERS_WHITELIST - ) - }) - - describe('nodeRemoveFromWhitelist', () => { - generateAPITests( - 'nodeRemoveFromWhitelist', - ipAddress, - undefined, - JSON_RPC_REQUEST_METHOD.NODE_REMOVE_FROM_WHITELIST - ) - }) - - describe('nodeUnbanByIpAddress', () => { - generateAPITests( - 'nodeUnbanByIpAddress', - ipAddress, - undefined, - JSON_RPC_REQUEST_METHOD.NODE_UNBAN_BY_IP - ) - }) - - describe('nodeUnbanById', () => { - generateAPITests( - 'nodeUnbanById', - 'nodeIdExample', - undefined, - JSON_RPC_REQUEST_METHOD.NODE_UNBAN_BY_ID, - true - ) - }) - - describe('nodeBanByIpAddress', () => { - generateAPITests( - 'nodeBanByIpAddress', - '127.0.0.1', - undefined, - JSON_RPC_REQUEST_METHOD.NODE_BAN_BY_IP, - true - ) - }) - - describe('nodeBanById', () => { - generateAPITests( - 'nodeBanById', - 'nodeIdExample', - undefined, - JSON_RPC_REQUEST_METHOD.NODE_BAN_BY_ID, - true - ) - }) - - describe('nodeStop', () => { - generateAPITests( - 'nodeStop', - [], - undefined, - JSON_RPC_REQUEST_METHOD.STOP_NODE, - false - ) - }) - - describe('nodeSignMessage', () => { - generateAPITests( - 'nodeSignMessage', - new Uint8Array([]), - { signature: 'mockSignature' }, - JSON_RPC_REQUEST_METHOD.NODE_SIGN_MESSAGE, - false - ) - }) - - describe('nodeGetStakingAddresses', () => { - generateAPITests( - 'nodeGetStakingAddresses', - [], - ['address1', 'address2'], - JSON_RPC_REQUEST_METHOD.GET_STAKING_ADDRESSES, - false - ) - }) - - describe('nodeRemoveStakingAddresses', () => { - generateAPITests( - 'nodeRemoveStakingAddresses', - ['address1', 'address2'], - undefined, - JSON_RPC_REQUEST_METHOD.REMOVE_STAKING_ADDRESSES, - true - ) - }) - - describe('nodeAddStakingSecretKeys', () => { - generateAPITests( - 'nodeAddStakingSecretKeys', - ['key1', 'key2'], - undefined, - JSON_RPC_REQUEST_METHOD.ADD_STAKING_PRIVATE_KEYS, - true - ) - }) -}) diff --git a/packages/massa-web3/test/web3/publicApiClient.spec.ts b/packages/massa-web3/test/web3/publicApiClient.spec.ts deleted file mode 100644 index 863c170d..00000000 --- a/packages/massa-web3/test/web3/publicApiClient.spec.ts +++ /dev/null @@ -1,265 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { PublicApiClient } from '../../src/web3/PublicApiClient' -import { JSON_RPC_REQUEST_METHOD } from '../../src/interfaces/JsonRpcMethods' -import { IClientConfig } from '../../src/interfaces/IClientConfig' -import { ProviderType, IProvider } from '../../src/interfaces/IProvider' -import { - mockAddresses, - mockAddressesInfo, - mockGraphInterval, - mockNodeStatusInfo, - mockBlockIds, - mockBlockData, - mockEndorsementIds, - mockEndorsementData, - mockOperationData, - mockStackersData, - mockDatastoreEntryInput, - mockDatastoreEntries, - mockOpIds, -} from './mockData' - -export const PERIOD_OFFSET = 5 - -describe('PublicApiClient', () => { - let client: PublicApiClient - let mockSendJsonRPCRequest: jest.SpyInstance - - // Function to generate tests for a set of similar operations to avoid code duplication - function generateAPITests( - operation: string, - mockData: any, - mockResponse: any, - jsonRpcRequestMethod: JSON_RPC_REQUEST_METHOD, - wrapArgsInArray: boolean - ) { - test(`should call sendJsonRPCRequest with correct arguments`, async () => { - mockSendJsonRPCRequest.mockResolvedValue(Promise.resolve(mockResponse)) - - await (client as any)[operation](mockData) - - let rpcArgs - - if (wrapArgsInArray) { - rpcArgs = [Array.isArray(mockData) ? mockData : []] - } else { - rpcArgs = Array.isArray(mockData) ? mockData : [] - } - - expect(mockSendJsonRPCRequest).toHaveBeenCalledWith( - jsonRpcRequestMethod, - rpcArgs - ) - }) - - test(`should return the correct result`, async () => { - mockSendJsonRPCRequest.mockResolvedValue(Promise.resolve(mockResponse)) - - const result = await (client as any)[operation](mockData) - - expect(result).toEqual(mockResponse) - }) - - test(`should handle errors correctly`, async () => { - const mockError = new Error('Error message') - mockSendJsonRPCRequest.mockRejectedValue(mockError) - - await expect((client as any)[operation](mockData)).rejects.toThrow( - mockError - ) - }) - - test(`should call trySafeExecute if retryStrategyOn is true`, async () => { - // Enable retry strategy - const originalRetryStrategy = (client as any).clientConfig.retryStrategyOn - ;(client as any).clientConfig.retryStrategyOn = true - - mockSendJsonRPCRequest.mockResolvedValue(Promise.resolve(mockResponse)) - - const result = await (client as any)[operation](mockData) - - let rpcArgs - if (wrapArgsInArray) { - rpcArgs = [Array.isArray(mockData) ? mockData : []] - } else { - rpcArgs = Array.isArray(mockData) ? mockData : [] - } - - expect(mockSendJsonRPCRequest).toHaveBeenCalledWith( - jsonRpcRequestMethod, - rpcArgs - ) - - expect(result).toEqual(mockResponse) - - // Restore retry strategy - ;(client as any).clientConfig.retryStrategyOn = originalRetryStrategy - }) - } - - beforeEach(() => { - const clientConfig: IClientConfig = { - providers: [ - { - url: 'https://mock-public-api.com', - type: ProviderType.PUBLIC, - } as IProvider, - { - url: 'https://mock-private-api.com', - type: ProviderType.PRIVATE, - } as IProvider, - ], - periodOffset: PERIOD_OFFSET, - } - client = new PublicApiClient(clientConfig) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - mockSendJsonRPCRequest = jest.spyOn(client as any, 'sendJsonRPCRequest') - }) - - describe('getGraphInterval', () => { - generateAPITests( - 'getGraphInterval', - [], - mockGraphInterval, - JSON_RPC_REQUEST_METHOD.GET_GRAPH_INTERVAL, - true - ) - }) - - describe('getBlockcliqueBlockBySlot', () => { - generateAPITests( - 'getBlockcliqueBlockBySlot', - [], - mockBlockData, - JSON_RPC_REQUEST_METHOD.GET_BLOCKCLIQUE_BLOCK_BY_SLOT, - true - ) - }) - - describe('getNodeStatus', () => { - generateAPITests( - 'getNodeStatus', - [], - mockNodeStatusInfo, - JSON_RPC_REQUEST_METHOD.GET_STATUS, - false - ) - }) - - describe('getAddresses', () => { - generateAPITests( - 'getAddresses', - mockAddresses, - mockAddressesInfo, - JSON_RPC_REQUEST_METHOD.GET_ADDRESSES, - true - ) - }) - - describe('getBlocks', () => { - generateAPITests( - 'getBlocks', - mockBlockIds, - mockBlockData, - JSON_RPC_REQUEST_METHOD.GET_BLOCKS, - true - ) - }) - - describe('getEndorsements', () => { - generateAPITests( - 'getEndorsements', - mockEndorsementIds, - mockEndorsementData, - JSON_RPC_REQUEST_METHOD.GET_ENDORSEMENTS, - true - ) - }) - - describe('getOperations', () => { - generateAPITests( - 'getOperations', - mockOpIds, - mockOperationData, - JSON_RPC_REQUEST_METHOD.GET_OPERATIONS, - true - ) - }) - - describe('getCliques', () => { - generateAPITests( - 'getCliques', - [], - mockEndorsementData, - JSON_RPC_REQUEST_METHOD.GET_CLIQUES, - false - ) - }) - - describe('getStakers', () => { - generateAPITests( - 'getStakers', - [], - mockStackersData, - JSON_RPC_REQUEST_METHOD.GET_STAKERS, - false - ) - }) - - describe('getDatastoreEntries', () => { - const transformedInput = mockDatastoreEntryInput.map((input) => ({ - address: input.address, - key: Array.prototype.slice.call(Buffer.from(input.key)), - })) - - test('should call sendJsonRPCRequest with correct arguments', async () => { - mockSendJsonRPCRequest.mockResolvedValue( - Promise.resolve(mockDatastoreEntries) - ) - - await client.getDatastoreEntries(mockDatastoreEntryInput) - - expect(mockSendJsonRPCRequest).toHaveBeenCalledWith( - JSON_RPC_REQUEST_METHOD.GET_DATASTORE_ENTRIES, - [transformedInput] - ) - }) - - test('should return correct result', async () => { - mockSendJsonRPCRequest.mockResolvedValue( - Promise.resolve(mockDatastoreEntries) - ) - - const result = await client.getDatastoreEntries(mockDatastoreEntryInput) - - expect(result).toEqual(mockDatastoreEntries) - }) - - test('should handle errors correctly', async () => { - const mockError = new Error('Error message') - mockSendJsonRPCRequest.mockRejectedValue(mockError) - - await expect( - client.getDatastoreEntries(mockDatastoreEntryInput) - ).rejects.toThrow(mockError) - }) - - test('should call trySafeExecute if retryStrategyOn is true', async () => { - const originalRetryStrategy = (client as any).clientConfig.retryStrategyOn - ;(client as any).clientConfig.retryStrategyOn = true - - mockSendJsonRPCRequest.mockResolvedValue( - Promise.resolve(mockDatastoreEntries) - ) - - const result = await client.getDatastoreEntries(mockDatastoreEntryInput) - - expect(mockSendJsonRPCRequest).toHaveBeenCalledWith( - JSON_RPC_REQUEST_METHOD.GET_DATASTORE_ENTRIES, - [transformedInput] - ) - expect(result).toEqual(mockDatastoreEntries) - ;(client as any).clientConfig.retryStrategyOn = originalRetryStrategy - }) - }) -}) diff --git a/packages/massa-web3/test/web3/smartContractsClient.spec.ts b/packages/massa-web3/test/web3/smartContractsClient.spec.ts deleted file mode 100644 index 37949ac6..00000000 --- a/packages/massa-web3/test/web3/smartContractsClient.spec.ts +++ /dev/null @@ -1,902 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function, @typescript-eslint/no-explicit-any */ -import { IBalance } from '../../src/interfaces/IBalance' -import { JSON_RPC_REQUEST_METHOD } from '../../src/interfaces/JsonRpcMethods' -import { EOperationStatus } from '../../src/interfaces/EOperationStatus' -import { fromMAS, MAX_GAS_CALL } from '@massalabs/web3-utils' -import { PublicApiClient } from '../../src/web3/PublicApiClient' -import { SmartContractsClient } from '../../src/web3/SmartContractsClient' -import { WalletClient } from '../../src/web3/WalletClient' -import { - mockClientConfig, - mockDeployerAccount as importedMockDeployerAccount, - mockCallData, - mockContractData, - mockNodeStatusInfo, - mockOpIds, - mockContractReadOperationData, - mockContractReadOperationResponse, - mockReadData, - mockOperationDataDetailed, - mockAddressesInfo, - mockEventFilter, - mockedEvents, - mockContractReadOnlyOperationResponse, - validSignature, - mockContractReadOperationDataWithError, - mockAddresses, - mockBalance, - BUILDNET_CHAIN_ID, -} from './mockData' -import { IExecuteReadOnlyResponse } from '../../src/interfaces/IExecuteReadOnlyResponse' -import { Web3Account } from '../../src/web3/accounts/Web3Account' -import { MnsResolver } from '../../src/web3/MnsResolver' - -// Mock to not wait for the timeout to finish -jest.mock('../../src/utils/time', () => { - return { - Timeout: jest.fn(), - wait: jest.fn().mockResolvedValue(true), - } -}) - -describe('SmartContractsClient', () => { - let smartContractsClient: SmartContractsClient - let mockPublicApiClient: PublicApiClient - let mockWalletClient: WalletClient - let mockDeployerAccount: Web3Account - let mockMnsResolver: MnsResolver - - beforeEach(() => { - // Initialize the mock objects - mockMnsResolver = new MnsResolver(mockClientConfig) - mockPublicApiClient = new PublicApiClient(mockClientConfig) - mockDeployerAccount = new Web3Account( - importedMockDeployerAccount, - mockPublicApiClient, - BUILDNET_CHAIN_ID - ) - mockWalletClient = new WalletClient( - mockClientConfig, - mockPublicApiClient, - mockMnsResolver, - mockDeployerAccount - ) - smartContractsClient = new SmartContractsClient( - mockClientConfig, - mockPublicApiClient, - mockWalletClient, - mockMnsResolver - ) - - // Mock getOperations - mockPublicApiClient.getOperations = jest - .fn() - .mockImplementation((operationIds: string[]) => { - return Promise.resolve( - mockOperationDataDetailed.filter((operation) => - operationIds.includes(operation.id) - ) - ) - }) - - mockPublicApiClient.getNodeStatus = jest - .fn() - .mockResolvedValue(mockNodeStatusInfo) - // Mock the getBaseAccount function - mockWalletClient.getBaseAccount = jest - .fn() - .mockReturnValue(mockDeployerAccount) - // Mock the walletSignMessage function - WalletClient.walletSignMessage = jest.fn().mockResolvedValue(validSignature) - ;(mockDeployerAccount as any).sign = jest - .fn() - .mockResolvedValue(validSignature) - // Mock the sendJsonRPCRequest function - ;(mockDeployerAccount as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockOpIds) - }) - - describe('deploySmartContract', () => { - let consoleWarnSpy: jest.SpyInstance - beforeEach(() => { - consoleWarnSpy = jest.spyOn(console, 'warn') - consoleWarnSpy.mockImplementation(() => {}) - }) - - afterEach(() => { - consoleWarnSpy.mockRestore() - }) - - test('should call sendJsonRPCRequest with correct arguments', async () => { - await smartContractsClient.deploySmartContract( - mockContractData, - mockDeployerAccount - ) - - expect( - (mockDeployerAccount as any).sendJsonRPCRequest - ).toHaveBeenCalledWith(JSON_RPC_REQUEST_METHOD.SEND_OPERATIONS, [ - [ - { - serialized_content: expect.any(Array), - creator_public_key: importedMockDeployerAccount.publicKey, - signature: validSignature.base58Encoded, - }, - ], - ]) - }) - - test('should return the correct result', async () => { - const result = - await smartContractsClient.deploySmartContract(mockContractData) - - expect(result).toBe(mockOpIds[0]) - }) - - // Write additional tests to handle any edge cases or error scenarios - test('should handle errors correctly', async () => { - const mockError = new Error('Error message') - ;(mockDeployerAccount as any).sendJsonRPCRequest = jest - .fn() - .mockRejectedValue(mockError) - - await expect( - smartContractsClient.deploySmartContract(mockContractData) - ).rejects.toThrow(mockError) - }) - - test('should throw error when no executor is provided and base account is not set', async () => { - mockWalletClient.getBaseAccount = jest.fn().mockReturnValue(null) - await expect( - smartContractsClient.deploySmartContract(mockContractData) - ).rejects.toThrow(`No tx sender available`) - }) - - test('should use default account when no executor is provided', async () => { - await smartContractsClient.deploySmartContract(mockContractData) - expect(mockWalletClient.getBaseAccount).toHaveBeenCalled() - }) - - test('should warn when contractDataBinary size exceeded half of the maximum size of a block', async () => { - consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}) - - const max_block_size = mockNodeStatusInfo.config.max_block_size - mockContractData.contractDataBinary = new Uint8Array( - max_block_size / 2 + 1 - ) // value > max_block_size / 2 - - await smartContractsClient.deploySmartContract(mockContractData) - - expect(consoleWarnSpy).toHaveBeenCalledWith( - 'Bytecode size exceeded half of the maximum size of a block, operation will certainly be rejected' - ) - }) - - test('should throw error when contractDataBinary does not exist', async () => { - const modifiedMockContractData = { ...mockContractData } - delete modifiedMockContractData.contractDataBinary - - await expect( - smartContractsClient.deploySmartContract(modifiedMockContractData) - ).rejects.toThrow( - `Expected non-null contract bytecode, but received null.` - ) - }) - - test('should throw error when no opId is returned', async () => { - ;(mockDeployerAccount as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue([]) - - await expect( - smartContractsClient.deploySmartContract(mockContractData) - ).rejects.toThrow( - `Deploy smart contract operation bad response. No results array in json rpc response. Inspect smart contract` - ) - }) - }) - - describe('callSmartContract', () => { - beforeEach(() => { - // mock getAccountBalance - mockWalletClient.getAccountBalance = jest - .fn() - .mockResolvedValue(mockBalance) - }) - afterEach(() => { - jest.clearAllMocks() - }) - - test('should call sendJsonRPCRequest with correct arguments', async () => { - await smartContractsClient.callSmartContract( - mockCallData, - mockDeployerAccount - ) - - expect( - (mockDeployerAccount as any).sendJsonRPCRequest - ).toHaveBeenCalledWith(JSON_RPC_REQUEST_METHOD.SEND_OPERATIONS, [ - [ - { - serialized_content: expect.any(Array), - creator_public_key: importedMockDeployerAccount.publicKey, - signature: validSignature.base58Encoded, - }, - ], - ]) - }) - - test('should default coins to 0 if not provided', async () => { - const mockCallDataWithoutCoins = { - ...mockCallData, - coins: undefined, - } - - const spy = jest.spyOn(smartContractsClient, 'callSmartContract') - - const result = await smartContractsClient.callSmartContract( - mockCallDataWithoutCoins, - mockDeployerAccount - ) - - expect(result).toBe(mockOpIds[0]) - expect(spy).toHaveBeenCalledWith( - expect.objectContaining({ - ...mockCallDataWithoutCoins, - coins: BigInt(0), - }), - mockDeployerAccount - ) - - spy.mockRestore() - }) - - test('should set default maxGas using readSmartContract if maxGas is not provided', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockContractReadOperationData) - - const mockCallDataWithoutMaxGas = { - ...mockCallData, - maxGas: undefined, - } - - const spy = jest.spyOn(smartContractsClient, 'readSmartContract') - - await smartContractsClient.callSmartContract( - mockCallDataWithoutMaxGas, - mockDeployerAccount - ) - - expect(spy).toHaveBeenCalledWith( - expect.objectContaining({ - ...mockCallDataWithoutMaxGas, - maxGas: BigInt(mockContractReadOperationData[0].gas_cost), - }) - ) - spy.mockRestore() - }) - - test('should throw custom error if maxGas is not provided and readSmartContract fails', async () => { - const error = 'Some error' - - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockRejectedValue(new Error(error)) - - const mockCallDataWithoutMaxGas = { - ...mockCallData, - maxGas: undefined, - } - - await expect( - smartContractsClient.callSmartContract( - mockCallDataWithoutMaxGas, - mockDeployerAccount - ) - ).rejects.toThrow( - `Operation failed: Max gas unspecified and auto-estimation failed. Error details: ${error}` - ) - }) - - test('should return the correct result', async () => { - const result = await smartContractsClient.callSmartContract( - mockCallData, - mockDeployerAccount - ) - - expect(result).toBe(mockOpIds[0]) - }) - - test('should use default account when no executor is provided', async () => { - await smartContractsClient.callSmartContract(mockCallData) - expect(mockWalletClient.getBaseAccount).toHaveBeenCalled() - }) - - test('should handle errors correctly', async () => { - const mockError = new Error('Error message') - ;(mockDeployerAccount as any).sendJsonRPCRequest.mockRejectedValue( - mockError - ) - - await expect( - smartContractsClient.callSmartContract(mockCallData) - ).rejects.toThrow(mockError) - }) - - test('should throw error when no executor is provided and base account is not set', async () => { - mockWalletClient.getBaseAccount = jest.fn().mockReturnValue(null) - await expect( - smartContractsClient.callSmartContract(mockCallData) - ).rejects.toThrow(`No tx sender available`) - }) - - test('should call trySafeExecute if retryStrategyOn is true', async () => { - const originalRetryStrategy = (mockDeployerAccount as any).clientConfig - .retryStrategyOn - ;(mockDeployerAccount as any).clientConfig.retryStrategyOn = true - - await smartContractsClient.callSmartContract(mockCallData) - - expect( - (mockDeployerAccount as any).sendJsonRPCRequest - ).toHaveBeenCalledWith(JSON_RPC_REQUEST_METHOD.SEND_OPERATIONS, [ - [ - { - serialized_content: expect.any(Array), - creator_public_key: importedMockDeployerAccount.publicKey, - signature: validSignature.base58Encoded, - }, - ], - ]) - ;(smartContractsClient as any).clientConfig.retryStrategyOn = - originalRetryStrategy - }) - - test('should throw error when no opId is returned', async () => { - ;(mockDeployerAccount as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue([]) - - await expect( - smartContractsClient.callSmartContract(mockCallData) - ).rejects.toThrow( - `Call smart contract operation bad response. No results array in json rpc response. Inspect smart contract` - ) - }) - - test('should throw error when maxGas is superior to the maximum gas allowed', async () => { - const modifiedMockCallData = { ...mockCallData } - modifiedMockCallData.maxGas = MAX_GAS_CALL + BigInt(1) - - await expect( - smartContractsClient.callSmartContract(modifiedMockCallData) - ).rejects.toThrow( - `The gas submitted ${modifiedMockCallData.maxGas.toString()} exceeds the max. allowed block gas of ${MAX_GAS_CALL.toString()}` - ) - }) - - test('should throw error when coins is superior to coins possessed by sender', async () => { - const modifiedMockCallData = { ...mockCallData } - modifiedMockCallData.coins = - BigInt(mockAddressesInfo[2].final_balance) + BigInt(1) - - await expect( - smartContractsClient.callSmartContract(modifiedMockCallData) - ).rejects.toThrow( - `The sender ${mockDeployerAccount.address()} does not have enough balance to pay for the coins` - ) - }) - }) - - describe('readSmartContract', () => { - test('should send the correct JSON RPC request', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockContractReadOperationData) - - await smartContractsClient.readSmartContract(mockReadData) - - expect( - (smartContractsClient as any).sendJsonRPCRequest - ).toHaveBeenCalledWith(JSON_RPC_REQUEST_METHOD.EXECUTE_READ_ONLY_CALL, [ - [ - { - max_gas: Number(mockReadData.maxGas), - target_address: mockReadData.targetAddress, - target_function: mockReadData.targetFunction, - parameter: mockReadData.parameter, - caller_address: mockReadData.callerAddress, - coins: '0.000000001', - fee: '0.000000001', - }, - ], - ]) - }) - - test('should return correct result', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockContractReadOperationData) - - const result = await smartContractsClient.readSmartContract(mockReadData) - - expect(result).toEqual(mockContractReadOperationResponse) - }) - - test('should throw error when the gas submitted exceeds the maximum allowed block gas', async () => { - const mockReadDataWithLargeMaxGas = { - ...mockReadData, - maxGas: BigInt(4_294_967_296), - } // value > MAX_GAS_CALL - - await expect( - smartContractsClient.readSmartContract(mockReadDataWithLargeMaxGas) - ).rejects.toThrow( - `The gas submitted ${mockReadDataWithLargeMaxGas.maxGas.toString()} exceeds the max. allowed block gas of ${MAX_GAS_CALL.toString()}` - ) - }) - - test('should throw error when no results array in json rpc response', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue([]) - - await expect( - smartContractsClient.readSmartContract(mockReadData) - ).rejects.toThrow( - `Read operation bad response. No results array in json rpc response. Inspect smart contract` - ) - }) - - test('should throw error when json rpc response has error', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockContractReadOperationDataWithError) - - await expect( - smartContractsClient.readSmartContract(mockReadData) - ).rejects.toThrow(mockContractReadOperationDataWithError[0].result.Error) - }) - - test('should call trySafeExecute if retryStrategyOn is true', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockContractReadOperationData) - - const originalRetryStrategy = (smartContractsClient as any).clientConfig - .retryStrategyOn - ;(smartContractsClient as any).clientConfig.retryStrategyOn = true - - await smartContractsClient.readSmartContract(mockReadData) - - expect( - (smartContractsClient as any).sendJsonRPCRequest - ).toHaveBeenCalledWith(JSON_RPC_REQUEST_METHOD.EXECUTE_READ_ONLY_CALL, [ - [ - { - max_gas: Number(mockReadData.maxGas), - target_address: mockReadData.targetAddress, - target_function: mockReadData.targetFunction, - parameter: mockReadData.parameter, - caller_address: mockReadData.callerAddress, - coins: '0.000000001', - fee: '0.000000001', - }, - ], - ]) - ;(smartContractsClient as any).clientConfig.retryStrategyOn = - originalRetryStrategy - }) - }) - - describe('getOperationStatus', () => { - test('should return EOperationStatus.NOT_FOUND when operation does not exist', async () => { - const opId = '0x005' // Doesn't exist - const status = await smartContractsClient.getOperationStatus(opId) - expect(status).toBe(EOperationStatus.NOT_FOUND) - }) - - test('should return EOperationStatus.FINAL_SUCCESS when operation executed as final and no error', async () => { - const opId = mockOpIds[0] - const status = await smartContractsClient.getOperationStatus(opId) - expect(status).toBe(EOperationStatus.FINAL_SUCCESS) - }) - - test('should return EOperationStatus.FINAL_ERROR when operation executed as final and error occured', async () => { - const opId = mockOpIds[1] - const status = await smartContractsClient.getOperationStatus(opId) - expect(status).toBe(EOperationStatus.FINAL_ERROR) - }) - - test('should return EOperationStatus.SPECULATIVE_SUCCESS when operation executed as speculative and was a success', async () => { - const opId = mockOpIds[2] - const status = await smartContractsClient.getOperationStatus(opId) - expect(status).toBe(EOperationStatus.SPECULATIVE_SUCCESS) - }) - - test('should return EOperationStatus.SPECULATIVE_ERROR when operation executed as speculative and error occured', async () => { - const opId = mockOpIds[3] - const status = await smartContractsClient.getOperationStatus(opId) - expect(status).toBe(EOperationStatus.SPECULATIVE_ERROR) - }) - test('should return EOperationStatus.AWAITING_INCLUSION when operation not executed, or executed & expired & was forgotten', async () => { - const opId = mockOpIds[4] - const status = await smartContractsClient.getOperationStatus(opId) - expect(status).toBe(EOperationStatus.AWAITING_INCLUSION) - }) - test('should return EOperationStatus.UNEXECUTED_OR_EXPIRED when operation not executed, or executed & expired & was forgotten', async () => { - const opId = mockOpIds[5] - const status = await smartContractsClient.getOperationStatus(opId) - expect(status).toBe(EOperationStatus.UNEXECUTED_OR_EXPIRED) - }) - test('should return EOperationStatus.INCONSISTENT when no conditions are met', async () => { - const opId = mockOpIds[6] - const status = await smartContractsClient.getOperationStatus(opId) - expect(status).toBe(EOperationStatus.INCONSISTENT) - }) - test.skip('should return EOperationStatus.INCLUDED_PENDING when operation is included in blocks', async () => { - const opId = mockOpIds[7] - const status = await smartContractsClient.getOperationStatus(opId) - expect(status).toBe(EOperationStatus.INCLUDED_PENDING) - }) - }) - - describe('awaitRequiredOperationStatus', () => { - const opId = mockOpIds[0] - const requiredStatus = EOperationStatus.FINAL_SUCCESS - let getOperationStatusMock - - beforeEach(() => { - getOperationStatusMock = jest.spyOn( - smartContractsClient, - 'getOperationStatus' - ) - }) - - afterEach(() => { - getOperationStatusMock.mockReset() - }) - - test('waiting for NOT_FOUND status to become the required status', async () => { - getOperationStatusMock - .mockResolvedValueOnce(EOperationStatus.NOT_FOUND) - .mockResolvedValueOnce(requiredStatus) - - const status = await smartContractsClient.awaitRequiredOperationStatus( - opId, - requiredStatus - ) - - expect(status).toBe(requiredStatus) - expect(smartContractsClient.getOperationStatus).toHaveBeenCalledTimes(2) - }) - }) - - describe('awaitMultipleRequiredOperationStatuses', () => { - const opId = mockOpIds[0] - const requiredStatus = EOperationStatus.FINAL_SUCCESS - const timeout = 1000 - let getOperationStatusMock - - beforeEach(() => { - getOperationStatusMock = jest.spyOn( - smartContractsClient, - 'getOperationStatus' - ) - }) - - afterEach(() => { - getOperationStatusMock.mockReset() - }) - - it('should return the expected status when all required statuses are met', async () => { - getOperationStatusMock - .mockResolvedValueOnce(EOperationStatus.NOT_FOUND) - .mockResolvedValueOnce(requiredStatus) - - const requiredStatuses = [ - EOperationStatus.FINAL_SUCCESS, - EOperationStatus.FINAL_ERROR, - ] - - const result = - await smartContractsClient.awaitMultipleRequiredOperationStatus( - opId, - requiredStatuses, - timeout - ) - - expect(result).toEqual(requiredStatus) - expect(smartContractsClient.getOperationStatus).toHaveBeenCalledTimes(2) - }) - - it('should throw an error when the required statuses are not met within the timeout', async () => { - getOperationStatusMock.mockResolvedValue(EOperationStatus.NOT_FOUND) // Always return NOT_FOUND - - const requiredStatuses = [ - EOperationStatus.FINAL_SUCCESS, - EOperationStatus.FINAL_ERROR, - ] - - await expect( - smartContractsClient.awaitMultipleRequiredOperationStatus( - opId, - requiredStatuses, - timeout - ) - ).rejects.toThrow( - `Failed to retrieve status of operation id: ${opId}: Timeout reached.` - ) - }) - }) - - describe('watch for operation status', () => { - beforeEach(() => { - jest.useFakeTimers() - }) - - afterEach(() => { - jest.useRealTimers() - }) - - it('should trigger the callback when the operation status changes', async () => { - const opId = mockOpIds[0] - const callback = jest.fn() - const interval = 10 - const status = EOperationStatus - - jest - .spyOn(smartContractsClient, 'getOperationStatus') - .mockResolvedValueOnce(status.NOT_FOUND) - .mockResolvedValueOnce(status.SPECULATIVE_SUCCESS) - .mockResolvedValueOnce(status.FINAL_SUCCESS) - - smartContractsClient.watchOperationStatus(opId, callback, interval) - - for (let i = 0; i < 3; i++) { - jest.advanceTimersByTime(20) - // allow any pending jobs in the PromiseJobs queue to run more information : - // https://stackoverflow.com/questions/52177631/jest-timer-and-promise-dont-work-well-settimeout-and-async-function - await Promise.resolve() - } - - expect(callback).toHaveBeenNthCalledWith(1, status.NOT_FOUND) - expect(callback).toHaveBeenNthCalledWith(2, status.SPECULATIVE_SUCCESS) - expect(callback).toHaveBeenNthCalledWith(3, status.FINAL_SUCCESS) - }) - - it('should continue watching if getOperationStatus throws an error', async () => { - const opId = mockOpIds[0] - const callback = jest.fn() - const interval = 5 - const status = EOperationStatus - const error = new Error('Error') - - jest - .spyOn(smartContractsClient, 'getOperationStatus') - .mockResolvedValueOnce(status.NOT_FOUND) - .mockRejectedValueOnce(error) - .mockResolvedValueOnce(status.FINAL_SUCCESS) - - smartContractsClient.watchOperationStatus(opId, callback, interval) - - for (let i = 0; i < 3; i++) { - jest.advanceTimersByTime(20) - await Promise.resolve() - } - - expect(callback).toHaveBeenNthCalledWith(1, status.NOT_FOUND) - expect(callback).toHaveBeenNthCalledWith(2, status.NOT_FOUND, error) - expect(callback).toHaveBeenNthCalledWith(3, status.FINAL_SUCCESS) - }) - }) - - describe('getContractBalance', () => { - const expectedBalance: IBalance = { - candidate: fromMAS(mockAddressesInfo[0].candidate_balance), - final: fromMAS(mockAddressesInfo[0].final_balance), - } - - test('should return the correct balance when the address exists', async () => { - mockPublicApiClient.getAddresses = jest - .fn() - .mockResolvedValue(mockAddressesInfo) - - const balance = await smartContractsClient.getContractBalance( - mockAddresses[0] - ) - - expect(balance).toEqual(expectedBalance) - expect(mockPublicApiClient.getAddresses).toHaveBeenCalledWith([ - mockAddresses[0], - ]) - }) - - test('should return null when the address does not exist', async () => { - mockPublicApiClient.getAddresses = jest.fn().mockResolvedValue([]) - - const balance = await smartContractsClient.getContractBalance( - mockAddresses[0] - ) - - expect(balance).toBeNull() - expect(mockPublicApiClient.getAddresses).toHaveBeenCalledWith([ - mockAddresses[0], - ]) - }) - }) - - describe('getFilteredScOutputEvents', () => { - test('should send the correct JSON RPC request', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockedEvents) - - await smartContractsClient.getFilteredScOutputEvents(mockEventFilter) - - expect( - (smartContractsClient as any).sendJsonRPCRequest - ).toHaveBeenCalledWith( - JSON_RPC_REQUEST_METHOD.GET_FILTERED_SC_OUTPUT_EVENT, - [mockEventFilter] - ) - }) - - test('should return the correct array of IEvent objects', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockedEvents) - - const result = - await smartContractsClient.getFilteredScOutputEvents(mockEventFilter) - - expect(result).toEqual(mockedEvents) - }) - - test('should call trySafeExecute if retryStrategyOn is true', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockedEvents) - - const originalRetryStrategy = (smartContractsClient as any).clientConfig - .retryStrategyOn - ;(smartContractsClient as any).clientConfig.retryStrategyOn = true - - await smartContractsClient.getFilteredScOutputEvents(mockEventFilter) - - expect( - (smartContractsClient as any).sendJsonRPCRequest - ).toHaveBeenCalledWith( - JSON_RPC_REQUEST_METHOD.GET_FILTERED_SC_OUTPUT_EVENT, - [mockEventFilter] - ) - ;(smartContractsClient as any).clientConfig.retryStrategyOn = - originalRetryStrategy - }) - }) - - describe('executeReadOnlySmartContract', () => { - test('should throw error if contractDataBinary is missing', async () => { - const consoleErrorSpy = jest - .spyOn(console, 'error') - .mockImplementation(() => {}) - - await expect( - smartContractsClient.executeReadOnlySmartContract({ - ...mockContractData, - contractDataBinary: undefined, - }) - ).rejects.toThrow( - `Expected non-null contract bytecode, but received null.` - ) - - // Restore console.error - consoleErrorSpy.mockRestore() - }) - - test('should throw error if address is missing', async () => { - await expect( - smartContractsClient.executeReadOnlySmartContract({ - ...mockContractData, - address: undefined, - }) - ).rejects.toThrow(`Expected contract address, but received null.`) - }) - - test('should send correct request', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue([{ result: { Ok: new Uint8Array([11, 22, 33]) } }]) - - await smartContractsClient.executeReadOnlySmartContract(mockContractData) - - expect( - (smartContractsClient as any).sendJsonRPCRequest - ).toHaveBeenCalledWith( - JSON_RPC_REQUEST_METHOD.EXECUTE_READ_ONLY_BYTECODE, - [ - [ - { - max_gas: Number(mockContractData.maxGas), - bytecode: mockContractData.contractDataBinary - ? Array.from(mockContractData.contractDataBinary) - : [], - address: mockContractData.address, - }, - ], - ] - ) - }) - - test('should return correct result', async () => { - const expectedResponse: IExecuteReadOnlyResponse = - mockContractReadOnlyOperationResponse - - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockContractReadOperationData) - - const result = - await smartContractsClient.executeReadOnlySmartContract( - mockContractData - ) - - expect(result).toEqual(expectedResponse) - }) - - test('should throw error if no result is returned', async () => { - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue([]) - - await expect( - smartContractsClient.executeReadOnlySmartContract(mockContractData) - ).rejects.toThrow( - `Read operation bad response. No results array in json rpc response. Inspect smart contract` - ) - }) - - test('should throw error if result contains an error', async () => { - const error = 'Some error' - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue([{ result: { Error: error } }]) - - await expect( - smartContractsClient.executeReadOnlySmartContract(mockContractData) - ).rejects.toThrow(`Execute read-only smart contract error`) - }) - - test('should call trySafeExecute if retryStrategyOn is true', async () => { - const originalRetryStrategy = (smartContractsClient as any).clientConfig - .retryStrategyOn - ;(smartContractsClient as any).clientConfig.retryStrategyOn = true - ;(smartContractsClient as any).sendJsonRPCRequest = jest - .fn() - .mockResolvedValue(mockContractReadOperationData) - - await smartContractsClient.executeReadOnlySmartContract(mockContractData) - - expect( - (smartContractsClient as any).sendJsonRPCRequest - ).toHaveBeenCalledWith( - JSON_RPC_REQUEST_METHOD.EXECUTE_READ_ONLY_BYTECODE, - [ - [ - { - max_gas: Number(mockContractData.maxGas), - bytecode: mockContractData.contractDataBinary - ? Array.from(mockContractData.contractDataBinary) - : [], - address: mockContractData.address, - }, - ], - ] - ) - ;(smartContractsClient as any).clientConfig.retryStrategyOn = - originalRetryStrategy - }) - }) -}) diff --git a/packages/massa-web3/test/web3/walletClient.spec.ts b/packages/massa-web3/test/web3/walletClient.spec.ts deleted file mode 100644 index 9c3b2b1f..00000000 --- a/packages/massa-web3/test/web3/walletClient.spec.ts +++ /dev/null @@ -1,997 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-var-requires */ -import { IAccount } from '../../src/interfaces/IAccount' -import { ClientFactory } from '../../src/web3/ClientFactory' -import { WalletClient } from '../../src/web3/WalletClient' -import { Client } from '../../src/web3/Client' -import { IProvider, ProviderType } from '../../src/interfaces/IProvider' -import { expect, test, describe, beforeEach, afterEach } from '@jest/globals' -import * as ed from '@noble/ed25519' -import { ISignature } from '../../src/interfaces/ISignature' -import { IFullAddressInfo } from '../../src/interfaces/IFullAddressInfo' -import { - BUILDNET_CHAIN_ID, - mockResultSendJsonRPCRequestWalletInfo, -} from './mockData' -import { ITransactionData } from '../../src/interfaces/ITransactionData' -import { OperationTypeId } from '../../src/interfaces/OperationTypes' -import { JSON_RPC_REQUEST_METHOD } from '../../src/interfaces/JsonRpcMethods' -import { mockAddressesInfo, mockNodeStatusInfo, mockOpIds } from './mockData' -import { IRollsData } from '../../src/interfaces/IRollsData' -import { fromMAS } from '@massalabs/web3-utils' -import { Web3Account } from '../../src/web3/accounts/Web3Account' -import { IBaseAccount } from '../../src/interfaces/IBaseAccount' - -// TODO: Use env variables and say it in the CONTRIBUTING.md -const deployerPrivateKey = - 'S12XuWmm5jULpJGXBnkeBsuiNmsGi2F4rMiTvriCzENxBR4Ev7vd' -const receiverPrivateKey = 'S1eK3SEXGDAWN6pZhdr4Q7WJv6UHss55EB14hPy4XqBpiktfPu6' - -// for CI testing: -const publicApi = 'https://mock-public-api.com' -const privateApi = 'https://mock-private-api.com' -const chainId = BUILDNET_CHAIN_ID - -const MAX_WALLET_ACCOUNTS = 256 - -export async function initializeClient() { - const deployerAccount: IAccount = - await WalletClient.getAccountFromSecretKey(deployerPrivateKey) - const web3Client: Client = await ClientFactory.createCustomClient( - [ - { url: publicApi, type: ProviderType.PUBLIC } as IProvider, - { url: privateApi, type: ProviderType.PRIVATE } as IProvider, - ], - chainId, - true, - deployerAccount // setting deployer account as base account - ) - return web3Client -} - -function createFullAddressInfo( - address: string | null, - publicKey: string | null, - secretKey: string | null -): IFullAddressInfo { - if (!address || !publicKey || !secretKey) { - throw new Error('Invalid address, public key or secret key') - } - return { - address, - candidate_balance: '0', - candidate_datastore_keys: [], - candidate_roll_count: 0, - created_blocks: [], - created_endorsements: [], - created_operations: [], - cycle_infos: [], - deferred_credits: [], - final_balance: '0', - final_datastore_keys: [], - final_roll_count: 0, - next_block_draws: [], - next_endorsement_draws: [], - thread: 0, - publicKey, - secretKey, - } -} - -describe('WalletClient', () => { - let web3Client: Client - // let walletClient: WalletClient; - let baseAccount: IAccount = { - address: 'AU1QRRX6o2igWogY8qbBtqLYsNzYNHwvnpMC48Y6CLCv4cXe9gmK', - secretKey: 'S12XuWmm5jULpJGXBnkeBsuiNmsGi2F4rMiTvriCzENxBR4Ev7vd', - publicKey: 'P129tbNd4oVMRsnFvQcgSq4PUAZYYDA1pvqtef2ER6W7JqgY1Bfg', - } - - beforeEach(async () => { - web3Client = await initializeClient() - }) - - afterEach(async () => { - web3Client.wallet().cleanWallet() - }) - - describe('setBaseAccount', () => { - test('should set base account', async () => { - const account = - await WalletClient.getAccountFromSecretKey(receiverPrivateKey) - await web3Client - .wallet() - .setBaseAccount( - new Web3Account(account, web3Client.publicApi(), chainId) - ) - const baseAccount = web3Client.wallet().getBaseAccount() - expect(baseAccount).not.toBeNull() - expect(baseAccount?.address()).toEqual(account.address) - }) - - test('should throw error if account is not valid', async () => { - web3Client.wallet().cleanWallet() - await expect( - web3Client.wallet().setBaseAccount({} as IBaseAccount) - ).rejects.toThrow() - const incorrectAccount = { - address: 'AU12Set6aygzt1k7ZkDwrkStYovVBzeGs8VgaZogy11s7fQzaytv3', - secretKey: 's1eK3SEXGDAWN6pZhdr4Q7WJv6UHss55EB14hPy4XqBpiktfPu6', // prefix is incorrect - publicKey: 'P121uDTpo58d3SxQTENXKqSJTpB21ueSAy8RqQ2virGVeWs339ub', - } as IAccount - await expect( - web3Client - .wallet() - .setBaseAccount( - new Web3Account(incorrectAccount, web3Client.publicApi(), chainId) - ) - ).rejects.toThrow() - }) - - test('should change base account if already set', async () => { - const firstAccount = - await WalletClient.getAccountFromSecretKey(receiverPrivateKey) - await web3Client - .wallet() - .setBaseAccount( - new Web3Account(firstAccount, web3Client.publicApi(), chainId) - ) - - const secondAccount = - await WalletClient.getAccountFromSecretKey(deployerPrivateKey) - await web3Client - .wallet() - .setBaseAccount( - new Web3Account(secondAccount, web3Client.publicApi(), chainId) - ) - - const baseAccount = web3Client.wallet().getBaseAccount() - expect(baseAccount).not.toBeNull() - expect(baseAccount?.address()).toEqual(secondAccount.address) - }) - }) - - describe('getBaseAccount', () => { - test('should return the base account', async () => { - const fetchedBaseAccount = web3Client.wallet().getBaseAccount() - expect(fetchedBaseAccount).not.toBeNull() - expect(fetchedBaseAccount?.address()).toEqual(baseAccount.address) - }) - - test('should return null if base account is not set', async () => { - web3Client.wallet().cleanWallet() - const fetchedBaseAccount = web3Client.wallet().getBaseAccount() - expect(fetchedBaseAccount).toBeNull() - }) - }) - - describe('getWalletAccountByAddress', () => { - test('should return the account for a valid address', async () => { - const accounts = [ - await WalletClient.walletGenerateNewAccount(), - await WalletClient.walletGenerateNewAccount(), - await WalletClient.walletGenerateNewAccount(), - ] - - await web3Client.wallet().addAccountsToWallet(accounts) - - const targetAccount = accounts[1] // Assume we want to find the second account - const fetchedAccount = web3Client - .wallet() - .getWalletAccountByAddress(targetAccount.address!) - - expect(fetchedAccount).not.toBeNull() - expect(fetchedAccount?.address).toEqual(targetAccount.address) - }) - - test('should return undefined for a non-existent address', async () => { - const nonexistentAddress = - 'AU12Set6aygzt1k7ZkDwrkStYovVBzeGs8VgaZogy11s7fQzaytv3' // This address doesn't exist in the wallet - const fetchedAccount = web3Client - .wallet() - .getWalletAccountByAddress(nonexistentAddress) - expect(fetchedAccount).toBeUndefined() - }) - - test('should return the account regardless of address case', async () => { - const accounts = [await WalletClient.walletGenerateNewAccount()] - - await web3Client.wallet().addAccountsToWallet(accounts) - - const targetAccount = accounts[0] // Assume we want to find the first account - const upperCaseAddress = targetAccount.address?.toUpperCase() - const fetchedAccount = web3Client - .wallet() - .getWalletAccountByAddress(upperCaseAddress!) - - expect(fetchedAccount).not.toBeNull() - expect(fetchedAccount?.address).toEqual(targetAccount.address) - }) - }) - describe('addSecretKeysToWallet', () => { - test('should throw an error when the number of accounts exceeds the maximum limit', async () => { - const secretKeys = new Array(MAX_WALLET_ACCOUNTS + 1).fill( - receiverPrivateKey - ) - - await expect( - web3Client.wallet().addSecretKeysToWallet(secretKeys) - ).rejects.toThrow( - new RegExp( - `Maximum number of allowed wallet accounts exceeded ${MAX_WALLET_ACCOUNTS}` - ) - ) - }) - - test('should not add duplicate accounts to the wallet (account already in wallet)', async () => { - const addedAccounts = await web3Client - .wallet() - .addSecretKeysToWallet([deployerPrivateKey, receiverPrivateKey]) - const walletAccounts = web3Client.wallet().getWalletAccounts() - - // only receiver account should be added - expect(addedAccounts[0].secretKey).toBe(deployerPrivateKey) - expect([baseAccount, addedAccounts[1]]).toStrictEqual(walletAccounts) - expect(addedAccounts.length).toBe(2) - expect(web3Client.wallet().getWalletAccounts().length).toBe(2) - }) - - test('should correctly create and add accounts to the wallet', async () => { - const accounts = [ - await WalletClient.walletGenerateNewAccount(), - await WalletClient.walletGenerateNewAccount(), - ] - const secretKeys: string[] = [ - accounts[0].secretKey!, - accounts[1].secretKey!, - ] - - const addedAccounts = await web3Client - .wallet() - .addSecretKeysToWallet(secretKeys) - - expect(addedAccounts.length).toBe(2) - - // Check that both accounts have been added - expect(addedAccounts).toEqual( - expect.arrayContaining([ - expect.objectContaining({ address: accounts[0].address }), - expect.objectContaining({ - address: accounts[1].address, - }), - ]) - ) - }) - }) - - describe('getWalletAccounts', () => { - test('should return all accounts in the wallet', async () => { - const accounts = [ - await WalletClient.walletGenerateNewAccount(), - await WalletClient.walletGenerateNewAccount(), - await WalletClient.walletGenerateNewAccount(), - ] - - await web3Client.wallet().addAccountsToWallet(accounts) - const walletAccounts = web3Client.wallet().getWalletAccounts() - expect(walletAccounts.length).toBe(3) // 3 generated - }) - - test('should return different accounts for different secret keys', async () => { - const secretKey1 = 'S12XuWmm5jULpJGXBnkeBsuiNmsGi2F4rMiTvriCzENxBR4Ev7vd' - const secretKey2 = 'S1eK3SEXGDAWN6pZhdr4Q7WJv6UHss55EB14hPy4XqBpiktfPu6' - - const accountFromPrivateKey1 = - await WalletClient.getAccountFromSecretKey(secretKey1) - const accountFromPrivateKey2 = - await WalletClient.getAccountFromSecretKey(secretKey2) - - expect(accountFromPrivateKey1.address).not.toEqual( - accountFromPrivateKey2.address - ) - expect(accountFromPrivateKey1.publicKey).not.toEqual( - accountFromPrivateKey2.publicKey - ) - }) - }) - - describe('walletInfo', () => { - test('should return an empty array if the wallet is empty', async () => { - web3Client.wallet().cleanWallet() // Make sure the wallet is empty - const walletInfo = await web3Client.wallet().walletInfo() - expect(walletInfo).toEqual([]) - }) - - test('should throw an error if the number of retrieved wallets does not match the number of addresses in the wallet', async () => { - jest - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .spyOn(web3Client.wallet() as any, 'getWalletAddressesInfo') - .mockImplementation(async () => { - return [ - /* return fewer or more addresses than in the wallet */ - ] - }) - - await web3Client.wallet().addAccountsToWallet([baseAccount]) - - await expect(web3Client.wallet().walletInfo()).rejects.toThrow( - /Requested wallets not fully retrieved./ - ) - }) - - test('should return IFullAddressInfo objects that include information from the corresponding IAddressInfo', async () => { - const accounts = [ - baseAccount, - await WalletClient.walletGenerateNewAccount(), - ] - await web3Client.wallet().addAccountsToWallet(accounts) // will not add the base account - - const mockAddressInfo: IFullAddressInfo[] = [ - createFullAddressInfo( - baseAccount.address, - baseAccount.publicKey, - baseAccount.secretKey - ), - createFullAddressInfo( - accounts[1].address, - accounts[1].publicKey, - accounts[1].secretKey - ), - ] - - jest - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .spyOn(web3Client.wallet() as any, 'getWalletAddressesInfo') - .mockImplementation(async () => { - return mockAddressInfo - }) - - const walletInfo = await web3Client.wallet().walletInfo() - // check that the returned walletInfo is an array of IFullAddressInfo with correct information - walletInfo.forEach((info, index) => { - expect(info.address).toBe(mockAddressInfo[index].address) - expect(info.publicKey).toBe(accounts[index].publicKey) - expect(info.secretKey).toBe(accounts[index].secretKey) - }) - }) - }) - - describe('getWalletAddressesInfo', () => { - beforeEach(() => { - jest - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .spyOn(web3Client.wallet() as any, 'sendJsonRPCRequest') - .mockResolvedValue(mockResultSendJsonRPCRequestWalletInfo) - }) - - test('should call getWalletAddressesInfo when walletInfo is called', async () => { - const spy = jest.spyOn( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - web3Client.wallet() as any, - 'getWalletAddressesInfo' - ) - const mockAddresses = [ - baseAccount.address, - await WalletClient.walletGenerateNewAccount().then( - (account) => account.address - ), - ] - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ;(web3Client.wallet() as any).wallet = mockAddresses.map((address) => ({ - address, - })) - - await web3Client.wallet().walletInfo() - - expect(spy).toHaveBeenCalledWith(mockAddresses) - }) - - test('should call sendJsonRPCRequest if retryStrategyOn is false', async () => { - const sendJsonRPCRequestSpy = jest.spyOn( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - web3Client.wallet() as any, - 'sendJsonRPCRequest' - ) - - const mockAddresses = [ - baseAccount.address, - await WalletClient.walletGenerateNewAccount().then( - (account) => account.address - ), - ] - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ;(web3Client.wallet() as any).wallet = mockAddresses.map((address) => ({ - address, - })) - - // Enable retry strategy - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const originalRetryStrategy = (web3Client.wallet() as any).clientConfig - .retryStrategyOn - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ;(web3Client.wallet() as any).clientConfig.retryStrategyOn = false - - await web3Client.wallet().walletInfo() - - expect(sendJsonRPCRequestSpy).toHaveBeenCalledWith( - JSON_RPC_REQUEST_METHOD.GET_ADDRESSES, - [mockAddresses] - ) - - // Restore original retry strategy setting - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ;(web3Client.wallet() as any).clientConfig.retryStrategyOn = - originalRetryStrategy - }) - }) - - describe('removeAddressesFromWallet', () => { - test('should remove specified addresses from the wallet', async () => { - const accountsToRemove = await web3Client - .wallet() - .addSecretKeysToWallet([ - receiverPrivateKey, - 'S1USr9AFUaH7taTKeWt94qGTgaS9XkpnH1SPpctRDoK3sSJkYWk', - 'S16cS2QnKmyxxiU68Bw9Lnmt2Yttva42nahDG68awziextJgBze', - ]) - let addressesToRemove = accountsToRemove.map((account) => account.address) - - expect(addressesToRemove.length).toBe(3) - expect(addressesToRemove).not.toContain(null) - await web3Client - .wallet() - .removeAddressesFromWallet(addressesToRemove as string[]) - - const walletAccounts = web3Client.wallet().getWalletAccounts() - addressesToRemove.forEach((address) => { - expect(walletAccounts).not.toContainEqual( - expect.objectContaining({ address }) - ) - }) - }) - }) - - describe('cleanWallet', () => { - test('remove all accounts from the wallet', async () => { - web3Client.wallet().cleanWallet() - const walletAccounts = await web3Client.wallet().getWalletAccounts() - expect(walletAccounts.length).toBe(0) // only base account should be left - }) - }) - - describe('walletSignMessage', () => { - test('should sign a message with a valid signer', async () => { - const data = 'Test message' - const signer = new Web3Account( - baseAccount, - web3Client.publicApi(), - chainId - ) - const modelSignedMessage = - '1TXucC8nai7BYpAnMPYrotVcKCZ5oxkfWHb2ykKj2tXmaGMDL1XTU5AbC6Z13RH3q59F8QtbzKq4gzBphGPWpiDonownxE' - - const signedMessage = await WalletClient.walletSignMessage(data, signer) - - expect(signedMessage).toHaveProperty('base58Encoded') - expect(typeof signedMessage.base58Encoded).toBe('string') - expect(signedMessage.base58Encoded).toEqual(modelSignedMessage) - }) - - test('should throw an error when no private key is available', async () => { - const data = 'Test message' - let baseAccountWithoutSecretKey: IAccount = { - ...baseAccount, - secretKey: null, - } - const signer = new Web3Account( - baseAccountWithoutSecretKey, - web3Client.publicApi(), - chainId - ) - - await expect( - WalletClient.walletSignMessage(data, signer) - ).rejects.toThrow('No private key to sign the message with') - }) - - test('should throw an error when no public key is available', async () => { - const data = 'Test message' - let baseAccountWithoutPublicKey: IAccount = { - ...baseAccount, - publicKey: null, - } - const signer = new Web3Account( - baseAccountWithoutPublicKey, - web3Client.publicApi(), - chainId - ) - - await expect( - WalletClient.walletSignMessage(data, signer) - ).rejects.toThrow('No public key to verify the signed message with') - }) - - test('should throw an error when signature length is invalid', async () => { - const data = 'Test message' - const signer = new Web3Account( - baseAccount, - web3Client.publicApi(), - chainId - ) - - // Create a spy on the 'sign' function to provide an incorrect mock implementation for this test - const signSpy = jest.spyOn(ed, 'sign') - signSpy.mockImplementation(() => Promise.resolve(Buffer.alloc(63))) // 63 instead of 64 - - await expect( - WalletClient.walletSignMessage(data, signer) - ).rejects.toThrow(/Invalid signature length. Expected 64, got/) - - // Restore the original 'sign' function after the test - signSpy.mockRestore() - }) - - test('should correctly process Buffer data', async () => { - const data = Buffer.from('Test message') - const modelSignedMessage = - '1TXucC8nai7BYpAnMPYrotVcKCZ5oxkfWHb2ykKj2tXmaGMDL1XTU5AbC6Z13RH3q59F8QtbzKq4gzBphGPWpiDonownxE' - const signer = new Web3Account( - baseAccount, - web3Client.publicApi(), - chainId - ) - - const signedMessage = await WalletClient.walletSignMessage(data, signer) - - expect(signedMessage).toHaveProperty('base58Encoded') - expect(typeof signedMessage.base58Encoded).toBe('string') - expect(signedMessage.base58Encoded).toEqual(modelSignedMessage) - }) - - test('should throw an error if the signature could not be verified with the public key', async () => { - const data = 'Test message' - const signer = new Web3Account( - baseAccount, - web3Client.publicApi(), - chainId - ) - - // Create a spy on the 'verify' function to provide an incorrect mock implementation for this test - const verifySpy = jest.spyOn(ed, 'verify') - verifySpy.mockImplementation(() => Promise.resolve(false)) // always return false - - await expect( - WalletClient.walletSignMessage(data, signer) - ).rejects.toThrow( - 'Signature could not be verified with public key. Please inspect' - ) - - // Restore the original 'verify' function after the test - verifySpy.mockRestore() - }) - }) - - describe('signMessage', () => { - test('should sign a message with a valid account', async () => { - const data = 'Test message' - const modelSignedMessage = - '1TXucC8nai7BYpAnMPYrotVcKCZ5oxkfWHb2ykKj2tXmaGMDL1XTU5AbC6Z13RH3q59F8QtbzKq4gzBphGPWpiDonownxE' - - const accountSignerAddress: string = baseAccount.address! - - const signedMessage = await web3Client - .wallet() - .signMessage(data, chainId, accountSignerAddress) - - expect(signedMessage).toHaveProperty('base58Encoded') - expect(typeof signedMessage.base58Encoded).toBe('string') - expect(signedMessage.base58Encoded).toEqual(modelSignedMessage) - }) - - test('should throw an error when the account is not found', async () => { - const data = 'Test message' - const nonExistentSignerAddress = 'nonExistentSignerAddress' - - await expect( - web3Client.wallet().signMessage(data, chainId, nonExistentSignerAddress) - ).rejects.toThrow( - `No signer account ${nonExistentSignerAddress} found in wallet` - ) - }) - - test('should correctly process Buffer data', async () => { - const data = Buffer.from('Test message') - const modelSignedMessage = - '1TXucC8nai7BYpAnMPYrotVcKCZ5oxkfWHb2ykKj2tXmaGMDL1XTU5AbC6Z13RH3q59F8QtbzKq4gzBphGPWpiDonownxE' - - const accountSignerAddress = baseAccount.address! - - const signedMessage = await web3Client - .wallet() - .signMessage(data, chainId, accountSignerAddress) - - expect(signedMessage).toHaveProperty('base58Encoded') - expect(typeof signedMessage.base58Encoded).toBe('string') - expect(signedMessage.base58Encoded).toEqual(modelSignedMessage) - }) - }) - - describe('walletGenerateNewAccount', () => { - test('should generate a new account', async () => { - const newAccount = await WalletClient.walletGenerateNewAccount() - // Check that the newAccount object has all necessary properties - expect(newAccount).toHaveProperty('address') - expect(newAccount).toHaveProperty('secretKey') - expect(newAccount).toHaveProperty('publicKey') - - // Check that the properties are of correct type - expect(typeof newAccount.address).toBe('string') - expect(typeof newAccount.secretKey).toBe('string') - expect(typeof newAccount.publicKey).toBe('string') - - // Check that the properties are not empty or null - expect(newAccount.address).not.toBeNull() - expect(newAccount.address).not.toBe('') - expect(newAccount.secretKey).not.toBeNull() - expect(newAccount.secretKey).not.toBe('') - expect(newAccount.publicKey).not.toBeNull() - expect(newAccount.publicKey).not.toBe('') - - // Check that keys and address have the correct length - expect(newAccount.address?.length).toBeGreaterThanOrEqual(50) - expect(newAccount.secretKey?.length).toBeGreaterThanOrEqual(50) - expect(newAccount.publicKey?.length).toBeGreaterThanOrEqual(50) - }) - - test('should generate unique accounts each time', async () => { - const newAccount1 = await WalletClient.walletGenerateNewAccount() - const newAccount2 = await WalletClient.walletGenerateNewAccount() - expect(newAccount1).not.toEqual(newAccount2) - }) - }) - - describe('getAccountFromSecretKey', () => { - test('should generate an account from a secret key', async () => { - const secretKey = 'S12syP5uCVEwaJwvXLqJyD1a2GqZjsup13UnhY6uzbtyu7ExXWZS' - const addressModel = - 'AU12KgrLq2vhMgi8aAwbxytiC4wXBDGgvTtqGTM5R7wEB9En8WBHB' - const publicKeyModel = - 'P12c2wsKxEyAhPC4ouNsgywzM41VsNSuwH9JdMbRt9bM8ZsMLPQA' - const accountFromSecretKey = - await WalletClient.getAccountFromSecretKey(secretKey) - // Check that the accountFromSecretKey object has all necessary properties - expect(accountFromSecretKey).toHaveProperty('address') - expect(accountFromSecretKey).toHaveProperty('secretKey') - expect(accountFromSecretKey).toHaveProperty('publicKey') - // Check that the secretKey matches the models - expect(accountFromSecretKey.address).toEqual(addressModel) - expect(accountFromSecretKey.publicKey).toEqual(publicKeyModel) - expect(accountFromSecretKey.secretKey).toEqual(secretKey) - }) - - test('should throw error if invalid secret key is provided', async () => { - const invalidSecretKey = 'invalidSecretKey' - await expect( - WalletClient.getAccountFromSecretKey(invalidSecretKey) - ).rejects.toThrow() - - const emptySecretKey = '' - await expect( - WalletClient.getAccountFromSecretKey(emptySecretKey) - ).rejects.toThrow() - - const nullSecretKey = null - await expect( - WalletClient.getAccountFromSecretKey(nullSecretKey as never) - ).rejects.toThrow() - }) - }) - - describe('verifySignature', () => { - test('should return true for a valid signature', async () => { - const message = 'Test message' - - const signerPublicKey = baseAccount.publicKey! - const validSignature: ISignature = { - publicKey: signerPublicKey, - base58Encoded: - '1TXucC8nai7BYpAnMPYrotVcKCZ5oxkfWHb2ykKj2tXmaGMDL1XTU5AbC6Z13RH3q59F8QtbzKq4gzBphGPWpiDonownxE', - } - const result = await web3Client - .wallet() - .verifySignature(message, validSignature) - - expect(result).toBe(true) - }) - - test('should return false for an invalid signature', async () => { - const consoleSpy = jest.spyOn(console, 'error') - consoleSpy.mockImplementation(() => null) - - const data = 'Test message' - - const signerPublicKey = baseAccount.publicKey! - const invalidSignature: ISignature = { - publicKey: signerPublicKey, - base58Encoded: - '2TXucC8nai7BYpAnMPYrotVcKCZ5oxkfWHb2ykKj2tXmaGMDL1XTU5AbC6Z13RH3q59F8QtbzKq4gzBphGPWpiDonownxE', // starts with 2 and not 1 - } - const result = await web3Client - .wallet() - .verifySignature(data, invalidSignature) - - expect(result).toBe(false) - - consoleSpy.mockRestore() - }) - }) - - describe('getAccountBalance', () => { - afterEach(() => { - jest.clearAllMocks() - }) - - test('should return balance for a valid address', async () => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ;(web3Client.wallet() as any).publicApiClient.getAddresses = jest - .fn() - .mockResolvedValue([mockAddressesInfo[2]]) - - const ACCOUNT_ADDRESS = - 'AU12WVAJoH2giHAjSxk9R1XK3YhpCw2QxmkCbtXxcr4T3XCUG55nr' - const expectedBalance = fromMAS(50) - - const balance = await web3Client - .wallet() - .getAccountBalance(ACCOUNT_ADDRESS!) - - expect(balance).not.toBeNull() - expect(balance).toHaveProperty('candidate') - expect(balance).toHaveProperty('final') - expect(balance?.candidate).toEqual(expectedBalance) - expect(balance?.final).toEqual(expectedBalance) - }) - - test('should return null for an invalid address', async () => { - const consoleSpy = jest.spyOn(console, 'error') - consoleSpy.mockImplementation(() => {}) - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ;(web3Client.wallet() as any).publicApiClient.getAddresses = jest - .fn() - .mockRejectedValue(new Error('Invalid address')) - const invalidAddress = 'invalid address' - - const balance = await web3Client - .wallet() - .getAccountBalance(invalidAddress) - - expect(balance).toBeNull() - - // Verify that console.error was called - expect(consoleSpy).toHaveBeenCalledWith( - 'Failed to get account balance:', - expect.any(Error) - ) - - consoleSpy.mockRestore() - }) - }) - - describe('addAccountsToWallet', () => { - test('should throw an error when the number of accounts exceeds the maximum limit', async () => { - const accounts = new Array(MAX_WALLET_ACCOUNTS + 1).fill(baseAccount) - await expect( - web3Client.wallet().addAccountsToWallet(accounts) - ).rejects.toThrow( - new RegExp( - `Maximum number of allowed wallet accounts exceeded ${MAX_WALLET_ACCOUNTS}` - ) - ) - }) - test('should throw an error when an account private key is missing', async () => { - const accountWithoutKey = { ...baseAccount, secretKey: null } - await expect( - web3Client.wallet().addAccountsToWallet([accountWithoutKey]) - ).rejects.toThrow(new Error('Missing account private key')) - }) - - test('should throw an error when the submitted public key does not match the private key', async () => { - const accountWithMismatchedPublicKey = { - ...baseAccount, - publicKey: 'mismatchedPublicKey', - } - await expect( - web3Client - .wallet() - .addAccountsToWallet([accountWithMismatchedPublicKey]) - ).rejects.toThrow( - new Error( - 'Public key does not correspond the the private key submitted' - ) - ) - }) - - test('should throw an error when the account address does not match the private key-derived address', async () => { - const accountWithMismatchedAddress = { - ...baseAccount, - address: 'mismatchedAddress', - } - await expect( - web3Client.wallet().addAccountsToWallet([accountWithMismatchedAddress]) - ).rejects.toThrow( - new Error('Account address not correspond the the address submitted') - ) - }) - - test('should not add duplicate accounts to the wallet', async () => { - await web3Client.wallet().addAccountsToWallet([baseAccount]) - await web3Client.wallet().addAccountsToWallet([baseAccount]) - const walletAccounts = web3Client.wallet().getWalletAccounts() - expect(walletAccounts.length).toBe(1) // only one unique account should be added - }) - - test('should correctly add accounts to the wallet', async () => { - const anotherAccount = await WalletClient.walletGenerateNewAccount() - const anotherAccountBis = await WalletClient.walletGenerateNewAccount() - const addedAccounts = await web3Client - .wallet() - .addAccountsToWallet([baseAccount, anotherAccount, anotherAccountBis]) - expect(addedAccounts.length).toBe(3) - expect(addedAccounts).toEqual( - expect.arrayContaining([ - expect.objectContaining({ address: baseAccount.address }), - expect.objectContaining({ - address: anotherAccount.address, - }), - expect.objectContaining({ - address: anotherAccountBis.address, - }), - ]) - ) - }) - }) - - describe('sendTransaction, buyRolls & sellRolls', () => { - let receiverAccount: IAccount - let mockTxData: ITransactionData - let mockRollsData: IRollsData - let mockAccount: Web3Account - - beforeAll(async () => { - receiverAccount = await WalletClient.walletGenerateNewAccount() - }) - - beforeEach(() => { - mockTxData = { - fee: 1n, - amount: 100n, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - recipientAddress: receiverAccount.address!, - } - mockRollsData = { - fee: 1n, - amount: 100n, - } - mockAccount = new Web3Account( - baseAccount, - web3Client.publicApi(), - chainId - ) - }) - - const operationTests = [ - { - operation: 'sendTransaction', - operationTypeId: OperationTypeId.Transaction, - data: () => mockTxData, - }, - { - operation: 'buyRolls', - operationTypeId: OperationTypeId.RollBuy, - data: () => mockRollsData, - }, - { - operation: 'sellRolls', - operationTypeId: OperationTypeId.RollSell, - data: () => mockRollsData, - }, - ] - - describe.each(operationTests)( - 'operation: %s', - ({ operation, operationTypeId, data }) => { - beforeEach(async () => { - const spyGetNodeStatus = jest.spyOn( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (web3Client.wallet() as any).publicApiClient, - 'getNodeStatus' - ) - spyGetNodeStatus.mockReturnValue(mockNodeStatusInfo) - - jest - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .spyOn(web3Client.wallet() as any, 'sendJsonRPCRequest') - .mockResolvedValue(mockOpIds) - jest - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .spyOn(mockAccount as any, 'sendJsonRPCRequest') - .mockResolvedValue(mockOpIds) - web3Client.wallet().setBaseAccount(mockAccount) - }) - - test('should throw an error if no sender account is available for the transaction', async () => { - jest - .spyOn(web3Client.wallet(), 'getBaseAccount') - .mockReturnValue(null) - - await expect(web3Client.wallet()[operation](data())).rejects.toThrow( - 'No tx sender available' - ) - }) - - test('should call compactBytesForOperation with correct arguments', async () => { - const spy = jest.spyOn( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - mockAccount as any, - 'compactBytesForOperation' - ) - - await web3Client.wallet()[operation](data()) - - expect(spy).toHaveBeenCalledWith( - data(), - operationTypeId, - expect.any(Number) // expiryPeriod - ) - }) - - test('should call sign with correct arguments', async () => { - const spy = jest.spyOn(mockAccount, 'sign') - - await web3Client.wallet()[operation](data()) - - expect(spy).toHaveBeenCalledWith( - expect.any(Buffer) // Buffer.concat([bytesPublicKey, bytesCompact]) - ) - }) - - test('should call sendJsonRPCRequest with correct arguments', async () => { - const spy = jest.spyOn( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - mockAccount as any, - 'sendJsonRPCRequest' - ) - - await web3Client.wallet()[operation](data()) - - expect(spy).toHaveBeenCalledWith( - JSON_RPC_REQUEST_METHOD.SEND_OPERATIONS, - expect.any(Array) // [[data]] - ) - }) - - test('should return an array of operation ids', async () => { - jest - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .spyOn(mockAccount as any, 'sendJsonRPCRequest') - .mockResolvedValue(mockOpIds) - - const opIds = await web3Client.wallet()[operation](data()) - - expect(opIds).toEqual([mockOpIds[0]]) - }) - } - ) - - describe('sendTransaction', () => { - test('should throw an error if no recipient address is a contract address starting by AS', async () => { - mockTxData.recipientAddress = - 'AS12KgrLq2vhMgi8aAwbxytiC4wXBDGgvTtqGTM5R7wEB9En8WBHB' - - await expect( - web3Client.wallet().sendTransaction(mockTxData) - ).rejects.toThrow() - }) - }) - }) -}) diff --git a/packages/massa-web3/tsconfig.json b/packages/massa-web3/tsconfig.json deleted file mode 100644 index 0acccb47..00000000 --- a/packages/massa-web3/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./dist" - }, - "include": [ - "./src/**/*.ts" - ], - "exclude": [ - "node_modules", - "**/*.spec.ts" - ] -} \ No newline at end of file diff --git a/packages/massa-web3/typedoc.json b/packages/massa-web3/typedoc.json deleted file mode 100644 index d36f0d5a..00000000 --- a/packages/massa-web3/typedoc.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "navigation": { - "includeGroups": true - }, - "sidebarLinks": { - "Wallet operations": "https://web3.docs.massa.net/classes/WalletClient.html", - "Smart contracts operations": "https://web3.docs.massa.net/classes/SmartContractsClient.html", - "Events": "https://web3.docs.massa.net/classes/EventPoller.html", - "Public API": "https://web3.docs.massa.net/classes/PublicApiClient.html", - "Private API": "https://web3.docs.massa.net/classes/PrivateApiClient.html" - }, - "navigationLinks": { - "Main documentation": "https://docs.massa.net/" - }, - "entryPoints": ["src"] -} \ No newline at end of file diff --git a/packages/web3-utils/.gitignore b/packages/web3-utils/.gitignore deleted file mode 100644 index dcb9d61c..00000000 --- a/packages/web3-utils/.gitignore +++ /dev/null @@ -1,76 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://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/ - -# TypeScript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env - -# next.js build output -.next - -# build folder -dist/ - -# bundle files -bundle.* - -# docs files -docs - -#.env files -.env - -# Misc -.DS_Store diff --git a/packages/web3-utils/.npmignore b/packages/web3-utils/.npmignore deleted file mode 100644 index c5383da0..00000000 --- a/packages/web3-utils/.npmignore +++ /dev/null @@ -1,6 +0,0 @@ -src/ -test/ -tsconfig.json -tslint.json -.npmrc -.vs/ diff --git a/packages/web3-utils/README.md b/packages/web3-utils/README.md deleted file mode 100644 index 6461f5d1..00000000 --- a/packages/web3-utils/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# web3-utils -Web3 utils class and tools that are useful to build more complex projects on the frontend. diff --git a/packages/web3-utils/jest.config.ts b/packages/web3-utils/jest.config.ts deleted file mode 100644 index 8fde534b..00000000 --- a/packages/web3-utils/jest.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import baseConfig from '../../jest.config' -import type { Config } from '@jest/types' - -const config: Config.InitialOptions = { - ...baseConfig, - rootDir: '../..', - displayName: 'web3-utils', - testMatch: ['/packages/web3-utils/test/**/*.(spec|test).ts?(x)'], -} - -export default config diff --git a/packages/web3-utils/package.json b/packages/web3-utils/package.json deleted file mode 100644 index 59abd8a2..00000000 --- a/packages/web3-utils/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "@massalabs/web3-utils", - "version": "1.4.11", - "description": "Set of utilities shared between multiple @massalabs packages", - "main": "dist/cmd/index.js", - "module": "dist/esm/index.js", - "types": "dist/esm/index.d.ts", - "scripts": { - "clean-dist": "rimraf dist/*", - "build-esm": "tsc --project tsconfig.esm.json", - "build-commonjs": "tsc --project tsconfig.commonjs.json", - "build": "npm-run-all clean-dist build-*", - "test": "jest --passWithNoTests", - "test:all": "npm run test", - "test:cov": "jest --coverage --silent --passWithNoTests", - "check-types": "tsc --noEmit", - "lint": "eslint .", - "lint:fix": "eslint . --fix", - "prettier": "prettier --check .", - "prettier:fix": "prettier --write .", - "fmt": "npm run prettier:fix && npm run lint:fix", - "fmt:check": "npm run prettier && npm run lint" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/massalabs/web3-utils.git" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/massalabs/web3-utils/issues" - }, - "homepage": "https://github.com/massalabs/massa-web3", - "dependencies": { - "bignumber.js": "^9.1.2", - "buffer": "^6.0.3", - "events": "^3.3.0", - "string_decoder": "^1.3.0" - }, - "devDependencies": { - "@types/jest": "^29.5.5", - "@typescript-eslint/eslint-plugin": "^5.52.0", - "@typescript-eslint/parser": "^5.52.0", - "jest": "^29.5.0", - "jest-environment-jsdom": "^29.5.0", - "npm-run-all": "^4.1.5", - "rimraf": "^5.0.1", - "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2", - "ts-node": "^10.9.1", - "tslib": "^2.6.1", - "typedoc": "^0.23.25", - "typescript": "^4.9.5", - "util": "^0.12.5" - } -} diff --git a/packages/web3-utils/powered-by.md b/packages/web3-utils/powered-by.md deleted file mode 100644 index 242e20d9..00000000 --- a/packages/web3-utils/powered-by.md +++ /dev/null @@ -1,227 +0,0 @@ -# Dependencies Report - -The following is a list of all the dependencies for this package: -## [buffer](git://github.com/feross/buffer.git) - -**License:** MIT - perpetual - -**Used version:** 6.0.3 - -**Many thanks to:** Feross Aboukhadijeh feross@feross.org https://feross.org - -## [events](git://github.com/Gozala/events.git) - -**License:** MIT - perpetual - -**Used version:** 3.3.0 - -**Many thanks to:** [Irakli Gozalishvili](rfobic@gmail.com> (http://jeditoolkit.com) - -## [string_decoder](git://github.com/nodejs/string_decoder.git) - -**License:** MIT - perpetual - -**Used version:** 1.3.0 - -**Many thanks to:** n/a - -## [@massalabs/eslint-config](git+https://github.com/massalabs/eslint-config.git) - -**License:** ISC - perpetual - -**Used version:** 0.0.10 - -**Many thanks to:** MassaLabs - -## [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped.git) - -**License:** MIT - perpetual - -**Used version:** 29.5.5 - -**Many thanks to:** n/a - -## [@typescript-eslint/eslint-plugin](git+https://github.com/typescript-eslint/typescript-eslint.git) - -**License:** MIT - perpetual - -**Used version:** 5.62.0 - -**Many thanks to:** n/a - -## [@typescript-eslint/parser](git+https://github.com/typescript-eslint/typescript-eslint.git) - -**License:** BSD-2-Clause - perpetual - -**Used version:** 5.62.0 - -**Many thanks to:** n/a - -## [eslint-config-airbnb-base](git+https://github.com/airbnb/javascript.git) - -**License:** MIT - perpetual - -**Used version:** 15.0.0 - -**Many thanks to:** Jake Teton-Landis (https://twitter.com/@jitl) - -## [eslint-config-standard](git://github.com/standard/eslint-config-standard.git) - -**License:** MIT - perpetual - -**Used version:** 17.1.0 - -**Many thanks to:** Feross Aboukhadijeh feross@feross.org https://feross.org - -## [eslint-plugin-import](git+https://github.com/import-js/eslint-plugin-import.git) - -**License:** MIT - perpetual - -**Used version:** 2.28.1 - -**Many thanks to:** [Ben Mosher](me@benmosher.com) - -## [eslint-plugin-jsdoc](git+https://github.com/gajus/eslint-plugin-jsdoc.git) - -**License:** BSD-3-Clause - perpetual - -**Used version:** 40.3.0 - -**Many thanks to:** Gajus Kuizinas gajus@gajus.com http://gajus.com - -## [eslint-plugin-node](git+https://github.com/mysticatea/eslint-plugin-node.git) - -**License:** MIT - perpetual - -**Used version:** 11.1.0 - -**Many thanks to:** Toru Nagashima - -## [eslint-plugin-promise](git+https://github.com/eslint-community/eslint-plugin-promise.git) - -**License:** ISC - perpetual - -**Used version:** 6.1.1 - -**Many thanks to:** [jden](jason@denizac.org) - -## [eslint](git+https://github.com/eslint/eslint.git) - -**License:** MIT - perpetual - -**Used version:** 8.51.0 - -**Many thanks to:** [Nicholas C. Zakas](nicholas+npm@nczconsulting.com) - -## [jest-environment-jsdom](git+https://github.com/jestjs/jest.git) - -**License:** MIT - perpetual - -**Used version:** 29.7.0 - -**Many thanks to:** n/a - -## [jest](git+https://github.com/jestjs/jest.git) - -**License:** MIT - perpetual - -**Used version:** 29.7.0 - -**Many thanks to:** n/a - -## [npm-run-all](git+https://github.com/mysticatea/npm-run-all.git) - -**License:** MIT - perpetual - -**Used version:** 4.1.5 - -**Many thanks to:** Toru Nagashima - -## [prettier-eslint](git+https://github.com/prettier/prettier-eslint.git) - -**License:** MIT - perpetual - -**Used version:** 15.0.1 - -**Many thanks to:** [Kent C. Dodds](kent@doddsfamily.us> (http://kentcdodds.com/) - -## [rimraf](git://github.com/isaacs/rimraf.git) - -**License:** ISC - perpetual - -**Used version:** 5.0.5 - -**Many thanks to:** [Isaac Z. Schlueter](i@izs.me> (http://blog.izs.me/) - -## [ts-jest](git+https://github.com/kulshekhar/ts-jest.git) - -**License:** MIT - perpetual - -**Used version:** 29.1.1 - -**Many thanks to:** [Kulshekhar Kabra](kulshekhar@users.noreply.github.com> (https://github.com/kulshekhar) - -## [ts-loader](git+https://github.com/TypeStrong/ts-loader.git) - -**License:** MIT - perpetual - -**Used version:** 9.5.0 - -**Many thanks to:** [John Reilly](johnny_reilly@hotmail.com> (https://johnnyreilly.com) - -## [ts-node](git://github.com/TypeStrong/ts-node.git) - -**License:** MIT - perpetual - -**Used version:** 10.9.1 - -**Many thanks to:** Blake Embrey hello@blakeembrey.com http://blakeembrey.me - -## [tslib](git+https://github.com/Microsoft/tslib.git) - -**License:** 0BSD - perpetual - -**Used version:** 2.6.2 - -**Many thanks to:** Microsoft Corp. - -## [typedoc](git://github.com/TypeStrong/TypeDoc.git) - -**License:** Apache-2.0 - perpetual - -**Used version:** 0.23.28 - -**Many thanks to:** n/a - -## [typescript](git+https://github.com/Microsoft/TypeScript.git) - -**License:** Apache-2.0 - perpetual - -**Used version:** 4.9.5 - -**Many thanks to:** Microsoft Corp. - -## [util](git://github.com/browserify/node-util.git) - -**License:** MIT - perpetual - -**Used version:** 0.12.5 - -**Many thanks to:** Joyent http://www.joyent.com - -## [webpack-cli](git+https://github.com/webpack/webpack-cli.git) - -**License:** MIT - perpetual - -**Used version:** 5.1.4 - -**Many thanks to:** n/a - -## [webpack](git+https://github.com/webpack/webpack.git) - -**License:** MIT - perpetual - -**Used version:** 5.88.2 - -**Many thanks to:** Tobias Koppers @sokra - diff --git a/packages/web3-utils/src/constants.ts b/packages/web3-utils/src/constants.ts deleted file mode 100644 index 3fec4f6b..00000000 --- a/packages/web3-utils/src/constants.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { fromMAS } from './converters' - -/* -------------------------------------------------------------------------- */ -/* KEYS */ -/* -------------------------------------------------------------------------- */ -export const SECRET_KEY_PREFIX = 'S' -export const PUBLIC_KEY_PREFIX = 'P' -export const ADDRESS_USER_PREFIX = 'AU' -export const ADDRESS_CONTRACT_PREFIX = 'AS' -export const ADDRESS_PREFIX_LENGTH = 2 -export const KEYS_VERSION_NUMBER = 0 - -/* -------------------------------------------------------------------------- */ -/* STORAGE COST */ -/* -------------------------------------------------------------------------- */ -export const STORAGE_BYTE_COST = fromMAS(0.0001) -export const NEW_LEDGER_ENTRY_COST = STORAGE_BYTE_COST * 4n -export const BASE_ACCOUNT_CREATION_COST = fromMAS(0.001) - -/* -------------------------------------------------------------------------- */ -/* GAS LIMIT */ -/* -------------------------------------------------------------------------- */ -export const MAX_GAS_EXECUTE_SC = 3_980_167_295n -export const MAX_GAS_DEPLOYMENT = MAX_GAS_EXECUTE_SC -export const MAX_GAS_CALL = 4_294_167_295n -export const MIN_GAS_CALL = 2100000n - -/* -------------------------------------------------------------------------- */ -/* NETWORK */ -/* -------------------------------------------------------------------------- */ -export const MAINNET = 'MainNet' -export const BUILDNET = 'BuildNet' -export const SECURENET = 'SecureNet' -export const LABNET = 'LabNet' -export const SANDBOX = 'Sandbox' - -export const MAINNET_CHAIN_ID = 77658377n -export const BUILDNET_CHAIN_ID = 77658366n -export const SECURENET_CHAIN_ID = 77658383n -export const LABNET_CHAIN_ID = 77658376n -export const SANDBOX_CHAIN_ID = 77n - -// Adjusted: Use the values of the constants as keys -export const CHAIN_ID_TO_NETWORK_NAME = { - [MAINNET_CHAIN_ID.toString()]: MAINNET, - [BUILDNET_CHAIN_ID.toString()]: BUILDNET, - [SECURENET_CHAIN_ID.toString()]: SECURENET, - [LABNET_CHAIN_ID.toString()]: LABNET, - [SANDBOX_CHAIN_ID.toString()]: SANDBOX, -} as const // type is inferred as the specific, unchangeable structure - -// Define ChainId type as the keys of CHAIN_ID_TO_NETWORK_NAME -export type ChainId = keyof typeof CHAIN_ID_TO_NETWORK_NAME - -// NETWORK_NAME_TO_CHAIN_ID mapping remains the same -export const CHAIN_ID = { - [MAINNET]: MAINNET_CHAIN_ID, - [BUILDNET]: BUILDNET_CHAIN_ID, - [SECURENET]: SECURENET_CHAIN_ID, - [LABNET]: LABNET_CHAIN_ID, - [SANDBOX]: SANDBOX_CHAIN_ID, -} as const // type is inferred as the specific, unchangeable structure - -// Define NetworkName type as the keys of NETWORK_NAME_TO_CHAIN_ID -export type NetworkName = keyof typeof CHAIN_ID - -export enum DefaultProviderUrls { - MAINNET = 'https://mainnet.massa.net/api/v2', - TESTNET = 'https://test.massa.net/api/v2', - BUILDNET = 'https://buildnet.massa.net/api/v2', - LABNET = 'https://labnet.massa.net/api/v2', - LOCALNET = 'http://127.0.0.1', -} - -export const CHAIN_ID_RPC_URL_MAP = { - [MAINNET_CHAIN_ID.toString()]: DefaultProviderUrls.MAINNET, - [BUILDNET_CHAIN_ID.toString()]: DefaultProviderUrls.BUILDNET, - [SANDBOX_CHAIN_ID.toString()]: DefaultProviderUrls.LOCALNET, -} as const // type is inferred as the specific, unchangeable structure - -export const CHAIN_ID_DNS_ADDRESS_MAP = { - [MAINNET_CHAIN_ID.toString()]: - 'AS1q5hUfxLXNXLKsYQVXZLK7MPUZcWaNZZsK7e9QzqhGdAgLpUGT', - [BUILDNET_CHAIN_ID.toString()]: - 'AS12qKAVjU1nr66JSkQ6N4Lqu4iwuVc6rAbRTrxFoynPrPdP1sj3G', -} as const // type is inferred as the specific, unchangeable structure diff --git a/packages/web3-utils/src/converters.ts b/packages/web3-utils/src/converters.ts deleted file mode 100644 index e7c1c675..00000000 --- a/packages/web3-utils/src/converters.ts +++ /dev/null @@ -1,78 +0,0 @@ -import BigNumber from 'bignumber.js' - -export const MASSA_SCALING_FACTOR = 9 - -/** - * Convert any value expressed in Massa back to nanoMassa (the smallest unit of Massa). - * This function takes an input value in Massa and returns the equivalent value in nanoMassa. - * - * @remarks - * Massa is a unit of currency and nanoMassa is a sub-unit, where 1 Massa equals 10^9 nanoMassa. - * This function uses the BigNumber library to perform calculations with arbitrary precision. - * - * @param amountInMassa - The amount to convert, expressed in Massa. Can be a number, string, BigNumber, or bigint. - * - * @returns The amount expressed in nanoMassa, as a bigint. - * - * @example - * ``` - * const nanoMassa = fromMAS(1); // returns 1000000000n - * ``` - */ -export const fromMAS = ( - amountInMassa: number | string | BigNumber | bigint -): bigint => { - const amount = new BigNumber(amountInMassa.toString()) - const scaleFactor = new BigNumber(10).pow(new BigNumber(MASSA_SCALING_FACTOR)) - const amountScaled = amount.times(scaleFactor) - return BigInt(amountScaled.toFixed(0)) -} - -/** - * Convert any value expressed in nanoMassa back to Massa. - * This function takes an input value in nanoMassa and returns the equivalent value in Massa. - * - * @remarks - * Massa is a unit of currency and nanoMassa is a sub-unit, where 1 Massa equals 10^9 nanoMassa. - * This function uses the BigNumber library to perform calculations with arbitrary precision. - * - * @param amountInNanoMassa - The amount to convert, expressed in nanoMassa. Can be a number, string, BigNumber, or bigint. - * - * @returns The amount expressed in Massa, as a BigNumber. - * - * @example - * ``` - * const massa = toMAS(1000000000n); // returns new BigNumber(1) - * ``` - */ -export const toMAS = ( - amountInNanoMassa: number | string | BigNumber | bigint -): BigNumber => { - const amount = new BigNumber(amountInNanoMassa.toString()) - const scaleFactor = new BigNumber(10).pow(new BigNumber(MASSA_SCALING_FACTOR)) - const amountScaled = amount.dividedBy(scaleFactor) - return new BigNumber(amountScaled.toFixed(MASSA_SCALING_FACTOR)) -} - -/** - * MassaUnits contains constants representing different magnitudes of the Massa currency. - * This object provides useful constants for working with Massa and its sub-units. - * - * @remarks - * MassaUnits contains the following properties: - * - oneMassa: Represents 1 Massa in nanoMassa (10^9 nanoMassa). - * - mMassa: Represents 1 milliMassa in nanoMassa (10^6 nanoMassa). - * - uMassa: Represents 1 microMassa in nanoMassa (10^3 nanoMassa). - * - * @example - * ``` - * const oneMassaInNano = MassaUnits.oneMassa; // returns 1000000000n - * const oneMilliMassaInNano = MassaUnits.mMassa; // returns 1000000n - * const oneMicroMassaInNano = MassaUnits.uMassa; // returns 1000n - * ``` - */ -export const MassaUnits = { - oneMassa: BigInt(10 ** 9), - mMassa: BigInt(10 ** 6), - uMassa: BigInt(10 ** 3), -} diff --git a/packages/web3-utils/src/index.ts b/packages/web3-utils/src/index.ts deleted file mode 100644 index a80be418..00000000 --- a/packages/web3-utils/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './arguments' -export * from './serializers' -export * from './interfaces' -export * from './constants' -export * from './converters' diff --git a/packages/web3-utils/src/interfaces/IContractReadOperationData.ts b/packages/web3-utils/src/interfaces/IContractReadOperationData.ts deleted file mode 100644 index b771e229..00000000 --- a/packages/web3-utils/src/interfaces/IContractReadOperationData.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { IEvent } from './IEvent' -import { IReadOperationResult } from './IReadOperationResult' -import { ISlot } from './ISlot' - -/** - * Represents the inputs of a read-only operation on a deployed contract. - * - * @see executed_at of type `ISlot` represents the time slot when the read operation was executed. - * @see result of type `IReadOperationResult` represents the result of the read operation. - * @see output_events of type `Array` represents any events that were emitted during the execution of the read operation. - * @see gas_cost of type `number` represents the amount of gas that was consumed by the read operation. - */ -export interface IContractReadOperationData { - executed_at: ISlot - result: IReadOperationResult - output_events: Array - gas_cost: number -} diff --git a/packages/web3-utils/src/interfaces/IContractReadOperationResponse.ts b/packages/web3-utils/src/interfaces/IContractReadOperationResponse.ts deleted file mode 100644 index 6b5eda02..00000000 --- a/packages/web3-utils/src/interfaces/IContractReadOperationResponse.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { IContractReadOperationData } from './IContractReadOperationData' - -/** - * Represents the output of a smart contract non persistent execution. - * (this operation did not modify the blockchain state) - * - * @see returnValue of type `Uint8Array` represents the return value of the read operation. - * @see info of type `IContractReadOperationData` represents the inputs of the read operation. - */ -export interface IContractReadOperationResponse { - returnValue: Uint8Array - info: IContractReadOperationData -} diff --git a/packages/web3-utils/src/interfaces/IEvent.ts b/packages/web3-utils/src/interfaces/IEvent.ts deleted file mode 100644 index fe147c74..00000000 --- a/packages/web3-utils/src/interfaces/IEvent.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { ISlot } from './ISlot' - -/** - * The IEvent interface represents an event emitted by a smart contract. - * - * @see id represents the identifier of the event (optional). - * @see data represents the data of the event (arbitrary JSON format). - * @see context represents the context of the event. It contains : - * @see context.slot: the slot at which the event was generated. - * @see context.block: the block at which the event was generated (null if unknown). - * @see context.read_only: whether the event was generated during a read-only call (boolean). - * @see context.call_stack: represents the call stack of the contract addresses, with the most recent at the end. - * @see context.index_in_slot: the index of the event in the slot. - * @see context.origin_operation_id: the operation id of the operation that generated the event (null if unknown). - * @see context.is_final: whether the event is final (boolean). - * @see context.is_error: whether the event was generated in a failed execution (boolean). - */ -export interface IEvent { - id?: string // event id - data: string // Arbitrary json string generated by the smart contract - context: { - slot: ISlot - block: null | string // block id, - read_only: boolean // wether the event was generated during read only call - call_stack: string[] // Addresses (most recent at the end) - index_in_slot: number - origin_operation_id: null | string // operation id - is_final: boolean // Whether the event is final - is_error: boolean // Whether the event was generated in a failed executed or not - } -} diff --git a/packages/web3-utils/src/interfaces/IReadOperationResult.ts b/packages/web3-utils/src/interfaces/IReadOperationResult.ts deleted file mode 100644 index 92024c5d..00000000 --- a/packages/web3-utils/src/interfaces/IReadOperationResult.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Represents the result of a read operation on the blockchain. - * - * @see Ok - Included in case of success. The result of the execution - * @see Error - Included in case of error. The error message - */ -export interface IReadOperationResult { - Ok?: Uint8Array - Error?: string -} diff --git a/packages/web3-utils/src/interfaces/ISlot.ts b/packages/web3-utils/src/interfaces/ISlot.ts deleted file mode 100644 index 3a331255..00000000 --- a/packages/web3-utils/src/interfaces/ISlot.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Represents a slot - * - * @see period - period of the slot - * @see thread - thread of the slot - */ -export interface ISlot { - period: number // will use by default ISlot{period: 0, thread: 0} - thread: number // will use by default ISlot{period: 0, thread: 0} -} diff --git a/packages/web3-utils/src/interfaces/index.ts b/packages/web3-utils/src/interfaces/index.ts deleted file mode 100644 index 98b0082a..00000000 --- a/packages/web3-utils/src/interfaces/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { ISlot } from './ISlot' -export { ISerializable, IDeserializedResult } from './ISerializable' -export { IReadOperationResult } from './IReadOperationResult' -export { IContractReadOperationData } from './IContractReadOperationData' -export { IContractReadOperationResponse } from './IContractReadOperationResponse' -export { IEvent } from './IEvent' diff --git a/packages/web3-utils/src/serializers/bignum.ts b/packages/web3-utils/src/serializers/bignum.ts deleted file mode 100644 index 2c1d25ca..00000000 --- a/packages/web3-utils/src/serializers/bignum.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { U64_MAX } from './numbers' - -/** - * The maximum value for an unsigned 128-bit integer (u128) represented as a BigInt. - */ -export const U128_MAX = BigInt('0xffffffffffffffffffffffffffffffff') - -/** - * The maximum value for an unsigned 256-bit integer (u256) represented as a BigInt. - */ -export const U256_MAX = BigInt( - '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' -) - -/** - * The maximum value for a signed 128-bit integer (i128) represented as a BigInt. - */ -export const I128_MAX = BigInt('0x7fffffffffffffffffffffffffffffff') - -/** - * The minimum value for a signed 128-bit integer (i128) represented as a BigInt. - */ -export const I128_MIN = BigInt('-170141183460469231731687303715884105728') - -function generic128ToBytes(val: bigint): Uint8Array { - const upper = val >> 64n - const lower = (val << 64n) >> 64n - - const buffer = new ArrayBuffer(16) - const view = new DataView(buffer) - - view.setBigUint64(0, lower, true) - view.setBigUint64(8, upper, true) - - return new Uint8Array(view.buffer) -} - -/** - * Converts an unsigned 128-bit integer (u128) BigInt into a Uint8Array. - * - * @param val - The BigInt to convert - * - * @throws Will throw an error if the input value is not within the valid u128 range (0 to 340282366920938463463374607431768211455) - * - * @returns A Uint8Array containing the serialized u128 BigInt value - * - */ -export function u128ToBytes(val: bigint): Uint8Array { - if (val < 0 || val > U128_MAX) { - throw new Error(`Unable to serialize invalid Uint128 value ${val}`) - } - - return generic128ToBytes(val) -} - -/** - * Converts a Uint8Array into an unsigned 128-bit integer (u128) BigInt. - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the u128 value (default: 0) - * - * @returns The deserialized u128BigInt value - * - */ -export function bytesToU128(arr: Uint8Array, offset = 0): bigint { - const view = new DataView(arr.buffer, offset) - - const lower = view.getBigUint64(0, true) // Lower 64 bits - const upper = view.getBigUint64(8, true) // Upper 64 bits - - return (upper << 64n) | lower -} - -/** - * Converts a signed 128-bit integer (i128) BigInt into a Uint8Array. - * - * @param val - The BigInt to convert - * - * @throws Will throw an error if the input value is not within the valid u128 range (0 to 340282366920938463463374607431768211455) - * - * @returns A Uint8Array containing the serialized u128 BigInt value - * - */ -export function i128ToBytes(val: bigint): Uint8Array { - if (val < I128_MIN || val > I128_MAX) { - throw new Error(`Unable to serialize invalid Int128 value ${val}`) - } - return generic128ToBytes(val) -} - -/** - * Converts a Uint8Array into a signed 128-bit integer (i128) BigInt. - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the i128 value (default: 0) - * - * @returns The deserialized i128 BigInt value - * - */ -export function bytesToI128(arr: Uint8Array, offset = 0): bigint { - const view = new DataView(arr.buffer, offset) - - const lower = view.getBigUint64(0, true) // Lower 64 bits - const upper = view.getBigInt64(8, true) // Upper 64 bits - - return (upper << 64n) | lower -} - -/** - * Converts an unsigned 256-bit integer (u256) BigInt into a Uint8Array. - * - * @param val - The BigInt to convert - * - * @throws Will throw an error if the input value is not within the valid u256 range (0 to 340282366920938463463374607431768211455) - * - * @returns A Uint8Array containing the serialized u256 BigInt value - * - */ -export function u256ToBytes(val: bigint): Uint8Array { - if (val < 0 || val > U256_MAX) { - throw new Error(`Unable to serialize invalid Uint256 value ${val}`) - } - - const p0 = val & U64_MAX - const p1 = (val >> 64n) & U64_MAX - const p2 = (val >> 128n) & U64_MAX - const p3 = (val >> 192n) & U64_MAX - - const buffer = new ArrayBuffer(32) - const view = new DataView(buffer) - - view.setBigUint64(0, p0, true) - view.setBigUint64(8, p1, true) - view.setBigUint64(16, p2, true) - view.setBigUint64(24, p3, true) - - return new Uint8Array(view.buffer) -} - -/** - * Converts a Uint8Array into an unsigned 256-bit integer (u256) BigInt. - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the u256 value (default: 0) - * - * @returns The deserialized u256BigInt value - * - */ -export function bytesToU256(arr: Uint8Array, offset = 0): bigint { - const view = new DataView(arr.buffer, offset) - - const p0 = view.getBigUint64(0, true) - const p1 = view.getBigUint64(8, true) - const p2 = view.getBigUint64(16, true) - const p3 = view.getBigUint64(24, true) - - return (p3 << 192n) | (p2 << 128n) | (p1 << 64n) | p0 -} diff --git a/packages/web3-utils/src/serializers/numbers.ts b/packages/web3-utils/src/serializers/numbers.ts deleted file mode 100644 index 6c57fbf9..00000000 --- a/packages/web3-utils/src/serializers/numbers.ts +++ /dev/null @@ -1,346 +0,0 @@ -/** - * This module aim's to provide number variable types serialization and conversion helper functions. - */ - -/** - * The maximum value for an unsigned 8-bit integer (u8). - */ -const U8_MAX = 0xff - -/** - * The maximum value for an unsigned 16-bit integer (u16). - */ -const U16_MAX = 0xffff - -/** - * The maximum value for an unsigned 32-bit integer (u32). - */ -const U32_MAX = 0xffffffff - -/** - * The maximum value for an unsigned 64-bit integer (u64) represented as a BigInt. - */ -export const U64_MAX = BigInt('0xffffffffffffffff') - -/** - * The minimum value for a signed 16-bit integer (i16). - */ -const I16_MIN = -32768 - -/** - * The maximum value for a signed 16-bit integer (i16). - */ -const I16_MAX = 32767 - -/** - * The minimum value for a signed 32-bit integer (i32). - */ -const I32_MIN = -0x80000000 - -/** - * The maximum value for a signed 32-bit integer (i32). - */ -const I32_MAX = 0x7fffffff - -/** - * The minimum value for a signed 64-bit integer (i64) represented as a BigInt. - */ -const I64_MIN = BigInt('-9223372036854775808') - -/** - * The maximum value for a signed 64-bit integer (i64) represented as a BigInt. - */ -export const I64_MAX = BigInt('0x7fffffffffffffff') - -/** - * Converts an unsigned 8-bit integer (u8) into a Uint8Array. - * - * @param val - The number to convert - * - * @throws Will throw an error if the input value is not within the valid u8 range (0 to 255) - * - * @returns A Uint8Array containing the serialized u8 value - * - */ -export function u8toByte(val: number): Uint8Array { - if (val < 0 || val > U8_MAX) { - throw new Error(`Unable to serialize invalid Uint8 value ${val}`) - } - return new Uint8Array([val]) -} - -/** - * Converts a Uint8Array into an unsigned 8-bit integer (u8). - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the u8 value (default: 0) - * - * @returns The deserialized u8 value - * - */ -export function byteToU8(arr: Uint8Array, offset = 0): number { - return arr[offset] -} - -/** - * Converts an unsigned 16-bit integer (u16) into a Uint8Array. - * - * @param val - The number to convert - * - * @throws Will throw an error if the input value is not within the valid u16 range - * - * @returns A Uint8Array containing the serialized u16 value - * - */ -export function u16toByte(val: number): Uint8Array { - if (val < 0 || val > U16_MAX) { - throw new Error(`Unable to serialize invalid Uint16 value ${val}`) - } - - const buffer = new ArrayBuffer(2) - const view = new DataView(buffer) - view.setUint16(0, val, true) - return new Uint8Array(view.buffer) -} - -/** - * Converts a Uint8Array into an unsigned 16-bit integer (u16). - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the u16 value (default: 0) - * - * @returns The deserialized u16 value - * - */ -export function byteToU16(arr: Uint8Array, offset = 0): number { - const view = new DataView(arr.buffer) - return view.getUint16(offset, true) -} - -/** - * Converts an unsigned 32-bit integer (u32) into a Uint8Array. - * - * @param val - The number to convert - * - * @throws Will throw an error if the input value is not within the valid u32 range (0 to 4,294,967,295) - * - * @returns A Uint8Array containing the serialized u32 value - * - */ -export function u32ToBytes(val: number): Uint8Array { - if (val < 0 || val > U32_MAX) { - throw new Error(`Unable to serialize invalid Uint32 value ${val}`) - } - const buffer = new ArrayBuffer(4) - const view = new DataView(buffer) - view.setUint32(0, val, true) - return new Uint8Array(view.buffer) -} - -/** - * Converts a Uint8Array into an unsigned 32-bit integer (u32). - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the u32 value (default: 0) - * - * @returns The deserialized u32 value - * - */ -export function bytesToU32(arr: Uint8Array, offset = 0): number { - const view = new DataView(arr.buffer) - return view.getUint32(offset, true) -} - -/** - * Converts an unsigned 64-bit integer (u64) BigInt into a Uint8Array. - * - * @param val - The BigInt to convert - * - * @throws Will throw an error if the input value is not within the valid u64 range (0 to 18,446,744,073,709,551,615) - * - * @returns A Uint8Array containing the serialized u64 BigInt value - * - */ -export function u64ToBytes(val: bigint): Uint8Array { - if (val < 0 || val > U64_MAX) { - throw new Error(`Unable to serialize invalid Uint64 value ${val}`) - } - const buffer = new ArrayBuffer(8) - const view = new DataView(buffer) - view.setBigUint64(0, val, true) - return new Uint8Array(view.buffer) -} - -/** - * Converts a Uint8Array into an unsigned 64-bit integer (u64) BigInt. - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the u64 value (default: 0) - * - * @returns The deserialized u64 BigInt value - * - */ -export function bytesToU64(arr: Uint8Array, offset = 0): bigint { - const view = new DataView(arr.buffer) - return view.getBigUint64(offset, true) -} - -/** - * Converts a signed 16-bit integer (i16) into a Uint8Array. - * - * @param val - The number to convert - * - * @throws Will throw an error if the input value is not within the valid i16 range - * - * @returns A Uint8Array containing the serialized i16 value - * - */ -export function i16ToBytes(val: number): Uint8Array { - if (val < I16_MIN || val > I16_MAX) { - throw new Error(`Unable to serialize invalid int16 value ${val}`) - } - const buffer = new ArrayBuffer(2) - const view = new DataView(buffer) - view.setInt16(0, val, true) - return new Uint8Array(view.buffer) -} - -/** - * Converts a Uint8Array into a signed 16-bit integer (i16). - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the i16 value (default: 0) - * - * @returns The deserialized i16 value - * - */ -export function bytesToI16(arr: Uint8Array, offset = 0): number { - const view = new DataView(arr.buffer) - return view.getInt16(offset, true) -} - -/** - * Converts a signed 32-bit integer (i32) into a Uint8Array. - * - * @param val - The number to convert - * - * @throws Will throw an error if the input value is not within the valid i32 range (-2,147,483,648 to 2,147,483,647) - * - * @returns A Uint8Array containing the serialized i32 value - * - */ -export function i32ToBytes(val: number): Uint8Array { - if (val < I32_MIN || val > I32_MAX) { - throw new Error(`Unable to serialize invalid int32 value ${val}`) - } - const buffer = new ArrayBuffer(4) - const view = new DataView(buffer) - view.setInt32(0, val, true) - return new Uint8Array(view.buffer) -} - -/** - * Converts a Uint8Array into a signed 32-bit integer (i32). - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the i32 value (default: 0) - * - * @returns The deserialized i32 value - * - */ -export function bytesToI32(arr: Uint8Array, offset = 0): number { - const view = new DataView(arr.buffer) - return view.getInt32(offset, true) -} - -/** - * Converts a i64 BigInt in a Uint8Array. - * - * @param val - The BigInt to convert - * - * @throws Will throw an error if the input value is not within the valid i64 range (-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807) - * - * @returns A Uint8Array containing the serialized i64 BigInt value - * - */ -export function i64ToBytes(val: bigint): Uint8Array { - if (val < I64_MIN || val > I64_MAX) { - throw new Error(`Unable to serialize invalid int64 value ${val.toString()}`) - } - const buffer = new ArrayBuffer(8) - const view = new DataView(buffer) - view.setBigInt64(0, val, true) - return new Uint8Array(view.buffer) -} - -/** - * Converts a Uint8Array into a i64 BigInt. - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the i64 value (default: 0) - * - * @returns The deserialized i64 BigInt value - * - */ -export function bytesToI64(arr: Uint8Array, offset = 0): bigint { - const view = new DataView(arr.buffer) - return view.getBigInt64(offset, true) -} - -/** - * Converts a 32-bit floating-point number (f32) into a Uint8Array. - * - * @param val - The number to convert - * - * @returns A Uint8Array containing the serialized f32 value - * - */ -export function f32ToBytes(val: number): Uint8Array { - const buffer = new ArrayBuffer(4) - const view = new DataView(buffer) - view.setFloat32(0, val, true) - return new Uint8Array(view.buffer) -} - -/** - * Converts a Uint8Array into a 32-bit floating-point number (f32). - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the f32 value (default: 0) - * - * @returns The deserialized f32 value - * - */ -export function bytesToF32(arr: Uint8Array, offset = 0): number { - const view = new DataView(arr.buffer) - return view.getFloat32(offset, true) -} - -/** - * Converts a 64-bit floating-point number (f64) into a Uint8Array. - * - * @param val - The BigInt to convert - * - * @returns A Uint8Array containing the serialized f64 value - * - */ -export function f64ToBytes(val: number): Uint8Array { - const buffer = new ArrayBuffer(8) - const view = new DataView(buffer) - view.setFloat64(0, val, true) - return new Uint8Array(view.buffer) -} - -/** - * Converts a Uint8Array into a f64 BigInt. - * - * @param arr - The array to convert - * @param offset - The optional offset in the Uint8Array at which to start reading the f64 value (default: 0) - * - * @returns The deserialized f64 value - * - */ -export function bytesToF64(arr: Uint8Array, offset = 0): number { - const view = new DataView(arr.buffer) - return view.getFloat64(offset, true) -} diff --git a/packages/web3-utils/src/serializers/strings.ts b/packages/web3-utils/src/serializers/strings.ts deleted file mode 100644 index f99eedb7..00000000 --- a/packages/web3-utils/src/serializers/strings.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Converts utf-16 string to a Uint8Array. - * - * @param str - the string to convert - * - * @returns the converted string - */ -export function strToBytes(str: string): Uint8Array { - if (!str.length) { - return new Uint8Array(0) - } - return new Uint8Array(Buffer.from(str, 'utf-8')) -} - -/** - * Converts Uint8Array to a string. - * - * @param arr - the array to convert - * - * @returns the converted array - */ -export function bytesToStr(arr: Uint8Array): string { - if (!arr.length) { - return '' - } - - if (typeof window === 'undefined') { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const StringDecoder = require('string_decoder').StringDecoder - const decoder = new StringDecoder('utf-8') - return decoder.write(Buffer.from(arr)) - } - - let TextDecoder = window.TextDecoder - if (typeof TextDecoder === 'undefined') { - // eslint-disable-next-line @typescript-eslint/no-var-requires - TextDecoder = require('util').TextDecoder - } - const textDecoder = new TextDecoder('utf-8') - return textDecoder.decode(arr) -} diff --git a/packages/web3-utils/test/arguments.spec.ts b/packages/web3-utils/test/arguments.spec.ts deleted file mode 100644 index 85047a6a..00000000 --- a/packages/web3-utils/test/arguments.spec.ts +++ /dev/null @@ -1,433 +0,0 @@ -/* eslint-disable @typescript-eslint/no-loss-of-precision */ -import { expect, it, describe } from '@jest/globals' -import { - IDeserializedResult, - ISerializable, -} from '../src/interfaces/ISerializable' -import { Args, ArrayTypes } from '../src/arguments' - -export class Divinity implements ISerializable { - constructor( - public age: number = 0, - public name: string = '' - ) {} - - serialize(): Uint8Array { - return Uint8Array.from( - new Args().addU32(this.age).addString(this.name).serialize() - ) - } - - deserialize(data: Uint8Array, offset: number): IDeserializedResult { - const args = new Args(data, offset) - this.age = args.nextU32() - this.name = args.nextString() - return { instance: this, offset: args.getOffset() } - } -} - -describe('Args class', () => { - it('should retrieve strings and U32 values from an Args object', () => { - // Create an argument class instance - const args1 = new Args() - // add some arguments - args1.addString('hello').addString('world').addU32(97) - - // use serialize to get the byte string - const byteString = args1.serialize() - - // create an argument class with the byte string - const args2 = new Args(byteString) - // assert that the first address is same we provide - // in the first call to add function - expect(args2.nextString()).toEqual('hello') - // and so on with the 2 following arguments - expect(args2.nextString()).toEqual('world') - expect(args2.nextU32()).toEqual(97) - }) - - it('should retrieve an U32 from an Args object', () => { - const args1 = new Args() - args1.addU32(97) - - const args4 = new Args(args1.serialize()) - expect(args4.nextU32()).toEqual(97) - }) - - it('should retrieve a string from an Args object', () => { - const valueA = 'a'.repeat(13) - const args1 = new Args() - args1.addString(valueA) - const byteString = args1.serialize() - const args2 = new Args(byteString) - expect(args2.nextString()).toEqual(valueA) - - const valueB = 'b'.repeat(65600) - const args3 = new Args() - args3.addString(valueB) - const byteString2 = args3.serialize() - const args4 = new Args(byteString2) - expect(args4.nextString()).toEqual(valueB) - }) - - it('should correctly serialize and deserialize an Args object containing an U32 and a string', () => { - const args1 = new Args() - args1.addU32(97) - args1.addString('hello') - args1.addString('world') - - const args2 = new Args(args1.serialize()) - expect(args2.nextU32()).toEqual(97) - expect(args2.nextString()).toEqual('hello') - expect(args2.nextString()).toEqual('world') - }) - - it('should correctly serialize and deserialize an Args object containing an i32', () => { - const args1 = new Args() - args1.addI32(-97) - const args2 = new Args(args1.serialize()) - expect(args2.nextI32()).toEqual(-97) - }) - - it('should correctly serialize and deserialize an Args object containing an u64, an i32 and a string', () => { - const args1 = new Args() - args1.addU64(BigInt(97)) - args1.addI32(-97) - args1.addString('hello') - args1.addString('world') - - const args2 = new Args(args1.serialize()) - expect(args2.nextU64()).toEqual(BigInt(97)) - expect(args2.nextI32()).toEqual(-97) - expect(args2.nextString()).toEqual('hello') - expect(args2.nextString()).toEqual('world') - }) - - it('should correctly serialize and deserialize an Args object containing an i64, an i32 and a string', () => { - const args1 = new Args() - args1.addI64(BigInt(-97)) - args1.addI32(-97) - args1.addString('hello') - args1.addString('world') - - const args2 = new Args(args1.serialize()) - expect(args2.nextI64()).toEqual(BigInt(-97)) - expect(args2.nextI32()).toEqual(-97) - expect(args2.nextString()).toEqual('hello') - expect(args2.nextString()).toEqual('world') - }) - - it('should correctly serialize and deserialize an Args object containing a f32, an i64 and a string', () => { - const args1 = new Args() - args1.addF32(1.234) - args1.addI64(BigInt(-97)) - args1.addString('hello') - args1.addString('world') - args1.addU8(12) - - const args2 = new Args(args1.serialize()) - expect(args2.nextF32()).toBeCloseTo(1.234, 1e-7) - expect(args2.nextI64()).toEqual(BigInt(-97)) - expect(args2.nextString()).toEqual('hello') - expect(args2.nextString()).toEqual('world') - }) - - it('should correctly serialize and deserialize an Args object containing a U8 and a boolean', () => { - const args1 = new Args() - args1.addU8(12) - args1.addBool(true) - - const args2 = new Args(args1.serialize()) - expect(args2.nextU8()).toEqual(BigInt(12)) - expect(args2.nextBool()).toEqual(true) - }) - - it('should correctly serialize and deserialize an Args object containing a f64, an i64 and a string', () => { - const args1 = new Args() - args1.addF64(146738984765738.234) - args1.addI64(BigInt(-97)) - args1.addString('hello') - args1.addString('world') - - const args2 = new Args(args1.serialize()) - expect(args2.nextF64()).toEqual(146738984765738.234) - expect(args2.nextI64()).toEqual(BigInt(-97)) - expect(args2.nextString()).toEqual('hello') - expect(args2.nextString()).toEqual('world') - }) - - it('should correctly serialize and deserialize an Args object containing a u128, i128, an u256 and a string', () => { - const u128Val = 146738984765738234n - const i128Val = -146738984765738234n - const u256Val = 146738984765738234146738984765738234n - const str = 'random string lolmao' - const args1 = new Args() - args1.addU128(u128Val) - args1.addI128(i128Val) - args1.addU256(u256Val) - args1.addString(str) - - const args2 = new Args(args1.serialize()) - expect(args2.nextU128()).toEqual(u128Val) - expect(args2.nextI128()).toEqual(i128Val) - expect(args2.nextU256()).toEqual(u256Val) - expect(args2.nextString()).toEqual(str) - }) - - it('should correctly serialize and deserialize an Args object containing a byteArray, an i64 and a string', () => { - const args1 = new Args() - const byteArray = new Uint8Array(4) - byteArray[0] = 1 - byteArray[1] = 2 - byteArray[2] = 3 - byteArray[3] = 4 - args1.addUint8Array(byteArray) - args1.addI64(BigInt(-97)) - args1.addString('hello') - args1.addString('world') - - const args2 = new Args(args1.serialize()) - expect(args2.nextUint8Array()).toEqual(byteArray) - expect(args2.nextI64()).toEqual(BigInt(-97)) - expect(args2.nextString()).toEqual('hello') - expect(args2.nextString()).toEqual('world') - }) - - it('should correctly serialize and deserialize an Args object containing a single serializable object', () => { - const classObject = new Divinity(14, 'Poseidon') - const args = new Args(new Args().addSerializable(classObject).serialize()) - const deserialized = args.nextSerializable(Divinity) - expect(deserialized.age).toEqual(14) - expect(deserialized.name).toEqual('Poseidon') - }) - - it('should correctly serialize and deserialize an Args object containing an array, a number, a string and an Object', () => { - const array = new Uint8Array(2) - array.set([65, 88]) - const age = 24 - const name = 'Me' - const classObject = new Divinity(14, 'Poseidon') - - const args = new Args( - new Args() - .addUint8Array(array) - .addU32(age) - .addString(name) - .addSerializable(classObject) - .serialize() - ) - - expect(args.nextUint8Array()).toEqual(array) - expect(args.nextU32()).toEqual(age) - expect(args.nextString()).toEqual(name) - const deserialized = args.nextSerializable(Divinity) - expect(deserialized.age).toEqual(14) - expect(deserialized.name).toEqual('Poseidon') - }) - - it('should return undefined when deserializing an empty array using nextSerializableObjectArray', () => { - const arrayOfSerializable = [] - const args = new Args( - new Args().addSerializableObjectArray(arrayOfSerializable).serialize() - ) - - const deserialized = args.nextSerializableObjectArray(Divinity) - expect(deserialized[0]).toBe(undefined) - }) - - it('should correctly serialize and deserialize an Args object containing an array of serializables', () => { - const arrayOfSerializable = [ - new Divinity(14, 'Poseidon'), - new Divinity(45, 'Superman'), - ] - const args = new Args( - new Args().addSerializableObjectArray(arrayOfSerializable).serialize() - ) - - const deserialized = args.nextSerializableObjectArray(Divinity) - - expect(deserialized.length).toEqual(2) - expect(deserialized[0].age).toEqual(14) - expect(deserialized[0].name).toEqual('Poseidon') - expect(deserialized[1].age).toEqual(45) - expect(deserialized[1].name).toEqual('Superman') - }) - - it('should correctly serialize and deserialize an Args object containing a mixed array of serializables and others', () => { - const array = new Uint8Array(2) - array.set([65, 88]) - const age = 24 - const name = 'Me' - - const arrayOfSerializable = [ - new Divinity(14, 'Poseidon'), - new Divinity(45, 'Superman'), - ] - const args = new Args( - new Args() - .addUint8Array(array) - .addSerializableObjectArray(arrayOfSerializable) - .addU32(age) - .addString(name) - .serialize() - ) - - expect(args.nextUint8Array()).toEqual(array) - const deserialized = args.nextSerializableObjectArray(Divinity) - expect(deserialized.length).toEqual(2) - expect(deserialized[0].age).toEqual(14) - expect(deserialized[0].name).toEqual('Poseidon') - expect(deserialized[1].age).toEqual(45) - expect(deserialized[1].name).toEqual('Superman') - expect(args.nextU32()).toEqual(age) - expect(args.nextString()).toEqual(name) - }) - - it('should correctly serialize and deserialize an Args object containing an array of booleans', () => { - const arrayBooleans = [false, false, true, true, false] - const serialized = new Args() - .addArray(arrayBooleans, ArrayTypes.BOOL) - .serialize() - const args = new Args(serialized) - const deserialized = args.nextArray(ArrayTypes.BOOL) - expect(deserialized).toEqual(arrayBooleans) - }) - - it('should correctly serialize and deserialize an Args object containing an array of U8s', () => { - const arrayU8s = [10, 20, 30] - const serialized = new Args().addArray(arrayU8s, ArrayTypes.U8).serialize() - const args = new Args(serialized) - const deserialized = args.nextArray(ArrayTypes.U8) - expect(deserialized).toEqual(arrayU8s) - }) - - it('should correctly serialize and deserialize an Args object containing an array of U32s', () => { - const arrayU32s = [100000, 200000, 300000] - const serialized = new Args() - .addArray(arrayU32s, ArrayTypes.U32) - .serialize() - const args = new Args(serialized) - const deserialized = args.nextArray(ArrayTypes.U32) - expect(deserialized).toEqual(arrayU32s) - }) - - it('should correctly serialize and deserialize an Args object containing an array of U64s', () => { - const arrayU64s = [ - BigInt(10000000000), - BigInt(2000000000), - BigInt(3000000000), - ] - const serialized = new Args() - .addArray(arrayU64s, ArrayTypes.U64) - .serialize() - const args = new Args(serialized) - const deserialized = args.nextArray(ArrayTypes.U64) - expect(deserialized).toEqual(arrayU64s) - }) - - it('should correctly serialize and deserialize an Args object containing an array of F32s', () => { - const arrayF32s = [8.4, -9.6] - const serialized = new Args() - .addArray(arrayF32s, ArrayTypes.F32) - .serialize() - const args = new Args(serialized) - const deserialized = args.nextArray(ArrayTypes.F32) - expect(deserialized[0]).toBeCloseTo(arrayF32s[0], 0.00001) - expect(deserialized[1]).toBeCloseTo(arrayF32s[1], 0.00001) - }) - - it('should correctly serialize and deserialize an Args object containing an array of F64s', () => { - const arrayF64s = [17800.47444, -97234.65711] - const serialized = new Args() - .addArray(arrayF64s, ArrayTypes.F64) - .serialize() - const args = new Args(serialized) - const deserialized = args.nextArray(ArrayTypes.F64) - expect(deserialized[0]).toBeCloseTo(arrayF64s[0], 0.00001) - expect(deserialized[1]).toBeCloseTo(arrayF64s[1], 0.00001) - }) - - it('should correctly serialize and deserialize an Args object containing an array of I32s', () => { - const arrayI32s = [-2300, 9760] - const serialized = new Args() - .addArray(arrayI32s, ArrayTypes.I32) - .serialize() - const args = new Args(serialized) - const deserialized = args.nextArray(ArrayTypes.I32) - expect(deserialized).toEqual(arrayI32s) - }) - - it('should correctly serialize and deserialize an Args object containing an array of I64s', () => { - const input = [BigInt(-2300345435), BigInt(97607665667)] - const serialized = new Args().addArray(input, ArrayTypes.I64).serialize() - const deserialized = new Args(serialized).nextArray(ArrayTypes.I64) - expect(deserialized).toEqual(input) - }) - - it('should correctly serialize and deserialize an Args object containing a byteArray, an i64, a string and a native array', () => { - const args1 = new Args() - const byteArray = new Uint8Array(4) - byteArray[0] = 1 - byteArray[1] = 2 - byteArray[2] = 3 - byteArray[3] = 4 - args1.addUint8Array(byteArray) - args1.addI64(BigInt(-97)) - args1.addString('hello') - args1.addString('world') - const i32Array = [100, 200, 300] - args1.addArray(i32Array, ArrayTypes.I32) - - const args2 = new Args(args1.serialize()) - expect(args2.nextUint8Array()).toEqual(byteArray) - expect(args2.nextI64()).toEqual(BigInt(-97)) - expect(args2.nextString()).toEqual('hello') - expect(args2.nextString()).toEqual('world') - expect(args2.nextArray(ArrayTypes.I32)).toEqual(i32Array) - }) - - it('should correctly serialize and deserialize an Args object containing a native serializable object', () => { - const array = new Uint8Array(2) - array.set([65, 88]) - const age = 24 - const name = 'Me' - const classObject = new Divinity(14, 'Poseidon') - const i32Array = [100, 200, 300] - - const args = new Args( - new Args() - .addUint8Array(array) - .addU32(age) - .addString(name) - .addArray(i32Array, ArrayTypes.I32) - .addSerializable(classObject) - .serialize() - ) - - expect(args.nextUint8Array()).toEqual(array) - expect(args.nextU32()).toEqual(age) - expect(args.nextString()).toEqual(name) - expect(args.nextArray(ArrayTypes.I32)).toEqual(i32Array) - const deserialized = args.nextSerializable(Divinity) - expect(deserialized.age).toEqual(14) - expect(deserialized.name).toEqual('Poseidon') - }) - - it('should correctly serialize and deserialize an array of Strings', () => { - const arrayStrings = ['hello there', 'evgeni', '๐Ÿ™‚๐Ÿ™‚'] - const serialized = new Args() - .addArray(arrayStrings, ArrayTypes.STRING) - .serialize() - const args = new Args(serialized) - const deserialized = args.nextArray(ArrayTypes.STRING) - expect(deserialized).toEqual(arrayStrings) - }) - - it('should correctly serialize and deserialize an empty string array', () => { - const array = [] - const serialized = new Args().addArray(array, ArrayTypes.STRING).serialize() - const args = new Args(serialized) - const deserialized = args.nextArray(ArrayTypes.STRING) - expect(deserialized).toEqual(array) - }) -}) diff --git a/packages/web3-utils/test/utils/fixtures/as-serializer.ts b/packages/web3-utils/test/utils/fixtures/as-serializer.ts deleted file mode 100644 index bcb84682..00000000 --- a/packages/web3-utils/test/utils/fixtures/as-serializer.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* This file contains a set of value of different types serialized using the AS serializer of @massalabs/as-types - The goal is to ensure the TS serializer/deserializer does the exact same thing as the AS one -*/ - -export const asTests = [ - { - name: 'ser/deser with emojis', - ser: 'strToBytes', - deser: 'bytesToStr', - val: 'Hello world ๐Ÿ™‚', - serialized: [ - 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 32, 240, 159, 153, - 130, - ], - }, - { - name: 'ser/deser Ascii', - ser: 'strToBytes', - deser: 'bytesToStr', - val: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', - serialized: [ - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - ], - }, - { - name: 'ser/deser u32', - ser: 'u32ToBytes', - deser: 'bytesToU32', - val: 666, - serialized: [154, 2, 0, 0], - }, - { - name: 'ser/deser i32', - ser: 'i32ToBytes', - deser: 'bytesToI32', - val: -666, - serialized: [102, 253, 255, 255], - }, - { - name: 'ser/deser u64', - ser: 'u64ToBytes', - deser: 'bytesToU64', - val: BigInt(666), - serialized: [154, 2, 0, 0, 0, 0, 0, 0], - }, - { - name: 'ser/deser i128', - ser: 'i128ToBytes', - deser: 'bytesToI128', - val: -123456789012345678901234567890n, - serialized: [ - 46, 245, 192, 177, 17, 31, 140, 60, 9, 240, 22, 113, 254, 255, 255, 255, - ], - }, - { - name: 'ser/deser u128', - ser: 'u128ToBytes', - deser: 'bytesToU128', - val: 123456789012345678901234567890n, - serialized: [ - 210, 10, 63, 78, 238, 224, 115, 195, 246, 15, 233, 142, 1, 0, 0, 0, - ], - }, - { - name: 'ser/deser u256', - ser: 'u256ToBytes', - deser: 'bytesToU256', - val: 340282366920938463479561609432376342295n, - serialized: [ - 23, 247, 200, 160, 142, 200, 163, 224, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ], - }, - { - name: 'ser/deser i64', - ser: 'i64ToBytes', - deser: 'bytesToI64', - val: BigInt(-666), - serialized: [102, 253, 255, 255, 255, 255, 255, 255], - }, - { - name: 'ser/deser f32', - ser: 'f32ToBytes', - deser: 'bytesToF32', - val: -666.666, - serialized: [160, 170, 38, 196], - }, - { - name: 'ser/deser f64', - ser: 'f64ToBytes', - deser: 'bytesToF64', - val: -666.666, - serialized: [23, 217, 206, 247, 83, 213, 132, 192], - }, -] diff --git a/packages/web3-utils/tsconfig.commonjs.json b/packages/web3-utils/tsconfig.commonjs.json deleted file mode 100644 index 6434050a..00000000 --- a/packages/web3-utils/tsconfig.commonjs.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - // Extends base TypeScript configuration from 'tsconfig.json' - "extends": "./tsconfig.json", - "compilerOptions": { - // Specifies the module system for the output bundle. "commonjs" is a standard for structuring and organizing JavaScript code. - "module": "commonjs", - // The location where the output files will be placed. - "outDir": "./dist/cmd/" - }, -} \ No newline at end of file diff --git a/packages/web3-utils/tsconfig.esm.json b/packages/web3-utils/tsconfig.esm.json deleted file mode 100644 index 8132b823..00000000 --- a/packages/web3-utils/tsconfig.esm.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "target": "ESNext", - "module": "ESNext", - "outDir": "./dist/esm/", - "sourceMap": true, - "inlineSources": true - }, - "exclude": [ - "node_modules", - "**/*.spec.ts" - ] -} \ No newline at end of file diff --git a/packages/web3-utils/tsconfig.json b/packages/web3-utils/tsconfig.json deleted file mode 100644 index 0acccb47..00000000 --- a/packages/web3-utils/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./dist" - }, - "include": [ - "./src/**/*.ts" - ], - "exclude": [ - "node_modules", - "**/*.spec.ts" - ] -} \ No newline at end of file diff --git a/scripts/coverage.sh b/scripts/coverage.sh index e063ecd0..62533081 100755 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -2,7 +2,7 @@ echo "Running coverage script..." echo "Coverage: $COVERAGE" -echo "Project: $PROJECT" +echo "Project: massa-web3" # Define the color based on coverage threshold determine_color() { @@ -18,19 +18,10 @@ determine_color() { } filename="README.md" - -declare -A project_map -project_map=( ["massa-web3"]=9 ["web3-utils"]=18 ) - -line_number=${project_map[$PROJECT]} - -# If no line number found, exit the script -if [ -z "$line_number" ]; then - echo "Project '$PROJECT' not found in the map." - exit 1 -fi +line_number=9 # Hardcoding the line number for massa-web3 echo "Line number: $line_number" + # Extract the current coverage badge from the specified line coverageLine=$(sed -n "${line_number}p" $filename) @@ -39,12 +30,11 @@ regex="!\[check-code-coverage\]\(https://img.shields.io/badge/coverage-([0-9]+([ echo "Coverage line: $coverageLine" - if [[ $coverageLine =~ $regex ]]; then oldCoverage="${BASH_REMATCH[1]}" - echo "Coverage for $PROJECT is $oldCoverage%" + echo "Coverage for massa-web3 is $oldCoverage%" else - echo "No coverage found for $PROJECT." + echo "No coverage found for massa-web3." exit 1 fi @@ -53,13 +43,13 @@ color=$(determine_color $COVERAGE) # Update the coverage badge if the difference in coverage is greater than or equal to 1% if (( $(echo "$COVERAGE != $oldCoverage" | bc -l) )); then - echo "Updating badge for $PROJECT." + echo "Updating badge for massa-web3." newLine="![check-code-coverage](https://img.shields.io/badge/coverage-$COVERAGE%25-$color)" sed -i "${line_number}s#.*#${newLine}#" $filename - echo "Updated badge for $PROJECT." + echo "Updated badge for massa-web3." coverageLine=$(sed -n "${line_number}p" $filename) echo "Coverage line: $coverageLine" else - echo "Coverage for $PROJECT has not changed. Skipping update." + echo "Coverage for massa-web3 has not changed. Skipping update." fi \ No newline at end of file diff --git a/scripts/deployerGeneration/deployer.wasm b/scripts/deployerGeneration/deployer.wasm new file mode 100644 index 00000000..82cd5c6f Binary files /dev/null and b/scripts/deployerGeneration/deployer.wasm differ diff --git a/scripts/deployerGeneration/generate-deployer.ts b/scripts/deployerGeneration/generate-deployer.ts new file mode 100644 index 00000000..136d4ff5 --- /dev/null +++ b/scripts/deployerGeneration/generate-deployer.ts @@ -0,0 +1,17 @@ +import path from 'path' +import fs from 'fs' + +console.log('Generating deployer bytecode...') +function populateDeployer(src?: string, dst?: string): void { + const wasmPath = src ?? path.join(__dirname, 'deployer.wasm') + const wasmData = fs.readFileSync(wasmPath) + + const output = `export const DEPLOYER_BYTECODE: Uint8Array = new Uint8Array([${[...wasmData]}]);\n` + + const outputDir = + dst ?? path.join(__dirname, '../../src/generated/deployer-bytecode.ts') + + fs.writeFileSync(outputDir, output) +} + +populateDeployer() diff --git a/scripts/generate_powered-by.sh b/scripts/generate_powered-by.sh deleted file mode 100755 index d9710d37..00000000 --- a/scripts/generate_powered-by.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash +x - -# Loop through the packages in your workspace (adjust the path as needed) -for packageDir in packages/*; do - if [ -d "$packageDir" ]; then - packageJson="$packageDir/package.json" - - if [ -f "$packageJson" ]; then - fileName="${packageDir}/powered-by.md" # Define the report file name within each package directory - - echo "# Dependencies Report" > "$fileName" - echo "" >> "$fileName" - echo "The following is a list of all the dependencies for this package:" >> "$fileName" - - report=$(cd "$packageDir" && license-report) - if [ -n "$report" ]; then - for row in $(echo "${report}" | jq -r '.[] | @base64'); do - _jq() { - echo "${row}" | base64 --decode | jq -r ${1} - } - - name=$(_jq '.name') - url=$(_jq '.link') - licenseType=$(_jq '.licenseType') - licensePeriod=$(_jq '.licensePeriod') - installedVersion=$(_jq '.installedVersion') - author=$(_jq '.author') - - if [[ $author == *" <"* ]]; then - author="[${author%% <*}](${author##*<}" - author="${author%?}" # remove the extra ">" at the end - author="${author})" # adding ")" at the end - fi - - echo "## [${name}](${url})" >> "$fileName" - echo "" >> "$fileName" - echo "**License:** ${licenseType} - ${licensePeriod}" >> "$fileName" - echo "" >> "$fileName" - echo "**Used version:** ${installedVersion}" >> "$fileName" - echo "" >> "$fileName" - echo "**Many thanks to:** ${author}" >> "$fileName" - echo "" >> "$fileName" - done - fi - fi - fi -done diff --git a/scripts/publish-dev.sh b/scripts/publish-dev.sh index 2e1697da..8da23d84 100755 --- a/scripts/publish-dev.sh +++ b/scripts/publish-dev.sh @@ -1,19 +1,16 @@ #!/bin/bash set -e +# Install dependencies and build the project npm ci npm run build -npm version --workspaces --preid dev --no-git-tag-version --no-commit-hooks prepatch -#Use timestamp as package suffix -TIME=$(date -u +%Y%m%d%H%M%S) -sed -i "/version/s/dev.0/dev.$TIME/g" packages/*/package.json -BRANCH=${GITHUB_REF##*/} -TAG="" -if [[ "$BRANCH" == "buildnet" ]]; then - TAG="buildnet-" -elif [[ "$BRANCH" == "testnet" ]]; then - TAG="testnet-" -fi +# Update the version with a prepatch, preid dev, no git tag, and no commit hooks +npm version --preid dev --no-git-tag-version --no-commit-hooks prepatch + +# Use timestamp as package suffix +TIME=$(date -u +%Y%m%d%H%M%S) +sed -i "/version/s/dev.0/dev.$TIME/g" package.json -npm publish --ws --access public --tag ${TAG}dev +# Publish the package +npm publish --access public --tag ${TAG}dev \ No newline at end of file diff --git a/scripts/publish-next.sh b/scripts/publish-next.sh new file mode 100755 index 00000000..f2702b0a --- /dev/null +++ b/scripts/publish-next.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +# Install dependencies and build the project +npm ci +npm run build + +TAG=next + +# Update the version with a premajor, preid next, no git tag, and no commit hooks +npm version --preid $TAG --no-git-tag-version --no-commit-hooks premajor + +# Use timestamp as package suffix +TIME=$(date -u +%Y%m%d%H%M%S) +sed -i "/version/s/$TAG.0/$TAG.$TIME/g" package.json + +# Publish the package +npm publish --access public --tag $TAG \ No newline at end of file diff --git a/scripts/publish.sh b/scripts/publish.sh index 7d9a7f9b..99c577d2 100755 --- a/scripts/publish.sh +++ b/scripts/publish.sh @@ -1,45 +1,18 @@ #!/bin/bash set -e -# Check if Node.js and npm are installed -if ! [ -x "$(command -v node)" ] || ! [ -x "$(command -v npm)" ]; then - echo "Node.js and npm are required to run this script." - exit 1 -fi - +# Install dependencies and build the project npm ci npm run build -ref=$1 -echo "Publishing packages for reference: $ref" -TAG="" +# Get the package name and current version from package.json +PACKAGE_NAME=$(jq -r '.name' package.json) +NEW_VERSION=$(jq -r '.version' package.json) +CURRENT_VERSION=$(npm view "$PACKAGE_NAME" version 2>/dev/null || true) -if [[ "$ref" == *"buildnet"* ]]; then - TAG="--tag buildnet" +if [ "$CURRENT_VERSION" == "$NEW_VERSION" ]; then + echo "${PACKAGE_NAME}@${NEW_VERSION} is already published. Skipping." +else + echo "Publishing ${PACKAGE_NAME}@${NEW_VERSION}" + npm publish fi - -for packageDir in packages/*; do - if [ -d "$packageDir" ]; then - PACKAGE_NAME=$(cat "$packageDir/package.json" | jq -r '.name') - PUBLISH_VERSION=$(cat "$packageDir/package.json" | jq -r '.version') - - # Check if the package name is in the reference - if [[ "$ref" == *"$PACKAGE_NAME"* ]]; then - # Check if the package version is already published - if [[ "$ref" == "buildnet" ]]; then - CURRENT_VERSION=$(npm view "$PACKAGE_NAME@buildnet" version 2>/dev/null || true) - else - CURRENT_VERSION=$(npm view "$PACKAGE_NAME" version 2>/dev/null || true) - fi - - if [ "$CURRENT_VERSION" == "$PUBLISH_VERSION" ]; then - echo "${PACKAGE_NAME}@${PUBLISH_VERSION} is already published. Skipping." - else - echo "Publishing ${PACKAGE_NAME}@${PUBLISH_VERSION}" - npm publish --workspace="$PACKAGE_NAME" "$TAG" - fi - else - echo "Skipping ${PACKAGE_NAME}" - fi - fi -done diff --git a/scripts/transform-code-snippet-tests.mjs b/scripts/transform-code-snippet-tests.mjs deleted file mode 100644 index 796769a4..00000000 --- a/scripts/transform-code-snippet-tests.mjs +++ /dev/null @@ -1,67 +0,0 @@ -import { readdir, readFile, writeFile } from 'fs'; -import { join } from 'path'; -const massaWeb3Path = 'packages/massa-web3'; - -const testCodeSnippetDirectory = `${massaWeb3Path}/test/code-snippets`; - -// Extract import statements from the content -const extractImports = (content) => { - const importRegex = /^import .* from .*;$/gm; - return content.match(importRegex) || []; -}; - -// Transform the content of a test file into a code snippet -const transformTestToSnippet = (content) => { - const itBodyRegex = - /it\(['"`].+['"`],\s*(?:async\s*)?\(\)\s*=>\s*\{([\s\S]*?)\}\);/g; - let transformedContent = ''; - let match; - - while ((match = itBodyRegex.exec(content)) !== null) { - transformedContent += match[1].trim() + '\n'; - } - - transformedContent = transformedContent.replace(/expect\([^]*?\);/g, ''); - - if (/await/.test(transformedContent)) { - transformedContent = `(async () => {\n${transformedContent}\n})();`; - } - - return transformedContent; -}; - -// Read and transform test files -readdir(testCodeSnippetDirectory, (err, files) => { - if (err) { - console.error(`Error reading the directory: ${err}`); - process.exit(1); - } - - const specFiles = files.filter((file) => file.endsWith('.spec.ts')); - - specFiles.forEach((fileName) => { - const filePath = join(testCodeSnippetDirectory, fileName); - readFile(filePath, 'utf8', (err, content) => { - if (err) { - console.error(`Error reading the file ${filePath}: ${err}`); - process.exit(1); - } - - const importStatements = extractImports(content).join('\n'); - const transformedContent = transformTestToSnippet(content); - const snippetContent = `${importStatements}\n\n${transformedContent}`; - - const newFilePath = join( - `${massaWeb3Path}/code-snippets`, - fileName.replace('.spec', ''), - ); - writeFile(newFilePath, snippetContent, 'utf8', (err) => { - if (err) { - console.error(`Error writing the file ${newFilePath}: ${err}`); - process.exit(1); - } - console.log(`Successfully transformed ${filePath} to ${newFilePath}`); - }); - }); - }); -}); diff --git a/src/account.ts b/src/account.ts new file mode 100644 index 00000000..d5f890dc --- /dev/null +++ b/src/account.ts @@ -0,0 +1,268 @@ +import { Version } from './crypto/interfaces/versioner' +import Sealer from './crypto/interfaces/sealer' +import { PasswordSeal } from './crypto/passwordSeal' +import { Address, PrivateKey, PublicKey, Signature } from './basicElements' + +/** + * A class representing an account. + */ +export class Account { + public sealer: Sealer + + private constructor( + public privateKey: PrivateKey, + public publicKey: PublicKey, + public address: Address, + public version: Version + ) {} + + /** + * Initializes a new account object from a private key. + * + * @param key - The private key of the account. + * @param version - The version of the account. + * + * @returns A new instance of the Account class. + */ + public static async fromPrivateKey( + key: string | PrivateKey, + version: Version = Version.V1 + ): Promise { + if (typeof key === 'string') { + key = PrivateKey.fromString(key) + } + const publicKey = await key.getPublicKey() + const address = publicKey.getAddress() + + return new Account(key, publicKey, address, version) + } + + /** + * Generates a new account object. + * + * @param version - The version of the account. + * + * @returns A new instance of the Account class. + */ + public static async generate(version?: Version): Promise { + const privateKey = PrivateKey.generate() + return Account.fromPrivateKey(privateKey, version) + } + + /** + * Signs a message. + * + * @remarks + * This function signs a byte-encoded message with the account private key. + * The message is first hashed and then signed. + * Do not pass a digest to this function as it will be hashed twice. + * + * @param message - The byte array to sign. + * + * @returns A signature object. + */ + sign(message: Uint8Array): Promise { + return this.privateKey.sign(message) + } + + /** + * Verifies a message signature. + * + * @remarks + * This function verifies a byte-encoded message signature using the account's public key. + * The message is first hashed and then the signature is verified against the hashed message. + * Do not pass a digest to this function as it will be hashed twice. + * + * @param signature - The signature to verify. + * @param message - The byte array that was signed. + * + * @returns A boolean indicating whether the signature is valid. + */ + verify(message: Uint8Array, signature: Signature): Promise { + return this.publicKey.verify(message, signature) + } + + /** + * Encodes the account to a serializable object. + * + * @remarks + * The serializable object can be serialized to any format (JSON, YAML, XML, etc.) on any support (file, database, browser storage, etc.). + * The keystore format is defined in the Massa standard format document: + * [Massa Standard Format](https://github.com/massalabs/massa-standards/blob/main/wallet/file-format.md) + * + * @param password - The password to encrypt the private key. + * @param salt - The salt to use for the encryption. If not provided, a random salt will be generated. + * @param nonce - The nonce to use for the encryption. If not provided, a random nonce will be generated. + * + * @returns A serializable object. + * + * @throws If the password is not provided for V0 and V1 keystores. + * @throws If the version is not supported. + */ + async toKeyStore( + password?: string, + salt?: Uint8Array, + nonce?: Uint8Array + ): Promise { + switch (this.version) { + case Version.V0: { + if (!password) { + throw new Error('Password is required for V0 keystore') + } + const passwordSeal = new PasswordSeal(password, salt, nonce) + + /* eslint-disable @typescript-eslint/naming-convention */ + // It is mandatory to follow the Massa standard. + return { + Address: this.address.toString(), + Version: this.version, + Nickname: '', + Salt: passwordSeal.salt, + Nonce: passwordSeal.nonce, + CipheredData: await passwordSeal + .seal(this.privateKey.toBytes()) + .then((a) => Array.from(a)), + PublicKey: Array.from(this.publicKey.toBytes()), + } as AccountV0KeyStore + /* eslint-enable @typescript-eslint/naming-convention */ + } + case Version.V1: { + if (!password) { + throw new Error('Password is required for V1 keystore') + } + const passwordSeal = new PasswordSeal(password, salt, nonce) + + /* eslint-disable @typescript-eslint/naming-convention */ + // It is mandatory to follow the Massa standard. + return { + Address: this.address.toString(), + Version: this.version, + Nickname: '', + Salt: passwordSeal.salt, + Nonce: passwordSeal.nonce, + CipheredData: await passwordSeal + .seal(this.privateKey.toBytes()) + .then((a) => Array.from(a)), + PublicKey: Array.from(this.publicKey.toBytes()), + } as AccountV1KeyStore + /* eslint-enable @typescript-eslint/naming-convention */ + } + default: + throw new Error(`unsupported version`) + } + } + + /** + * Decodes the account from a serializable object. + * + * @remarks + * The serializable object can be serialized to any format (JSON, YAML, XML, etc.) on any support (file, database, browser storage, etc.). + * The keystore format is defined in the Massa standard format document: + * [Massa Standard Format](https://github.com/massalabs/massa-standards/blob/main/wallet/file-format.md) + * + * @param password - The password to decrypt the private key. + * @param keystore - The serializable object to decode. + * + * @returns A new Account instance. + * + * @throws If the password is not provided for V0 and V1 keystores. + * @throws If the version is not supported. + */ + static async fromKeyStore( + keystore: AccountKeyStore, + password?: string + ): Promise { + switch (keystore.Version) { + case Version.V0: { + if (!password) { + throw new Error('Password is required for V0 keystore') + } + const passwordSeal = new PasswordSeal( + password, + keystore.Salt, + keystore.Nonce + ) + const privateKeyBytes = await passwordSeal.unseal(keystore.CipheredData) + const privateKey = PrivateKey.fromBytes(privateKeyBytes) + const publicKey = PublicKey.fromBytes( + Uint8Array.from(keystore.PublicKey) + ) + const address = publicKey.getAddress() + // TODO: add a consistency check with the address in the keystore + + return new Account(privateKey, publicKey, address, keystore.Version) + } + case Version.V1: { + if (!password) { + throw new Error('Password is required for V1 keystore') + } + const passwordSeal = new PasswordSeal( + password, + keystore.Salt, + keystore.Nonce + ) + + const privateKeyBytes = await passwordSeal.unseal(keystore.CipheredData) + + const privateKey = PrivateKey.fromBytes(privateKeyBytes) + const publicKey = PublicKey.fromBytes( + Uint8Array.from(keystore.PublicKey) + ) + const address = publicKey.getAddress() + // TODO: add a consistency check with the address in the keystore + return new Account(privateKey, publicKey, address, keystore.Version) + } + default: + throw new Error(`unsupported version`) + } + } + + /** + * Uses the environment variables to create an account. + * + * @param key - The environment variable key containing the private key. + * + * @remarks + * The `PRIVATE_KEY` or the provided key is required in the environment variables. + * + * @returns An account instance. + */ + static async fromEnv(key?: string): Promise { + return Account.fromPrivateKey(PrivateKey.fromEnv(key)) + } + + // TODO fix js-yaml import in browser + // /** + // * Uses the environment variables to create an account. + // * + // * @returns An account instance. + // */ + // static async fromYaml(path: string, password: string): Promise { + // if (typeof window !== 'undefined' || !fs || !yaml) { + // throw new Error('This function is not available in the browser') + // } + // // check that file exists + // if (!fs.existsSync(path)) { + // throw new Error(`wallet file "${path}" does not exist.`) + // } + + // const ks = yaml.load(fs.readFileSync(path, 'utf8')) as AccountKeyStore + // return Account.fromKeyStore(ks, password) + // } +} + +/* eslint-disable @typescript-eslint/naming-convention */ +// It is mandatory to follow the Massa standard. +export type AccountKeyStoreBase = { + Address: string + Nickname: string + Salt: Uint8Array + Nonce: Uint8Array + CipheredData: Uint8Array + PublicKey: number[] +} + +export type AccountV0KeyStore = AccountKeyStoreBase & { Version: Version.V0 } +export type AccountV1KeyStore = AccountKeyStoreBase & { Version: Version.V1 } +/* eslint-enable @typescript-eslint/naming-convention */ +export type AccountKeyStore = AccountV0KeyStore | AccountV1KeyStore diff --git a/src/basicElements/address.ts b/src/basicElements/address.ts new file mode 100644 index 00000000..1543ab8c --- /dev/null +++ b/src/basicElements/address.ts @@ -0,0 +1,254 @@ +import Base58 from '../crypto/base58' +import Serializer from '../crypto/interfaces/serializer' +import { Version, Versioner } from '../crypto/interfaces/versioner' +import VarintVersioner from '../crypto/varintVersioner' +import { PublicKey } from './keys' +import varint from 'varint' + +const ADDRESS_USER_PREFIX = 'AU' +const ADDRESS_CONTRACT_PREFIX = 'AS' +const UNDERLYING_HASH_LEN = 32 + +const DEFAULT_VERSION = Version.V0 + +export enum AddressType { + EOA = 0, + Contract = 1, +} + +/** + * Get the address version. + * + * @returns the address version. + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function getVersion(data: string | Uint8Array): Version { + // when a new version will come, implement the logic to detect version here + // This should be done without serializer and versionner as they are potentially not known at this point + return Version.V0 +} + +/** + * Get the address prefix. + * + * @remarks + * Throws an error if the prefix is not valid. + * + * @returns the address version. + */ +function getPrefix(str: string): string { + const expected = [ADDRESS_USER_PREFIX, ADDRESS_CONTRACT_PREFIX] + for (const prefix of expected) { + if (str.startsWith(prefix)) { + return prefix + } + } + throw new Error( + `invalid address prefix: one of ${expected.join(' or ')} was expected.` + ) +} + +/** + * A class representing an address. + * + * @remarks + * For now, an address is intrinsically linked (to be understood as a digest of) to the public key. + * + * @privateRemarks + * Interfaces are used to make the code more modular. To add a new version, you simply need to: + * - Add a new case in the switch statement with the new algorithms to use. + * - Change the DEFAULT_VERSION version matching the last version. + * - Change the getVersion method to detect the version from user input. + * - check the `fromPublicKey` method to potentially adapt how an address is derived from a public key. + * - Voila! The code will automatically handle the new version. + */ +export class Address { + // The address in byte format. Address type and version included. + private bytes: Uint8Array + + public isEOA = false + + protected constructor( + public serializer: Serializer, + public versioner: Versioner, + public version: Version + ) {} + + /** + * Initialize a new address object from a version. + * + * @param version - The version of the address. + * + * @returns A new address instance. + * + * @throws If the version is not supported. + */ + protected static initFromVersion( + version: Version = DEFAULT_VERSION + ): Address { + switch (version) { + case Version.V0: + return new Address(new Base58(), new VarintVersioner(), version) + default: + throw new Error(`unsupported version: ${version}`) + } + } + + /** + * Initializes a new address object from a serialized string. + * + * @param str - The serialized address string. + * + * @returns A new address instance. + * + * @throws If the address string is invalid. + */ + public static fromString(str: string): Address { + try { + const version = getVersion(str) + const address = Address.initFromVersion(version) + const prefix = getPrefix(str) + + address.isEOA = prefix === ADDRESS_USER_PREFIX + const versionedBytes = address.serializer.deserialize( + str.slice(prefix.length) + ) + const { version: extractedVersion } = + address.versioner.extract(versionedBytes) + // safety check + if (extractedVersion !== version) { + throw new Error( + `invalid version: ${version}. ${address.version} was expected.` + ) + } + + address.bytes = Uint8Array.from([ + ...varint.encode( + address.isEOA ? AddressType.EOA : AddressType.Contract + ), + ...versionedBytes, + ]) + return address + } catch (e) { + throw new Error(`invalid address string: ${e.message}`) + } + } + + /** + * Get the address type from bytes. + * + * @returns the address type enum. + */ + private getType(): number { + if (!this.bytes) { + throw new Error('address bytes is not initialized') + } + return varint.decode(this.bytes) + } + + /** + * Initializes a new address object from a public key. + * + * @param publicKey - The public key to derive the address from. + * + * @returns A new address object. + */ + public static fromPublicKey(publicKey: PublicKey): Address { + if (publicKey.version !== Version.V0) { + throw new Error(`unsupported public key version: ${publicKey.version}`) + } + const address = Address.initFromVersion(Version.V0) + const rawBytes = publicKey.hasher.hash(publicKey.toBytes()) + address.bytes = Uint8Array.from([ + AddressType.EOA, + ...address.versioner.attach(Version.V0, rawBytes), + ]) + address.isEOA = true + return address + } + + /** + * Initializes a new address object from versioned bytes. + * + * @param bytes - The versioned bytes. + * + * @returns A new address object. + */ + public static fromBytes(bytes: Uint8Array): Address { + const version = getVersion(bytes) + const address = Address.initFromVersion(version) + address.bytes = bytes + + // safety check + const addressType = address.getType() + const versionedBytes = bytes.slice(varint.encodingLength(addressType)) + const { version: extractedVersion } = + address.versioner.extract(versionedBytes) + if (extractedVersion !== version) { + throw new Error( + `invalid version: ${version}. ${address.version} was expected.` + ) + } + + address.isEOA = addressType === AddressType.EOA + return address + } + + /** + * Versions the address key bytes. + * + * @returns The versioned address key bytes. + */ + public toBytes(): Uint8Array { + return this.bytes + } + + /** + * Serializes the address to a string. + * + * @remarks + * A address is serialized as follows: + * - The version is serialized as a varint and prepended to the address bytes. + * - The result is then sent to the serializer. + * + * @returns The serialized address string. + */ + toString(): string { + // skip address type bytes + const versionedBytes = this.bytes.slice( + varint.encodingLength(this.getType()) + ) + return `${ + this.isEOA ? ADDRESS_USER_PREFIX : ADDRESS_CONTRACT_PREFIX + }${this.serializer.serialize(versionedBytes)}` + } + + /** + * Get address in binary format from a bytes buffer. + * + * @returns The address in bytes format. + */ + static extractFromBuffer( + data: Uint8Array, + offset = 0 + ): { data: Uint8Array; length: number } { + // addr type + varint.decode(data, offset) + const typeLen = varint.decode.bytes + if (typeLen === undefined) { + throw new Error('invalid address: type not found.') + } + + // version + varint.decode(data, offset + typeLen) + const versionLen = varint.decode.bytes + if (versionLen === undefined) { + throw new Error('invalid address: version not found.') + } + + const addrLen = typeLen + versionLen + UNDERLYING_HASH_LEN + + const extractedData = data.slice(offset, offset + addrLen) + return { data: extractedData, length: addrLen } + } +} diff --git a/packages/web3-utils/src/arguments.ts b/src/basicElements/args.ts similarity index 64% rename from packages/web3-utils/src/arguments.ts rename to src/basicElements/args.ts index 518d7b9b..41075989 100644 --- a/packages/web3-utils/src/arguments.ts +++ b/src/basicElements/args.ts @@ -1,5 +1,50 @@ -import { ISerializable } from './interfaces/ISerializable' -import * as ser from './serializers' +import { + U8, + U16, + U32, + U64, + U128, + U256, + arrayToBytes, + bytesToArray, + bytesToF32, + bytesToF64, + bytesToSerializableObjectArray, + bytesToStr, + deserializeObj, + f32ToBytes, + f64ToBytes, + serializableObjectsArrayToBytes, + strToBytes, + I8, + I16, + I32, + I64, + I128, + I256, +} from './serializers' + +/** + * Interface for serializable objects + * + * @see serialize - serialize object to Uint8Array + * @see deserialize - deserialize Uint8Array to object + */ +export type Serializable = { + serialize(): Uint8Array + deserialize(data: Uint8Array, offset: number): DeserializedResult +} + +/** + * Interface for deserialized result + * + * @see instance - deserialized instance + * @see offset - offset of the deserialized instance + */ +export type DeserializedResult = { + instance: T + offset: number +} /** * Typed Arguments facilitating the differentiation @@ -12,18 +57,23 @@ export enum ArgTypes { STRING, BOOL, U8, + U16, U32, U64, - I128, U128, U256, + I8, + I16, I32, I64, + I128, + I256, F32, F64, ARRAY, UINT8ARRAY, SERIALIZABLE, + //eslint-disable-next-line @typescript-eslint/naming-convention SERIALIZABLE_OBJECT_ARRAY, } @@ -31,18 +81,22 @@ export enum ArrayTypes { STRING, BOOL, U8, + U16, U32, U64, - I128, U128, U256, + I8, + I16, I32, I64, + I128, + I256, F32, F64, } -export interface IParam { +export type IParam = { type: ArgTypes // eslint-disable-next-line @typescript-eslint/no-explicit-any value: any @@ -56,6 +110,10 @@ export interface IParam { */ export type NativeType = string | boolean | number | bigint +const BYTES_32_OFFSET = 4 +const BYTES_64_OFFSET = 8 +export const DEFAULT_OFFSET = 0 + /** * Storage and serialization class for remote function call arguments. * @@ -66,9 +124,7 @@ export type NativeType = string | boolean | number | bigint * */ export class Args { - private offset = 0 - private serialized: Uint8Array - private argsList: Array = [] + private argsList: IParam[] = [] /** * Constructor to either serialize or deserialize data passed from/to DApps and remote Smart contracts. @@ -76,12 +132,12 @@ export class Args { * @param serialized - The optional serialized arguments to deserialize. * @param offset - The optional offset to start deserializing from. */ - constructor(serialized: Array | Uint8Array = [], offset = 0) { - this.serialized = Uint8Array.from(serialized) - this.offset = offset - } + constructor( + public serialized = new Uint8Array(), + public offset = DEFAULT_OFFSET + ) {} - public getArgsList(): Array { + public getArgsList(): IParam[] { return this.argsList } @@ -99,8 +155,8 @@ export class Args { * * @returns A byte array. */ - public serialize(): Array { - return Array.from(this.serialized) + public serialize(): Uint8Array { + return Uint8Array.from(this.serialized) } // Getters @@ -114,14 +170,25 @@ export class Args { * @returns the deserialized string */ public nextString(): string { - const length = this.nextU32() + const length = Number(this.nextU32()) const end = this.offset + length - const result = ser.bytesToStr(this.serialized.slice(this.offset, end)) + const result = bytesToStr(this.serialized.slice(this.offset, end)) this.offset = end return result } + private nextInteger( + extractor: ( + buffer: Uint8Array, + offset: number + ) => { value: bigint; offset: number } + ): bigint { + const { value, offset } = extractor(this.serialized, this.offset) + this.offset = offset + return value + } + /** * Returns the next unsigned byte in the serialized byte array. * @@ -130,11 +197,20 @@ export class Args { * * @returns the deserialized number. */ - public nextU8(): bigint { - const value = ser.byteToU8(this.serialized, this.offset) + public nextU8(): U8.U8_t { + return this.nextInteger(U8.fromBuffer) + } - this.offset++ - return BigInt(value) + /** + * Returns the next unsigned short integer in the serialized byte array. + * + * @remarks + * Increments to offset to point the data after the one that as been deserialized in the byte array. + * + * @returns the deserialized number. + */ + public nextU16(): U16.U16_t { + return this.nextInteger(U16.fromBuffer) } /** @@ -145,11 +221,8 @@ export class Args { * * @returns the deserialized number */ - public nextU32(): number { - const value = ser.bytesToU32(this.serialized, this.offset) - - this.offset += 4 - return value + public nextU32(): U32.U32_t { + return this.nextInteger(U32.fromBuffer) } /** @@ -160,68 +233,56 @@ export class Args { * * @returns the deserialized number. */ - public nextU64(): bigint { - const value = ser.bytesToU64(this.serialized, this.offset) - - this.offset += 8 - return value + public nextU64(): U64.U64_t { + return this.nextInteger(U64.fromBuffer) } /** - * Returns the next int128 in the serialized byte array. + * Returns the next uint128 in the serialized byte array. * * @remarks * Increments to offset to point the data after the one that as been deserialized in the byte array. * * @returns the deserialized number. */ - public nextI128(): bigint { - const value = ser.bytesToI128(this.serialized, this.offset) - - this.offset += 16 - return value + public nextU128(): U128.U128_t { + return this.nextInteger(U128.fromBuffer) } /** - * Returns the next uint128 in the serialized byte array. + * Returns the next uint256 in the serialized byte array. * * @remarks * Increments to offset to point the data after the one that as been deserialized in the byte array. * * @returns the deserialized number. */ - public nextU128(): bigint { - const value = ser.bytesToU128(this.serialized, this.offset) - - this.offset += 16 - return value + public nextU256(): U256.U256_t { + return this.nextInteger(U256.fromBuffer) } /** - * Returns the next uint256 in the serialized byte array. + * Returns the next signed byte in the serialized byte array. * * @remarks * Increments to offset to point the data after the one that as been deserialized in the byte array. * * @returns the deserialized number. */ - public nextU256(): bigint { - const value = ser.bytesToU256(this.serialized, this.offset) - - this.offset += 32 - return value + public nextI8(): I8.I8_t { + return this.nextInteger(I8.fromBuffer) } /** - * Returns the next boolean in the serialized byte array. + * Returns the next signed short integer in the serialized byte array. * * @remarks * Increments to offset to point the data after the one that as been deserialized in the byte array. * - * @returns the deserialized boolean. + * @returns the deserialized number. */ - nextBool(): boolean { - return !!this.serialized[this.offset++] + public nextI16(): I16.I16_t { + return this.nextInteger(I16.fromBuffer) } /** @@ -232,11 +293,20 @@ export class Args { * * @returns the deserialized number. */ - public nextI32(): number { - const value = ser.bytesToI32(this.serialized, this.offset) + public nextI32(): I32.I32_t { + return this.nextInteger(I32.fromBuffer) + } - this.offset += 4 - return value + /** + * Returns the next signed long integer in the serialized byte array. + * + * @remarks + * Increments to offset to point the data after the one that as been deserialized in the byte array. + * + * @returns the deserialized number. + */ + public nextI64(): I64.I64_t { + return this.nextInteger(I64.fromBuffer) } /** @@ -247,11 +317,32 @@ export class Args { * * @returns the deserialized number. */ - public nextI64(): bigint { - const value = ser.bytesToI64(this.serialized, this.offset) + public nextI128(): I128.I128_t { + return this.nextInteger(I128.fromBuffer) + } - this.offset += 8 - return BigInt(value) + /** + * Returns the next signed long integer in the serialized byte array. + * + * @remarks + * Increments to offset to point the data after the one that as been deserialized in the byte array. + * + * @returns the deserialized number. + */ + public nextI256(): I256.I256_t { + return this.nextInteger(I256.fromBuffer) + } + + /** + * Returns the next boolean in the serialized byte array. + * + * @remarks + * Increments to offset to point the data after the one that as been deserialized in the byte array. + * + * @returns the deserialized boolean. + */ + nextBool(): boolean { + return !!this.serialized[this.offset++] } /** @@ -263,9 +354,9 @@ export class Args { * @returns the deserialized number. */ public nextF32(): number { - const value = ser.bytesToF32(this.serialized, this.offset) + const value = bytesToF32(this.serialized, this.offset) - this.offset += 4 + this.offset += BYTES_32_OFFSET return value } @@ -278,9 +369,9 @@ export class Args { * @returns the deserialized number. */ public nextF64(): number { - const value = ser.bytesToF64(this.serialized, this.offset) + const value = bytesToF64(this.serialized, this.offset) - this.offset += 8 + this.offset += BYTES_64_OFFSET return value } @@ -293,7 +384,7 @@ export class Args { * @returns the deserialized byte array. */ public nextUint8Array(): Uint8Array { - const length = this.nextU32() + const length = Number(this.nextU32()) const byteArray = this.serialized.slice(this.offset, this.offset + length) this.offset += length @@ -310,8 +401,8 @@ export class Args { * * @returns the deserialized object T */ - public nextSerializable>(ctor: new () => T): T { - let deserializationResult = ser.deserializeObj( + public nextSerializable>(ctor: new () => T): T { + const deserializationResult = deserializeObj( this.serialized, this.offset, ctor @@ -330,10 +421,10 @@ export class Args { * * @returns the deserialized array of object that implement ISerializable */ - public nextSerializableObjectArray>( + public nextSerializableObjectArray>( ctor: new () => T ): T[] { - const length = this.nextU32() + const length = Number(this.nextU32()) if (!length) { return [] @@ -345,7 +436,7 @@ export class Args { const buffer = this.getNextData(length) - const value = ser.bytesToSerializableObjectArray(buffer, ctor) + const value = bytesToSerializableObjectArray(buffer, ctor) this.offset += length return value } @@ -361,7 +452,7 @@ export class Args { * @returns the next array of object that are native type */ nextArray(type: ArrayTypes): T[] { - const length = this.nextU32() + const length = Number(this.nextU32()) if (!length) { return [] @@ -372,7 +463,7 @@ export class Args { } const buffer = this.getNextData(length) - const value = ser.bytesToArray(buffer, type) + const value = bytesToArray(buffer, type) this.offset += length return value } @@ -386,41 +477,45 @@ export class Args { * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addU8(value: number): this { - this.serialized = Args.concatArrays(this.serialized, ser.u8toByte(value)) + public addU8(value: U8.U8_t): this { + this.serialized = Args.concatArrays(this.serialized, U8.toBytes(value)) this.offset++ this.argsList.push({ type: ArgTypes.U8, value: value }) return this } + public addU16(value: U16.U16_t): this { + this.serialized = Args.concatArrays(this.serialized, U16.toBytes(value)) + this.offset += U16.SIZE_BYTE + this.argsList.push({ type: ArgTypes.U16, value: value }) + return this + } + /** - * Adds a boolean to the serialized arguments. + * Adds an unsigned integer to the serialized arguments. * - * @param value - the boolean to add. + * @param value - the number to add. * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addBool(value: boolean): this { - this.serialized = Args.concatArrays( - this.serialized, - ser.u8toByte(value ? 1 : 0) - ) - this.offset++ - this.argsList.push({ type: ArgTypes.BOOL, value: value }) + public addU32(value: U32.U32_t): this { + this.serialized = Args.concatArrays(this.serialized, U32.toBytes(value)) + this.offset += U32.SIZE_BYTE + this.argsList.push({ type: ArgTypes.U32, value: value }) return this } /** - * Adds an unsigned integer to the serialized arguments. + * Adds an unsigned long integer to the serialized arguments. * * @param value - the number to add. * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addU32(value: number): this { - this.serialized = Args.concatArrays(this.serialized, ser.u32ToBytes(value)) - this.offset += 4 - this.argsList.push({ type: ArgTypes.U32, value: value }) + public addU64(value: U64.U64_t): this { + this.serialized = Args.concatArrays(this.serialized, U64.toBytes(value)) + this.offset += U64.SIZE_BYTE + this.argsList.push({ type: ArgTypes.U64, value: value }) return this } @@ -431,65 +526,52 @@ export class Args { * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addU64(bigInt: bigint): this { - this.serialized = Args.concatArrays(this.serialized, ser.u64ToBytes(bigInt)) - - this.offset += 8 - this.argsList.push({ type: ArgTypes.U64, value: bigInt }) + public addU128(bigInt: U128.U128_t): this { + this.serialized = Args.concatArrays(this.serialized, U128.toBytes(bigInt)) + this.offset += U128.SIZE_BYTE + this.argsList.push({ type: ArgTypes.U128, value: bigInt }) return this } /** - * Adds a signed long integer to the serialized arguments. + * Adds an unsigned long integer to the serialized arguments. * * @param value - the number to add. * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addI128(bigInt: bigint): this { - this.serialized = Args.concatArrays( - this.serialized, - ser.i128ToBytes(bigInt) - ) - - this.offset += 16 - this.argsList.push({ type: ArgTypes.I128, value: bigInt }) + public addU256(bigInt: U256.U256_t): this { + this.serialized = Args.concatArrays(this.serialized, U256.toBytes(bigInt)) + this.offset += U256.SIZE_BYTE + this.argsList.push({ type: ArgTypes.U256, value: bigInt }) return this } /** - * Adds an unsigned long integer to the serialized arguments. + * Adds a signed byte to the serialized arguments. * * @param value - the number to add. * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addU128(bigInt: bigint): this { - this.serialized = Args.concatArrays( - this.serialized, - ser.u128ToBytes(bigInt) - ) - - this.offset += 16 - this.argsList.push({ type: ArgTypes.U128, value: bigInt }) + public addI8(value: I8.I8_t): this { + this.serialized = Args.concatArrays(this.serialized, I8.toBytes(value)) + this.offset++ + this.argsList.push({ type: ArgTypes.I8, value: value }) return this } /** - * Adds an unsigned long integer to the serialized arguments. + * Adds a signed short integer to the serialized arguments. * * @param value - the number to add. * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addU256(bigInt: bigint): this { - this.serialized = Args.concatArrays( - this.serialized, - ser.u256ToBytes(bigInt) - ) - - this.offset += 32 - this.argsList.push({ type: ArgTypes.U256, value: bigInt }) + public addI16(value: I16.I16_t): this { + this.serialized = Args.concatArrays(this.serialized, I16.toBytes(value)) + this.offset += I16.SIZE_BYTE + this.argsList.push({ type: ArgTypes.I16, value: value }) return this } @@ -500,9 +582,9 @@ export class Args { * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addI32(value: number): this { - this.serialized = Args.concatArrays(this.serialized, ser.i32ToBytes(value)) - this.offset += 4 + public addI32(value: I32.I32_t): this { + this.serialized = Args.concatArrays(this.serialized, I32.toBytes(value)) + this.offset += I32.SIZE_BYTE this.argsList.push({ type: ArgTypes.I32, value: value }) return this } @@ -514,10 +596,55 @@ export class Args { * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addI64(bigInt: bigint): this { - this.serialized = Args.concatArrays(this.serialized, ser.i64ToBytes(bigInt)) - this.offset += 8 - this.argsList.push({ type: ArgTypes.I64, value: bigInt }) + public addI64(value: I64.I64_t): this { + this.serialized = Args.concatArrays(this.serialized, I64.toBytes(value)) + this.offset += I64.SIZE_BYTE + this.argsList.push({ type: ArgTypes.I64, value: value }) + return this + } + + /** + * Adds a signed long integer to the serialized arguments. + * + * @param value - the number to add. + * + * @returns the serialized arguments to be able to chain `add` method calls. + */ + public addI128(value: I128.I128_t): this { + this.serialized = Args.concatArrays(this.serialized, I128.toBytes(value)) + this.offset += I128.SIZE_BYTE + this.argsList.push({ type: ArgTypes.I128, value: value }) + return this + } + + /** + * Adds a signed long integer to the serialized arguments. + * + * @param value - the number to add. + * + * @returns the serialized arguments to be able to chain `add` method calls. + */ + public addI256(value: I256.I256_t): this { + this.serialized = Args.concatArrays(this.serialized, I256.toBytes(value)) + this.offset += I256.SIZE_BYTE + this.argsList.push({ type: ArgTypes.I256, value: value }) + return this + } + + /** + * Adds a boolean to the serialized arguments. + * + * @param value - the boolean to add. + * + * @returns the serialized arguments to be able to chain `add` method calls. + */ + public addBool(value: boolean): this { + this.serialized = Args.concatArrays( + this.serialized, + U8.toBytes(value ? 1n : 0n) + ) + this.offset++ + this.argsList.push({ type: ArgTypes.BOOL, value: value }) return this } @@ -529,8 +656,8 @@ export class Args { * @returns the serialized arguments to be able to chain `add` method calls. */ public addF32(value: number): this { - this.serialized = Args.concatArrays(this.serialized, ser.f32ToBytes(value)) - this.offset += 4 + this.serialized = Args.concatArrays(this.serialized, f32ToBytes(value)) + this.offset += BYTES_32_OFFSET this.argsList.push({ type: ArgTypes.F32, value: value }) return this } @@ -543,8 +670,8 @@ export class Args { * @returns the serialized arguments to be able to chain `add` method calls. */ public addF64(value: number): this { - this.serialized = Args.concatArrays(this.serialized, ser.f64ToBytes(value)) - this.offset += 8 + this.serialized = Args.concatArrays(this.serialized, f64ToBytes(value)) + this.offset += BYTES_64_OFFSET this.argsList.push({ type: ArgTypes.F64, value: value }) return this } @@ -557,7 +684,7 @@ export class Args { * @returns the serialized arguments to be able to chain `add` method calls. */ public addUint8Array(array: Uint8Array): this { - this.addU32(array.length) + this.addU32(U32.fromNumber(array.length)) this.serialized = Args.concatArrays(this.serialized, array) this.offset += array.length // Remove the U32 from the argsList @@ -586,10 +713,10 @@ export class Args { value = value.slice(0, maxSize) } - const serialized = ser.strToBytes(value) - this.addU32(serialized.length) - this.serialized = Args.concatArrays(this.serialized, ser.strToBytes(value)) - this.offset += ser.strToBytes(value).length + const serialized = strToBytes(value) + this.addU32(U32.fromNumber(serialized.length)) + this.serialized = Args.concatArrays(this.serialized, strToBytes(value)) + this.offset += strToBytes(value).length // Remove the U32 from the argsList this.argsList.pop() @@ -610,7 +737,7 @@ export class Args { * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addSerializable(value: ISerializable): this { + public addSerializable(value: Serializable): this { const serializedValue = value.serialize() this.serialized = Args.concatArrays(this.serialized, serializedValue) this.offset += serializedValue.length @@ -632,11 +759,9 @@ export class Args { * * @returns the serialized arguments to be able to chain `add` method calls. */ - public addSerializableObjectArray>( - arg: T[] - ): this { - const content: Uint8Array = ser.serializableObjectsArrayToBytes(arg) - this.addU32(content.length) + public addSerializableObjectArray>(arg: T[]): this { + const content: Uint8Array = serializableObjectsArrayToBytes(arg) + this.addU32(U32.fromNumber(content.length)) this.serialized = Args.concatArrays(this.serialized, content) this.offset += content.length @@ -663,8 +788,8 @@ export class Args { * @returns the serialized arguments to be able to chain `add` method calls. */ addArray(arg: NativeType[], type: ArrayTypes): this { - const content = ser.arrayToBytes(arg, type) - this.addU32(content.length) + const content = arrayToBytes(arg, type) + this.addU32(U32.fromNumber(content.length)) this.serialized = Args.concatArrays(this.serialized, content) this.offset += content.length diff --git a/src/basicElements/bytecode.ts b/src/basicElements/bytecode.ts new file mode 100644 index 00000000..3f02a97b --- /dev/null +++ b/src/basicElements/bytecode.ts @@ -0,0 +1,65 @@ +/** + * A module to compile and execute byte code. + * + * @remarks + * The difference between byte code and a smart contract is that the byte code is the raw code that will be + * executed on the blockchain, while a smart contract is the code that is already deployed on the blockchain. + * The byte code is only ephemeral and will be executed only once. + * A smart contract has an address and exposes functions that can be called multiple times. + * + */ +import { PublicAPI } from '../client' +import { PrivateKey } from './keys' +import { + OperationManager, + getAbsoluteExpirePeriod, +} from '../operation/operationManager' +import { U64_t } from './serializers/number/u64' +import { ExecuteOperation, OperationType } from '../operation' + +export const MAX_GAS_EXECUTE = 3980167295n + +type ExecuteOption = { + fee?: U64_t + periodToLive?: number + maxCoins?: U64_t + maxGas?: U64_t + datastore?: Map +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function compile(_source: string): Promise { + throw new Error('Not implemented') +} + +/** + * + * Executes a byte code on the blockchain. + * + * @param client - The client to connect to the desired blockchain. + * @param privateKey - The private key of the account that will execute the byte code. + * @param byteCode - The byte code to execute. + * @param opts - Optional execution details. + * + * @returns The operation. + */ +export async function execute( + client: PublicAPI, + privateKey: PrivateKey, + byteCode: Uint8Array, + opts: ExecuteOption +): Promise { + const operation = new OperationManager(privateKey, client) + + const details: ExecuteOperation = { + fee: opts?.fee ?? (await client.getMinimalFee()), + expirePeriod: await getAbsoluteExpirePeriod(client, opts.periodToLive), + type: OperationType.ExecuteSmartContractBytecode, + maxCoins: opts?.maxCoins ?? 0n, + maxGas: opts?.maxGas || MAX_GAS_EXECUTE, + contractDataBinary: byteCode, + datastore: opts.datastore, + } + + return operation.send(details) +} diff --git a/src/basicElements/index.ts b/src/basicElements/index.ts new file mode 100644 index 00000000..f058fe4d --- /dev/null +++ b/src/basicElements/index.ts @@ -0,0 +1,8 @@ +export * from './address' +export * from './signature' +export * from './keys' +export * from './storage' +export * from './args' +export * from './serializers' +export * as Mas from './mas' +export * from './serializers' diff --git a/src/basicElements/internal.ts b/src/basicElements/internal.ts new file mode 100644 index 00000000..cc5f274e --- /dev/null +++ b/src/basicElements/internal.ts @@ -0,0 +1,41 @@ +import Serializer from '../crypto/interfaces/serializer' +import { Versioner, Version } from '../crypto/interfaces/versioner' + +/** + * Deserialize a string data into non versioned bytes and checks that expected version match. + * + * @returns the extracted data. + */ +export function extractData( + serializer: Serializer, + versioner: Versioner, + data: string, + expectedVersion: Version +): Uint8Array { + const raw = serializer.deserialize(data) + const { data: extractedData, version } = versioner.extract(raw) + if (version !== expectedVersion) { + throw new Error( + `invalid version: ${version}. ${expectedVersion} was expected.` + ) + } + return extractedData +} + +/** + * Get the prefix of a string and validate it against the expected ones. + * + * @remarks + * If several prefixes are expected, their length must be the same. + * + * @returns the extracted prefix. + */ +export function mustExtractPrefix(str: string, ...expected: string[]): string { + const prefix = str.slice(0, expected[0].length) + if (!expected.includes(prefix)) { + throw new Error( + `invalid prefix: ${prefix}. ${expected.length > 1 ? 'one of ' : ''}${expected.join(' or ')} was expected.` + ) + } + return prefix +} diff --git a/src/basicElements/keys.ts b/src/basicElements/keys.ts new file mode 100644 index 00000000..c8e39309 --- /dev/null +++ b/src/basicElements/keys.ts @@ -0,0 +1,379 @@ +import { Signature } from './signature' +import { Address } from './address' +import Base58 from '../crypto/base58' +import Blake3 from '../crypto/blake3' +import Ed25519 from '../crypto/ed25519' +import Hasher from '../crypto/interfaces/hasher' +import Serializer from '../crypto/interfaces/serializer' +import Signer from '../crypto/interfaces/signer' +import { Version, Versioner } from '../crypto/interfaces/versioner' +import VarintVersioner from '../crypto/varintVersioner' + +const PRIVATE_KEY_PREFIX = 'S' +const PUBLIC_KEY_PREFIX = 'P' + +/** + * Get the version from string or bytes key. + * + * @remarks + * For now the function is common for private & public key but it might change in the future. + * + * @returns the key version. + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function getVersion(data: string | Uint8Array): Version { + // When a new version will come, implement the logic to detect version here + // This should be done without serializer and versionner as they are potentially not known at this point + return Version.V0 +} + +/** + * A class representing a private key. + * + * @remarks + * The private key is used to sign operations during interactions with the blockchain. + * + * @privateRemarks + * Interfaces are used to make the code more modular. To add a new version, you simply need to + * extend the `initFromVersion` method: + * - Add a new case in the switch statement with the new algorithms to use. + * - Add a new default version matching the last version. + * - Voila! The code will automatically handle the new version. + */ +export class PrivateKey { + // The key in byte format. Version included. + private bytes: Uint8Array + private prefix = PRIVATE_KEY_PREFIX + + // eslint-disable-next-line max-params + protected constructor( + public hasher: Hasher, + public signer: Signer, + public serializer: Serializer, + public versioner: Versioner, + public version: Version + ) {} + + /** + * Initializes a new private key object from a version. + * + * @param version - The version of the private key. If not defined, the last version will be used. + * + * @returns A new private key instance. + */ + protected static initFromVersion(version: Version = Version.V0): PrivateKey { + switch (version) { + case Version.V0: + return new PrivateKey( + new Blake3(), + new Ed25519(), + new Base58(), + new VarintVersioner(), + version + ) + default: + throw new Error(`unsupported version: ${version}`) + } + } + + private checkPrefix(str: string): void { + if (!str.startsWith(this.prefix)) { + throw new Error( + `invalid private key prefix: ${this.prefix} was expected.` + ) + } + } + + /** + * Initializes a new private key object from a serialized string. + * + * @param str - The serialized private key string. + * + * @returns A new private key instance. + * + * @throws If the private key prefix is invalid. + */ + public static fromString(str: string): PrivateKey { + try { + const version = getVersion(str) + const privateKey = PrivateKey.initFromVersion(version) + privateKey.checkPrefix(str) + privateKey.bytes = privateKey.serializer.deserialize( + str.slice(privateKey.prefix.length) + ) + return privateKey + } catch (e) { + throw new Error(`invalid private key string: ${e.message}`) + } + } + + /** + * Initializes a new private key object from a byte array. + * + * @param bytes - The private key in byte format. + * + * @returns A new private key instance. + */ + public static fromBytes(bytes: Uint8Array): PrivateKey { + const version = getVersion(bytes) + const privateKey = PrivateKey.initFromVersion(version) + privateKey.bytes = bytes + return privateKey + } + + /** + * Initializes a new private key object from the environment variables. + * + * @param key - The environment variable name containing the private key. + * + * @remarks + * The `PRIVATE_KEY` or the provided key is required in the environment variables. + * + * @returns A new private key instance. + */ + public static fromEnv(key = 'PRIVATE_KEY'): PrivateKey { + const privateKey = process.env[key] + + if (!privateKey) { + throw new Error(`missing \`${key}\` environment variable`) + } + + return PrivateKey.fromString(privateKey) + } + + /** + * Initializes a random private key. + * + * @param version - The version of the private key. If not defined, the last version will be used. + * + * @returns A new private key instance. + */ + public static generate(version?: Version): PrivateKey { + const privateKey = PrivateKey.initFromVersion(version) + const rawBytes = privateKey.signer.generatePrivateKey() + privateKey.bytes = privateKey.versioner.attach(privateKey.version, rawBytes) + return privateKey + } + + /** + * Returns the public key matching to the current private key. + * + * @returns A new public key instance. + */ + public async getPublicKey(): Promise { + return PublicKey.fromPrivateKey(this) + } + + /** + * Signs the message with the private key. + * + * @remarks + * This function signs a byte-encoded message. The message is first hashed and then signed. + * Do not pass a digest to this function as it will be hashed twice. + * + * @param message - The byte array to sign. + * + * @returns The signature byte array. + */ + public async sign(message: Uint8Array): Promise { + const { data } = this.versioner.extract(this.bytes) + const signature = await this.signer.sign(data, this.hasher.hash(message)) + return Signature.fromBytes(this.versioner.attach(this.version, signature)) + } + + /** + * Private key in bytes. + * + * @returns The versioned private key bytes. + */ + public toBytes(): Uint8Array { + return this.bytes + } + + /** + * Serializes the private key to a string. + * + * @remarks + * A private key is serialized as follows: + * - The version is serialized as a varint and prepended to the private key bytes. + * - The result is then sent to the serializer. + * + * @returns The serialized private key string. + */ + public toString(): string { + return `${this.prefix}${this.serializer.serialize(this.bytes)}` + } +} + +/** + * A class representing a public key. + * + * @remarks + * The public key is an essential component of asymmetric cryptography. It is intrinsically linked to the private key. + * + * @privateRemarks + * Interfaces are used to make the code more modular. To add a new version, you simply need to: + * - extend the `initFromVersion` method: + * - Add a new case in the switch statement with the new algorithms to use. + * - Add a new default version matching the last version. + * - check the `fromPrivateKey` method to potentially adapt how a public key is derived from a private key. + * - Voila! The code will automatically handle the new version. + */ +export class PublicKey { + // The key in byte format. Version included. + private bytes: Uint8Array + private prefix = PUBLIC_KEY_PREFIX + + // eslint-disable-next-line max-params + protected constructor( + public hasher: Hasher, + public signer: Signer, + public serializer: Serializer, + public versioner: Versioner, + public version: Version + ) {} + + /** + * Initializes a new public key object from a version. + * + * @param version - The version of the private key. If not defined, the last version will be used. + * + * @returns A new public key instance. + * + * @throws If the version is not supported. + */ + protected static initFromVersion(version: Version = Version.V0): PublicKey { + switch (version) { + case Version.V0: + return new PublicKey( + new Blake3(), + new Ed25519(), + new Base58(), + new VarintVersioner(), + version + ) + default: + throw new Error(`unsupported version: ${version}`) + } + } + + private checkPrefix(str: string): void { + if (!str.startsWith(this.prefix)) { + throw new Error(`invalid public key prefix: ${this.prefix} was expected.`) + } + } + + /** + * Initializes a new public key object from a serialized string. + * + * @param str - The serialized public key string. + * + * @returns A new public key instance. + * + * @throws If the public key prefix is invalid. + */ + public static fromString(str: string): PublicKey { + try { + const version = getVersion(str) + const publicKey = PublicKey.initFromVersion(version) + publicKey.checkPrefix(str) + publicKey.bytes = publicKey.serializer.deserialize( + str.slice(publicKey.prefix.length) + ) + return publicKey + } catch (e) { + throw new Error(`invalid public key string: ${e.message}`) + } + } + + /** + * Initializes a new public key object from a byte array. + * + * @param bytes - The public key in byte format. + * + * @returns A new public key instance. + */ + public static fromBytes(bytes: Uint8Array): PublicKey { + const version = getVersion(bytes) + const publicKey = PublicKey.initFromVersion(version) + publicKey.bytes = bytes + return publicKey + } + + /** + * Initializes a new public key object from a private key. + * + * @param privateKey - The private key to derive the public key from. + * + * @returns A new public key instance. + */ + public static async fromPrivateKey( + privateKey: PrivateKey + ): Promise { + const publicKey = PublicKey.initFromVersion() + const { data } = publicKey.versioner.extract(privateKey.toBytes()) + const publicKeyBytes = await publicKey.signer.getPublicKey(data) + publicKey.bytes = publicKey.versioner.attach( + publicKey.version, + publicKeyBytes + ) + return publicKey + } + + /** + * Get an address from the public key. + * + * @returns A new address object. + */ + public getAddress(): Address { + return Address.fromPublicKey(this) + } + + /** + * Checks the message signature with the public key. + * + * @remarks + * This function very a byte-encoded message. The message is first hashed and then verified. + * Do not pass a digest to this function as it will be hashed twice. + * + * @param signature - The signature to verify. + * @param data - The data signed by the signature. + * + * @returns A boolean indicating whether the signature is valid. + */ + public async verify( + data: Uint8Array, + signature: Signature + ): Promise { + const { data: rawSignature } = this.versioner.extract(signature.toBytes()) + const { data: rawPublicKey } = this.versioner.extract(this.bytes) + return await this.signer.verify( + rawPublicKey, + this.hasher.hash(data), + rawSignature + ) + } + + /** + * Public key in bytes. + * + * @returns The versioned public key bytes. + */ + public toBytes(): Uint8Array { + return this.bytes + } + + /** + * Serializes the public key to a string. + * + * @remarks + * A public key is serialized as follows: + * - The version is serialized as a varint and prepended to the public key bytes. + * - The result is then sent to the serializer. + * + * @returns The serialized public key string. + */ + public toString(): string { + return `${this.prefix}${this.serializer.serialize(this.bytes)}` + } +} diff --git a/src/basicElements/mas.ts b/src/basicElements/mas.ts new file mode 100644 index 00000000..67bc86d6 --- /dev/null +++ b/src/basicElements/mas.ts @@ -0,0 +1,124 @@ +import Decimal from 'decimal.js' +import { U64_t, fromNumber } from './serializers/number/u64' + +export const NB_DECIMALS = 9 +export const SIZE_U256_BIT = 256 +const POWER_TEN = 10 + +export const ERROR_NOT_SAFE_INTEGER = 'value is not a safe integer.' +export const ERROR_VALUE_TOO_LARGE = 'value is too large.' + +/** + * Defines 'Mas' as a type for representing nano massa, + * the smallest unit in Massa currency equivalent to 10^9. + */ +export type Mas = U64_t + +/** + * Converts an integer value to the smallest unit of the Massa currency. + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger#description + * + * @param value - The integer value. + * @returns The value in the smallest unit of the Massa currency. + * + * @throws An error if the value is not a safe integer. + */ +export function fromMas(value: U64_t): Mas { + return fromNumber(value * BigInt(POWER_TEN) ** BigInt(NB_DECIMALS)) +} + +/** + * Converts an integer value in milli Massa to the smallest unit of the Massa currency. + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger#description + * + * @param value - The value in milli Massa. + * @returns The value in the smallest unit of the Massa currency. + * + * @throws An error if the value is not a safe integer. + */ +export function fromMilliMas(value: U64_t): Mas { + const milli = 3 + return fromNumber(value * BigInt(POWER_TEN) ** BigInt(NB_DECIMALS - milli)) +} + +/** + * Converts an integer value in micro Massa to the smallest unit of the Massa currency. + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger#description + * + * @param value - The value in micro Massa. + * @returns The value in the smallest unit of the Massa currency. + * + * @throws An error if the value is not a safe integer. + */ +export function fromMicroMas(value: U64_t): Mas { + const micro = 6 + return fromNumber(value * BigInt(POWER_TEN) ** BigInt(NB_DECIMALS - micro)) +} + +/** + * Converts an integer value in nano Massa to the smallest unit of the Massa currency. + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger#description + * + * @param value - The value in nano Massa. + * @returns The value in the smallest unit of the Massa currency. + * + * @throws An error if the value is not a safe integer. + */ +export function fromNanoMas(value: U64_t): Mas { + const nano = 9 + return fromNumber(value * BigInt(POWER_TEN) ** BigInt(NB_DECIMALS - nano)) +} + +/** + * Converts a decimal value in Mas to the smallest unit of the Massa currency. + * + * @param value - The decimal value. + * @returns The value in the smallest unit of the Massa currency. + * + * @throws An error if the format is not a decimal. + * @throws An error if the value is too large to be represented by an U256 or has too many decimals. + */ +export function fromString(value: string): Mas { + const parts = value.split('.') + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + if (parts.length > 2) { + throw new Error('invalid format') + } + + const integerPart = parts[0] + const decimalPart = parts[1] || '' + if (decimalPart.length > NB_DECIMALS) { + throw new Error(ERROR_VALUE_TOO_LARGE) + } + + const mas = BigInt(integerPart + decimalPart.padEnd(NB_DECIMALS, '0')) + + return fromNumber(mas) +} +/** + * Converts a Mas value to a string with rounding approximation. + * + * @param value - The Mas value. + * @param decimalPlaces - The number of decimal places to include in the string. + * @returns The value as a string. + * + * @throws An error if the value is too large to be represented by a U256. + */ +export function toString( + value: Mas, + decimalPlaces: number | null = null +): string { + if (BigInt(value) >= 1n << BigInt(SIZE_U256_BIT)) { + throw new Error(ERROR_VALUE_TOO_LARGE) + } + + const scaledValue = new Decimal(value.toString()).div(`1e+${NB_DECIMALS}`) + + return decimalPlaces !== null + ? scaledValue.toFixed(decimalPlaces, Decimal.ROUND_HALF_UP) + : scaledValue.toString() +} diff --git a/packages/web3-utils/src/serializers/arrays.ts b/src/basicElements/serializers/arrays.ts similarity index 60% rename from packages/web3-utils/src/serializers/arrays.ts rename to src/basicElements/serializers/arrays.ts index ee45b875..a89ef681 100644 --- a/packages/web3-utils/src/serializers/arrays.ts +++ b/src/basicElements/serializers/arrays.ts @@ -1,19 +1,17 @@ /* eslint-disable no-case-declarations */ -import { Args, NativeType, ArrayTypes } from '../arguments' -import { IDeserializedResult, ISerializable } from '../interfaces/ISerializable' +import { + Args, + NativeType, + ArrayTypes, + DeserializedResult, + Serializable, + DEFAULT_OFFSET, +} from '../args' import { bytesToStr } from './strings' import { byteToBool } from './bool' -import { - byteToU8, - bytesToF32, - bytesToF64, - bytesToI32, - bytesToI64, - bytesToU32, - bytesToU64, -} from './numbers' -import { bytesToI128, bytesToU128, bytesToU256 } from './bignum' +import { bytesToF32, bytesToF64 } from './numbers' +import { U8, U16, U32, U64, U128, U256, I8, I16, I32, I64, I128, I256 } from '.' /** * Get the byte size of a typed array unit. @@ -22,24 +20,26 @@ import { bytesToI128, bytesToU128, bytesToU256 } from './bignum' * * @returns The size of the typed array unit. */ -export const getDatatypeSize = (type: ArrayTypes): number => { +// eslint-disable-next-line @typescript-eslint/naming-convention +export function getDatatypeSize(type: ArrayTypes): number { switch (type) { case ArrayTypes.BOOL: case ArrayTypes.U8: - return 1 + case ArrayTypes.I8: + return U8.SIZE_BYTE case ArrayTypes.F32: case ArrayTypes.I32: case ArrayTypes.U32: - return 4 + return U32.SIZE_BYTE case ArrayTypes.F64: case ArrayTypes.I64: case ArrayTypes.U64: - return 8 + return U64.SIZE_BYTE case ArrayTypes.I128: case ArrayTypes.U128: - return 16 + return U128.SIZE_BYTE case ArrayTypes.U256: - return 32 + return U256.SIZE_BYTE default: throw new Error(`Unsupported type: ${Object.keys(ArrayTypes)[type]}`) } @@ -53,11 +53,12 @@ export const getDatatypeSize = (type: ArrayTypes): number => { * @returns The serialized array as Uint8Array. */ -export function serializableObjectsArrayToBytes>( +export function serializableObjectsArrayToBytes>( source: T[] ): Uint8Array { return source.reduce( (acc, curr) => Args.concatArrays(acc, curr.serialize()), + //eslint-disable-next-line @typescript-eslint/no-magic-numbers new Uint8Array(0) ) } @@ -67,36 +68,35 @@ export function serializableObjectsArrayToBytes>( * * @param data - The bytes array to deserialize. * @param offset - The offset to start deserializing from. - * @param Clazz - The class used for deserialization. + * @param obj - The class used for deserialization. * * @returns The deserialized array of objects. */ -export function deserializeObj>( +export function deserializeObj>( data: Uint8Array, offset: number, - Clazz: new () => T -): IDeserializedResult { - const deserialized = new Clazz().deserialize(data, offset) - return deserialized + obj: new () => T +): DeserializedResult { + return new obj().deserialize(data, offset) } /** * Converts a Uint8Array into an array of deserialized type parameters. * * @param source - The Uint8Array to convert. - * @param Clazz - The class constructor for deserialization. + * @param obj - The class constructor for deserialization. * * @returns An array of deserialized objects. */ -export function bytesToSerializableObjectArray>( +export function bytesToSerializableObjectArray>( source: Uint8Array, - Clazz: new () => T + obj: new () => T ): T[] { const array: T[] = [] - let offset = 0 + let offset = DEFAULT_OFFSET while (offset < source.length) { - let deserializationResult = deserializeObj(source, offset, Clazz) + const deserializationResult = deserializeObj(source, offset, obj) offset = deserializationResult.offset array.push(deserializationResult.instance) } @@ -120,7 +120,7 @@ export function arrayToBytes( source: NativeType[], type: ArrayTypes ): Uint8Array { - let args = new Args() + const args = new Args() source.forEach((value) => { switch (type) { case ArrayTypes.STRING: @@ -130,34 +130,46 @@ export function arrayToBytes( args.addBool(value as boolean) break case ArrayTypes.U8: - args.addU8(value as number) + args.addU8(value as U8.U8_t) break - case ArrayTypes.F64: - args.addF64(value as number) + case ArrayTypes.U16: + args.addU16(value as U16.U16_t) break - case ArrayTypes.F32: - args.addF32(value as number) + case ArrayTypes.U32: + args.addU32(value as U32.U32_t) break - case ArrayTypes.I32: - args.addI32(value as number) + case ArrayTypes.U64: + args.addU64(value as U64.U64_t) break - case ArrayTypes.I64: - args.addI64(value as bigint) + case ArrayTypes.U128: + args.addU128(value as U128.U128_t) break - case ArrayTypes.U32: - args.addU32(value as number) + case ArrayTypes.U256: + args.addU256(value as U256.U256_t) break - case ArrayTypes.U64: - args.addU64(value as bigint) + case ArrayTypes.I8: + args.addI8(value as I8.I8_t) + break + case ArrayTypes.I16: + args.addI16(value as I16.I16_t) + break + case ArrayTypes.I32: + args.addI32(value as I32.I32_t) + break + case ArrayTypes.I64: + args.addI64(value as I64.I64_t) break case ArrayTypes.I128: - args.addI128(value as bigint) + args.addI128(value as I128.I128_t) break - case ArrayTypes.U128: - args.addU128(value as bigint) + case ArrayTypes.I256: + args.addI256(value as I256.I256_t) break - case ArrayTypes.U256: - args.addU256(value as bigint) + case ArrayTypes.F64: + args.addF64(value as number) + break + case ArrayTypes.F32: + args.addF32(value as number) break default: throw new Error(`Unsupported type: ${type}`) @@ -180,21 +192,22 @@ export function arrayToBytes( export function bytesToArray(source: Uint8Array, type: ArrayTypes): T[] { const sourceLength = source.length - let byteOffset = 0 + let byteOffset = DEFAULT_OFFSET const result: T[] = [] - let eltSize: number + let elementSize = 0 if (type !== ArrayTypes.STRING) { - eltSize = getDatatypeSize(type) + elementSize = getDatatypeSize(type) } while (byteOffset < sourceLength) { if (type === ArrayTypes.STRING) { - eltSize = bytesToU32(source, byteOffset) - byteOffset += 4 + const { value, offset } = U32.fromBuffer(source, byteOffset) + elementSize = Number(value) + byteOffset = offset } - const elt = source.slice(byteOffset, byteOffset + eltSize) - byteOffset += eltSize + const elt = source.slice(byteOffset, byteOffset + elementSize) + byteOffset += elementSize switch (type) { case ArrayTypes.STRING: @@ -204,34 +217,46 @@ export function bytesToArray(source: Uint8Array, type: ArrayTypes): T[] { result.push(byteToBool(elt) as T) break case ArrayTypes.U8: - result.push(byteToU8(elt) as T) + result.push(U8.fromBytes(elt) as T) break - case ArrayTypes.F32: - result.push(bytesToF32(elt) as T) + case ArrayTypes.U16: + result.push(U16.fromBytes(elt) as T) break - case ArrayTypes.F64: - result.push(bytesToF64(elt) as T) + case ArrayTypes.U32: + result.push(U32.fromBytes(elt) as T) break - case ArrayTypes.I32: - result.push(bytesToI32(elt) as T) + case ArrayTypes.U64: + result.push(U64.fromBytes(elt) as T) break - case ArrayTypes.I64: - result.push(bytesToI64(elt) as T) + case ArrayTypes.U128: + result.push(U128.fromBytes(elt) as T) break - case ArrayTypes.U32: - result.push(bytesToU32(elt) as T) + case ArrayTypes.U256: + result.push(U256.fromBytes(elt) as T) break - case ArrayTypes.U64: - result.push(bytesToU64(elt) as T) + case ArrayTypes.I8: + result.push(I8.fromBytes(elt) as T) + break + case ArrayTypes.I16: + result.push(I16.fromBytes(elt) as T) + break + case ArrayTypes.I32: + result.push(I32.fromBytes(elt) as T) + break + case ArrayTypes.I64: + result.push(I64.fromBytes(elt) as T) break case ArrayTypes.I128: - result.push(bytesToI128(elt) as T) + result.push(I128.fromBytes(elt) as T) break - case ArrayTypes.U128: - result.push(bytesToU128(elt) as T) + case ArrayTypes.I256: + result.push(I256.fromBytes(elt) as T) break - case ArrayTypes.U256: - result.push(bytesToU256(elt) as T) + case ArrayTypes.F32: + result.push(bytesToF32(elt) as T) + break + case ArrayTypes.F64: + result.push(bytesToF64(elt) as T) break } } diff --git a/packages/web3-utils/src/serializers/bool.ts b/src/basicElements/serializers/bool.ts similarity index 79% rename from packages/web3-utils/src/serializers/bool.ts rename to src/basicElements/serializers/bool.ts index db2c2ff8..e11b729a 100644 --- a/packages/web3-utils/src/serializers/bool.ts +++ b/src/basicElements/serializers/bool.ts @@ -1,3 +1,5 @@ +const FIRST = 0 +const SECOND = 1 /** * Converts a Uint8Array to a boolean value. * @@ -6,7 +8,7 @@ * @returns The converted boolean value. */ export function byteToBool(arr: Uint8Array): boolean { - return !!arr[0] + return !!arr[FIRST] } /** @@ -17,5 +19,5 @@ export function byteToBool(arr: Uint8Array): boolean { * @returns The converted Uint8Array. */ export function boolToByte(val: boolean): Uint8Array { - return new Uint8Array([val ? 1 : 0]) + return new Uint8Array([val ? SECOND : FIRST]) } diff --git a/packages/web3-utils/src/serializers/index.ts b/src/basicElements/serializers/index.ts similarity index 76% rename from packages/web3-utils/src/serializers/index.ts rename to src/basicElements/serializers/index.ts index 0618a1ca..bf65db1f 100644 --- a/packages/web3-utils/src/serializers/index.ts +++ b/src/basicElements/serializers/index.ts @@ -4,7 +4,7 @@ * booleans, and arrays containing native types. */ -import { Args, IParam } from '../arguments' +import { Args, IParam } from '../args' /** * This module exports encoding and decoding functions for strings. @@ -18,13 +18,6 @@ export * from './strings' */ export * from './numbers' -/** - * This module exports functions needed to process numeric data, such as integers and - * floating point numbers and their binary representations in Uint8Array. - * The functions handle signed and unsigned integers bignumbers integers. - */ -export * from './bignum' - /** * This module exports encoding and decoding functions for booleans. */ @@ -38,6 +31,11 @@ export * from './arrays' export function argsListToBytes(argsList: IParam[]): Uint8Array { return argsList.reduce( (acc, curr) => Args.concatArrays(acc, new TextEncoder().encode(curr.value)), + // eslint-disable-next-line @typescript-eslint/no-magic-numbers new Uint8Array(0) ) } + +export * from './number/index' + +export * from './interface' diff --git a/packages/web3-utils/src/interfaces/ISerializable.ts b/src/basicElements/serializers/interface/ISerializable.ts similarity index 77% rename from packages/web3-utils/src/interfaces/ISerializable.ts rename to src/basicElements/serializers/interface/ISerializable.ts index cea6eca6..1d91f74f 100644 --- a/packages/web3-utils/src/interfaces/ISerializable.ts +++ b/src/basicElements/serializers/interface/ISerializable.ts @@ -4,6 +4,7 @@ * @see serialize - serialize object to Uint8Array * @see deserialize - deserialize Uint8Array to object */ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions export interface ISerializable { serialize(): Uint8Array deserialize(data: Uint8Array, offset: number): IDeserializedResult @@ -15,6 +16,7 @@ export interface ISerializable { * @see instance - deserialized instance * @see offset - offset of the deserialized instance */ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions export interface IDeserializedResult { instance: T offset: number diff --git a/src/basicElements/serializers/interface/index.ts b/src/basicElements/serializers/interface/index.ts new file mode 100644 index 00000000..dbd4f4da --- /dev/null +++ b/src/basicElements/serializers/interface/index.ts @@ -0,0 +1 @@ +export * from './ISerializable' diff --git a/src/basicElements/serializers/number/i128.ts b/src/basicElements/serializers/number/i128.ts new file mode 100644 index 00000000..14819084 --- /dev/null +++ b/src/basicElements/serializers/number/i128.ts @@ -0,0 +1,59 @@ +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type I128_t = bigint + +export const SIZE_BYTE = 16 +export const SIZE_BIT = 128 +export const MIN = -(1n << (BigInt(SIZE_BIT) - 1n)) +export const MAX = (1n << (BigInt(SIZE_BIT) - 1n)) - 1n + +/** + * Converts an I128 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is out of range for I128 + */ +export function toBytes(value: I128_t): Uint8Array { + return integerToByte(SIZE_BIT, value, true) +} + +/** + * Converts bytes to an I128 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the I128 value. + * + * @param bytes - The bytes to convert + * @returns The I128 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): I128_t { + return integerFromByte(SIZE_BIT, bytes, true) +} + +/** + * Converts an I128 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the I128 value (default: 0) + * @returns The I128 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: I128_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, true, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an I128 value + * + * @param value - The number to convert + * @returns The I128 representation of the number + * @throws if the value is not a safe integer or out of range for I128 + */ +export function fromNumber(value: number | bigint): I128_t { + return numberToInteger(SIZE_BIT, value, true) +} diff --git a/src/basicElements/serializers/number/i16.ts b/src/basicElements/serializers/number/i16.ts new file mode 100644 index 00000000..039b3004 --- /dev/null +++ b/src/basicElements/serializers/number/i16.ts @@ -0,0 +1,59 @@ +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type I16_t = bigint + +export const SIZE_BYTE = 2 +export const SIZE_BIT = 16 +export const MIN = -(1n << (BigInt(SIZE_BIT) - 1n)) +export const MAX = (1n << (BigInt(SIZE_BIT) - 1n)) - 1n + +/** + * Converts an I16 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is out of range for I16 + */ +export function toBytes(value: I16_t): Uint8Array { + return integerToByte(SIZE_BIT, value, true) +} + +/** + * Converts bytes to an I16 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the I16 value. + * + * @param bytes - The bytes to convert + * @returns The I16 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): I16_t { + return integerFromByte(SIZE_BIT, bytes, true) +} + +/** + * Converts an I16 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the I16 value (default: 0) + * @returns The I16 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: I16_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, true, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an I16 value + * + * @param value - The number to convert + * @returns The I16 representation of the number + * @throws if the value is not a safe integer or out of range for I16 + */ +export function fromNumber(value: number): I16_t { + return numberToInteger(SIZE_BIT, value, true) +} diff --git a/src/basicElements/serializers/number/i256.ts b/src/basicElements/serializers/number/i256.ts new file mode 100644 index 00000000..a953cef5 --- /dev/null +++ b/src/basicElements/serializers/number/i256.ts @@ -0,0 +1,59 @@ +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type I256_t = bigint + +export const SIZE_BYTE = 32 +export const SIZE_BIT = 256 +export const MIN = -(1n << (BigInt(SIZE_BIT) - 1n)) +export const MAX = (1n << (BigInt(SIZE_BIT) - 1n)) - 1n + +/** + * Converts an I256 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is out of range for I256 + */ +export function toBytes(value: I256_t): Uint8Array { + return integerToByte(SIZE_BIT, value, true) +} + +/** + * Converts bytes to an I256 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the I256 value. + * + * @param bytes - The bytes to convert + * @returns The I256 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): I256_t { + return integerFromByte(SIZE_BIT, bytes, true) +} + +/** + * Converts an I256 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the I256 value (default: 0) + * @returns The I256 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: I256_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, true, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an I256 value + * + * @param value - The number to convert + * @returns The I256 representation of the number + * @throws if the value is not a safe integer or out of range for I256 + */ +export function fromNumber(value: number | bigint): I256_t { + return numberToInteger(SIZE_BIT, value, true) +} diff --git a/src/basicElements/serializers/number/i32.ts b/src/basicElements/serializers/number/i32.ts new file mode 100644 index 00000000..1ccbf86b --- /dev/null +++ b/src/basicElements/serializers/number/i32.ts @@ -0,0 +1,59 @@ +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type I32_t = bigint + +export const SIZE_BYTE = 4 +export const SIZE_BIT = 32 +export const MIN = -(1n << (BigInt(SIZE_BIT) - 1n)) +export const MAX = (1n << (BigInt(SIZE_BIT) - 1n)) - 1n + +/** + * Converts an I32 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is out of range for I32 + */ +export function toBytes(value: I32_t): Uint8Array { + return integerToByte(SIZE_BIT, value, true) +} + +/** + * Converts bytes to an I32 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the I32 value. + * + * @param bytes - The bytes to convert + * @returns The I32 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): I32_t { + return integerFromByte(SIZE_BIT, bytes, true) +} + +/** + * Converts an I32 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the I32 value (default: 0) + * @returns The I32 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: I32_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, true, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an I32 value + * + * @param value - The number to convert + * @returns The I32 representation of the number + * @throws if the value is not a safe integer or out of range for I32 + */ +export function fromNumber(value: number): I32_t { + return numberToInteger(SIZE_BIT, value, true) +} diff --git a/src/basicElements/serializers/number/i64.ts b/src/basicElements/serializers/number/i64.ts new file mode 100644 index 00000000..d926c82d --- /dev/null +++ b/src/basicElements/serializers/number/i64.ts @@ -0,0 +1,59 @@ +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type I64_t = bigint + +export const SIZE_BYTE = 8 +export const SIZE_BIT = 64 +export const MIN = -(1n << (BigInt(SIZE_BIT) - 1n)) +export const MAX = (1n << (BigInt(SIZE_BIT) - 1n)) - 1n + +/** + * Converts an I64 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is out of range for I64 + */ +export function toBytes(value: I64_t): Uint8Array { + return integerToByte(SIZE_BIT, value, true) +} + +/** + * Converts bytes to an I64 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the I64 value. + * + * @param bytes - The bytes to convert + * @returns The I64 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): I64_t { + return integerFromByte(SIZE_BIT, bytes, true) +} + +/** + * Converts an I64 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the I64 value (default: 0) + * @returns The I64 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: I64_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, true, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an I64 value + * + * @param value - The number to convert + * @returns The I64 representation of the number + * @throws if the value is not a safe integer or out of range for I64 + */ +export function fromNumber(value: number | bigint): I64_t { + return numberToInteger(SIZE_BIT, value, true) +} diff --git a/src/basicElements/serializers/number/i8.ts b/src/basicElements/serializers/number/i8.ts new file mode 100644 index 00000000..97140f4d --- /dev/null +++ b/src/basicElements/serializers/number/i8.ts @@ -0,0 +1,59 @@ +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type I8_t = bigint + +export const SIZE_BYTE = 1 +export const SIZE_BIT = 8 +export const MIN = -(1n << (BigInt(SIZE_BIT) - 1n)) +export const MAX = (1n << (BigInt(SIZE_BIT) - 1n)) - 1n + +/** + * Converts an I8 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is out of range for I8 + */ +export function toBytes(value: I8_t): Uint8Array { + return integerToByte(SIZE_BIT, value, true) +} + +/** + * Converts bytes to an I8 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the I8 value. + * + * @param bytes - The bytes to convert + * @returns The I8 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): I8_t { + return integerFromByte(SIZE_BIT, bytes, true) +} + +/** + * Converts an I8 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the I8 value (default: 0) + * @returns The I8 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: I8_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, true, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an I8 value + * + * @param value - The number to convert + * @returns The I8 representation of the number + * @throws if the value is not a safe integer or out of range for I8 + */ +export function fromNumber(value: number): I8_t { + return numberToInteger(SIZE_BIT, value, true) +} diff --git a/src/basicElements/serializers/number/index.ts b/src/basicElements/serializers/number/index.ts new file mode 100644 index 00000000..967f5001 --- /dev/null +++ b/src/basicElements/serializers/number/index.ts @@ -0,0 +1,12 @@ +export * as U8 from './u8' +export * as U16 from './u16' +export * as U32 from './u32' +export * as U64 from './u64' +export * as U128 from './u128' +export * as U256 from './u256' +export * as I8 from './i8' +export * as I16 from './i16' +export * as I32 from './i32' +export * as I64 from './i64' +export * as I128 from './i128' +export * as I256 from './i256' diff --git a/src/basicElements/serializers/number/integers.ts b/src/basicElements/serializers/number/integers.ts new file mode 100644 index 00000000..f8a84d32 --- /dev/null +++ b/src/basicElements/serializers/number/integers.ts @@ -0,0 +1,155 @@ +import { U8, U16, U32, U64, U128, U256 } from '..' + +function mustBeValidSigned(sizeInBits: number, value: bigint): void { + const min = -(1n << (BigInt(sizeInBits) - 1n)) + const max = (1n << (BigInt(sizeInBits) - 1n)) - 1n + if (value < min || value > max) { + throw new Error(`value ${value} is out of range for an I${sizeInBits}.`) + } +} + +function mustBeValidUnsigned(sizeInBits: number, value: bigint): void { + if (value < 0n) { + throw new Error("negative value can't be serialized as unsigned integer.") + } + if (value >= 1n << BigInt(sizeInBits)) { + throw new Error(`value ${value} is too large for an U${sizeInBits}.`) + } +} + +export function integerToByte( + sizeInBits: number, + value: bigint, + signed = false +): Uint8Array { + signed + ? mustBeValidSigned(sizeInBits, value) + : mustBeValidUnsigned(sizeInBits, value) + + const buffer = new ArrayBuffer(sizeInBits / U8.SIZE_BIT) + const view = new DataView(buffer) + switch (sizeInBits) { + case U8.SIZE_BIT: + signed ? view.setInt8(0, Number(value)) : view.setUint8(0, Number(value)) + break + case U16.SIZE_BIT: + signed + ? view.setInt16(0, Number(value), true) + : view.setUint16(0, Number(value), true) + break + case U32.SIZE_BIT: + signed + ? view.setInt32(0, Number(value), true) + : view.setUint32(0, Number(value), true) + break + case U64.SIZE_BIT: + signed + ? view.setBigInt64(0, value, true) + : view.setBigUint64(0, value, true) + break + case U128.SIZE_BIT: + setBigUint128(view, value) + break + case U256.SIZE_BIT: + setBigUint256(view, value) + break + default: + throw new Error( + `unsupported ${signed ? 'I' : 'U'}${sizeInBits} serialization.` + ) + } + return new Uint8Array(view.buffer) +} + +export function integerFromByte( + sizeInBits: number, + bytes: Uint8Array, + signed = false, + index = 0 +): bigint { + if (bytes.length < index + sizeInBits / U8.SIZE_BIT) { + throw new Error('not enough bytes to read the value.') + } + const view = new DataView(bytes.buffer) + switch (sizeInBits) { + case U8.SIZE_BIT: + return signed ? BigInt(view.getInt8(index)) : BigInt(view.getUint8(index)) + case U16.SIZE_BIT: + return signed + ? BigInt(view.getInt16(index, true)) + : BigInt(view.getUint16(index, true)) + case U32.SIZE_BIT: + return signed + ? BigInt(view.getInt32(index, true)) + : BigInt(view.getUint32(index, true)) + case U64.SIZE_BIT: + return signed + ? view.getBigInt64(index, true) + : view.getBigUint64(index, true) + case U128.SIZE_BIT: + return signed ? getBigInt128(view, index) : getBigUint128(view, index) + case U256.SIZE_BIT: + return signed ? getBigInt256(view, index) : getBigUint256(view, index) + default: + throw new Error( + `unsupported ${signed ? 'I' : 'U'}${sizeInBits} deserialization` + ) + } +} + +export function numberToInteger( + sizeInBits: number, + value: number | bigint, + signed = false +): bigint { + if (typeof value === 'number' && !Number.isSafeInteger(value)) { + throw new Error(`value ${value} is not a safe integer.`) + } + const int = BigInt(value) + signed + ? mustBeValidSigned(sizeInBits, int) + : mustBeValidUnsigned(sizeInBits, int) + return int +} + +function setBigUint128(view: DataView, value: bigint): void { + const offset = 0 + view.setBigUint64(offset, value & U64.MAX, true) + view.setBigUint64(offset + U64.SIZE_BYTE, value >> BigInt(U64.SIZE_BIT), true) +} + +function getBigUint128(view: DataView, offset: number): bigint { + const low = view.getBigUint64(offset, true) + offset += U64.SIZE_BYTE + const high = view.getBigUint64(offset, true) + return (high << BigInt(U64.SIZE_BIT)) | low +} + +function setBigUint256(view: DataView, value: bigint): void { + let offset = 0 + for (let i = 0; i < U256.SIZE_BYTE / U64.SIZE_BYTE; i++) { + view.setBigUint64(offset, value & U64.MAX, true) + offset += U64.SIZE_BYTE + value >>= BigInt(U64.SIZE_BIT) + } +} + +function getBigUint256(view: DataView, offset: number): bigint { + let result = 0n + const nbParts = U256.SIZE_BYTE / U64.SIZE_BYTE + + for (let i = 0; i < nbParts; i++) { + const part = view.getBigUint64(offset + i * U64.SIZE_BYTE, true) + result = result | (part << BigInt(i * U64.SIZE_BIT)) + } + + return result +} + +function getBigInt128(view: DataView, offset: number): bigint { + return BigInt.asIntN(U128.SIZE_BIT, getBigUint128(view, offset)) +} + +function getBigInt256(view: DataView, offset: number): bigint { + return BigInt.asIntN(U256.SIZE_BIT, getBigUint256(view, offset)) +} diff --git a/src/basicElements/serializers/number/u128.ts b/src/basicElements/serializers/number/u128.ts new file mode 100644 index 00000000..807cd065 --- /dev/null +++ b/src/basicElements/serializers/number/u128.ts @@ -0,0 +1,59 @@ +import { U8 } from '.' +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type U128_t = bigint + +export const SIZE_BYTE = 16 +export const SIZE_BIT = SIZE_BYTE * U8.SIZE_BIT +export const MAX = (1n << BigInt(SIZE_BIT)) - 1n + +/** + * Converts an U128 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is negative or too large for U128 + */ +export function toBytes(value: U128_t): Uint8Array { + return integerToByte(SIZE_BIT, value) +} + +/** + * Converts bytes to an U128 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the U8 value. + * + * @param bytes - The bytes to convert + * @returns The U128 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): U128_t { + return integerFromByte(SIZE_BIT, bytes) +} + +/** + * Converts an U128 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the U128 value (default: 0) + * @returns The U128 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: U128_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, false, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an U128 value + * + * @param value - The number to convert + * @returns The U128 representation of the number + * @throws if the value is not a safe integer, negative or too large for U128 + */ +export function fromNumber(value: number | bigint): U128_t { + return numberToInteger(SIZE_BIT, value) +} diff --git a/src/basicElements/serializers/number/u16.ts b/src/basicElements/serializers/number/u16.ts new file mode 100644 index 00000000..6c3e5200 --- /dev/null +++ b/src/basicElements/serializers/number/u16.ts @@ -0,0 +1,59 @@ +import { U8 } from '.' +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type U16_t = bigint + +export const SIZE_BYTE = 2 +export const SIZE_BIT = SIZE_BYTE * U8.SIZE_BIT +export const MAX = (1n << BigInt(SIZE_BIT)) - 1n + +/** + * Converts an U16 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is negative or too large for U16 + */ +export function toBytes(value: U16_t): Uint8Array { + return integerToByte(SIZE_BIT, value) +} + +/** + * Converts bytes to an U16 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the U8 value. + * + * @param bytes - The bytes to convert + * @returns The U16 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): U16_t { + return integerFromByte(SIZE_BIT, bytes) +} + +/** + * Converts an U16 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the U16 value (default: 0) + * @returns The U16 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: U16_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, false, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an U16 value + * + * @param value - The number to convert + * @returns The U16 representation of the number + * @throws if the value is not a safe integer, negative or too large for U16 + */ +export function fromNumber(value: number): U16_t { + return numberToInteger(SIZE_BIT, value) +} diff --git a/src/basicElements/serializers/number/u256.ts b/src/basicElements/serializers/number/u256.ts new file mode 100644 index 00000000..491b5959 --- /dev/null +++ b/src/basicElements/serializers/number/u256.ts @@ -0,0 +1,56 @@ +import { U8 } from '.' +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type U256_t = bigint + +export const SIZE_BYTE = 32 +export const SIZE_BIT = SIZE_BYTE * U8.SIZE_BIT +export const MAX = (1n << BigInt(SIZE_BIT)) - 1n + +/** + * Converts a U256 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is negative or too large for U256 + */ +export function toBytes(value: U256_t): Uint8Array { + return integerToByte(SIZE_BIT, value) +} + +/** + * Converts bytes to a U256 value + * + * @param bytes - The bytes to convert + * @returns The U256 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): U256_t { + return integerFromByte(SIZE_BIT, bytes) +} + +/** + * Converts a U256 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the U256 value (default: 0) + * @returns The U256 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: U256_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, false, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to a U256 value + * + * @param value - The number to convert + * @returns The U256 representation of the number + * @throws if the value is not a safe integer, negative or too large for U256 + */ +export function fromNumber(value: number | bigint): U256_t { + return numberToInteger(SIZE_BIT, value) +} diff --git a/src/basicElements/serializers/number/u32.ts b/src/basicElements/serializers/number/u32.ts new file mode 100644 index 00000000..923f696a --- /dev/null +++ b/src/basicElements/serializers/number/u32.ts @@ -0,0 +1,59 @@ +import { U8 } from '.' +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type U32_t = bigint + +export const SIZE_BYTE = 4 +export const SIZE_BIT = SIZE_BYTE * U8.SIZE_BIT +export const MAX = (1n << BigInt(SIZE_BIT)) - 1n + +/** + * Converts an U32 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is negative or too large for U32 + */ +export function toBytes(value: U32_t): Uint8Array { + return integerToByte(SIZE_BIT, value) +} + +/** + * Converts bytes to an U32 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the U8 value. + * + * @param bytes - The bytes to convert + * @returns The U32 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): U32_t { + return integerFromByte(SIZE_BIT, bytes) +} + +/** + * Converts an U32 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the U32 value (default: 0) + * @returns The U32 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: U32_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, false, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an U32 value + * + * @param value - The number to convert + * @returns The U32 representation of the number + * @throws if the value is not a safe integer, negative or too large for U32 + */ +export function fromNumber(value: number): U32_t { + return numberToInteger(SIZE_BIT, value) +} diff --git a/src/basicElements/serializers/number/u64.ts b/src/basicElements/serializers/number/u64.ts new file mode 100644 index 00000000..67fe5af4 --- /dev/null +++ b/src/basicElements/serializers/number/u64.ts @@ -0,0 +1,59 @@ +import { U8 } from '.' +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type U64_t = bigint + +export const SIZE_BYTE = 8 +export const SIZE_BIT = SIZE_BYTE * U8.SIZE_BIT +export const MAX = (1n << BigInt(SIZE_BIT)) - 1n + +/** + * Converts an U64 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is negative or too large for U64 + */ +export function toBytes(value: U64_t): Uint8Array { + return integerToByte(SIZE_BIT, value) +} + +/** + * Converts bytes to an U64 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the U8 value. + * + * @param bytes - The bytes to convert + * @returns The U64 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): U64_t { + return integerFromByte(SIZE_BIT, bytes) +} + +/** + * Converts an U64 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the U64 value (default: 0) + * @returns The U64 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: U64_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, false, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an U64 value + * + * @param value - The number to convert + * @returns The U64 representation of the number + * @throws if the value is not a safe integer, negative or too large for U64 + */ +export function fromNumber(value: number | bigint): U64_t { + return numberToInteger(SIZE_BIT, value) +} diff --git a/src/basicElements/serializers/number/u8.ts b/src/basicElements/serializers/number/u8.ts new file mode 100644 index 00000000..64478107 --- /dev/null +++ b/src/basicElements/serializers/number/u8.ts @@ -0,0 +1,58 @@ +import { numberToInteger, integerFromByte, integerToByte } from './integers' + +//eslint-disable-next-line @typescript-eslint/naming-convention +export type U8_t = bigint + +export const SIZE_BYTE = 1 +export const SIZE_BIT = 8 +export const MAX = (1n << BigInt(SIZE_BIT)) - 1n + +/** + * Converts an U8 value to bytes + * + * @param value - The number to convert + * @returns The bytes representation of the number + * @throws if the value is negative or too large for U8 + */ +export function toBytes(value: U8_t): Uint8Array { + return integerToByte(SIZE_BIT, value) +} + +/** + * Converts bytes to an U8 value + * + * @remarks + * Silently ignores bytes that are not needed to represent the U8 value. + * + * @param bytes - The bytes to convert + * @returns The U8 representation of the bytes + */ +export function fromBytes(bytes: Uint8Array): U8_t { + return integerFromByte(SIZE_BIT, bytes) +} + +/** + * Converts an U8 value to a number + * @param buffer - The buffer to read from + * @param offset - The optional offset in the buffer at which to start reading the U8 value (default: 0) + * @returns The U8 representation of the bytes + */ +export function fromBuffer( + buffer: Uint8Array, + offset: number +): { value: U8_t; offset: number } { + const value = integerFromByte(SIZE_BIT, buffer, false, offset) + offset += SIZE_BYTE + return { value, offset } +} + +/** + * Converts a number to an U8 value + * + * @param value - The number to convert + * @returns The U8 representation of the number + * @throws if the value is not a safe integer, negative or too large for U8 + */ +export function fromNumber(value: number): U8_t { + return numberToInteger(SIZE_BIT, value) +} diff --git a/src/basicElements/serializers/numbers.ts b/src/basicElements/serializers/numbers.ts new file mode 100644 index 00000000..87a78e56 --- /dev/null +++ b/src/basicElements/serializers/numbers.ts @@ -0,0 +1,63 @@ +/** + * This module aim's to provide number variable types serialization and conversion helper functions. + */ + +import { U32, U64 } from '.' + +/** + * Converts a 32-bit floating-point number (f32) into a Uint8Array. + * + * @param val - The number to convert + * + * @returns A Uint8Array containing the serialized f32 value + * + */ +export function f32ToBytes(val: number): Uint8Array { + const buffer = new ArrayBuffer(U32.SIZE_BYTE) + const view = new DataView(buffer) + view.setFloat32(0, val, true) + return new Uint8Array(view.buffer) +} + +/** + * Converts a Uint8Array into a 32-bit floating-point number (f32). + * + * @param arr - The array to convert + * @param offset - The optional offset in the Uint8Array at which to start reading the f32 value (default: 0) + * + * @returns The deserialized f32 value + * + */ +export function bytesToF32(arr: Uint8Array, offset = 0): number { + const view = new DataView(arr.buffer) + return view.getFloat32(offset, true) +} + +/** + * Converts a 64-bit floating-point number (f64) into a Uint8Array. + * + * @param val - The BigInt to convert + * + * @returns A Uint8Array containing the serialized f64 value + * + */ +export function f64ToBytes(val: number): Uint8Array { + const buffer = new ArrayBuffer(U64.SIZE_BYTE) + const view = new DataView(buffer) + view.setFloat64(0, val, true) + return new Uint8Array(view.buffer) +} + +/** + * Converts a Uint8Array into a f64 BigInt. + * + * @param arr - The array to convert + * @param offset - The optional offset in the Uint8Array at which to start reading the f64 value (default: 0) + * + * @returns The deserialized f64 value + * + */ +export function bytesToF64(arr: Uint8Array, offset = 0): number { + const view = new DataView(arr.buffer) + return view.getFloat64(offset, true) +} diff --git a/src/basicElements/serializers/strings.ts b/src/basicElements/serializers/strings.ts new file mode 100644 index 00000000..879a20bf --- /dev/null +++ b/src/basicElements/serializers/strings.ts @@ -0,0 +1,28 @@ +/** + * Converts utf-16 string to a Uint8Array. + * + * @param str - the string to convert + * + * @returns the converted string + */ +export function strToBytes(str: string): Uint8Array { + if (!str.length) { + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + return new Uint8Array(0) + } + return new TextEncoder().encode(str) +} + +/** + * Converts Uint8Array to a string. + * + * @param arr - the array to convert + * + * @returns A string representation of the array in utf-8 encoding + */ +export function bytesToStr(arr: Uint8Array): string { + if (!arr.length) { + return '' + } + return new TextDecoder().decode(arr) +} diff --git a/src/basicElements/signature.ts b/src/basicElements/signature.ts new file mode 100644 index 00000000..9de13e10 --- /dev/null +++ b/src/basicElements/signature.ts @@ -0,0 +1,122 @@ +import Base58 from '../crypto/base58' +import Serializer from '../crypto/interfaces/serializer' +import { Version, Versioner } from '../crypto/interfaces/versioner' +import VarintVersioner from '../crypto/varintVersioner' + +const DEFAULT_VERSION = Version.V0 + +/** + * Get the signature version. + * * + * @returns the signature version. + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +function getVersion(data: string | Uint8Array): Version { + // when a new version will come, implement the logic to detect version here + // This should be done without serializer and versionner as they are potentially not known at this point + return Version.V0 +} + +/** + * A class representing a signature. + */ +export class Signature { + // The signature in byte format. Version included. + private bytes: Uint8Array + + protected constructor( + public serializer: Serializer, + public versioner: Versioner, + public version: Version + ) {} + + /** + * Initializes a new signature object from a version. + * + * @param version - The version of the signature. + * + * @returns A new signature instance. + */ + protected static initFromVersion( + version: Version = DEFAULT_VERSION + ): Signature { + switch (version) { + case Version.V0: + return new Signature(new Base58(), new VarintVersioner(), version) + default: + throw new Error(`unsupported version: ${version}`) + } + } + + /** + * Initializes a new signature object from a serialized string. + * + * @param str - The serialized signature string. + * + * @returns A new signature instance. + * + * @throws If the signature string is invalid. + */ + public static fromString(str: string): Signature { + const version = getVersion(str) + const signature = Signature.initFromVersion(version) + + try { + signature.bytes = signature.serializer.deserialize(str) + const { version: extractedVersion } = signature.versioner.extract( + signature.bytes + ) + + // safety check + if (extractedVersion !== version) { + throw new Error( + `invalid version: ${version}. ${signature.version} was expected.` + ) + } + } catch (e) { + throw new Error(`invalid signature string: ${e.message}`) + } + + return signature + } + + /** + * Initializes a signature object from a byte array. + * + * @param bytes - The signature bytes. + * + * @returns A signature object. + */ + public static fromBytes(bytes: Uint8Array): Signature { + const version = getVersion(bytes) + const signature = Signature.initFromVersion(version) + signature.bytes = bytes + + // safety check + const { version: extractedVersion } = signature.versioner.extract(bytes) + if (extractedVersion !== version) { + throw new Error( + `invalid version: ${version}. ${signature.version} was expected.` + ) + } + return signature + } + + /** + * Get signature in bytes format. + * + * @returns The versioned signature key bytes. + */ + public toBytes(): Uint8Array { + return this.bytes + } + + /** + * Serializes the signature to a string. + * + * @returns The serialized signature string. + */ + public toString(): string { + return this.serializer.serialize(this.bytes) + } +} diff --git a/src/basicElements/storage.ts b/src/basicElements/storage.ts new file mode 100644 index 00000000..a7b54992 --- /dev/null +++ b/src/basicElements/storage.ts @@ -0,0 +1,49 @@ +import { Mas, fromMicroMas } from './mas' +import { U32 } from './serializers' + +const BYTE_COST_MICRO_MASSA = 100n + +const ACCOUNT_SIZE_BYTES = 10 + +/** + * Calculates the cost of a given number of bytes. + * + * @param numberOfBytes - The number of bytes. + * + * @returns The cost in the smallest unit of the Massa currency. + */ +export function bytes(numberOfBytes: number): Mas { + return BigInt(numberOfBytes) * fromMicroMas(BYTE_COST_MICRO_MASSA) +} + +/** + * Calculates the cost of creating a new account. + * + * @returns The cost in the smallest unit of the Massa currency. + */ +export function account(): Mas { + return bytes(ACCOUNT_SIZE_BYTES) +} + +/** + * Calculates the cost of deploying a smart contract. + * + * @remarks + * The cost of deploying a smart contract includes the cost of creating a new account. + * + * @param numberOfBytes - The number of bytes of the smart contract. + * + * @returns The cost in the smallest unit of the Massa currency. + */ +export function smartContract(numberOfBytes: number): Mas { + return bytes(numberOfBytes) + account() +} + +/** + * Calculates the cost of creating a new entry in the datastore. + * + * @returns The cost in the smallest unit of the Massa currency. + */ +export function newEntry(): Mas { + return bytes(U32.SIZE_BYTE) +} diff --git a/src/client/connector.ts b/src/client/connector.ts new file mode 100644 index 00000000..7bbbc17f --- /dev/null +++ b/src/client/connector.ts @@ -0,0 +1,414 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + +import * as t from '../generated/client-types' +import { getHttpRpcClient, HttpRpcClient } from './http' +import { ClientOptions } from './types' + +export class Connector { + private client: HttpRpcClient = {} as HttpRpcClient + + constructor(url: string, opts: Partial = {}) { + this.client = getHttpRpcClient(url, opts) + } + + /** + * Execute a smart contract in a read only context + */ + + public execute_read_only_bytecode: t.ExecuteReadOnlyBytecode = (params) => { + return this.client.request('execute_read_only_bytecode', params) + } + + /** + * Call a function of a contract in a read only context + */ + + public execute_read_only_call: t.ExecuteReadOnlyCall = (params) => { + return this.client.request('execute_read_only_call', params) + } + + /** + * To check when your address is selected to stake. + */ + + public get_addresses: t.GetAddresses = (params) => { + return this.client.request('get_addresses', params) + } + + /** + * Returns the bytecode of the given addresses. + */ + + public get_addresses_bytecode: t.GetAddressesBytecode = (params) => { + return this.client.request('get_addresses_bytecode', params) + } + + /** + * Get blocks + */ + + public get_blocks: t.GetBlocks = (params) => { + return this.client.request('get_blocks', params) + } + + /** + * Get a block in the blockclique + */ + + public get_blockclique_block_by_slot: t.GetBlockcliqueBlockBySlot = ( + params + ) => { + return this.client.request('get_blockclique_block_by_slot', params) + } + + /** + * Get cliques + */ + + public get_cliques: t.GetCliques = () => { + return this.client.request('get_cliques', {}) + } + + /** + * Get a data entry both at the latest final and active executed slots for the given addresses. + */ + + public get_datastore_entries: t.GetDatastoreEntries = (params) => { + return this.client.request('get_datastore_entries', params) + } + + /** + * Get transfers for specified slots + */ + + public get_slots_transfers: t.GetSlotsTransfers = (params) => { + return this.client.request('get_slots_transfers', params) + } + + /** + * Get endorsements + */ + + public get_endorsements: t.GetEndorsements = (params) => { + return this.client.request('get_endorsements', params) + } + + /** + * Returns events optionally filtered + */ + + public get_filtered_sc_output_event: t.GetFilteredScOutputEvent = ( + params + ) => { + return this.client.request('get_filtered_sc_output_event', params) + } + + /** + * Get graph interval + */ + + public get_graph_interval: t.GetGraphInterval = (params) => { + return this.client.request('get_graph_interval', params) + } + + /** + * Get operations + */ + + public get_operations: t.GetOperations = (params) => { + return this.client.request('get_operations', params) + } + + /** + * Get stakers + */ + + public get_stakers: t.GetStakers = (params) => { + return this.client.request('get_stakers', params) + } + + /** + * Summary of the current state + */ + + public get_status: t.GetStatus = () => { + return this.client.request('get_status', {}) + } + + /** + * Add a vec of new secret(private) keys for the node to use to stake + */ + + public add_staking_secret_keys: t.AddStakingSecretKeys = (params) => { + return this.client.request('add_staking_secret_keys', params) + } + + /** + * Return hashset of staking addresses + */ + + public get_staking_addresses: t.GetStakingAddresses = () => { + return this.client.request('get_staking_addresses', {}) + } + + /** + * Add to bootstrap blacklist given IP addresses + */ + + public node_add_to_bootstrap_blacklist: t.NodeAddToBootstrapBlacklist = ( + params + ) => { + return this.client.request('node_add_to_bootstrap_blacklist', params) + } + + /** + * Add to bootstrap whitelist given IP addresses + */ + + public node_add_to_bootstrap_whitelist: t.NodeAddToBootstrapWhitelist = ( + params + ) => { + return this.client.request('node_add_to_bootstrap_whitelist', params) + } + + /** + * Add to peers whitelist given IP addresses + */ + + public node_add_to_peers_whitelist: t.NodeAddToPeersWhitelist = (params) => { + return this.client.request('node_add_to_peers_whitelist', params) + } + + /** + * Ban given ids + */ + + public node_ban_by_id: t.NodeBanById = (params) => { + return this.client.request('node_ban_by_id', params) + } + + /** + * Ban given IP addresses + */ + + public node_ban_by_ip: t.NodeBanByIp = (params) => { + return this.client.request('node_ban_by_ip', params) + } + + /** + * Returns bootstrap blacklist IP addresses + */ + + public node_bootstrap_blacklist: t.NodeBootstrapBlacklist = () => { + return this.client.request('node_bootstrap_blacklist', {}) + } + + /** + * Returns bootstrap whitelist IP addresses + */ + + public node_bootstrap_whitelist: t.NodeBootstrapWhitelist = () => { + return this.client.request('node_bootstrap_whitelist', {}) + } + + /** + * Allow everyone to bootstrap from the node + */ + + public node_bootstrap_whitelist_allow_all: t.NodeBootstrapWhitelistAllowAll = + () => { + return this.client.request('node_bootstrap_whitelist_allow_all', {}) + } + + /** + * Returns peers whitelist IP addresses + */ + + public node_peers_whitelist: t.NodePeersWhitelist = () => { + return this.client.request('node_peers_whitelist', {}) + } + + /** + * Remove from bootstrap blacklist given IP addresses + */ + + public node_remove_from_bootstrap_blacklist: t.NodeRemoveFromBootstrapBlacklist = + (params) => { + return this.client.request('node_remove_from_bootstrap_blacklist', params) + } + + /** + * Remove from bootstrap whitelist given IP addresses + */ + + public node_remove_from_bootstrap_whitelist: t.NodeRemoveFromBootstrapWhitelist = + (params) => { + return this.client.request('node_remove_from_bootstrap_whitelist', params) + } + + /** + * Remove from peers whitelist given IP addresses + */ + + public node_remove_from_peers_whitelist: t.NodeRemoveFromPeersWhitelist = ( + params + ) => { + return this.client.request('node_remove_from_peers_whitelist', params) + } + + /** + * Remove from whitelist given IP addresses + */ + + public node_remove_from_whitelist: t.NodeRemoveFromWhitelist = (params) => { + return this.client.request('node_remove_from_whitelist', params) + } + + /** + * Remove a vec of addresses used to stake + */ + + public remove_staking_addresses: t.RemoveStakingAddresses = (params) => { + return this.client.request('remove_staking_addresses', params) + } + + /** + * Sign message with nodeโ€™s key + */ + + public node_sign_message: t.NodeSignMessage = (params) => { + return this.client.request('node_sign_message', params) + } + + /** + * Gracefully stop the node + */ + + public stop_node: t.StopNode = () => { + return this.client.request('stop_node', {}) + } + + /** + * Unban given ids + */ + + public node_unban_by_id: t.NodeUnbanById = (params) => { + return this.client.request('node_unban_by_id', params) + } + + /** + * Unban given IP addresses + */ + + public node_unban_by_ip: t.NodeUnbanByIp = (params) => { + return this.client.request('node_unban_by_ip', params) + } + + /** + * Whitelist given IP addresses + */ + + public node_whitelist: t.NodeWhitelist = (params) => { + return this.client.request('node_whitelist', params) + } + + /** + * Adds operations to pool + */ + + public send_operations: t.SendOperations = (params) => { + return this.client.request('send_operations', params) + } + + /** + * Get largest stakers + */ + + public get_largest_stakers: t.GetLargestStakers = (params) => { + return this.client.request('get_largest_stakers', params) + } + + /** + * Get next block best parents + */ + + public get_next_block_best_parents: t.GetNextBlockBestParents = () => { + return this.client.request('get_next_block_best_parents', {}) + } + + /** + * Get Massa node version + */ + + public get_version: t.GetVersion = () => { + return this.client.request('get_version', {}) + } + + /** + * New produced blocks + */ + + public subscribe_new_blocks: t.SubscribeNewBlocks = () => { + return this.client.request('subscribe_new_blocks', {}) + } + + /** + * New produced blocks headers + */ + + public subscribe_new_blocks_headers: t.SubscribeNewBlocksHeaders = () => { + return this.client.request('subscribe_new_blocks_headers', {}) + } + + /** + * New produced blocks with operations content + */ + + public subscribe_new_filled_blocks: t.SubscribeNewFilledBlocks = () => { + return this.client.request('subscribe_new_filled_blocks', {}) + } + + /** + * Subscribe to new operations + */ + + public subscribe_new_operations: t.SubscribeNewOperations = () => { + return this.client.request('subscribe_new_operations', {}) + } + + /** + * Unsubscribe from new produced blocks + */ + + public unsubscribe_new_blocks: t.UnsubscribeNewBlocks = (params) => { + return this.client.request('unsubscribe_new_blocks', params) + } + + /** + * Unsubscribe from new produced blocks headers + */ + + public unsubscribe_new_blocks_headers: t.UnsubscribeNewBlocksHeaders = ( + params + ) => { + return this.client.request('unsubscribe_new_blocks_headers', params) + } + + /** + * Unsubscribe from new produced filled blocks + */ + + public unsubscribe_new_filled_blocks: t.UnsubscribeNewFilledBlocks = ( + params + ) => { + return this.client.request('unsubscribe_new_filled_blocks', params) + } + + /** + * Unsubscribe from new received operations + */ + + public unsubscribe_new_operations: t.UnsubscribeNewOperations = (params) => { + return this.client.request('unsubscribe_new_operations', params) + } +} diff --git a/src/client/constants.ts b/src/client/constants.ts new file mode 100644 index 00000000..38305b51 --- /dev/null +++ b/src/client/constants.ts @@ -0,0 +1 @@ +export const NB_THREADS = 32 diff --git a/src/client/formatObjects.ts b/src/client/formatObjects.ts new file mode 100644 index 00000000..4ae9d327 --- /dev/null +++ b/src/client/formatObjects.ts @@ -0,0 +1,55 @@ +import { NodeStatus } from '../generated/client-types' +import { NodeStatusInfo } from '../provider' + +export function formatNodeStatusObject(status: NodeStatus): NodeStatusInfo { + return { + config: { + blockReward: status.config.block_reward, + deltaF0: status.config.delta_f0, + endTimestamp: status.config.end_timestamp, + genesisTimestamp: status.config.genesis_timestamp, + maxBlockSize: status.config.max_block_size, + operationValidityPeriods: status.config.operation_validity_periods, + periodsPerCycle: status.config.periods_per_cycle, + rollPrice: status.config.roll_price, + t0: status.config.t0, + threadCount: status.config.thread_count, + }, + connectedNodes: status.connected_nodes, + consensusStats: { + cliqueCount: status.consensus_stats.clique_count, + endTimespan: status.consensus_stats.end_timespan, + finalBlockCount: status.consensus_stats.final_block_count, + staleBlockCount: status.consensus_stats.stale_block_count, + startTimespan: status.consensus_stats.start_timespan, + }, + currentCycle: status.current_cycle, + currentTime: status.current_time, + currentCycleTime: status.current_cycle_time, + nextCycleTime: status.next_cycle_time, + lastSlot: status.last_slot, + nextSlot: status.next_slot, + networkStats: { + activeNodeCount: status.network_stats.active_node_count, + bannedPeerCount: status.network_stats.banned_peer_count, + inConnectionCount: status.network_stats.in_connection_count, + knownPeerCount: status.network_stats.known_peer_count, + outConnectionCount: status.network_stats.out_connection_count, + }, + nodeId: status.node_id, + nodeIp: status.node_ip, + poolStats: status.pool_stats, + version: status.version, + executionStats: { + timeWindowStart: status.execution_stats.time_window_start, + timeWindowEnd: status.execution_stats.time_window_end, + finalBlockCount: status.execution_stats.final_block_count, + finalExecutedOperationsCount: + status.execution_stats.final_executed_operations_count, + activeCursor: status.execution_stats.active_cursor, + finalCursor: status.execution_stats.final_cursor, + }, + chainId: status.chain_id, + minimalFees: status.minimal_fees, + } +} diff --git a/src/client/http.ts b/src/client/http.ts new file mode 100644 index 00000000..3ee1196d --- /dev/null +++ b/src/client/http.ts @@ -0,0 +1,65 @@ +/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-non-null-assertion*/ + +import { DEFAULT_RETRY_OPTS, withRetry } from './retry' +import { ClientOptions } from './types' + +export type HttpRpcClient = { + request( + endpoint: string, + params: HttpRequestParameters + ): Promise +} + +const headers = { + 'Content-Type': 'application/json', +} + +function createIdStore(): { current: number; take(): number; reset(): void } { + return { + current: 0, + take(): number { + return this.current++ + }, + reset(): void { + this.current = 0 + }, + } +} + +const idCache = createIdStore() + +export function getHttpRpcClient( + url: string, + opts: Partial = {} +): HttpRpcClient { + if (!opts.retry) { + opts.retry = DEFAULT_RETRY_OPTS + } + return { + async request( + endpoint: string, + params: HttpRequestParameters + ): Promise { + const response = await withRetry(() => { + const init: RequestInit = { + body: JSON.stringify({ + jsonrpc: '2.0', + method: endpoint, + params: [params], + id: idCache.take(), + }), + headers, + method: 'POST', + } + return fetch(url, init) + }, opts.retry!) + + const data = await response.json() + + if (!response.ok || !!data.error) { + throw new Error(data.error?.message) + } + return data.result + }, + } +} diff --git a/src/client/index.ts b/src/client/index.ts new file mode 100644 index 00000000..4a8add1b --- /dev/null +++ b/src/client/index.ts @@ -0,0 +1,5 @@ +export * from './types' +export * from './jsonRPCClient' +export * from './publicAPI' +export * from './constants' +export * from './formatObjects' diff --git a/src/client/jsonRPCClient.ts b/src/client/jsonRPCClient.ts new file mode 100644 index 00000000..e0fe0d25 --- /dev/null +++ b/src/client/jsonRPCClient.ts @@ -0,0 +1,16 @@ +import { PublicApiUrl } from '..' +import { PublicAPI } from './publicAPI' + +export class JsonRPCClient extends PublicAPI { + static buildnet(): JsonRPCClient { + return new JsonRPCClient(PublicApiUrl.Buildnet) + } + + static testnet(): JsonRPCClient { + return new JsonRPCClient(PublicApiUrl.Testnet) + } + + static mainnet(): JsonRPCClient { + return new JsonRPCClient(PublicApiUrl.Mainnet) + } +} diff --git a/src/client/publicAPI.ts b/src/client/publicAPI.ts new file mode 100644 index 00000000..edc776d4 --- /dev/null +++ b/src/client/publicAPI.ts @@ -0,0 +1,313 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + +import { Mas, strToBytes } from '../basicElements' +import { + SendOperationInput, + EventFilter as EvtFilter, + ReadOnlyCallResult, + ClientOptions, + DatastoreEntry, +} from '.' +import * as t from '../generated/client-types' +import { MAX_GAS_CALL } from '../smartContracts' +import { OperationStatus, ReadOnlyParams } from '../operation' +import isEqual from 'lodash.isequal' +import { Connector } from './connector' + +export class PublicAPI { + connector: Connector + lastStatus: t.NodeStatus + + // eslint-disable-next-line max-params + constructor( + public url: string, + public options: Partial = {} + ) { + this.connector = new Connector(url, this.options) + } + + async executeReadOnlyBytecode( + readOnlyBytecodeExecution: t.ReadOnlyBytecodeExecution + ): Promise { + return this.connector + .execute_read_only_bytecode([readOnlyBytecodeExecution]) + .then((r) => r[0]) + } + + async executeMultipleReadOnlyBytecode( + readOnlyBytecodeExecutions: t.ReadOnlyBytecodeExecution[] + ): Promise { + return this.connector.execute_read_only_bytecode(readOnlyBytecodeExecutions) + } + + async executeReadOnlyCall( + params: ReadOnlyParams + ): Promise { + const [res] = await this.connector.execute_read_only_call([ + { + max_gas: Number(params.maxGas ?? MAX_GAS_CALL), + target_address: params.target, + target_function: params.func, + parameter: Array.from(params.parameter), + caller_address: params.caller, + coins: params.coins ? Mas.toString(params.coins) : null, + fee: params.fee ? Mas.toString(params.fee) : null, + }, + ]) + + if (!res) { + throw new Error('No result returned from execute_read_only_call') + } + + return { + // @ts-expect-error - wrong type returned by the API interface + value: new Uint8Array(res.result.Ok), + info: { + gasCost: res.gas_cost, + error: res.result.Error, + events: res.output_events, + stateChanges: { + ledgerChanges: res.state_changes.ledger_changes, + asyncPoolChanges: res.state_changes.async_pool_changes, + posChanges: res.state_changes.pos_changes, + executedOpsChanges: res.state_changes.executed_ops_changes, + executedDenunciationsChanges: + res.state_changes.executed_denunciations_changes, + executionTrailHashChange: + res.state_changes.execution_trail_hash_change, + }, + }, + } + } + + async executeMultipleReadOnlyCall( + readOnlyCalls: t.ReadOnlyCall[] + ): Promise { + return this.connector.execute_read_only_call(readOnlyCalls) + } + + async getAddressInfo(address: string): Promise { + return this.getMultipleAddressInfo([address]).then((r) => r[0]) + } + + async getBalance(address: string, final = true): Promise { + return this.getAddressInfo(address).then((r) => { + return Mas.fromString(final ? r.final_balance : r.candidate_balance) + }) + } + + async getMultipleAddressInfo(addresses: string[]): Promise { + return this.connector.get_addresses(addresses) + } + + async getAddressesBytecode(addressFilter: t.AddressFilter): Promise { + return this.connector + .get_addresses_bytecode([addressFilter]) + .then((r) => r[0]) + } + + async executeMultipleGetAddressesBytecode( + addressFilters: t.AddressFilter[] + ): Promise { + return this.connector.get_addresses_bytecode(addressFilters) + } + + async getBlock(blockId: t.BlockId): Promise { + return this.connector.get_blocks([blockId]).then((r) => r[0]) + } + + // todo should return an array of blockInfo, right? + async getMultipleBlocks(blockIds: t.BlockId[]): Promise { + return this.connector.get_blocks(blockIds) + } + + async getBlockcliqueBlock(slot: t.Slot): Promise { + return this.connector.get_blockclique_block_by_slot(slot) + } + + async getCliques(): Promise { + return this.connector.get_cliques() + } + + async getDataStoreKeys( + contract: string, + filter: Uint8Array = new Uint8Array(), + final = true + ): Promise { + const addrInfo = await this.getAddressInfo(contract) + const keys = final + ? addrInfo.final_datastore_keys + : addrInfo.candidate_datastore_keys + return keys + .filter( + (key) => + !filter.length || + isEqual(Uint8Array.from(key.slice(0, filter.length)), filter) + ) + .map((key) => Uint8Array.from(key)) + } + + async getDatastoreEntries( + inputs: DatastoreEntry[], + final = true + ): Promise { + const entriesQuery = inputs.map((entry) => { + const byteKey: Uint8Array = + typeof entry.key === 'string' ? strToBytes(entry.key) : entry.key + return { + key: Array.from(byteKey), + address: entry.address, + } + }) + const res = await this.connector.get_datastore_entries(entriesQuery) + return res.map((r: t.DatastoreEntryOutput) => { + const val = final ? r.final_value : r.candidate_value + return Uint8Array.from(val ?? []) + }) + } + + async getDatastoreEntry( + key: string | Uint8Array, + address: string, + final = true + ): Promise { + return this.getDatastoreEntries([{ key, address }], final).then((r) => r[0]) + } + + async getSlotTransfers(slot: t.Slot): Promise { + return this.connector.get_slots_transfers([slot]).then((r) => r[0]) + } + + async getMultipleSlotTransfers(slots: t.Slot[]): Promise { + return this.connector.get_slots_transfers(slots) + } + + async getEndorsement(endorsementId: string): Promise { + return this.getMultipleEndorsements([endorsementId]).then((r) => r[0]) + } + + async getMultipleEndorsements( + endorsementIds: string[] + ): Promise { + return this.connector.get_endorsements(endorsementIds) + } + + async getEvents(filter: EvtFilter): Promise { + const formattedFilter = { + start: filter.start, + end: filter.end, + emitter_address: filter.smartContractAddress, + original_caller_address: filter.callerAddress, + original_operation_id: filter.operationId, + is_final: filter.isFinal, + is_error: filter.isError, + } + + return this.connector.get_filtered_sc_output_event(formattedFilter) + } + + async getGraphInterval( + start?: number, + end?: number + ): Promise { + return this.connector.get_graph_interval({ start, end }) + } + + async getOperations(operationIds: string[]): Promise { + return this.connector.get_operations(operationIds) + } + + async getOperation(operationId: string): Promise { + return this.getOperations([operationId]).then((r) => r[0]) + } + + async getOperationStatus(operationId: string): Promise { + const op = await this.getOperation(operationId) + + if (op.op_exec_status === null) { + if (op.is_operation_final === null) { + return OperationStatus.NotFound + } + + throw new Error('unexpected status') + } + + if (op.in_pool) { + return OperationStatus.PendingInclusion + } + + if (!op.is_operation_final) { + return op.op_exec_status + ? OperationStatus.SpeculativeSuccess + : OperationStatus.SpeculativeError + } + + return op.op_exec_status ? OperationStatus.Success : OperationStatus.Error + } + + // todo rename PageRequest pagination + async getStakers(pagination: t.Pagination): Promise { + return this.connector.get_stakers(pagination) + } + + async status(): Promise { + this.lastStatus = await this.connector.get_status() + return this.lastStatus + } + + async getMinimalFee(): Promise { + if (!this.lastStatus) { + await this.status() + } + if (!this.lastStatus.minimal_fees) { + throw new Error('minimal fees: not available') + } + return Mas.fromString(this.lastStatus.minimal_fees) + } + + async getChainId(): Promise { + if (!this.lastStatus) { + await this.status() + } + return BigInt(this.lastStatus.chain_id) + } + + async fetchPeriod(): Promise { + const status = await this.status() + if (!status.last_slot) { + throw new Error('last slot: not available') + } + return status.last_slot.period + } + + async getCurrentSlot(): Promise { + const { last_slot } = await this.status() + return last_slot + } + + private static convertOperationInput( + data: SendOperationInput + ): t.OperationInput { + return { + serialized_content: Array.from(data.data), + creator_public_key: data.publicKey, + signature: data.signature, + } + } + + async sendOperation(data: SendOperationInput): Promise { + return this.sendOperations([data]).then((r) => r[0]) + } + + async sendOperations(data: SendOperationInput[]): Promise { + return this.sendMultipleOperations( + data.map((e) => PublicAPI.convertOperationInput(e)) + ) + } + + async sendMultipleOperations( + data: t.OperationInput[] + ): Promise { + return this.connector.send_operations(data) + } +} diff --git a/src/client/retry.ts b/src/client/retry.ts new file mode 100644 index 00000000..082495f9 --- /dev/null +++ b/src/client/retry.ts @@ -0,0 +1,29 @@ +const DEFAULT_RETRIES = 3 +const DEFAULT_DELAY = 300 + +export const DEFAULT_RETRY_OPTS = { + retries: DEFAULT_RETRIES, + delay: DEFAULT_DELAY, +} + +// Wrapped rpc call with retry strategy +export function withRetry( + fn: () => Promise, + opt: { retries: number; delay: number } +): Promise { + return new Promise((resolve, reject) => { + function attempt(): void { + fn() + .then(resolve) + .catch((error) => { + if (opt.retries === 0) { + reject(error) + } else { + opt.retries-- + setTimeout(attempt, opt.delay) + } + }) + } + attempt() + }) +} diff --git a/src/client/types.ts b/src/client/types.ts new file mode 100644 index 00000000..6c7ddf95 --- /dev/null +++ b/src/client/types.ts @@ -0,0 +1,53 @@ +import { EventExecutionContext } from '../generated/client-types' + +export type Slot = { + period: number + thread: number +} + +export type ClientOptions = { + retry: { retries: number; delay: number } +} + +export type SCEvent = { + data: string + context: EventExecutionContext +} + +export type SendOperationInput = { + data: Uint8Array + publicKey: string + signature: string +} + +export type EventFilter = { + start?: Slot + end?: Slot + smartContractAddress?: string + callerAddress?: string + operationId?: string + isFinal?: boolean + isError?: boolean +} + +export type ReadOnlyCallResult = { + value: Uint8Array + info: { + gasCost: number + error?: string + events: SCEvent[] + stateChanges: { + ledgerChanges: Record + asyncPoolChanges: Record[] + posChanges: Record + executedOpsChanges: Record + executedDenunciationsChanges: Record + executionTrailHashChange: string + } + } +} + +export type DatastoreEntry = { + address: string + key: Uint8Array | string +} diff --git a/src/contracts-wrappers/index.ts b/src/contracts-wrappers/index.ts new file mode 100644 index 00000000..b53ea181 --- /dev/null +++ b/src/contracts-wrappers/index.ts @@ -0,0 +1,3 @@ +export * from './token' +export * from './tokens' +export * from './mns' diff --git a/src/contracts-wrappers/mns.ts b/src/contracts-wrappers/mns.ts new file mode 100644 index 00000000..0dea2dce --- /dev/null +++ b/src/contracts-wrappers/mns.ts @@ -0,0 +1,107 @@ +import { Args, bytesToStr, strToBytes, U256 } from '../basicElements' +import { Operation } from '../operation' +import { Provider } from '../provider' +import { CallSCOptions, ReadSCOptions, SmartContract } from '../smartContracts' +import { checkNetwork } from './tokens' + +export const MNS_CONTRACTS = { + mainnet: 'AS1q5hUfxLXNXLKsYQVXZLK7MPUZcWaNZZsK7e9QzqhGdAgLpUGT', + buildnet: 'AS12qKAVjU1nr66JSkQ6N4Lqu4iwuVc6rAbRTrxFoynPrPdP1sj3G', +} + +/** + * @class MNS + * @extends SmartContract + * + * The MNS class provides methods to interact with the Massa Name Service (MNS) smart contract. + * It allows resolving domain names, reverse resolving addresses, allocating domains, freeing domains, + * and updating domain targets. + * MNS contract is available here: https://github.com/massalabs/massa-name-service/blob/main/smart-contract/assembly/contracts/main.ts + * + * @example + * ```typescript + * const mns = await MNS.mainnet(provider); + * const address = await mns.resolve("example"); + * ``` + * + */ + +export class MNS extends SmartContract { + static mainnet(provider: Provider): MNS { + checkNetwork(provider, true) + return new MNS(provider, MNS_CONTRACTS.mainnet) + } + + static buildnet(provider: Provider): MNS { + checkNetwork(provider, false) + return new MNS(provider, MNS_CONTRACTS.buildnet) + } + + // Resolve domain name (without "".massa") to address + async resolve(name: string, options?: ReadSCOptions): Promise { + const res = await this.read( + 'dnsResolve', + new Args().addString(name), + options + ) + return bytesToStr(res.value) + } + + async fromAddress( + address: string, + options?: ReadSCOptions + ): Promise { + const res = await this.read( + 'dnsReverseResolve', + new Args().addString(address), + options + ) + return bytesToStr(res.value).split(',') + } + + async alloc( + name: string, + owner: string, + options?: CallSCOptions + ): Promise { + return this.call( + 'dnsAlloc', + new Args().addString(name).addString(owner), + options + ) + } + + private async getTokenId(name: string): Promise { + // Constants are taken from the smart contract + // https://github.com/massalabs/massa-name-service/blob/476189525c00d189f8914627abf82b8fdf144c6e/smart-contract/assembly/contracts/main.ts#L64 + // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-magic-numbers + const [DOMAIN_SEPARATOR_KEY, TOKEN_ID_KEY_PREFIX] = [0x42, 0x01] + const key = Uint8Array.from([ + DOMAIN_SEPARATOR_KEY, + TOKEN_ID_KEY_PREFIX, + ...strToBytes(name), + ]) + const data = await this.provider.readStorage(this.address, [key], true) + if (!data.length) { + throw new Error(`Domain ${name} not found`) + } + return U256.fromBytes(data[0]) + } + + async free(name: string, options?: CallSCOptions): Promise { + const tokenId = await this.getTokenId(name) + return this.call('dnsFree', new Args().addU256(tokenId), options) + } + + async updateTarget( + name: string, + newTarget: string, + options?: CallSCOptions + ): Promise { + return this.call( + 'dnsUpdateTarget', + new Args().addString(name).addString(newTarget), + options + ) + } +} diff --git a/src/contracts-wrappers/token.ts b/src/contracts-wrappers/token.ts new file mode 100644 index 00000000..0c6d381d --- /dev/null +++ b/src/contracts-wrappers/token.ts @@ -0,0 +1,123 @@ +import { Args, bytesToStr, U256, U8 } from '../basicElements' +import { Operation } from '../operation' +import { CallSCOptions, ReadSCOptions, SmartContract } from '../smartContracts' + +/** + * @class MRC20 + * + * + * Class representing an MRC20 token smart contract. + * Extends the SmartContract class to provide methods for interacting with an MRC20 token. + * MRC20 contract is available here: https://github.com/massalabs/massa-standards/blob/main/smart-contracts/assembly/contracts/FT/token.ts + * + * @example + * ```typescript + * const token = new MRC20(provider, ); + * const balance = await token.balanceOf(); + * console.log(`Your balance: ${balance}`); + * + * const transferOperation = await token.transfer(, BigInt(10000)); + * console.log(`Transfer operation id: ${transferOperation.id}`); + * ``` + */ + +export class MRC20 extends SmartContract { + async version(options?: ReadSCOptions): Promise { + const res = await this.read('version', undefined, options) + return bytesToStr(res.value) + } + + async name(options?: ReadSCOptions): Promise { + const res = await this.read('name', undefined, options) + return bytesToStr(res.value) + } + + async symbol(options?: ReadSCOptions): Promise { + const res = await this.read('symbol', undefined, options) + return bytesToStr(res.value) + } + + async decimals(options?: ReadSCOptions): Promise { + const res = await this.read('decimals', undefined, options) + return Number(U8.fromBytes(res.value)) + } + + async totalSupply(options?: ReadSCOptions): Promise { + const res = await this.read('totalSupply', undefined, options) + return U256.fromBytes(res.value) + } + + async balanceOf(address: string, options?: ReadSCOptions): Promise { + const res = await this.read( + 'balanceOf', + new Args().addString(address), + options + ) + return U256.fromBytes(res.value) + } + + async transfer( + to: string, + amount: bigint, + options?: CallSCOptions + ): Promise { + return this.call( + 'transfer', + new Args().addString(to).addU256(amount), + options + ) + } + + async allowance( + ownerAddress: string, + spenderAddress: string, + options?: ReadSCOptions + ): Promise { + const res = await this.read( + 'allowance', + new Args().addString(ownerAddress).addString(spenderAddress), + options + ) + return U256.fromBytes(res.value) + } + + async increaseAllowance( + spenderAddress: string, + amount: bigint, + options?: CallSCOptions + ): Promise { + return this.call( + 'increaseAllowance', + new Args().addString(spenderAddress).addU256(amount), + options + ) + } + + async decreaseAllowance( + spenderAddress: string, + amount: bigint, + options?: CallSCOptions + ): Promise { + return this.call( + 'decreaseAllowance', + new Args().addString(spenderAddress).addU256(amount), + options + ) + } + + async transferFrom( + spenderAddress: string, + recipientAddress: string, + amount: bigint, + options?: CallSCOptions + ): Promise { + return this.call( + 'transferFrom', + new Args() + .addString(spenderAddress) + .addString(recipientAddress) + .addU256(amount), + options + ) + } +} diff --git a/src/contracts-wrappers/tokens.ts b/src/contracts-wrappers/tokens.ts new file mode 100644 index 00000000..2b65eca6 --- /dev/null +++ b/src/contracts-wrappers/tokens.ts @@ -0,0 +1,112 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { Provider } from '../provider' +import { CHAIN_ID, Network } from '../utils' +import { MRC20 } from './token' + +export const MAINNET_TOKENS = { + USDCe: 'AS1hCJXjndR4c9vekLWsXGnrdigp4AaZ7uYG3UKFzzKnWVsrNLPJ', + USDTb: 'AS12LKs9txoSSy8JgFJgV96m8k5z9pgzjYMYSshwN67mFVuj3bdUV', + DAIe: 'AS1ZGF1upwp9kPRvDKLxFAKRebgg7b3RWDnhgV7VvdZkZsUL7Nuv', + WETHe: 'AS124vf3YfAJCSCQVYKczzuWWpXrximFpbTmX4rheLs5uNSftiiRY', + WETHb: 'AS125oPLYRTtfVjpWisPZVTLjBhCFfQ1jDsi75XNtRm1NZux54eCj', + PUR: 'AS133eqPPaPttJ6hJnk3sfoG5cjFFqBDi1VGxdo2wzWkq8AfZnan', +} + +export const BUILDNET_TOKENS = { + DAIs: 'AS12LpYyAjYRJfYhyu7fkrS224gMdvFHVEeVWoeHZzMdhis7UZ3Eb', + WETHs: 'AS1gt69gqYD92dqPyE6DBRJ7KjpnQHqFzFs2YCkBcSnuxX5bGhBC', + USDCs: 'AS12k8viVmqPtRuXzCm6rKXjLgpQWqbuMjc37YHhB452KSUUb9FgL', + USDTbt: 'AS12ix1Qfpue7BB8q6mWVtjNdNE9UV3x4MaUo7WhdUubov8sJ3CuP', + WETHbt: 'AS12RmCXTA9NZaTBUBnRJuH66AGNmtEfEoqXKxLdmrTybS6GFJPFs', +} + +export function checkNetwork(provider: Provider, isMainnet: boolean): void { + provider.networkInfos().then((network: Network) => { + if (isMainnet && network.chainId !== CHAIN_ID.Mainnet) { + console.warn('This contract is only available on mainnet') + } else if (!isMainnet && network.chainId === CHAIN_ID.Mainnet) { + console.warn('This contract is only available on buildnet') + } + }) +} + +///////////////// MAINNET TOKENS ////////////////////// + +export class USDCe extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, true) + super(provider, MAINNET_TOKENS.USDCe) + } +} + +export class USDTb extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, true) + super(provider, MAINNET_TOKENS.USDTb) + } +} + +export class DAIe extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, true) + super(provider, MAINNET_TOKENS.DAIe) + } +} + +export class WETHe extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, true) + super(provider, MAINNET_TOKENS.WETHe) + } +} + +export class WETHb extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, true) + super(provider, MAINNET_TOKENS.WETHb) + } +} + +export class PUR extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, true) + super(provider, MAINNET_TOKENS.PUR) + } +} + +///////////////// BUILDNET TOKENS ////////////////////// + +export class DAIs extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, false) + super(provider, BUILDNET_TOKENS.DAIs) + } +} + +export class WETHs extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, false) + super(provider, BUILDNET_TOKENS.WETHs) + } +} + +export class USDCs extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, false) + super(provider, BUILDNET_TOKENS.USDCs) + } +} + +export class USDTbt extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, false) + super(provider, BUILDNET_TOKENS.USDTbt) + } +} + +export class WETHbt extends MRC20 { + constructor(public provider: Provider) { + checkNetwork(provider, false) + super(provider, BUILDNET_TOKENS.WETHbt) + } +} diff --git a/src/crypto/base58.ts b/src/crypto/base58.ts new file mode 100644 index 00000000..ab8e1213 --- /dev/null +++ b/src/crypto/base58.ts @@ -0,0 +1,17 @@ +import bs58check from 'bs58check' +import Serializer from './interfaces/serializer' + +/** + * Base58 implementation of the Serializer interface. + */ +export default class Base58 implements Serializer { + // eslint-disable-next-line class-methods-use-this -- Expected by the interface. + serialize(data: Uint8Array): string { + return bs58check.encode(data) + } + + // eslint-disable-next-line class-methods-use-this -- Expected by the interface. + deserialize(data: string): Uint8Array { + return bs58check.decode(data) + } +} diff --git a/src/crypto/blake3.ts b/src/crypto/blake3.ts new file mode 100644 index 00000000..b5e3d376 --- /dev/null +++ b/src/crypto/blake3.ts @@ -0,0 +1,12 @@ +import { blake3 as hashBlake3 } from '@noble/hashes/blake3' +import Hasher from './interfaces/hasher' + +/** + * Blake3 implementation of the Hasher interface. + */ +export default class Blake3 implements Hasher { + // eslint-disable-next-line class-methods-use-this -- Expected by the interface. + hash(data: Buffer | Uint8Array | string): Uint8Array { + return hashBlake3(data) + } +} diff --git a/src/crypto/cross-browser.ts b/src/crypto/cross-browser.ts new file mode 100644 index 00000000..5b94b28f --- /dev/null +++ b/src/crypto/cross-browser.ts @@ -0,0 +1,217 @@ +/* This module contains cryptographic functions federating between Node.js and the browser. + * @packageDocumentation + * + * @privateRemarks + * If you extend this module, please check that the functions are working in both Node.js and the browser. + */ + +const KEY_SIZE_BYTES = 32 +const IV_SIZE_BYTES = 12 +const AUTH_TAG_SIZE_BYTES = 16 + +const U8_SIZE_BITS = 8 + +function isNode(): boolean { + // inspired from secure-random.js + // we check for process.pid to prevent browserify from tricking us + return ( + typeof process !== 'undefined' && + typeof process.pid === 'number' && + typeof process.versions?.node === 'string' + ) +} + +async function pbkdf2Node( + password: string, + salt: Buffer, + opts: PBKDF2Options +): Promise { + const { iterations, keyLength, hash } = opts + // eslint-disable-next-line @typescript-eslint/no-var-requires + const crypto = require('crypto') + return new Promise((resolve, reject) => { + crypto.pbkdf2( + password, + salt, + iterations, + keyLength, + hash, + (err, derivedKey) => { + if (err) reject(err) + else resolve(derivedKey) + } + ) + }) +} + +async function pbkdf2Browser( + password: string, + salt: Buffer, + opts: PBKDF2Options +): Promise { + const { iterations, keyLength, hash } = opts + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const crypto = window.crypto || (window as any).msCrypto + + if (!crypto) throw new Error('Your browser does not expose window.crypto.') + + const keyMaterial = await crypto.subtle.importKey( + 'raw', + new TextEncoder().encode(password), + { name: 'PBKDF2' }, + false, + ['deriveBits', 'deriveKey'] + ) + const derivedKey = await crypto.subtle.deriveKey( + { + name: 'PBKDF2', + salt: salt, + iterations: iterations, + hash: { name: hash }, + }, + keyMaterial, + { name: 'AES-GCM', length: keyLength * U8_SIZE_BITS }, + false, + ['encrypt', 'decrypt'] + ) + + const exportedKey = await crypto.subtle.exportKey('raw', derivedKey) + const buffer = Buffer.from(exportedKey) + + return buffer +} + +export type PBKDF2Options = { + iterations: number + keyLength: number + hash: string +} + +/** + * Derives a cryptographic key using PBKDF2. + * + * @param password - The password from which to derive the key. + * @param salt - The cryptographic salt. + * @param opts - Options for the derivation. + * + * @returns The derived key. + */ +export async function pbkdf2( + password: string, + salt: Buffer, + opts: PBKDF2Options +): Promise { + if (isNode()) { + return pbkdf2Node(password, salt, opts) + } + + return pbkdf2Browser(password, salt, opts) +} + +/** + * Seals data using AES-256-GCM encryption. + * + * @param data - The data to encrypt. + * @param key - The 32-byte secret key. + * @param iv - The 12-byte initialization vector. + * + * @throws If the key is not 32 bytes. + * @throws If the iv is not 12 bytes. + * + * @returns The encrypted data. + */ +export async function aesGCMEncrypt( + data: Uint8Array, + key: Uint8Array, + iv: Uint8Array +): Promise { + if (key.length !== KEY_SIZE_BYTES) { + throw new Error(`key must be ${KEY_SIZE_BYTES} bytes`) + } + if (iv.length !== IV_SIZE_BYTES) { + throw new Error(`iv must be ${IV_SIZE_BYTES} bytes`) + } + if (isNode()) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const crypto = require('crypto') + const cipher = crypto.createCipheriv('aes-256-gcm', key, iv) + const encrypted = Buffer.concat([ + cipher.update(data), + cipher.final(), + cipher.getAuthTag(), + ]) + return encrypted + } + + const keyData = await window.crypto.subtle.importKey( + 'raw', + key, + { name: 'AES-GCM' }, + false, + ['encrypt'] + ) + const encrypted = await window.crypto.subtle.encrypt( + { name: 'AES-GCM', iv: iv }, + keyData, + data + ) + return Buffer.from(encrypted) +} + +/** + * Unseals data using AES-256-GCM decryption. + * + * @remarks + * The authentication tag shall be appended to the encryptedData. + * + * @param encryptedData - The data to decrypt. + * @param key - The 32-byte secret key. + * @param iv - The 12-byte initialization vector. + * + * @throws If the key is not 32 bytes. + * @throws If the iv is not 12 bytes. + * + * @returns The decrypted data. + */ +export async function aesGCMDecrypt( + encryptedData: Uint8Array, + key: Uint8Array, + iv: Uint8Array +): Promise { + if (key.length !== KEY_SIZE_BYTES) { + throw new Error(`key must be ${KEY_SIZE_BYTES} bytes`) + } + if (iv.length !== IV_SIZE_BYTES) { + throw new Error(`iv must be ${IV_SIZE_BYTES} bytes`) + } + if (isNode()) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const crypto = require('crypto') + encryptedData = Buffer.from(encryptedData) + const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv) + decipher.setAuthTag( + encryptedData.slice(encryptedData.length - AUTH_TAG_SIZE_BYTES) + ) + const decrypted = Buffer.concat([ + decipher.update( + encryptedData.slice(0, encryptedData.length - AUTH_TAG_SIZE_BYTES) + ), + decipher.final(), + ]) + return decrypted + } + + const keyData = await window.crypto.subtle.importKey( + 'raw', + key, + { name: 'AES-GCM' }, + false, + ['decrypt'] + ) + const decrypted = await window.crypto.subtle.decrypt( + { name: 'AES-GCM', iv: iv }, + keyData, + encryptedData + ) + return Buffer.from(decrypted) +} diff --git a/src/crypto/ed25519.ts b/src/crypto/ed25519.ts new file mode 100644 index 00000000..ffad33ca --- /dev/null +++ b/src/crypto/ed25519.ts @@ -0,0 +1,31 @@ +import * as ed from '@noble/ed25519' +import Signer from './interfaces/signer' + +/** + * Ed25519 implementation of the Signer interface. + */ +export default class Ed25519 implements Signer { + // eslint-disable-next-line class-methods-use-this -- Expected by the interface. + generatePrivateKey(): Uint8Array { + return ed.utils.randomPrivateKey() + } + + // eslint-disable-next-line class-methods-use-this -- Expected by the interface. + async getPublicKey(privateKey: Uint8Array): Promise { + return ed.getPublicKey(privateKey) + } + + // eslint-disable-next-line class-methods-use-this -- Expected by the interface. + async sign(privateKey: Uint8Array, data: Uint8Array): Promise { + return ed.sign(data, privateKey) + } + + // eslint-disable-next-line class-methods-use-this -- Expected by the interface. + async verify( + publicKey: Uint8Array, + data: Uint8Array, + signature: Uint8Array + ): Promise { + return ed.verify(signature, data, publicKey) + } +} diff --git a/src/crypto/interfaces/hasher.ts b/src/crypto/interfaces/hasher.ts new file mode 100644 index 00000000..4cb42335 --- /dev/null +++ b/src/crypto/interfaces/hasher.ts @@ -0,0 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- True interface. +export default interface Hasher { + hash(data: Buffer | Uint8Array | string): Uint8Array +} diff --git a/src/crypto/interfaces/sealer.ts b/src/crypto/interfaces/sealer.ts new file mode 100644 index 00000000..d4419dc8 --- /dev/null +++ b/src/crypto/interfaces/sealer.ts @@ -0,0 +1,7 @@ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- True interface. +export default interface Sealer { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + seal(data: Uint8Array): Promise + // eslint-disable-next-line @typescript-eslint/no-explicit-any + unseal(data: any): Promise +} diff --git a/src/crypto/interfaces/serializer.ts b/src/crypto/interfaces/serializer.ts new file mode 100644 index 00000000..c924d159 --- /dev/null +++ b/src/crypto/interfaces/serializer.ts @@ -0,0 +1,5 @@ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- True interface. +export default interface Serializer { + serialize(data: Uint8Array): string + deserialize(data: string): Uint8Array +} diff --git a/src/crypto/interfaces/signer.ts b/src/crypto/interfaces/signer.ts new file mode 100644 index 00000000..1af2146f --- /dev/null +++ b/src/crypto/interfaces/signer.ts @@ -0,0 +1,11 @@ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- True interface. +export default interface Signer { + generatePrivateKey(): Uint8Array + getPublicKey(privateKey: Uint8Array): Promise + sign(privateKey: Uint8Array, data: Uint8Array): Promise + verify( + publicKey: Uint8Array, + data: Uint8Array, + signature: Uint8Array + ): Promise +} diff --git a/src/crypto/interfaces/versioner.ts b/src/crypto/interfaces/versioner.ts new file mode 100644 index 00000000..f00e70ea --- /dev/null +++ b/src/crypto/interfaces/versioner.ts @@ -0,0 +1,10 @@ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- True interface. +export interface Versioner { + attach(version: Version, data: Uint8Array): Uint8Array + extract(data: Uint8Array): { version: Version; data: Uint8Array } +} + +export enum Version { + V0 = 0, + V1 = 1, +} diff --git a/src/crypto/passwordSeal.ts b/src/crypto/passwordSeal.ts new file mode 100644 index 00000000..5055aad9 --- /dev/null +++ b/src/crypto/passwordSeal.ts @@ -0,0 +1,106 @@ +import Sealer from './interfaces/sealer' +import randomUint8Array from 'secure-random' + +import { + PBKDF2Options, + aesGCMDecrypt, + aesGCMEncrypt, + pbkdf2, +} from './cross-browser' + +const KEY_SIZE_BYTES = 32 +const NONCE_SIZE_BYTES = 12 +const SALT_SIZE_BYTES = 16 +const OWASP_ITERATIONS = 600000 + +function createKey(password: string, salt: Buffer): Promise { + const opts: PBKDF2Options = { + iterations: OWASP_ITERATIONS, + keyLength: KEY_SIZE_BYTES, + hash: 'sha256', + } + return pbkdf2(password, salt, opts) +} + +/** + * Password-based implementation of the Sealer interface. + */ +export class PasswordSeal implements Sealer { + private password: string + public salt: Uint8Array + public nonce: Uint8Array + + constructor(password: string, salt?: Uint8Array, nonce?: Uint8Array) { + this.salt = salt ?? randomUint8Array(SALT_SIZE_BYTES) + this.nonce = nonce ?? randomUint8Array(NONCE_SIZE_BYTES) + this.validate() + + this.password = password + } + + private validate(): void { + if (!this.salt || this.salt.length !== SALT_SIZE_BYTES) { + throw new Error(`Salt must be ${SALT_SIZE_BYTES} bytes`) + } + if (!this.nonce || this.nonce.length !== NONCE_SIZE_BYTES) { + throw new Error(`Nonce must be ${NONCE_SIZE_BYTES} bytes`) + } + } + + /** + * Seals data using password-based PKDF2 AES-256-GCM encryption. + * + * @param data - The data to encrypt. + * + * @returns Protected data. + */ + async seal(data: Uint8Array): Promise { + this.validate() + const key = await createKey(this.password, Buffer.from(this.salt)) + return aesGCMEncrypt(data, key, Buffer.from(this.nonce)) + } + + /** + * Unseals data using password-based PKDF2 AES-256-GCM decryption. + * + * @param data - The encrypted data. + * + * @returns Clear data. + */ + async unseal(data: Uint8Array): Promise { + this.validate() + const key = await createKey(this.password, Buffer.from(this.salt)) + return aesGCMDecrypt(data, key, Buffer.from(this.nonce)) + } + + /** + * Creates a Sealer from environment variables. + * + * @remarks + * The expected environment variables are: + * - PASSWORD, + * - SALT - base64 encoded, and + * - NONCE - base64 encoded. + * + * @returns A password-based sealer instance. + */ + static fromEnv(): Sealer { + const pwd = process.env.PASSWORD + if (!pwd) { + throw new Error('Missing PASSWORD environment variable') + } + const salt = process.env.SALT + ? Uint8Array.from(Buffer.from(process.env.SALT, 'base64')) + : undefined + if (!salt) { + throw new Error('Missing base64 encoded SALT in .env file') + } + const nonce = process.env.NONCE + ? Uint8Array.from(Buffer.from(process.env.NONCE, 'base64')) + : undefined + if (!nonce) { + throw new Error('Missing base64 encoded NONCE in .env file') + } + return new PasswordSeal(pwd, salt, nonce) + } +} diff --git a/src/crypto/varintVersioner.ts b/src/crypto/varintVersioner.ts new file mode 100644 index 00000000..d2b89836 --- /dev/null +++ b/src/crypto/varintVersioner.ts @@ -0,0 +1,34 @@ +import varint from 'varint' +import { Versioner, Version } from './interfaces/versioner' + +/** + * Varint-based implementation of the Versioner interface. + */ +export default class VarintVersioner implements Versioner { + /** + * Prepends the version to the data. + * + * @param version - The version to attach. + * @param data - The data to attach the version to. + * + * @returns The versioned data. + */ + // eslint-disable-next-line class-methods-use-this -- Expected by the interface. + attach(version: Version, data: Uint8Array): Uint8Array { + const versionArray = varint.encode(version) + return new Uint8Array([...versionArray, ...data]) + } + + /** + * Extracts the version from the data. + * + * @param data - The versioned data. + * + * @returns The version and the data. + */ + // eslint-disable-next-line class-methods-use-this -- Expected by the interface. + extract(data: Uint8Array): { version: Version; data: Uint8Array } { + const version = varint.decode(data) + return { data: data.slice(varint.decode.bytes), version } + } +} diff --git a/src/dataStore.ts b/src/dataStore.ts new file mode 100644 index 00000000..168709fa --- /dev/null +++ b/src/dataStore.ts @@ -0,0 +1,74 @@ +import { Args, U64, U8 } from './basicElements' + +const CONTRACTS_NUMBER_KEY = new Uint8Array([0]) + +type DatastoreContract = { + data: Uint8Array + args: Uint8Array + coins: bigint +} + +/** + * Generates a key for coin data in the datastore. + * + * @param offset - The offset to use when generating the key. + * @returns A Uint8Array representing the key. + */ +function coinsKey(offset: number): Uint8Array { + return new Args() + .addU64(BigInt(offset + 1)) + .addUint8Array(U8.toBytes(1n)) + .serialize() +} + +/** + * Generates a key for args data in the datastore. + * + * @param offset - The offset to use when generating the key. + * @returns A Uint8Array representing the key. + */ +function argsKey(offset: number): Uint8Array { + return new Args() + .addU64(BigInt(offset + 1)) + .addUint8Array(U8.toBytes(0n)) + .serialize() +} + +/** + * Generates a key for contract data in the datastore. + * + * @param offset - The offset to use when generating the key. + * @returns A Uint8Array representing the key. + */ +function contractKey(offset: number): Uint8Array { + return U64.toBytes(BigInt(offset + 1)) +} + +/** + * Populates the datastore with the contracts. + * + * @remarks + * This function is to be used in conjunction with the deployer smart contract. + * The deployer smart contract expects to have an execution datastore in a specific state. + * This function populates the datastore according to that expectation. + * + * @param contracts - The contracts to populate the datastore with. + * + * @returns The populated datastore. + */ +export function populateDatastore( + contracts: DatastoreContract[] +): Map { + const datastore = new Map() + + // set the number of contracts in the first key of the datastore + datastore.set(CONTRACTS_NUMBER_KEY, U64.toBytes(BigInt(contracts.length))) + + contracts.forEach((contract, i) => { + datastore.set(contractKey(i), contract.data) + datastore.set(argsKey(i), contract.args) + datastore.set(coinsKey(i), U64.toBytes(contract.coins)) + }) + + return datastore +} diff --git a/src/errors/base.ts b/src/errors/base.ts new file mode 100644 index 00000000..38cba6c0 --- /dev/null +++ b/src/errors/base.ts @@ -0,0 +1,54 @@ +import { ErrorCodes } from './utils/codes' + +export type BaseParameters = { + code?: ErrorCodes + docsPath?: string + metaMessages?: string[] +} & ( + | { + cause?: never + details?: string + } + | { + cause: ErrorBase | Error + details?: never + } +) + +/** + * ErrorBase extends the native Error class to provide additional metadata handling for richer error information. + * This class can serve as a base for more specific error types in a wallet or similar system. + */ +export class ErrorBase extends Error { + metaMessages: string[] + docsPath?: string + code: ErrorCodes + cause?: Error + + override name = 'MassaWeb3Error' + constructor(shortMessage: string, args?: BaseParameters) { + super() + + const metaMessageStr = + args?.metaMessages?.map((msg) => `Meta: ${msg}`).join('\n') || '' + const docsMessageStr = args?.docsPath + ? `Docs: see ${args?.docsPath} for more information.` + : '' + + const detailsMessage = args?.details ? `Details: ${args.details}` : '' + + this.message = [ + shortMessage, + metaMessageStr, + docsMessageStr, + detailsMessage, + ] + .filter(Boolean) + .join('\n\n') + + this.metaMessages = args?.metaMessages || [] + this.docsPath = args?.docsPath + this.code = args?.code ?? ErrorCodes.UnknownError + this.cause = args?.cause + } +} diff --git a/src/errors/index.ts b/src/errors/index.ts new file mode 100644 index 00000000..cd734ae2 --- /dev/null +++ b/src/errors/index.ts @@ -0,0 +1,4 @@ +export { ErrorBase } from './base' +export { ErrorMaxGas } from './maxGas' +export { ErrorMinimalFee } from './minimalFee' +export { ErrorInsufficientBalance } from './insufficientBalance' diff --git a/src/errors/insufficientBalance.ts b/src/errors/insufficientBalance.ts new file mode 100644 index 00000000..1e2f9f36 --- /dev/null +++ b/src/errors/insufficientBalance.ts @@ -0,0 +1,38 @@ +import { ErrorBase } from './base' +import { ErrorCodes } from './utils/codes' + +type InsufficientBalanceParameters = { + userBalance: bigint + neededBalance: bigint + cause?: Error +} + +/** + * Error class for handling cases when a user's balance is insufficient for a specified operation. + */ +export class ErrorInsufficientBalance extends ErrorBase { + /** + * Explicitly sets the error name for easier identification in error handling processes. + */ + override name = 'ErrorInsufficientBalance' + + /** + * Constructs an ErrorInsufficientBalance with a detailed message about the shortage. + * @param userBalance - The current balance of the user in nanoMassa. + * @param neededBalance - The balance required to successfully perform the operation in nanoMassa. + * @param cause - Optional error object that triggered this error, useful for chaining errors. + */ + constructor({ + userBalance, + neededBalance, + cause, + }: InsufficientBalanceParameters) { + super( + `Insufficient balance for the operation. User has ${userBalance} nanoMassa, but ${neededBalance} nanoMassa is needed.`, + { + code: ErrorCodes.InsufficientBalance, + cause, + } + ) + } +} diff --git a/src/errors/maxGas.ts b/src/errors/maxGas.ts new file mode 100644 index 00000000..8857511c --- /dev/null +++ b/src/errors/maxGas.ts @@ -0,0 +1,34 @@ +import { ErrorBase } from './base' +import { ErrorCodes } from './utils/codes' + +type ErrorMaxGasParameters = { + isHigher: boolean + amount: bigint + cause?: Error +} + +/** + * Error class for handling gas limit errors related to operations, whether exceeding max or falling below min allowed limits. + */ +export class ErrorMaxGas extends ErrorBase { + /** + * Override the name to clearly identify this as a ErrorMaxGas. + */ + override name = 'ErrorMaxGas' + + /** + * Constructs a ErrorMaxGas with a message indicating whether the gas limit was exceeded or insufficient. + * @param isHigher - Boolean indicating if the actual gas used was higher than allowed (true) or lower (false). + * @param amount - The critical amount of gas that was either exceeded or not reached. + * @param cause - Optional cause of the error for deeper error chaining. + */ + constructor({ isHigher, amount, cause }: ErrorMaxGasParameters) { + super( + `The gas limit for the operation was ${isHigher ? 'higher than the maximum' : 'below the minimum'} amount of ${amount}.`, + { + code: ErrorCodes.MaxGasLimit, + cause, + } + ) + } +} diff --git a/src/errors/minimalFee.ts b/src/errors/minimalFee.ts new file mode 100644 index 00000000..94b339af --- /dev/null +++ b/src/errors/minimalFee.ts @@ -0,0 +1,31 @@ +import { ErrorBase } from './base' +import { ErrorCodes } from './utils/codes' + +type ErrorMinimalFeeParameters = { + minimalFee: bigint + cause?: Error +} + +/** + * ErrorMinimalFee is a specific type of error that is thrown when the provided fee for an operation + * is below the minimum required fee for that operation. It extends ErrorBase to provide additional context and metadata. + */ +export class ErrorMinimalFee extends ErrorBase { + override name = 'ErrorMinimalFee' // Override the default error name with a more specific one. + + /** + * Constructs a new ErrorMinimalFee with a message indicating the minimum required fee. + * @param minimalFee - The minimum fee that was required for the operation. + * @param cause - Optional. The underlying cause of the error for error chaining. + */ + constructor({ minimalFee, cause }: ErrorMinimalFeeParameters) { + // Call the base class constructor with a detailed message and the relevant error code. + super( + `Minimal fees for the operation on this client are ${minimalFee}. Please adjust the fee.`, + { + code: ErrorCodes.MinimalFee, + cause, + } + ) + } +} diff --git a/src/errors/utils/codes.ts b/src/errors/utils/codes.ts new file mode 100644 index 00000000..680ebf30 --- /dev/null +++ b/src/errors/utils/codes.ts @@ -0,0 +1,6 @@ +export enum ErrorCodes { + UnknownError, + MaxGasLimit, + InsufficientBalance, + MinimalFee, +} diff --git a/src/events/eventsPoller.ts b/src/events/eventsPoller.ts new file mode 100644 index 00000000..363dbfff --- /dev/null +++ b/src/events/eventsPoller.ts @@ -0,0 +1,112 @@ +import { Provider } from '../provider' +import { EventFilter, NB_THREADS, SCEvent, Slot } from '../client' +import EventEmitter from 'eventemitter3' + +/** Smart Contracts Event Poller */ +export const ON_MASSA_EVENT_DATA = 'ON_MASSA_EVENT' +export const ON_MASSA_EVENT_ERROR = 'ON_MASSA_ERROR' + +export const DEFAULT_POLL_INTERVAL_MS = 1000 + +// get the next slot +function nextSlot(prevSlot: Slot): Slot { + const slot = prevSlot + if (slot.thread < NB_THREADS - 1) { + slot.thread++ + } else { + slot.thread = 0 + slot.period++ + } + return slot +} + +/** + * The EventPoller class provides a convenient way to poll events from the Massa network. + */ +export class EventPoller extends EventEmitter { + private intervalId: NodeJS.Timeout + private lastSlot: Slot + + /** + * Constructor of the EventPoller object. + * + * @param provider - The provider to use for polling. + * @param eventsFilter - The filter to use for the events. + * @param pollIntervalMs - The interval in milliseconds to poll for events. + */ + public constructor( + private readonly provider: Provider, + private readonly eventsFilter: EventFilter, + private readonly pollIntervalMs: number + ) { + super() + } + + private poll = async (): Promise => { + try { + if (this.lastSlot) { + this.eventsFilter.start = nextSlot(this.lastSlot) + } + + const events = await this.provider.getEvents(this.eventsFilter) + + if (events.length) { + this.emit(ON_MASSA_EVENT_DATA, events) + this.lastSlot = events[events.length - 1].context.slot + } + } catch (ex) { + this.emit(ON_MASSA_EVENT_ERROR, ex) + } + } + + /** + * Stops polling for events. + */ + private stop = (): void => { + if (this.intervalId) { + clearInterval(this.intervalId) + } + } + + /** + * Starts polling for events. + */ + private start(): void { + this.stop() + this.intervalId = setInterval(this.poll, this.pollIntervalMs) + } + + /** + * Starts polling for events and returns the stopPolling function. + * + * @param provider - The provider to use for polling. + * @param eventsFilter - The filter to use for the events. + * @param onData - The callback function to call when new events are found. + * @param onError - The callback function to call when an error occurs. + * @param pollIntervalMs - The interval in milliseconds to poll for events. Default is 1000Ms. + * + * @returns An object containing the stopPolling function. + */ + // eslint-disable-next-line max-params + public static start( + provider: Provider, + eventsFilter: EventFilter, + onData?: (data: SCEvent[]) => void, + onError?: (err: Error) => void, + pollIntervalMs = DEFAULT_POLL_INTERVAL_MS + ): { stopPolling: () => void } { + const eventPoller = new EventPoller(provider, eventsFilter, pollIntervalMs) + if (onData) { + eventPoller.on(ON_MASSA_EVENT_DATA, onData) + } + if (onError) { + eventPoller.on(ON_MASSA_EVENT_ERROR, onError) + } + + eventPoller.start() + + return { + stopPolling: eventPoller.stop, + } + } +} diff --git a/src/events/index.ts b/src/events/index.ts new file mode 100644 index 00000000..57f00471 --- /dev/null +++ b/src/events/index.ts @@ -0,0 +1 @@ +export * from './eventsPoller' diff --git a/src/generated/client-types.ts b/src/generated/client-types.ts new file mode 100644 index 00000000..0e76b8f5 --- /dev/null +++ b/src/generated/client-types.ts @@ -0,0 +1,1453 @@ +/** + * + * Max available gas + * + */ +export type NumberPsns2WbD = number; +export type Integer2AHOqbcQ = number; +/** + * + * Bytecode to execute + * + */ +export type UnorderedSetOfInteger2AHOqbcQjNvs9B0Z = Integer2AHOqbcQ[]; +/** + * + * Address + * + */ +export type Address = string; +/** + * + * An operation datastore + * + */ +export type UnorderedSetOfInteger2AHOqbcQtXvTMhya = Integer2AHOqbcQ[]; +/** + * + * Whether to start execution from final or active state + * + */ +export type BooleanHNwwo80P = boolean; +/** + * + * Amount in coins, optional + * + */ +export type NumberZ1JdLCIz = number; +/** + * + * Fee, optional + * + */ +export type NumberSnYk3VhE = number; +/** + * + * Read only bytecode execution + * + */ +export interface ReadOnlyBytecodeExecution { + max_gas: NumberPsns2WbD; + bytecode: UnorderedSetOfInteger2AHOqbcQjNvs9B0Z; + address?: Address; + operation_datastore?: UnorderedSetOfInteger2AHOqbcQtXvTMhya; + is_final?: BooleanHNwwo80P; + coins?: NumberZ1JdLCIz; + fee?: NumberSnYk3VhE; +} +/** + * + * Target address + * + */ +export type StringYvGZTlwQ = string; +/** + * + * Target function + * + */ +export type StringBtBJC5Iw = string; +/** + * + * Function parameter + * + */ +export type UnorderedSetOfInteger2AHOqbcQzYHdsLoW = Integer2AHOqbcQ[]; +export type NullQu0Arl1F = null; +export type StringDoaGddGA = string; +/** + * + * Caller's address, optional + * + */ +export type OneOfNullQu0Arl1FStringDoaGddGAHzYKhN99 = NullQu0Arl1F | StringDoaGddGA; +/** + * + * Amount in coins, optional + * + */ +export type OneOfNullQu0Arl1FStringDoaGddGAEUSQB1KK = NullQu0Arl1F | StringDoaGddGA; +/** + * + * Fee, optional + * + */ +export type OneOfNullQu0Arl1FStringDoaGddGANOhzhrxe = NullQu0Arl1F | StringDoaGddGA; +/** + * + * Read only call + * + */ +export interface ReadOnlyCall { + max_gas: NumberPsns2WbD; + target_address: StringYvGZTlwQ; + target_function: StringBtBJC5Iw; + parameter: UnorderedSetOfInteger2AHOqbcQzYHdsLoW; + caller_address: OneOfNullQu0Arl1FStringDoaGddGAHzYKhN99; + coins: OneOfNullQu0Arl1FStringDoaGddGAEUSQB1KK; + fee: OneOfNullQu0Arl1FStringDoaGddGANOhzhrxe; +} +/** + * + * true means final, false means candidate + * + */ +export type Boolean7Xei3MDX = boolean; +/** + * + * Address filter + * + */ +export interface AddressFilter { + address?: Address; + is_final?: Boolean7Xei3MDX; +} +/** + * + * Block identifier + * + */ +export type BlockId = string; +export type NumberHo1ClIqD = number; +export type UnorderedSetOfInteger2AHOqbcQBha3UJIJ = Integer2AHOqbcQ[]; +export interface DatastoreEntryInput { + address: Address; + key: UnorderedSetOfInteger2AHOqbcQBha3UJIJ; +} +/** + * + * Slot + * + */ +export interface Slot { + period: NumberHo1ClIqD; + thread: NumberHo1ClIqD; +} +/** + * + * Optional emitter address + * + */ +export type String5J7NQ8B1 = string; +/** + * + * Optional caller address + * + */ +export type StringCc6XlKeq = string; +/** + * + * Optional operation id + * + */ +export type StringUcQL9QGN = string; +/** + * + * Optional filter to filter only candidate or final events + * + */ +export type BooleanObf9WMA0 = boolean; +/** + * + * Optional filter to retrieve events generated in a failed execution + * + */ +export type BooleanAXlyTrPe = boolean; +/** + * + * `PrivateKey` is used for signature and decryption + * + */ +export type PrivateKey = string; +/** + * + * Ip address + * + */ +export type StringBBdNk2Ku = string; +/** + * + * ip address + * + */ +export type StringOGpKXaCP = string; +/** + * + * the content creator public key + * + */ +export type PublicKey = string; +/** + * + * signature + * + */ +export type Signature = string; +export type UnorderedSetOfInteger2AHOqbcQarZIQlOy = Integer2AHOqbcQ[]; +/** + * + * Operation input + * + */ +export interface OperationInput { + creator_public_key: PublicKey; + signature: Signature; + serialized_content: UnorderedSetOfInteger2AHOqbcQarZIQlOy; +} +/** + * + * An PageRequest object, which contains limit (max elements par page) and a page offset. + * + */ +export interface Pagination { + limit: NumberHo1ClIqD; + offset: NumberHo1ClIqD; +} +export interface ExecuteAt { + period: NumberHo1ClIqD; + thread: NumberHo1ClIqD; +} +export type StringUJarsTOs = string; +/** + * + * Included in case of success. The result of the execution + * + */ +export type UnorderedSetOfStringUJarsTOsgviiNMvH = StringUJarsTOs[]; +/** + * + * Included in case of error. The error message + * + */ +export type StringOz2F8Z2Y = string; +/** + * + * The result of a read-only execution + * + */ +export interface ReadOnlyResult { + Ok?: UnorderedSetOfStringUJarsTOsgviiNMvH; + Error?: StringOz2F8Z2Y; +} +/** + * + * String of the event you sended + * + */ +export type StringBt9L6T1F = string; +/** + * + * Wether the event was generated during read only call + * + */ +export type BooleanQYH7IQYB = boolean; +/** + * + * Addresses, most recent at the end + * + */ +export type UnorderedSetOfAddressqhKJr2Tw = Address[]; +/** + * + * Index of the event in the slot + * + */ +export type NumberHGt16B6Y = number; +/** + * + * Operation id + * + */ +export type OperationId = string; +/** + * + * Whether the event is final + * + */ +export type BooleanSPcYqJj2 = boolean; +/** + * + * Whether the event was generated in a failed executed or not + * + */ +export type BooleanIqtEc7R0 = boolean; +/** + * + * Context generated by the execution context + * + */ +export interface EventExecutionContext { + slot: Slot; + block?: BlockId; + read_only: BooleanQYH7IQYB; + call_stack: UnorderedSetOfAddressqhKJr2Tw; + index_in_slot: NumberHGt16B6Y; + origin_operation_id?: OperationId; + is_final: BooleanSPcYqJj2; + is_error?: BooleanIqtEc7R0; +} +export interface SCOutputEvent { + data: StringBt9L6T1F; + context: EventExecutionContext; +} +export type UnorderedSetOfSCOutputEventHwhiOmzE = SCOutputEvent[]; +/** + * + * The gas cost for the execution + * + */ +export type NumberAIaYfWME = number; +/** + * + * ledger changes + * + */ +export interface ObjectD93Z4FAG { [key: string]: any; } +export interface ObjectHAgrRKSz { [key: string]: any; } +/** + * + * async pool changes + * + */ +export type UnorderedSetOfObjectHAgrRKSz46QV1Tyv = ObjectHAgrRKSz[]; +/** + * + * pos changes + * + */ +export interface ObjectYWuwfL0B { [key: string]: any; } +/** + * + * executed operations changes + * + */ +export interface ObjectTK16EAH4 { [key: string]: any; } +/** + * + * executed denunciation changes + * + */ +export interface Object413CQ8L2 { [key: string]: any; } +/** + * + * execution trail hash change + * + */ +export type StringIytPJwYq = string; +export interface StateChanges { + ledger_changes: ObjectD93Z4FAG; + async_pool_changes: UnorderedSetOfObjectHAgrRKSz46QV1Tyv; + pos_changes: ObjectYWuwfL0B; + executed_ops_changes: ObjectTK16EAH4; + executed_denunciations_changes: Object413CQ8L2; + execution_trail_hash_change: StringIytPJwYq; +} +export interface ExecuteReadOnlyResponse { + executed_at: ExecuteAt; + result: ReadOnlyResult; + output_events: UnorderedSetOfSCOutputEventHwhiOmzE; + gas_cost: NumberAIaYfWME; + state_changes: StateChanges; +} +/** + * + * The thread the address belongs to + * + */ +export type NumberSYJcvZVm = number; +/** + * + * The final balance + * + */ +export type StringFFlpWNJb = string; +/** + * + * The final roll count + * + */ +export type NumberPAAsFK4N = number; +export type UnorderedSetOfNumberHo1ClIqDAokMKuEf = NumberHo1ClIqD[]; +/** + * + * The final datastore keys + * + */ +export type UnorderedSetOfUnorderedSetOfNumberHo1ClIqDAokMKuEfIixaMtvV = UnorderedSetOfNumberHo1ClIqDAokMKuEf[]; +/** + * + * The candidate balance + * + */ +export type StringSZbUM3UB = string; +/** + * + * The candidate roll count + * + */ +export type NumberUycrgn8X = number; +/** + * + * The candidate datastore keys + * + */ +export type UnorderedSetOfUnorderedSetOfNumberHo1ClIqDAokMKuEfmvpf11Qe = UnorderedSetOfNumberHo1ClIqDAokMKuEf[]; +export interface ObjectOfSlotStringDoaGddGAQZyvCcRS { + slot?: Slot; + amount?: StringDoaGddGA; + [k: string]: any; +} +/** + * + * The deferred credits + * + */ +export type UnorderedSetOfObjectOfSlotStringDoaGddGAQZyvCcRS732D8Bc5 = ObjectOfSlotStringDoaGddGAQZyvCcRS[]; +/** + * + * The next block draws + * + */ +export type UnorderedSetOfSlotpnXhUhWs = Slot[]; +export interface ObjectOfSlotNumberHo1ClIqDMPMjgxrm { + slot?: Slot; + index?: NumberHo1ClIqD; + [k: string]: any; +} +/** + * + * The next endorsement draws + * + */ +export type UnorderedSetOfObjectOfSlotNumberHo1ClIqDMPMjgxrm06Ae306Q = ObjectOfSlotNumberHo1ClIqDMPMjgxrm[]; +/** + * + * BlockIds of created blocks + * + */ +export type UnorderedSetOfBlockIdpdDCfi0P = BlockId[]; +/** + * + * OperationIds of created operations + * + */ +export type UnorderedSetOfOperationId971EzIER = OperationId[]; +/** + * + * Endorsement id + * + */ +export type EndorsementId = string; +/** + * + * EndorsementIds of created endorsements + * + */ +export type UnorderedSetOfEndorsementIdNN27ZC1J = EndorsementId[]; +export type BooleanVyG3AETh = boolean; +export type OneOfNullQu0Arl1FNumberHo1ClIqDKWtQwzS8 = NullQu0Arl1F | NumberHo1ClIqD; +export interface ExecutionAddressCycleInfo { + cycle: NumberHo1ClIqD; + is_final: BooleanVyG3AETh; + ok_count: NumberHo1ClIqD; + nok_count: NumberHo1ClIqD; + active_rolls?: OneOfNullQu0Arl1FNumberHo1ClIqDKWtQwzS8; +} +/** + * + * Cycle infos + * + */ +export type UnorderedSetOfExecutionAddressCycleInfo8D3STgcL = ExecutionAddressCycleInfo[]; +export interface AddressInfo { + address: Address; + thread: NumberSYJcvZVm; + final_balance: StringFFlpWNJb; + final_roll_count: NumberPAAsFK4N; + final_datastore_keys: UnorderedSetOfUnorderedSetOfNumberHo1ClIqDAokMKuEfIixaMtvV; + candidate_balance: StringSZbUM3UB; + candidate_roll_count: NumberUycrgn8X; + candidate_datastore_keys: UnorderedSetOfUnorderedSetOfNumberHo1ClIqDAokMKuEfmvpf11Qe; + deferred_credits: UnorderedSetOfObjectOfSlotStringDoaGddGAQZyvCcRS732D8Bc5; + next_block_draws: UnorderedSetOfSlotpnXhUhWs; + next_endorsement_draws: UnorderedSetOfObjectOfSlotNumberHo1ClIqDMPMjgxrm06Ae306Q; + created_blocks: UnorderedSetOfBlockIdpdDCfi0P; + created_operations: UnorderedSetOfOperationId971EzIER; + created_endorsements: UnorderedSetOfEndorsementIdNN27ZC1J; + cycle_infos: UnorderedSetOfExecutionAddressCycleInfo8D3STgcL; +} +/** + * + * true if final + * + */ +export type BooleanZxUVUy6M = boolean; +/** + * + * true if candidate + * + */ +export type BooleanMazVJcyf = boolean; +/** + * + * true if discarded + * + */ +export type BooleanHJvzO9WE = boolean; +/** + * + * true if in the greatest clique + * + */ +export type BooleanHjqkwJfo = boolean; +/** + * + * Current version + * + */ +export type NumberTbrodUsH = number; +/** + * + * Announced version + * + */ +export type OneOfNullQu0Arl1FNumberHo1ClIqD4U4GpKJM = NullQu0Arl1F | NumberHo1ClIqD; +export type UnorderedSetOfStringDoaGddGADvj0XlFa = StringDoaGddGA[]; +/** + * + * Endorsement content + * + */ +export interface EndorsementContent { + slot: Slot; + index: NumberHo1ClIqD; + endorsed_block: BlockId; +} +export interface ObjectOfStringDoaGddGAEndorsementIdPublicKeyAddressEndorsementContentWrpyYBUS { + content?: EndorsementContent; + signature?: StringDoaGddGA; + content_creator_pub_key?: PublicKey; + content_creator_address?: Address; + id?: EndorsementId; + [k: string]: any; +} +/** + * + * Endorsements + * + */ +export type UnorderedSetOfObjectOfStringDoaGddGAEndorsementIdPublicKeyAddressEndorsementContentWrpyYBUSwrpyYBUS = ObjectOfStringDoaGddGAEndorsementIdPublicKeyAddressEndorsementContentWrpyYBUS[]; +export interface ObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUS { + public_key?: StringDoaGddGA; + slot?: Integer2AHOqbcQ; + index?: Integer2AHOqbcQ; + hash_1?: StringDoaGddGA; + hash_2?: StringDoaGddGA; + signature_1?: StringDoaGddGA; + signature_2?: StringDoaGddGA; + [k: string]: any; +} +export interface ObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUS { + public_key?: StringDoaGddGA; + slot?: Integer2AHOqbcQ; + hash_1?: StringDoaGddGA; + hash_2?: StringDoaGddGA; + signature_1?: StringDoaGddGA; + signature_2?: StringDoaGddGA; + [k: string]: any; +} +export type OneOfObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUSObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUSGJLAASWC = ObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUS | ObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUS; +/** + * + * Denunciations + * + */ +export type UnorderedSetOfOneOfObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUSObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUSGJLAASWCwrpyYBUS = OneOfObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUSObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUSGJLAASWC[]; +/** + * + * header type + * + */ +export interface Header { + current_version?: NumberTbrodUsH; + announced_version?: OneOfNullQu0Arl1FNumberHo1ClIqD4U4GpKJM; + operation_merkle_root: StringDoaGddGA; + parents: UnorderedSetOfStringDoaGddGADvj0XlFa; + slot: Slot; + endorsements?: UnorderedSetOfObjectOfStringDoaGddGAEndorsementIdPublicKeyAddressEndorsementContentWrpyYBUSwrpyYBUS; + denunciations?: UnorderedSetOfOneOfObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUSObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUSGJLAASWCwrpyYBUS; +} +/** + * + * signed operation + * + */ +export interface WrappedHeader { + content: Header; + signature: Signature; + content_creator_pub_key: PublicKey; + content_creator_address: Address; + id?: BlockId; +} +/** + * + * Operations + * + */ +export type UnorderedSetOfStringDoaGddGAucaTsQyS = StringDoaGddGA[]; +export interface Block { + header: WrappedHeader; + operations: UnorderedSetOfStringDoaGddGAucaTsQyS; +} +export interface BlockInfoContent { + is_final: BooleanZxUVUy6M; + is_candidate: BooleanMazVJcyf; + is_discarded?: BooleanHJvzO9WE; + is_in_blockclique: BooleanHjqkwJfo; + block: Block; +} +export interface BlockInfo { + id: StringDoaGddGA; + content?: BlockInfoContent; +} +/** + * + * The block ids of the blocks in that clique + * + */ +export type UnorderedSetOfBlockId1V6I15AQ = BlockId[]; +/** + * + * Depends on descendants and endorsement count + * + */ +export type Number7BVjpZ2Z = number; +/** + * + * True if it is the clique of higher fitness + * + */ +export type BooleanXIboFXzF = boolean; +/** + * + * Clique + * + */ +export interface Clique { + block_ids: UnorderedSetOfBlockId1V6I15AQ; + fitness: Number7BVjpZ2Z; + is_blockclique: BooleanXIboFXzF; +} +/** + * + * The candidate datastore entry value bytes + * + */ +export type OneOfNullQu0Arl1FUnorderedSetOfInteger2AHOqbcQarZIQlOy81SHPJsX = UnorderedSetOfInteger2AHOqbcQarZIQlOy | NullQu0Arl1F; +/** + * + * The final datastore entry value bytes + * + */ +export type OneOfNullQu0Arl1FUnorderedSetOfInteger2AHOqbcQarZIQlOyGOQJrRPK = UnorderedSetOfInteger2AHOqbcQarZIQlOy | NullQu0Arl1F; +/** + * + * Datastore entry + * + */ +export interface DatastoreEntryOutput { + candidate_value: OneOfNullQu0Arl1FUnorderedSetOfInteger2AHOqbcQarZIQlOy81SHPJsX; + final_value: OneOfNullQu0Arl1FUnorderedSetOfInteger2AHOqbcQarZIQlOyGOQJrRPK; +} +/** + * + * Address of the sender + * + */ +export type StringYVTrFSaQ = string; +/** + * + * Address of the receiver + * + */ +export type StringZyWeUFZ8 = string; +/** + * + * Amount transferred + * + */ +export type IntegerCOVAu0Eq = number; +/** + * + * Amount received by the receiver + * + */ +export type IntegerVC2Agt39 = number; +/** + * + * Context of the transfer : operation or asyncronous execution + * + */ +export interface Object0XCk2T5H { [key: string]: any; } +/** + * + * True if the operation succeed otherwise false + * + */ +export type BooleanYDqyb5Vp = boolean; +/** + * + * Fees passed to the operation + * + */ +export type NumberV8R93Gu7 = number; +/** + * + * ID of the block in which the operation is included + * + */ +export type StringUyVBK2CK = string; +/** + * + * Describe a transfer of MAS + * + */ +export interface Transfer { + from: StringYVTrFSaQ; + to: StringZyWeUFZ8; + amount: IntegerCOVAu0Eq; + effective_amount_received: IntegerVC2Agt39; + context: Object0XCk2T5H; + succeed: BooleanYDqyb5Vp; + fee: NumberV8R93Gu7; + block_id: StringUyVBK2CK; +} +export type UnorderedSetOfTransferQEyQHpyL = Transfer[]; +/** + * + * Block Id + * + */ +export type UnorderedSetOfBlockId7G1Sy5Qv = BlockId[]; +/** + * + * Endorsement + * + */ +export interface Endorsement { + content: EndorsementContent; + content_creator_pub_key: PublicKey; + content_creator_address?: Address; + id?: EndorsementId; + signature: StringDoaGddGA; +} +/** + * + * Endorsement info + * + */ +export interface EndorsementInfo { + id: EndorsementId; + in_pool: BooleanVyG3AETh; + in_blocks: UnorderedSetOfBlockId7G1Sy5Qv; + is_final: BooleanVyG3AETh; + endorsement: Endorsement; +} +/** + * + * Public key + * + */ +export type StringVuVvWRdT = string; +/** + * + * Block Id + * + */ +export type StringU8LlHDu1 = string; +/** + * + * As many block Ids as there are threads + * + */ +export type UnorderedSetOfStringDoaGddGAMZnHm9WS = StringDoaGddGA[]; +export interface GraphInterval { + creator: StringVuVvWRdT; + id: StringU8LlHDu1; + is_final: BooleanVyG3AETh; + is_in_blockclique: BooleanVyG3AETh; + is_stale: BooleanVyG3AETh; + parents: UnorderedSetOfStringDoaGddGAMZnHm9WS; + slot: Slot; +} +/** + * + * Operation id + * + */ +export type StringYTemzr68 = string; +/** + * + * Block ids +The operation appears in `in_blocks` +If it appears in multiple blocks, these blocks are in different cliques + * + */ +export type UnorderedSetOfBlockIdyEy9Dvpn = BlockId[]; +/** + * + * True if operation is still in pool + * + */ +export type BooleanSJ3TNusg = boolean; +/** + * + * True if the operation is final (for example in a final block) + * + */ +export type OneOfBooleanVyG3AEThNullQu0Arl1FCuqCzoUJ = NullQu0Arl1F | BooleanVyG3AETh; +/** + * + * Thread in which the operation can be included + * + */ +export type NumberZoWtBk8U = number; +/** + * + * the fee they have decided for this operation + * + */ +export type StringV3754ZDT = string; +/** + * + * after `expire_period` slot the operation won't be included in a block + * + */ +export type NumberSbfeGjn7 = number; +/** + * + * Represent an Amount in coins + * + */ +export type StringNIrlyE1J = string; +/** + * + * transfer coins from sender to recipient + * + */ +export interface Transaction { + amount: StringNIrlyE1J; + recipient_address: StringDoaGddGA; +} +/** + * + * Vec of bytes to execute + * + */ +export type UnorderedSetOfNumberHo1ClIqDd5W02PgX = NumberHo1ClIqD[]; +/** + * + * Maximum amount of gas that the execution of the contract is allowed to cost. + * + */ +export type NumberQUXtpAPK = number; +export interface ObjectOfUnorderedSetOfInteger2AHOqbcQarZIQlOyUnorderedSetOfInteger2AHOqbcQarZIQlOyDbxIogvI { + entry?: UnorderedSetOfInteger2AHOqbcQarZIQlOy; + bytes?: UnorderedSetOfInteger2AHOqbcQarZIQlOy; + [k: string]: any; +} +/** + * + * A tuple which contains (key, value) + * + */ +export interface Datastore { [key: string]: any; } +/** + * + * Execute a smart contract. + * + */ +export interface ExecuteSC { + data: UnorderedSetOfNumberHo1ClIqDd5W02PgX; + max_gas: NumberQUXtpAPK; + datastore: Datastore; +} +/** + * + * Function name + * + */ +export type String7HCIMJir = string; +/** + * + * Parameter to pass to the function + * + */ +export type StringSjIor0MV = string; +/** + * + * Amount + * + */ +export type Number5Mo1HId6 = number; +/** + * + * Calls an exported function from a stored smart contract + * + */ +export interface CallSC { + target_addr: Address; + target_func: String7HCIMJir; + param: StringSjIor0MV; + max_gas: NumberHo1ClIqD; + coins: Number5Mo1HId6; +} +/** + * + * roll count + * + */ +export type NumberJdJmnq9D = number; +/** + * + * the sender buys `roll_count` rolls. Roll price is defined in configuration + * + */ +export interface RollBuy { + roll_count: NumberJdJmnq9D; +} +/** + * + * the sender sells `roll_count` rolls. Roll price is defined in configuration + * + */ +export interface RollSell { + roll_count: NumberJdJmnq9D; +} +/** + * + * the type specific operation part + * + */ +export interface OperationType { + Transaction?: Transaction; + ExecutSC?: ExecuteSC; + CallSC?: CallSC; + RollBuy?: RollBuy; + RollSell?: RollSell; +} +/** + * + * Operation + * + */ +export interface Operation { + fee: StringV3754ZDT; + expire_period: NumberSbfeGjn7; + op: OperationType; +} +/** + * + * The operation itself + * + */ +export interface WrappedOperation { + content: Operation; + signature: Signature; + content_creator_pub_key?: PublicKey; + content_creator_address?: Address; + id?: OperationId; +} +/** + * + * true if the operation execution succeeded, false if failed, None means unknown + * + */ +export type OneOfBooleanVyG3AEThNullQu0Arl1FE3Qax0Os = NullQu0Arl1F | BooleanVyG3AETh; +/** + * + * Operation info + * + */ +export interface OperationInfo { + id: StringYTemzr68; + in_blocks: UnorderedSetOfBlockIdyEy9Dvpn; + in_pool: BooleanSJ3TNusg; + is_operation_final: OneOfBooleanVyG3AEThNullQu0Arl1FCuqCzoUJ; + thread: NumberZoWtBk8U; + operation: WrappedOperation; + op_exec_status?: OneOfBooleanVyG3AEThNullQu0Arl1FE3Qax0Os; +} +export interface ObjectOfAddressNumberHo1ClIqDFbgdJFtJ { + address?: Address; + active_rolls?: NumberHo1ClIqD; + [k: string]: any; +} +/** + * + * A tuple which contains (address, active_rolls) + * + */ +export interface Staker { [key: string]: any; } +/** + * + * Used to compute finality threshold + * + */ +export type Number2A9FvvYh = number; +/** + * + * (Only in tesnets) +Time in milliseconds when the blockclique started. + * + */ +export type OneOfNullQu0Arl1FNumberHo1ClIqDXysINzQy = NullQu0Arl1F | NumberHo1ClIqD; +/** + * + * Time in milliseconds when the blockclique started. + * + */ +export type NumberSgfzurLm = number; +/** + * + * Maximum size (in bytes) of a block + * + */ +export type NumberUwkWWxaa = number; +/** + * + * Maximum operation validity period count + * + */ +export type NumberTs6Cn6JQ = number; +/** + * + * cycle duration in periods + * + */ +export type NumberGrsxxfaH = number; +/** + * + * Time between the periods in the same thread. + * + */ +export type Number8ImKBhpQ = number; +/** + * + * Number of threads + * + */ +export type NumberAxwlzLso = number; +/** + * + * Compact configuration + * + */ +export interface Config { + block_reward: StringNIrlyE1J; + delta_f0: Number2A9FvvYh; + end_timestamp?: OneOfNullQu0Arl1FNumberHo1ClIqDXysINzQy; + genesis_timestamp: NumberSgfzurLm; + max_block_size?: NumberUwkWWxaa; + operation_validity_periods: NumberTs6Cn6JQ; + periods_per_cycle: NumberGrsxxfaH; + roll_price: StringNIrlyE1J; + t0: Number8ImKBhpQ; + thread_count: NumberAxwlzLso; +} +export interface ObjectOfStringDoaGddGAStringDoaGddGAXJdFCZe6 { + node_id?: StringDoaGddGA; + ip_address?: StringDoaGddGA; + [k: string]: any; +} +/** + * + * Connected nodes (node id, ip address, true if the connection is outgoing, false if incoming) + * + */ +export interface ConnectedNodes { [key: string]: any; } +/** + * + * Stats time interval, millis since 1970-01-01 + * + */ +export type NumberLpoULYcx = number; +/** + * + * Consensus stats + * + */ +export interface ConsensusStats { + clique_count: NumberHo1ClIqD; + end_timespan: NumberLpoULYcx; + final_block_count: NumberHo1ClIqD; + stale_block_count: NumberHo1ClIqD; + start_timespan: NumberLpoULYcx; +} +/** + * + * Current cycle + * + */ +export type NumberSWFW9I8Z = number; +/** + * + * Time in milliseconds since 1970-01-01 + * + */ +export type NumberYQZ1VVuw = number; +/** + * + * current cycle starting time in milliseconds since 1970-01-01 + * + */ +export type NumberQuWRP8Oa = number; +/** + * + * next cycle starting time in milliseconds since 1970-01-01 + * + */ +export type NumberSDEXjSo6 = number; +/** + * + * Active node count + * + */ +export type NumberWc2YJi2H = number; +/** + * + * Banned node count + * + */ +export type NumberZdt4Udf4 = number; +/** + * + * In connections count + * + */ +export type NumberLgEVA2Rp = number; +/** + * + * Total known peers count + * + */ +export type NumberNw53IytE = number; +/** + * + * Out connections count + * + */ +export type NumberXuleKeT9 = number; +/** + * + * Network stats + * + */ +export interface NetworkStats { + active_node_count: NumberWc2YJi2H; + banned_peer_count: NumberZdt4Udf4; + in_connection_count: NumberLgEVA2Rp; + known_peer_count: NumberNw53IytE; + out_connection_count: NumberXuleKeT9; +} +/** + * + * Our node id + * + */ +export type StringOFgZzVe7 = string; +/** + * + * Optional node ip if provided + * + */ +export type OneOfNullQu0Arl1FStringDoaGddGANsst9HIR = NullQu0Arl1F | StringDoaGddGA; +/** + * + * Pool stats + * + */ +export type PoolStats = NumberHo1ClIqD[]; +/** + * + * Application version, checked during handshakes + * + */ +export type Version = string; +/** + * + * Time window start + * + */ +export type NumberDk8ZmyGi = number; +/** + * + * Time window end + * + */ +export type NumberWbCeho3I = number; +/** + * + * number of final blocks in the time window + * + */ +export type NumberGCfSuERd = number; +/** + * + * number of final executed operations in the time window + * + */ +export type NumberJ4Dz6P30 = number; +/** + * + * Execution stats + * + */ +export interface ExecutionStats { + time_window_start: NumberDk8ZmyGi; + time_window_end: NumberWbCeho3I; + final_block_count: NumberGCfSuERd; + final_executed_operations_count: NumberJ4Dz6P30; + active_cursor: Slot; + final_cursor: Slot; +} +/** + * + * Chain id + * + */ +export type NumberBte4OVdF = number; +/** + * + * Minimal fee + * + */ +export type StringTXHumHoA = string; +type AlwaysFalse = any; +/** + * + * Ip address + * + */ +export type IpAddress = string; +/** + * + * public key + * + */ +export type StringTPMT1Yxd = string; +/** + * + * signature + * + */ +export type StringXHbmHEWh = string; +export type UnorderedSetOfStakerX7P278VS = Staker[]; +export interface ObjectOfNumberHo1ClIqDBlockIdHCnqqlza { + BlockId?: BlockId; + period?: NumberHo1ClIqD; + [k: string]: any; +} +/** + * + * A tuple which contains (BlockId, period) + * + */ +export interface BlockParent { [key: string]: any; } +/** + * + * true if incompatible with a final block + * + */ +export type Boolean4XbLtRCK = boolean; +/** + * + * Operations + * + */ +export type UnorderedSetOfOperationInfowrpyYBUS = OperationInfo[]; +/** + * + * filled block + * + */ +export interface FilledBlock { + header: WrappedHeader; + operations: UnorderedSetOfOperationInfowrpyYBUS; +} +export interface FilledBlockInfoContent { + is_final: BooleanZxUVUy6M; + is_stale: Boolean4XbLtRCK; + is_in_blockclique: BooleanHjqkwJfo; + block: FilledBlock; +} +export type UnorderedSetOfReadOnlyBytecodeExecutionK4Ht8Zdn = ReadOnlyBytecodeExecution[]; +export type UnorderedSetOfReadOnlyCallm6DMxyzd = ReadOnlyCall[]; +export type UnorderedSetOfAddressjJsnATCO = Address[]; +export type UnorderedSetOfAddressFilteraFrapw7X = AddressFilter[]; +export type UnorderedSetOfBlockIdZXK9XY8A = BlockId[]; +export type UnorderedSetOfDatastoreEntryInputBdlngHsZ = DatastoreEntryInput[]; +export type UnorderedSetOfSlotn0BdrHhh = Slot[]; +/** + * + * Event filter + * + */ +export interface EventFilter { + start?: Slot; + end?: Slot; + emitter_address?: String5J7NQ8B1; + original_caller_address?: StringCc6XlKeq; + original_operation_id?: StringUcQL9QGN; + is_final?: BooleanObf9WMA0; + is_error?: BooleanAXlyTrPe; +} +export interface ObjectOfNumberHo1ClIqDNumberHo1ClIqDTmeT75Fq { + start?: NumberHo1ClIqD; + end?: NumberHo1ClIqD; +} +export type UnorderedSetOfPrivateKeyG69QLiLP = PrivateKey[]; +export type UnorderedSetOfStringBBdNk2Kup3WUWKiM = StringBBdNk2Ku[]; +export type UnorderedSetOfStringOGpKXaCP4RgV7KAw = StringOGpKXaCP[]; +export type UnorderedSetOfOperationInput9XcIbRG1 = OperationInput[]; +/** + * + * ApiRequest for apiV2 + * + */ +export interface ApiRequest { + page_request?: Pagination; +} +export type UnorderedSetOfExecuteReadOnlyResponsewrpyYBUS = ExecuteReadOnlyResponse[]; +export type UnorderedSetOfAddressInfoCm3Tm6FQ = AddressInfo[]; +export type UnorderedSetOfStringUJarsTOsGY6FcFnU = StringUJarsTOs[]; +export type UnorderedSetOfBlockInfowrpyYBUS = BlockInfo[]; +export type UnorderedSetOfCliqueeS9LyMHx = Clique[]; +export type UnorderedSetOfDatastoreEntryOutputhcgFMMvn = DatastoreEntryOutput[]; +export type UnorderedSetOfUnorderedSetOfTransferQEyQHpyLoFgVJgXU = UnorderedSetOfTransferQEyQHpyL[]; +export type UnorderedSetOfEndorsementInfowrpyYBUS = EndorsementInfo[]; +export type UnorderedSetOfGraphIntervalwrpyYBUS = GraphInterval[]; +export type UnorderedSetOfOperationInfoMdPofISE = OperationInfo[]; +/** + * + * Node status + * + */ +export interface NodeStatus { + config: Config; + connected_nodes: ConnectedNodes; + consensus_stats: ConsensusStats; + current_cycle: NumberSWFW9I8Z; + current_time: NumberYQZ1VVuw; + current_cycle_time: NumberQuWRP8Oa; + next_cycle_time: NumberSDEXjSo6; + last_slot: Slot; + network_stats: NetworkStats; + next_slot: Slot; + node_id: StringOFgZzVe7; + node_ip?: OneOfNullQu0Arl1FStringDoaGddGANsst9HIR; + pool_stats: PoolStats; + version: Version; + execution_stats: ExecutionStats; + chain_id: NumberBte4OVdF; + minimal_fees?: StringTXHumHoA; +} +export type UnorderedSetOfIpAddressWpGgzO6M = IpAddress[]; +/** + * + * Public key and a signature it has produced used for serialization/deserialization purpose + * + */ +export interface PubkeySig { + public_key: StringTPMT1Yxd; + signature: StringXHbmHEWh; +} +export type UnorderedSetOfOperationId5TxbV4NZ = OperationId[]; +/** + * + * PagedVec of stakers for apiV2 + * + */ +export interface PagedVecStaker { + content?: UnorderedSetOfStakerX7P278VS; + total_count?: NumberHo1ClIqD; +} +export type UnorderedSetOfBlockParentxrssVm84 = BlockParent[]; +export interface FilledBlockInfo { + id: StringDoaGddGA; + content?: FilledBlockInfoContent; +} +/** + * + * Generated! Represents an alias to any of the provided schemas + * + */ +export type AnyOfUnorderedSetOfReadOnlyBytecodeExecutionK4Ht8ZdnUnorderedSetOfReadOnlyCallm6DMxyzdUnorderedSetOfAddressjJsnATCOUnorderedSetOfAddressFilteraFrapw7XUnorderedSetOfBlockIdZXK9XY8ASlotUnorderedSetOfDatastoreEntryInputBdlngHsZUnorderedSetOfSlotn0BdrHhhUnorderedSetOfStringDoaGddGADvj0XlFaEventFilterObjectOfNumberHo1ClIqDNumberHo1ClIqDTmeT75FqUnorderedSetOfStringDoaGddGADvj0XlFaPaginationUnorderedSetOfPrivateKeyG69QLiLPUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringDoaGddGADvj0XlFaUnorderedSetOfStringDoaGddGADvj0XlFaUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfAddressjJsnATCOStringUJarsTOsUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringOGpKXaCP4RgV7KAwUnorderedSetOfOperationInput9XcIbRG1ApiRequestInteger2AHOqbcQInteger2AHOqbcQInteger2AHOqbcQInteger2AHOqbcQUnorderedSetOfExecuteReadOnlyResponsewrpyYBUSUnorderedSetOfExecuteReadOnlyResponsewrpyYBUSUnorderedSetOfAddressInfoCm3Tm6FQUnorderedSetOfStringUJarsTOsGY6FcFnUUnorderedSetOfBlockInfowrpyYBUSBlockUnorderedSetOfCliqueeS9LyMHxUnorderedSetOfDatastoreEntryOutputhcgFMMvnUnorderedSetOfUnorderedSetOfTransferQEyQHpyLoFgVJgXUUnorderedSetOfEndorsementInfowrpyYBUSUnorderedSetOfSCOutputEventHwhiOmzEUnorderedSetOfGraphIntervalwrpyYBUSUnorderedSetOfOperationInfoMdPofISEUnorderedSetOfStakerX7P278VSNodeStatusAlwaysFalseUnorderedSetOfAddressjJsnATCOAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseUnorderedSetOfIpAddressWpGgzO6MUnorderedSetOfIpAddressWpGgzO6MAlwaysFalseUnorderedSetOfIpAddressWpGgzO6MAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalsePubkeySigAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseUnorderedSetOfOperationId5TxbV4NZPagedVecStakerUnorderedSetOfBlockParentxrssVm84VersionBlockInfoWrappedHeaderFilledBlockInfoOperationBooleanVyG3AEThBooleanVyG3AEThBooleanVyG3AEThBooleanVyG3AETh = UnorderedSetOfReadOnlyBytecodeExecutionK4Ht8Zdn | UnorderedSetOfReadOnlyCallm6DMxyzd | UnorderedSetOfAddressjJsnATCO | UnorderedSetOfAddressFilteraFrapw7X | UnorderedSetOfBlockIdZXK9XY8A | Slot | UnorderedSetOfDatastoreEntryInputBdlngHsZ | UnorderedSetOfSlotn0BdrHhh | UnorderedSetOfStringDoaGddGADvj0XlFa | EventFilter | ObjectOfNumberHo1ClIqDNumberHo1ClIqDTmeT75Fq | Pagination | UnorderedSetOfPrivateKeyG69QLiLP | UnorderedSetOfStringBBdNk2Kup3WUWKiM | StringUJarsTOs | UnorderedSetOfStringOGpKXaCP4RgV7KAw | UnorderedSetOfOperationInput9XcIbRG1 | ApiRequest | Integer2AHOqbcQ | UnorderedSetOfExecuteReadOnlyResponsewrpyYBUS | UnorderedSetOfAddressInfoCm3Tm6FQ | UnorderedSetOfStringUJarsTOsGY6FcFnU | UnorderedSetOfBlockInfowrpyYBUS | Block | UnorderedSetOfCliqueeS9LyMHx | UnorderedSetOfDatastoreEntryOutputhcgFMMvn | UnorderedSetOfUnorderedSetOfTransferQEyQHpyLoFgVJgXU | UnorderedSetOfEndorsementInfowrpyYBUS | UnorderedSetOfSCOutputEventHwhiOmzE | UnorderedSetOfGraphIntervalwrpyYBUS | UnorderedSetOfOperationInfoMdPofISE | UnorderedSetOfStakerX7P278VS | NodeStatus | AlwaysFalse | UnorderedSetOfIpAddressWpGgzO6M | PubkeySig | UnorderedSetOfOperationId5TxbV4NZ | PagedVecStaker | UnorderedSetOfBlockParentxrssVm84 | Version | BlockInfo | WrappedHeader | FilledBlockInfo | Operation | BooleanVyG3AETh; +export type ExecuteReadOnlyBytecode = (ReadOnlyBytecodeExecution: UnorderedSetOfReadOnlyBytecodeExecutionK4Ht8Zdn) => Promise; +export type ExecuteReadOnlyCall = (ReadOnlyCall: UnorderedSetOfReadOnlyCallm6DMxyzd) => Promise; +export type GetAddresses = (address: UnorderedSetOfAddressjJsnATCO) => Promise; +export type GetAddressesBytecode = (addressFilter: UnorderedSetOfAddressFilteraFrapw7X) => Promise; +export type GetBlocks = (blockId: UnorderedSetOfBlockIdZXK9XY8A) => Promise; +export type GetBlockcliqueBlockBySlot = (slot: Slot) => Promise; +export type GetCliques = () => Promise; +export type GetDatastoreEntries = (DatastoreEntryInputs: UnorderedSetOfDatastoreEntryInputBdlngHsZ) => Promise; +export type GetSlotsTransfers = (slots: UnorderedSetOfSlotn0BdrHhh) => Promise; +export type GetEndorsements = (endorsementId: UnorderedSetOfStringDoaGddGADvj0XlFa) => Promise; +export type GetFilteredScOutputEvent = (EventFilter: EventFilter) => Promise; +export type GetGraphInterval = (TimeInterval: ObjectOfNumberHo1ClIqDNumberHo1ClIqDTmeT75Fq) => Promise; +export type GetOperations = (operationId: UnorderedSetOfStringDoaGddGADvj0XlFa) => Promise; +export type GetStakers = (PageRequest: Pagination) => Promise; +export type GetStatus = () => Promise; +export type AddStakingSecretKeys = (SecretKeys: UnorderedSetOfPrivateKeyG69QLiLP) => Promise; +export type GetStakingAddresses = () => Promise; +export type NodeAddToBootstrapBlacklist = (ip: UnorderedSetOfStringBBdNk2Kup3WUWKiM) => Promise; +export type NodeAddToBootstrapWhitelist = (ip: UnorderedSetOfStringBBdNk2Kup3WUWKiM) => Promise; +export type NodeAddToPeersWhitelist = (ip: UnorderedSetOfStringBBdNk2Kup3WUWKiM) => Promise; +export type NodeBanById = (id: UnorderedSetOfStringDoaGddGADvj0XlFa) => Promise; +export type NodeBanByIp = (ip: UnorderedSetOfStringDoaGddGADvj0XlFa) => Promise; +export type NodeBootstrapBlacklist = () => Promise; +export type NodeBootstrapWhitelist = () => Promise; +export type NodeBootstrapWhitelistAllowAll = () => Promise; +export type NodePeersWhitelist = () => Promise; +export type NodeRemoveFromBootstrapBlacklist = (ip: UnorderedSetOfStringBBdNk2Kup3WUWKiM) => Promise; +export type NodeRemoveFromBootstrapWhitelist = (ip: UnorderedSetOfStringBBdNk2Kup3WUWKiM) => Promise; +export type NodeRemoveFromPeersWhitelist = (ip: UnorderedSetOfStringBBdNk2Kup3WUWKiM) => Promise; +export type NodeRemoveFromWhitelist = (ip: UnorderedSetOfStringBBdNk2Kup3WUWKiM) => Promise; +export type RemoveStakingAddresses = (addresses: UnorderedSetOfAddressjJsnATCO) => Promise; +export type NodeSignMessage = (message: StringUJarsTOs) => Promise; +export type StopNode = () => Promise; +export type NodeUnbanById = (id: UnorderedSetOfStringBBdNk2Kup3WUWKiM) => Promise; +export type NodeUnbanByIp = (ip: UnorderedSetOfStringBBdNk2Kup3WUWKiM) => Promise; +export type NodeWhitelist = (ip: UnorderedSetOfStringOGpKXaCP4RgV7KAw) => Promise; +export type SendOperations = (OperationInput: UnorderedSetOfOperationInput9XcIbRG1) => Promise; +export type GetLargestStakers = (ApiRequest: ApiRequest) => Promise; +export type GetNextBlockBestParents = () => Promise; +export type GetVersion = () => Promise; +export type SubscribeNewBlocks = () => Promise; +export type SubscribeNewBlocksHeaders = () => Promise; +export type SubscribeNewFilledBlocks = () => Promise; +export type SubscribeNewOperations = () => Promise; +export type UnsubscribeNewBlocks = (subscriptionId: Integer2AHOqbcQ) => Promise; +export type UnsubscribeNewBlocksHeaders = (subscriptionId: Integer2AHOqbcQ) => Promise; +export type UnsubscribeNewFilledBlocks = (subscriptionId: Integer2AHOqbcQ) => Promise; +export type UnsubscribeNewOperations = (subscriptionId: Integer2AHOqbcQ) => Promise; \ No newline at end of file diff --git a/src/generated/deployer-bytecode.ts b/src/generated/deployer-bytecode.ts new file mode 100644 index 00000000..04811058 --- /dev/null +++ b/src/generated/deployer-bytecode.ts @@ -0,0 +1 @@ +export const DEPLOYER_BYTECODE: Uint8Array = new Uint8Array([0,97,115,109,1,0,0,0,1,74,13,96,1,127,1,127,96,2,127,127,1,127,96,1,127,0,96,0,0,96,3,127,127,127,0,96,2,127,127,0,96,0,1,127,96,1,126,1,127,96,4,127,127,127,127,0,96,4,127,127,127,126,1,127,96,2,126,127,1,127,96,2,127,126,1,127,96,4,127,127,127,127,1,127,2,226,1,7,3,101,110,118,5,97,98,111,114,116,0,8,5,109,97,115,115,97,26,97,115,115,101,109,98,108,121,95,115,99,114,105,112,116,95,104,97,115,95,111,112,95,107,101,121,0,0,5,109,97,115,115,97,27,97,115,115,101,109,98,108,121,95,115,99,114,105,112,116,95,103,101,116,95,111,112,95,100,97,116,97,0,0,5,109,97,115,115,97,25,97,115,115,101,109,98,108,121,95,115,99,114,105,112,116,95,99,114,101,97,116,101,95,115,99,0,0,5,109,97,115,115,97,31,97,115,115,101,109,98,108,121,95,115,99,114,105,112,116,95,102,117,110,99,116,105,111,110,95,101,120,105,115,116,115,0,1,5,109,97,115,115,97,20,97,115,115,101,109,98,108,121,95,115,99,114,105,112,116,95,99,97,108,108,0,9,5,109,97,115,115,97,30,97,115,115,101,109,98,108,121,95,115,99,114,105,112,116,95,103,101,110,101,114,97,116,101,95,101,118,101,110,116,0,2,3,49,48,2,2,3,5,5,4,3,6,1,1,4,4,7,0,2,3,2,3,0,6,0,0,10,0,0,1,0,1,11,0,1,0,5,1,7,2,0,0,0,1,1,0,3,0,12,2,4,2,5,3,1,0,1,6,69,13,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,1,65,0,11,127,0,65,160,42,11,127,1,65,224,170,2,11,7,69,7,5,95,95,110,101,119,0,16,5,95,95,112,105,110,0,20,7,95,95,117,110,112,105,110,0,21,9,95,95,99,111,108,108,101,99,116,0,22,11,95,95,114,116,116,105,95,98,97,115,101,3,11,6,109,101,109,111,114,121,2,0,4,109,97,105,110,0,52,8,1,24,12,1,91,10,155,95,48,97,1,1,127,32,0,40,2,4,65,124,113,34,1,69,4,64,32,0,40,2,8,69,32,0,65,224,170,2,73,113,69,4,64,65,0,65,160,8,65,128,1,65,18,16,0,0,11,15,11,32,0,40,2,8,34,0,69,4,64,65,0,65,160,8,65,132,1,65,16,16,0,0,11,32,1,32,0,54,2,8,32,0,32,1,32,0,40,2,4,65,3,113,114,54,2,4,11,159,1,1,3,127,32,0,35,1,70,4,64,32,0,40,2,8,34,1,69,4,64,65,0,65,160,8,65,148,1,65,30,16,0,0,11,32,1,36,1,11,32,0,16,7,35,2,33,1,32,0,40,2,12,34,2,65,2,77,4,127,65,1,5,32,2,65,160,42,40,2,0,75,4,64,65,128,9,65,192,9,65,21,65,28,16,0,0,11,32,2,65,2,116,65,164,42,106,40,2,0,65,32,113,11,33,3,32,1,40,2,8,33,2,32,0,35,0,69,65,2,32,3,27,32,1,114,54,2,4,32,0,32,2,54,2,8,32,2,32,0,32,2,40,2,4,65,3,113,114,54,2,4,32,1,32,0,54,2,8,11,149,1,1,2,127,65,224,12,16,54,65,128,9,16,54,65,176,11,16,54,65,224,36,16,54,65,240,9,16,54,65,176,41,16,54,65,240,41,16,54,65,128,38,16,54,65,144,25,16,54,65,176,33,16,54,35,10,34,0,4,64,32,0,16,54,11,65,192,12,16,54,65,144,41,16,54,65,240,39,16,54,35,7,34,1,40,2,4,65,124,113,33,0,3,64,32,0,32,1,71,4,64,32,0,40,2,4,65,3,113,65,3,71,4,64,65,0,65,160,8,65,160,1,65,16,16,0,0,11,32,0,65,20,106,16,23,32,0,40,2,4,65,124,113,33,0,12,1,11,11,11,148,2,1,4,127,32,1,40,2,0,34,2,65,1,113,69,4,64,65,0,65,240,10,65,140,2,65,14,16,0,0,11,32,2,65,124,113,34,2,65,12,73,4,64,65,0,65,240,10,65,142,2,65,14,16,0,0,11,32,2,65,128,2,73,4,127,32,2,65,4,118,5,65,31,65,252,255,255,255,3,32,2,32,2,65,252,255,255,255,3,79,27,34,2,103,107,34,4,65,7,107,33,3,32,2,32,4,65,4,107,118,65,16,115,11,34,2,65,16,73,32,3,65,23,73,113,69,4,64,65,0,65,240,10,65,156,2,65,14,16,0,0,11,32,1,40,2,8,33,5,32,1,40,2,4,34,4,4,64,32,4,32,5,54,2,8,11,32,5,4,64,32,5,32,4,54,2,4,11,32,1,32,0,32,3,65,4,116,32,2,106,65,2,116,106,40,2,96,70,4,64,32,0,32,3,65,4,116,32,2,106,65,2,116,106,32,5,54,2,96,32,5,69,4,64,32,0,32,3,65,2,116,106,34,1,40,2,4,65,126,32,2,119,113,33,2,32,1,32,2,54,2,4,32,2,69,4,64,32,0,32,0,40,2,0,65,126,32,3,119,113,54,2,0,11,11,11,11,195,3,1,5,127,32,1,69,4,64,65,0,65,240,10,65,201,1,65,14,16,0,0,11,32,1,40,2,0,34,3,65,1,113,69,4,64,65,0,65,240,10,65,203,1,65,14,16,0,0,11,32,1,65,4,106,32,1,40,2,0,65,124,113,106,34,4,40,2,0,34,2,65,1,113,4,64,32,0,32,4,16,10,32,1,32,3,65,4,106,32,2,65,124,113,106,34,3,54,2,0,32,1,65,4,106,32,1,40,2,0,65,124,113,106,34,4,40,2,0,33,2,11,32,3,65,2,113,4,64,32,1,65,4,107,40,2,0,34,1,40,2,0,34,6,65,1,113,69,4,64,65,0,65,240,10,65,221,1,65,16,16,0,0,11,32,0,32,1,16,10,32,1,32,6,65,4,106,32,3,65,124,113,106,34,3,54,2,0,11,32,4,32,2,65,2,114,54,2,0,32,3,65,124,113,34,2,65,12,73,4,64,65,0,65,240,10,65,233,1,65,14,16,0,0,11,32,4,32,1,65,4,106,32,2,106,71,4,64,65,0,65,240,10,65,234,1,65,14,16,0,0,11,32,4,65,4,107,32,1,54,2,0,32,2,65,128,2,73,4,127,32,2,65,4,118,5,65,31,65,252,255,255,255,3,32,2,32,2,65,252,255,255,255,3,79,27,34,2,103,107,34,3,65,7,107,33,5,32,2,32,3,65,4,107,118,65,16,115,11,34,2,65,16,73,32,5,65,23,73,113,69,4,64,65,0,65,240,10,65,251,1,65,14,16,0,0,11,32,0,32,5,65,4,116,32,2,106,65,2,116,106,40,2,96,33,3,32,1,65,0,54,2,4,32,1,32,3,54,2,8,32,3,4,64,32,3,32,1,54,2,4,11,32,0,32,5,65,4,116,32,2,106,65,2,116,106,32,1,54,2,96,32,0,32,0,40,2,0,65,1,32,5,116,114,54,2,0,32,0,32,5,65,2,116,106,34,0,32,0,40,2,4,65,1,32,2,116,114,54,2,4,11,205,1,1,2,127,32,1,32,2,75,4,64,65,0,65,240,10,65,249,2,65,14,16,0,0,11,32,1,65,19,106,65,112,113,65,4,107,33,1,32,0,40,2,160,12,34,4,4,64,32,4,65,4,106,32,1,75,4,64,65,0,65,240,10,65,128,3,65,16,16,0,0,11,32,1,65,16,107,32,4,70,4,64,32,4,40,2,0,33,3,32,1,65,16,107,33,1,11,5,32,0,65,164,12,106,32,1,75,4,64,65,0,65,240,10,65,141,3,65,5,16,0,0,11,11,32,2,65,112,113,32,1,107,34,2,65,20,73,4,64,15,11,32,1,32,3,65,2,113,32,2,65,8,107,34,2,65,1,114,114,54,2,0,32,1,65,0,54,2,4,32,1,65,0,54,2,8,32,1,65,4,106,32,2,106,34,2,65,2,54,2,0,32,0,32,2,54,2,160,12,32,0,32,1,16,11,11,150,1,1,2,127,63,0,34,1,65,0,76,4,127,65,1,32,1,107,64,0,65,0,72,5,65,0,11,4,64,0,11,65,224,170,2,65,0,54,2,0,65,128,183,2,65,0,54,2,0,3,64,32,0,65,23,73,4,64,32,0,65,2,116,65,224,170,2,106,65,0,54,2,4,65,0,33,1,3,64,32,1,65,16,73,4,64,32,0,65,4,116,32,1,106,65,2,116,65,224,170,2,106,65,0,54,2,96,32,1,65,1,106,33,1,12,1,11,11,32,0,65,1,106,33,0,12,1,11,11,65,224,170,2,65,132,183,2,63,0,65,16,116,16,12,65,224,170,2,36,9,11,240,3,1,3,127,2,64,2,64,2,64,2,64,35,3,14,3,0,1,2,3,11,65,1,36,3,65,0,36,6,16,9,35,2,36,1,35,6,15,11,35,0,69,33,1,35,1,40,2,4,65,124,113,33,0,3,64,32,0,35,2,71,4,64,32,0,36,1,32,1,32,0,40,2,4,65,3,113,71,4,64,32,0,32,0,40,2,4,65,124,113,32,1,114,54,2,4,65,0,36,6,32,0,65,20,106,16,23,35,6,15,11,32,0,40,2,4,65,124,113,33,0,12,1,11,11,65,0,36,6,16,9,35,2,35,1,40,2,4,65,124,113,70,4,64,35,12,33,0,3,64,32,0,65,224,170,2,73,4,64,32,0,40,2,0,34,2,4,64,32,2,16,54,11,32,0,65,4,106,33,0,12,1,11,11,35,1,40,2,4,65,124,113,33,0,3,64,32,0,35,2,71,4,64,32,1,32,0,40,2,4,65,3,113,71,4,64,32,0,32,0,40,2,4,65,124,113,32,1,114,54,2,4,32,0,65,20,106,16,23,11,32,0,40,2,4,65,124,113,33,0,12,1,11,11,35,8,33,0,35,2,36,8,32,0,36,2,32,1,36,0,32,0,40,2,4,65,124,113,36,1,65,2,36,3,11,35,6,15,11,35,1,34,0,35,2,71,4,64,32,0,40,2,4,34,1,65,124,113,36,1,35,0,69,32,1,65,3,113,71,4,64,65,0,65,160,8,65,229,1,65,20,16,0,0,11,32,0,65,224,170,2,73,4,64,32,0,65,0,54,2,4,32,0,65,0,54,2,8,5,35,4,32,0,40,2,0,65,124,113,65,4,106,107,36,4,32,0,65,4,106,34,0,65,224,170,2,79,4,64,35,9,69,4,64,16,13,11,35,9,33,1,32,0,65,4,107,33,2,32,0,65,15,113,65,1,32,0,27,4,127,65,1,5,32,2,40,2,0,65,1,113,11,4,64,65,0,65,240,10,65,175,4,65,3,16,0,0,11,32,2,32,2,40,2,0,65,1,114,54,2,0,32,1,32,2,16,11,11,11,65,10,15,11,35,2,34,0,32,0,54,2,4,32,0,32,0,54,2,8,65,0,36,3,11,65,0,11,212,1,1,2,127,32,1,65,128,2,73,4,127,32,1,65,4,118,5,65,31,32,1,65,1,65,27,32,1,103,107,116,106,65,1,107,32,1,32,1,65,254,255,255,255,1,73,27,34,1,103,107,34,3,65,7,107,33,2,32,1,32,3,65,4,107,118,65,16,115,11,34,1,65,16,73,32,2,65,23,73,113,69,4,64,65,0,65,240,10,65,202,2,65,14,16,0,0,11,32,0,32,2,65,2,116,106,40,2,4,65,127,32,1,116,113,34,1,4,127,32,0,32,1,104,32,2,65,4,116,106,65,2,116,106,40,2,96,5,32,0,40,2,0,65,127,32,2,65,1,106,116,113,34,1,4,127,32,0,32,1,104,34,1,65,2,116,106,40,2,4,34,2,69,4,64,65,0,65,240,10,65,215,2,65,18,16,0,0,11,32,0,32,2,104,32,1,65,4,116,106,65,2,116,106,40,2,96,5,65,0,11,11,11,180,4,1,5,127,32,0,65,236,255,255,255,3,79,4,64,65,240,9,65,160,8,65,133,2,65,31,16,0,0,11,35,4,35,5,79,4,64,2,64,65,128,16,33,2,3,64,32,2,16,14,107,33,2,35,3,69,4,64,35,4,173,66,200,1,126,66,228,0,128,167,65,128,8,106,36,5,12,2,11,32,2,65,0,74,13,0,11,35,4,34,2,32,2,35,5,107,65,128,8,73,65,10,116,106,36,5,11,11,35,9,69,4,64,16,13,11,35,9,33,4,32,0,65,16,106,34,2,65,252,255,255,255,3,75,4,64,65,240,9,65,240,10,65,202,3,65,29,16,0,0,11,32,4,65,12,32,2,65,19,106,65,112,113,65,4,107,32,2,65,12,77,27,34,5,16,15,34,2,69,4,64,63,0,34,2,65,4,32,4,40,2,160,12,32,2,65,16,116,65,4,107,71,116,32,5,65,1,65,27,32,5,103,107,116,65,1,107,106,32,5,32,5,65,254,255,255,255,1,73,27,106,65,255,255,3,106,65,128,128,124,113,65,16,118,34,3,32,2,32,3,74,27,64,0,65,0,72,4,64,32,3,64,0,65,0,72,4,64,0,11,11,32,4,32,2,65,16,116,63,0,65,16,116,16,12,32,4,32,5,16,15,34,2,69,4,64,65,0,65,240,10,65,240,3,65,16,16,0,0,11,11,32,5,32,2,40,2,0,65,124,113,75,4,64,65,0,65,240,10,65,242,3,65,14,16,0,0,11,32,4,32,2,16,10,32,2,40,2,0,33,3,32,5,65,4,106,65,15,113,4,64,65,0,65,240,10,65,229,2,65,14,16,0,0,11,32,3,65,124,113,32,5,107,34,6,65,16,79,4,64,32,2,32,5,32,3,65,2,113,114,54,2,0,32,2,65,4,106,32,5,106,34,3,32,6,65,4,107,65,1,114,54,2,0,32,4,32,3,16,11,5,32,2,32,3,65,126,113,54,2,0,32,2,65,4,106,32,2,40,2,0,65,124,113,106,34,3,32,3,40,2,0,65,125,113,54,2,0,11,32,2,32,1,54,2,12,32,2,32,0,54,2,16,35,8,34,1,40,2,8,33,3,32,2,32,1,35,0,114,54,2,4,32,2,32,3,54,2,8,32,3,32,2,32,3,40,2,4,65,3,113,114,54,2,4,32,1,32,2,54,2,8,35,4,32,2,40,2,0,65,124,113,65,4,106,106,36,4,32,2,65,20,106,34,1,65,0,32,0,252,11,0,32,1,11,28,0,32,0,32,1,65,2,116,106,32,2,54,2,0,32,2,4,64,32,0,32,2,65,1,16,53,11,11,192,1,1,1,127,3,64,32,1,65,144,206,0,79,4,64,32,1,65,144,206,0,112,33,3,32,1,65,144,206,0,110,33,1,32,0,32,2,65,4,107,34,2,65,1,116,106,32,3,65,228,0,110,65,2,116,65,236,21,106,53,2,0,32,3,65,228,0,112,65,2,116,65,236,21,106,53,2,0,66,32,134,132,55,3,0,12,1,11,11,32,1,65,228,0,79,4,64,32,0,32,2,65,2,107,34,2,65,1,116,106,32,1,65,228,0,112,65,2,116,65,236,21,106,40,2,0,54,2,0,32,1,65,228,0,110,33,1,11,32,1,65,10,79,4,64,32,0,32,2,65,2,107,65,1,116,106,32,1,65,2,116,65,236,21,106,40,2,0,54,2,0,5,32,0,32,2,65,1,107,65,1,116,106,32,1,65,48,106,59,1,0,11,11,140,4,1,4,127,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,65,0,54,2,0,2,64,32,0,80,4,64,35,12,65,4,106,36,12,65,224,21,33,2,12,1,11,32,0,66,255,255,255,255,15,88,4,64,35,12,32,0,167,34,1,65,160,141,6,73,4,127,32,1,65,228,0,73,4,127,32,1,65,10,79,65,1,106,5,32,1,65,144,206,0,79,65,3,106,32,1,65,232,7,79,106,11,5,32,1,65,128,173,226,4,73,4,127,32,1,65,192,132,61,79,65,6,106,5,32,1,65,128,148,235,220,3,79,65,8,106,32,1,65,128,194,215,47,79,106,11,11,34,3,65,1,116,65,2,16,16,34,2,54,2,0,32,2,32,1,32,3,16,18,5,35,12,32,0,66,128,128,154,166,234,175,227,1,84,4,127,32,0,66,128,160,148,165,141,29,84,4,127,32,0,66,128,208,219,195,244,2,90,65,10,106,32,0,66,128,200,175,160,37,90,106,5,32,0,66,128,128,233,131,177,222,22,90,65,13,106,32,0,66,128,192,202,243,132,163,2,90,106,11,5,32,0,66,128,128,168,236,133,175,209,177,1,84,4,127,32,0,66,128,128,132,254,166,222,225,17,90,65,16,106,5,32,0,66,128,128,160,207,200,224,200,227,138,127,90,65,18,106,32,0,66,128,128,144,187,186,214,173,240,13,90,106,11,11,34,1,65,1,116,65,2,16,16,34,2,54,2,0,3,64,32,0,66,128,194,215,47,90,4,64,32,2,32,1,65,4,107,34,1,65,1,116,106,32,0,32,0,66,128,194,215,47,128,34,0,66,128,194,215,47,126,125,167,34,3,65,144,206,0,112,34,4,65,228,0,110,65,2,116,65,236,21,106,53,2,0,32,4,65,228,0,112,65,2,116,65,236,21,106,53,2,0,66,32,134,132,55,3,0,32,2,32,1,65,4,107,34,1,65,1,116,106,32,3,65,144,206,0,110,34,3,65,228,0,110,65,2,116,65,236,21,106,53,2,0,32,3,65,228,0,112,65,2,116,65,236,21,106,53,2,0,66,32,134,132,55,3,0,12,1,11,11,32,2,32,0,167,32,1,16,18,11,35,12,65,4,106,36,12,11,32,2,11,97,1,3,127,32,0,4,64,32,0,65,20,107,34,1,40,2,4,65,3,113,65,3,70,4,64,65,176,41,65,160,8,65,210,2,65,7,16,0,0,11,32,1,16,7,35,7,34,3,40,2,8,33,2,32,1,32,3,65,3,114,54,2,4,32,1,32,2,54,2,8,32,2,32,1,32,2,40,2,4,65,3,113,114,54,2,4,32,3,32,1,54,2,8,11,32,0,11,110,1,2,127,32,0,69,4,64,15,11,32,0,65,20,107,34,1,40,2,4,65,3,113,65,3,71,4,64,65,240,41,65,160,8,65,224,2,65,5,16,0,0,11,35,3,65,1,70,4,64,32,1,16,8,5,32,1,16,7,35,8,34,0,40,2,8,33,2,32,1,32,0,35,0,114,54,2,4,32,1,32,2,54,2,8,32,2,32,1,32,2,40,2,4,65,3,113,114,54,2,4,32,0,32,1,54,2,8,11,11,57,0,35,3,65,0,74,4,64,3,64,35,3,4,64,16,14,26,12,1,11,11,11,16,14,26,3,64,35,3,4,64,16,14,26,12,1,11,11,35,4,173,66,200,1,126,66,228,0,128,167,65,128,8,106,36,5,11,229,2,1,3,127,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,2,64,32,0,65,8,107,40,2,0,14,15,0,1,2,10,3,4,11,5,11,11,6,10,7,8,10,9,11,15,11,15,11,15,11,32,0,40,2,4,34,0,4,64,32,0,16,54,11,15,11,15,11,32,0,40,2,8,34,0,4,64,32,0,16,54,11,15,11,32,0,32,0,65,20,107,40,2,16,106,33,1,3,64,32,0,32,1,73,4,64,32,0,40,2,0,34,2,4,64,32,2,16,54,11,32,0,65,4,106,33,0,12,1,11,11,15,11,15,11,35,12,65,4,107,36,12,35,12,65,224,42,72,13,3,35,12,34,2,65,0,54,2,0,32,2,32,0,54,2,0,32,0,40,2,4,33,1,32,2,32,0,54,2,0,32,1,32,0,40,2,12,65,2,116,106,33,2,3,64,32,1,32,2,73,4,64,32,1,40,2,0,34,3,4,64,32,3,16,54,11,32,1,65,4,106,33,1,12,1,11,11,35,12,32,0,54,2,0,32,0,40,2,0,34,0,4,64,32,0,16,54,11,35,12,65,4,106,36,12,15,11,0,11,32,0,40,2,0,34,0,4,64,32,0,16,54,11,15,11,35,12,65,4,107,36,12,35,12,65,224,42,72,13,0,35,12,34,1,65,0,54,2,0,32,1,32,0,54,2,0,32,0,40,2,0,34,0,4,64,32,0,16,54,11,35,12,65,4,106,36,12,15,11,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,90,0,65,212,8,65,208,8,54,2,0,65,216,8,65,208,8,54,2,0,65,208,8,36,2,63,0,65,16,116,65,224,170,2,107,65,1,118,36,5,65,164,10,65,160,10,54,2,0,65,168,10,65,160,10,54,2,0,65,160,10,36,7,65,196,10,65,192,10,54,2,0,65,200,10,65,192,10,54,2,0,65,192,10,36,8,16,26,36,10,11,181,1,1,2,127,35,12,65,12,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,1,66,0,55,3,0,32,1,65,0,54,2,8,32,1,65,8,65,4,16,16,34,1,54,2,0,35,12,34,2,32,1,54,2,4,32,1,65,0,54,2,0,32,2,32,1,54,2,4,65,0,16,50,33,2,35,12,32,2,54,2,8,32,1,32,2,54,2,4,32,2,4,64,32,1,32,2,65,0,16,53,11,35,12,34,2,32,1,54,2,4,32,2,32,0,54,2,8,32,1,32,0,54,2,4,32,0,4,64,32,1,32,0,65,0,16,53,11,35,12,34,0,32,1,54,2,4,32,1,65,0,54,2,0,32,0,65,12,106,36,12,32,1,11,106,1,2,127,35,12,65,12,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,0,66,0,55,3,0,32,0,65,0,54,2,8,65,0,65,5,16,16,34,1,65,160,12,65,0,252,10,0,0,32,0,32,1,54,2,0,35,12,34,0,65,0,54,2,4,32,0,32,1,54,2,8,32,1,16,25,33,0,35,12,65,12,106,36,12,32,0,11,152,1,1,1,127,35,12,65,8,107,36,12,2,64,35,12,65,224,42,72,13,0,35,12,34,1,66,0,55,3,0,32,1,32,0,54,2,0,32,1,32,0,16,1,34,0,54,2,4,35,12,32,0,54,2,0,35,12,65,4,107,36,12,35,12,65,224,42,72,13,0,35,12,34,1,65,0,54,2,0,32,1,32,0,54,2,0,32,0,65,20,107,40,2,16,69,4,64,65,128,9,65,224,11,65,206,0,65,41,16,0,0,11,32,0,45,0,0,33,0,35,12,65,4,106,36,12,35,12,65,8,106,36,12,32,0,15,11,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,66,1,1,127,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,1,65,0,54,2,0,32,1,32,0,54,2,0,32,0,16,2,33,0,35,12,65,4,106,36,12,32,0,11,123,1,2,127,35,12,65,12,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,2,66,0,55,3,0,32,2,65,0,54,2,8,32,2,65,12,65,7,16,16,34,2,54,2,0,35,12,34,3,32,2,54,2,4,32,2,32,0,55,3,0,32,3,32,2,54,2,4,32,3,32,1,54,2,8,32,2,32,1,54,2,8,32,1,4,64,32,2,32,1,65,0,16,53,11,35,12,65,12,106,36,12,32,2,11,139,4,2,1,126,6,127,35,12,65,12,107,36,12,2,64,2,64,35,12,65,224,42,72,13,0,35,12,34,2,66,0,55,3,0,32,2,65,0,54,2,8,32,2,32,0,54,2,0,32,0,40,2,0,65,8,106,33,3,32,2,32,0,54,2,4,32,2,32,0,40,2,4,34,2,54,2,0,32,3,32,2,65,20,107,40,2,16,74,4,64,35,12,65,160,15,54,2,8,66,0,65,160,15,16,29,33,0,12,2,11,35,12,34,2,32,0,54,2,4,32,2,65,16,107,36,12,35,12,65,224,42,72,13,0,35,12,34,2,66,0,55,3,0,32,2,66,0,55,3,8,32,2,32,0,54,2,8,32,2,32,0,40,2,4,34,3,54,2,4,32,2,32,0,54,2,8,32,0,40,2,0,33,4,32,2,32,0,54,2,8,32,0,40,2,0,65,8,106,33,5,32,2,65,8,107,36,12,35,12,65,224,42,72,13,0,35,12,34,6,66,0,55,3,0,32,6,32,3,54,2,0,32,3,65,20,107,40,2,16,33,6,32,4,65,0,72,4,127,32,4,32,6,106,34,4,65,0,32,4,65,0,74,27,5,32,4,32,6,32,4,32,6,72,27,11,33,4,35,12,34,7,32,3,54,2,4,32,7,32,5,65,0,72,4,127,32,5,32,6,106,34,5,65,0,32,5,65,0,74,27,5,32,5,32,6,32,5,32,6,72,27,11,32,4,107,34,5,65,0,32,5,65,0,74,27,34,5,65,0,65,8,65,0,16,51,34,6,54,2,4,35,12,34,7,32,6,54,2,0,32,6,40,2,4,32,3,32,4,106,32,5,252,10,0,0,32,7,65,8,106,36,12,35,12,32,6,54,2,0,32,2,32,6,40,2,4,34,2,54,2,12,35,12,32,0,54,2,0,35,12,32,0,54,2,4,32,0,32,0,40,2,0,65,8,106,54,2,0,35,12,65,16,106,36,12,35,12,32,2,54,2,0,35,12,65,4,107,36,12,35,12,65,224,42,72,13,0,35,12,34,0,65,0,54,2,0,32,0,32,2,54,2,0,32,2,41,3,0,33,1,32,0,65,4,106,36,12,32,1,65,0,16,29,33,0,12,1,11,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,65,12,106,36,12,32,0,11,66,1,1,127,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,1,65,0,54,2,0,32,1,32,0,54,2,0,32,0,16,30,33,0,35,12,65,4,106,36,12,32,0,11,153,3,1,5,127,35,12,65,16,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,4,66,0,55,3,0,32,4,66,0,55,3,8,32,1,65,1,107,34,4,65,0,72,4,64,35,12,65,16,106,36,12,65,176,17,15,11,32,4,69,4,64,35,12,34,1,32,0,40,2,0,34,0,54,2,0,32,1,65,16,106,36,12,32,0,65,176,17,32,0,27,15,11,3,64,32,1,32,3,74,4,64,35,12,32,0,32,3,65,2,116,106,40,2,0,34,5,54,2,4,32,5,4,64,35,12,32,5,54,2,8,32,2,32,5,65,20,107,40,2,16,65,1,118,106,33,2,11,32,3,65,1,106,33,3,12,1,11,11,65,0,33,3,35,12,34,1,65,176,17,54,2,8,32,1,32,2,65,172,17,40,2,0,65,1,118,34,1,32,4,108,106,65,1,116,65,2,16,16,34,5,54,2,12,65,0,33,2,3,64,32,2,32,4,72,4,64,35,12,32,0,32,2,65,2,116,106,40,2,0,34,6,54,2,4,32,6,4,64,35,12,32,6,54,2,8,32,5,32,3,65,1,116,106,32,6,32,6,65,20,107,40,2,16,65,1,118,34,6,65,1,116,252,10,0,0,32,3,32,6,106,33,3,11,32,1,4,64,32,5,32,3,65,1,116,106,65,176,17,32,1,65,1,116,252,10,0,0,32,1,32,3,106,33,3,11,32,2,65,1,106,33,2,12,1,11,11,35,12,32,0,32,4,65,2,116,106,40,2,0,34,0,54,2,4,32,0,4,64,35,12,32,0,54,2,8,32,5,32,3,65,1,116,106,32,0,32,0,65,20,107,40,2,16,65,126,113,252,10,0,0,11,35,12,65,16,106,36,12,32,5,11,89,1,2,127,35,12,65,8,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,1,66,0,55,3,0,32,1,32,0,54,2,4,32,0,65,20,107,40,2,16,65,2,118,33,2,32,1,65,176,17,54,2,0,32,0,32,2,16,32,33,0,35,12,65,8,106,36,12,32,0,11,161,1,1,4,127,35,12,65,8,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,3,66,0,55,3,0,32,3,32,0,54,2,0,32,0,65,20,107,40,2,16,33,2,32,3,32,1,54,2,0,32,1,65,20,107,40,2,16,34,4,32,2,106,34,3,65,252,255,255,255,3,75,4,64,65,176,11,65,224,11,65,178,1,65,7,16,0,0,11,35,12,34,5,32,0,54,2,4,32,5,32,3,65,5,16,16,34,3,54,2,4,32,3,32,0,32,2,252,10,0,0,32,2,32,3,106,32,1,32,4,252,10,0,0,35,12,65,8,106,36,12,32,3,11,175,1,1,2,127,35,12,65,20,107,36,12,2,64,35,12,65,224,42,72,13,0,35,12,34,2,65,0,65,20,252,11,0,32,2,32,0,54,2,0,32,2,32,0,54,2,16,32,2,32,0,40,2,4,34,3,54,2,8,32,2,65,4,107,36,12,35,12,65,224,42,72,13,0,35,12,34,2,65,0,54,2,0,32,2,65,8,16,50,34,2,54,2,0,32,2,32,1,55,3,0,35,12,65,4,106,36,12,35,12,32,2,54,2,12,32,3,32,2,16,34,33,2,35,12,32,2,54,2,4,32,0,32,2,54,2,4,32,2,4,64,32,0,32,2,65,0,16,53,11,35,12,65,20,106,36,12,32,0,15,11,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,67,1,1,127,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,1,65,0,54,2,0,32,1,32,0,54,2,0,32,0,40,2,4,33,0,32,1,65,4,106,36,12,32,0,11,149,1,1,3,127,35,12,65,8,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,3,66,0,55,3,0,32,3,32,0,54,2,0,32,0,65,20,107,40,2,16,65,126,113,33,2,32,3,32,1,54,2,0,32,1,65,20,107,40,2,16,65,126,113,34,3,32,2,106,34,4,69,4,64,35,12,65,8,106,36,12,65,176,17,15,11,35,12,32,4,65,2,16,16,34,4,54,2,4,32,4,32,0,32,2,252,10,0,0,32,2,32,4,106,32,1,32,3,252,10,0,0,35,12,65,8,106,36,12,32,4,11,67,1,1,127,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,1,65,0,54,2,0,32,1,32,0,54,2,0,32,0,40,2,0,33,0,32,1,65,4,106,36,12,32,0,11,173,1,1,2,127,35,12,65,20,107,36,12,2,64,35,12,65,224,42,72,13,0,35,12,34,3,65,0,65,20,252,11,0,32,3,32,0,54,2,0,32,3,32,0,54,2,16,32,3,32,0,40,2,4,34,2,54,2,8,32,3,65,4,107,36,12,35,12,65,224,42,72,13,0,35,12,34,3,65,0,54,2,0,32,3,65,4,16,50,34,3,54,2,0,32,3,32,1,54,2,0,35,12,65,4,106,36,12,35,12,32,3,54,2,12,32,2,32,3,16,34,33,1,35,12,32,1,54,2,4,32,0,32,1,54,2,4,32,1,4,64,32,0,32,1,65,0,16,53,11,35,12,65,20,106,36,12,15,11,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,149,1,1,1,127,35,12,65,20,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,2,65,0,65,20,252,11,0,32,2,32,0,54,2,0,32,2,32,1,54,2,4,32,0,32,1,65,20,107,40,2,16,16,39,35,12,32,0,54,2,0,35,12,32,0,54,2,16,35,12,32,0,40,2,4,34,2,54,2,8,35,12,32,1,54,2,12,32,2,32,1,16,34,33,1,35,12,32,1,54,2,4,32,0,32,1,54,2,4,32,1,4,64,32,0,32,1,65,0,16,53,11,35,12,65,20,106,36,12,32,0,11,136,1,1,2,127,35,12,65,20,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,1,65,0,65,20,252,11,0,65,1,65,5,16,16,34,2,65,128,35,45,0,0,58,0,0,32,1,32,2,54,2,0,16,26,33,1,35,12,32,1,54,2,16,32,1,32,0,66,1,124,16,35,33,1,35,12,32,1,54,2,8,35,12,32,2,54,2,12,32,1,32,2,16,40,33,1,35,12,32,1,54,2,4,32,1,16,36,33,1,35,12,65,20,106,36,12,32,1,11,62,1,1,127,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,1,65,0,54,2,0,32,1,32,0,54,2,0,32,0,16,6,35,12,65,4,106,36,12,11,251,4,1,5,127,35,12,65,4,107,36,12,2,64,35,12,65,224,42,72,13,0,35,12,34,1,65,0,54,2,0,32,1,32,0,54,2,0,32,0,65,20,107,40,2,16,65,1,118,69,4,64,65,0,65,5,16,16,34,0,65,224,37,65,0,252,10,0,0,35,12,65,4,106,36,12,32,0,15,11,35,12,34,1,32,0,54,2,0,32,1,65,8,107,36,12,35,12,65,224,42,72,13,0,35,12,34,1,66,0,55,3,0,32,1,32,0,54,2,0,32,0,33,1,32,0,32,0,65,20,107,40,2,16,106,33,3,3,64,32,1,32,3,73,4,64,32,1,47,1,0,34,4,65,128,1,73,4,127,32,2,65,1,106,5,32,4,65,128,16,73,4,127,32,2,65,2,106,5,32,4,65,128,248,3,113,65,128,176,3,70,32,1,65,2,106,32,3,73,113,4,64,32,1,47,1,2,65,128,248,3,113,65,128,184,3,70,4,64,32,2,65,4,106,33,2,32,1,65,4,106,33,1,12,5,11,11,32,2,65,3,106,11,11,33,2,32,1,65,2,106,33,1,12,1,11,11,35,12,32,2,65,1,16,16,34,2,54,2,4,35,12,32,0,54,2,0,32,0,34,1,32,0,65,20,107,40,2,16,65,126,113,106,33,4,32,2,33,0,3,64,32,1,32,4,73,4,64,32,1,47,1,0,34,3,65,128,1,73,4,127,32,0,32,3,58,0,0,32,0,65,1,106,5,32,3,65,128,16,73,4,127,32,0,32,3,65,6,118,65,192,1,114,32,3,65,63,113,65,128,1,114,65,8,116,114,59,1,0,32,0,65,2,106,5,32,3,65,128,240,3,113,65,128,176,3,70,4,64,32,3,65,128,184,3,73,32,1,65,2,106,32,4,73,113,4,64,32,1,47,1,2,34,5,65,128,248,3,113,65,128,184,3,70,4,64,32,0,32,3,65,255,7,113,65,10,116,65,128,128,4,106,32,5,65,255,7,113,114,34,3,65,63,113,65,128,1,114,65,24,116,32,3,65,6,118,65,63,113,65,128,1,114,65,16,116,114,32,3,65,12,118,65,63,113,65,128,1,114,65,8,116,114,32,3,65,18,118,65,240,1,114,114,54,2,0,32,0,65,4,106,33,0,32,1,65,4,106,33,1,12,6,11,11,65,128,38,65,192,38,65,230,5,65,49,16,0,0,11,32,0,32,3,65,12,118,65,224,1,114,32,3,65,6,118,65,63,113,65,128,1,114,65,8,116,114,59,1,0,32,0,32,3,65,63,113,65,128,1,114,58,0,2,32,0,65,3,106,11,11,33,0,32,1,65,2,106,33,1,12,1,11,11,35,12,65,8,106,36,12,35,12,65,4,106,36,12,32,2,15,11,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,166,4,1,6,127,35,12,65,16,107,36,12,2,64,35,12,65,224,42,72,13,0,35,12,34,3,66,0,55,3,0,32,3,66,0,55,3,8,65,0,65,5,16,16,34,1,65,192,36,65,0,252,10,0,0,32,3,32,1,54,2,0,3,64,35,12,34,3,32,0,54,2,4,32,3,65,4,107,36,12,35,12,65,224,42,72,13,1,35,12,34,3,65,0,54,2,0,32,3,32,0,54,2,0,32,0,40,2,12,33,4,32,3,65,4,106,36,12,32,2,32,4,72,4,64,35,12,34,3,32,0,54,2,8,32,3,65,8,107,36,12,35,12,65,224,42,72,13,2,35,12,34,4,66,0,55,3,0,32,4,32,0,54,2,0,32,2,32,0,40,2,12,79,4,64,65,128,9,65,144,36,65,242,0,65,42,16,0,0,11,35,12,34,4,32,0,54,2,0,32,4,32,0,40,2,4,32,2,65,2,116,106,40,2,0,34,4,54,2,4,32,4,69,4,64,65,224,36,65,144,36,65,246,0,65,40,16,0,0,11,35,12,65,8,106,36,12,35,12,32,4,54,2,4,35,12,65,16,107,36,12,35,12,65,224,42,72,13,2,35,12,34,5,66,0,55,3,0,32,5,66,0,55,3,8,16,26,33,5,35,12,32,5,54,2,4,35,12,32,4,54,2,12,35,12,32,4,40,2,0,34,4,54,2,8,35,12,65,24,107,36,12,35,12,65,224,42,72,13,2,35,12,34,6,65,0,65,24,252,11,0,32,6,32,4,54,2,0,32,6,32,4,16,43,34,4,54,2,4,35,12,32,5,54,2,0,35,12,32,4,54,2,8,32,5,32,4,65,20,107,40,2,16,16,39,35,12,32,5,54,2,0,35,12,32,5,54,2,20,35,12,32,5,40,2,4,34,6,54,2,12,35,12,32,4,54,2,16,32,6,32,4,16,34,33,4,35,12,32,4,54,2,8,32,5,32,4,54,2,4,32,4,4,64,32,5,32,4,65,0,16,53,11,35,12,65,24,106,36,12,35,12,32,5,54,2,0,32,5,16,36,33,4,35,12,65,16,106,36,12,32,3,32,4,54,2,12,35,12,32,1,54,2,4,35,12,32,4,54,2,8,35,12,32,1,32,4,16,34,34,1,54,2,0,32,2,65,1,106,33,2,12,1,11,11,35,12,65,16,106,36,12,32,1,15,11,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,67,1,1,127,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,1,65,0,54,2,0,32,1,32,0,54,2,0,32,0,40,2,8,33,0,32,1,65,4,106,36,12,32,0,11,107,1,1,127,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,2,65,0,54,2,0,32,2,32,0,54,2,0,32,1,32,0,40,2,8,79,4,64,65,128,9,65,176,39,65,167,1,65,45,16,0,0,11,35,12,34,2,32,0,54,2,0,32,1,32,0,40,2,4,106,45,0,0,33,0,32,2,65,4,106,36,12,32,0,11,100,1,1,127,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,2,65,0,54,2,0,32,2,32,0,54,2,0,32,1,32,0,65,20,107,40,2,16,65,1,118,79,4,64,35,12,65,4,106,36,12,65,127,15,11,32,0,32,1,65,1,116,106,47,1,0,33,0,35,12,65,4,106,36,12,32,0,11,163,5,1,5,127,35,12,65,8,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,2,66,0,55,3,0,32,2,32,0,54,2,0,32,0,16,45,65,3,111,33,2,35,12,32,0,54,2,0,32,0,16,45,32,2,107,33,4,35,12,32,0,54,2,0,32,0,16,45,65,3,109,65,2,116,65,4,65,0,32,2,27,106,33,2,35,12,32,2,65,1,116,65,2,16,16,34,3,54,2,4,35,12,32,0,54,2,0,32,0,16,45,69,4,64,35,12,65,8,106,36,12,65,176,17,15,11,32,3,65,2,107,33,2,3,64,32,1,32,4,72,4,64,35,12,32,0,54,2,0,32,0,32,1,16,46,65,16,116,33,5,35,12,32,0,54,2,0,32,5,32,0,32,1,65,1,106,16,46,65,8,116,114,33,5,35,12,32,0,54,2,0,32,0,32,1,65,2,106,16,46,32,5,114,33,5,35,12,65,240,39,54,2,0,32,2,65,2,106,34,2,65,240,39,32,5,65,18,118,16,47,59,1,0,35,12,65,240,39,54,2,0,32,2,65,2,106,34,2,65,240,39,32,5,65,12,118,65,63,113,16,47,59,1,0,35,12,65,240,39,54,2,0,32,2,65,2,106,34,2,65,240,39,32,5,65,6,118,65,63,113,16,47,59,1,0,35,12,65,240,39,54,2,0,32,2,65,2,106,34,2,65,240,39,32,5,65,63,113,16,47,59,1,0,32,1,65,3,106,33,1,12,1,11,11,35,12,32,0,54,2,0,2,64,2,64,32,0,16,45,32,4,107,34,4,65,1,71,4,64,32,4,65,2,70,13,1,12,2,11,35,12,32,0,54,2,0,32,0,32,1,16,46,65,16,116,33,0,35,12,65,240,39,54,2,0,32,2,65,2,106,34,1,65,240,39,32,0,65,18,118,16,47,59,1,0,35,12,65,240,39,54,2,0,32,1,65,2,106,34,1,65,240,39,32,0,65,12,118,65,63,113,16,47,59,1,0,35,12,65,144,41,54,2,0,32,1,65,2,106,34,0,65,144,41,65,0,16,47,59,1,0,35,12,65,144,41,54,2,0,32,0,65,144,41,65,0,16,47,59,1,2,12,1,11,35,12,32,0,54,2,0,32,0,32,1,16,46,65,16,116,33,4,35,12,32,0,54,2,0,32,4,32,0,32,1,65,1,106,16,46,65,8,116,114,33,0,35,12,65,240,39,54,2,0,32,2,65,2,106,34,1,65,240,39,32,0,65,18,118,16,47,59,1,0,35,12,65,240,39,54,2,0,32,1,65,2,106,34,1,65,240,39,32,0,65,12,118,65,63,113,16,47,59,1,0,35,12,65,240,39,54,2,0,32,1,65,2,106,34,1,65,240,39,32,0,65,6,118,65,63,113,16,47,59,1,0,35,12,65,144,41,54,2,0,32,1,65,144,41,65,0,16,47,59,1,2,11,35,12,65,8,106,36,12,32,3,11,210,19,2,8,127,3,126,35,12,65,24,107,36,12,2,64,35,12,65,224,42,72,13,0,35,12,34,0,65,0,65,24,252,11,0,32,0,65,20,107,36,12,35,12,65,224,42,72,13,0,35,12,34,0,65,0,65,20,252,11,0,65,1,65,5,16,16,34,1,65,144,13,45,0,0,58,0,0,32,0,32,1,54,2,0,35,12,32,1,54,2,4,32,1,16,27,69,4,64,65,176,13,65,176,14,65,52,65,3,16,0,0,11,35,12,34,0,32,1,54,2,4,32,0,32,1,16,28,34,0,54,2,8,35,12,32,0,54,2,16,32,0,16,25,33,1,35,12,32,1,54,2,4,35,12,65,128,15,54,2,12,35,12,65,48,107,36,12,35,12,65,224,42,72,13,0,35,12,34,0,65,0,65,48,252,11,0,32,0,32,1,54,2,0,32,0,32,1,16,31,34,1,54,2,4,35,12,33,0,35,12,65,128,15,54,2,8,35,12,65,144,17,54,2,0,35,12,65,128,15,54,2,12,65,144,17,65,1,65,128,15,16,17,35,12,65,144,17,54,2,0,35,12,65,176,17,54,2,16,32,0,65,144,17,16,33,34,2,54,2,20,35,12,32,1,54,2,24,35,12,32,1,54,2,28,35,12,32,1,54,2,16,35,12,32,1,40,2,8,34,0,54,2,0,35,12,65,4,107,36,12,35,12,65,224,42,72,13,0,35,12,65,0,54,2,0,32,0,4,127,35,12,32,0,54,2,0,32,0,65,20,107,40,2,16,65,1,118,5,65,0,11,33,0,35,12,65,4,106,36,12,32,0,4,64,35,12,34,0,32,2,54,2,32,32,0,32,1,54,2,0,32,0,32,1,40,2,8,34,1,54,2,36,32,1,69,4,64,65,144,18,65,144,19,65,52,65,32,16,0,0,11,32,0,32,1,54,2,40,35,12,34,0,65,240,17,54,2,0,32,0,32,2,54,2,12,65,240,17,65,0,32,2,16,17,35,12,65,240,17,54,2,0,35,12,32,1,54,2,12,65,240,17,65,2,32,1,16,17,35,12,65,240,17,54,2,0,35,12,65,176,17,54,2,16,65,240,17,16,33,65,144,19,65,52,65,7,16,0,0,11,35,12,34,0,32,1,54,2,44,32,0,32,1,54,2,0,32,1,41,3,0,33,10,32,0,65,48,106,36,12,35,12,65,20,106,36,12,35,12,65,0,65,2,65,13,65,128,20,16,51,34,7,54,2,0,3,64,32,9,32,10,84,4,64,35,12,34,2,65,12,107,36,12,35,12,65,224,42,72,13,2,35,12,34,1,66,0,55,3,0,32,1,65,0,54,2,8,16,26,33,0,35,12,32,0,54,2,4,32,0,32,9,66,1,124,16,35,33,0,35,12,32,0,54,2,0,32,1,32,0,16,36,34,0,54,2,8,35,12,32,0,54,2,0,32,0,16,27,69,4,64,35,12,65,144,34,54,2,0,32,9,66,1,124,16,19,33,0,35,12,32,0,54,2,4,65,144,34,32,0,16,37,65,176,14,65,196,0,65,3,16,0,0,11,35,12,32,0,54,2,0,32,0,16,28,33,1,35,12,65,12,106,36,12,35,12,32,1,54,2,4,35,12,65,4,107,36,12,35,12,65,224,42,72,13,2,35,12,34,0,65,0,54,2,0,32,0,32,1,54,2,0,32,1,16,3,33,1,35,12,32,1,54,2,0,35,12,65,12,107,36,12,35,12,65,224,42,72,13,2,35,12,34,0,66,0,55,3,0,32,0,65,0,54,2,8,32,0,65,4,65,11,16,16,34,6,54,2,0,35,12,34,0,32,6,54,2,4,32,0,32,1,54,2,8,32,6,32,1,54,2,0,32,1,4,64,32,6,32,1,65,0,16,53,11,35,12,65,12,106,36,12,35,12,65,4,106,36,12,32,2,32,6,54,2,8,35,12,32,6,54,2,4,35,12,65,224,12,54,2,12,35,12,65,12,107,36,12,35,12,65,224,42,72,13,2,35,12,34,0,66,0,55,3,0,32,0,65,0,54,2,8,32,0,32,6,54,2,8,32,6,16,38,33,0,35,12,32,0,54,2,0,35,12,65,224,12,54,2,4,32,0,65,224,12,16,4,33,0,35,12,65,12,106,36,12,32,0,4,64,35,12,34,0,32,6,54,2,4,32,0,65,224,12,54,2,12,32,0,65,12,107,36,12,35,12,65,224,42,72,13,3,35,12,34,0,66,0,55,3,0,32,0,65,0,54,2,8,32,0,32,9,16,41,34,0,54,2,0,35,12,32,0,54,2,4,32,0,16,27,4,127,32,9,16,41,33,0,35,12,32,0,54,2,8,32,0,16,28,33,0,35,12,32,0,54,2,8,32,0,16,25,5,16,26,11,33,3,35,12,65,12,106,36,12,35,12,32,3,54,2,16,35,12,65,16,107,36,12,35,12,65,224,42,72,13,3,35,12,34,2,66,0,55,3,0,32,2,66,0,55,3,8,32,2,65,20,107,36,12,35,12,65,224,42,72,13,3,35,12,34,0,65,0,65,20,252,11,0,65,1,65,5,16,16,34,1,65,160,35,45,0,0,58,0,0,32,0,32,1,54,2,0,16,26,33,0,35,12,32,0,54,2,16,32,0,32,9,66,1,124,16,35,33,0,35,12,32,0,54,2,8,35,12,32,1,54,2,12,32,0,32,1,16,40,33,0,35,12,32,0,54,2,4,32,0,16,36,33,0,35,12,65,20,106,36,12,32,2,32,0,54,2,0,35,12,32,0,54,2,4,32,0,16,27,4,64,35,12,32,0,54,2,12,32,0,16,28,33,0,35,12,32,0,54,2,12,32,0,16,25,33,0,35,12,32,0,54,2,8,32,0,16,31,33,1,35,12,32,1,54,2,4,35,12,65,8,107,36,12,35,12,65,224,42,72,13,4,35,12,34,0,66,0,55,3,0,32,0,32,1,54,2,0,32,0,32,1,54,2,4,32,1,41,3,0,33,8,32,0,65,8,106,36,12,5,66,0,33,8,11,35,12,65,16,106,36,12,35,12,65,16,107,36,12,35,12,65,224,42,72,13,3,35,12,34,0,66,0,55,3,0,32,0,66,0,55,3,8,32,0,32,6,54,2,12,32,6,16,38,33,1,35,12,32,1,54,2,0,35,12,65,224,12,54,2,4,35,12,32,3,54,2,12,32,3,16,36,33,0,35,12,32,0,54,2,8,32,1,65,224,12,32,0,32,8,16,5,26,35,12,65,16,106,36,12,11,35,12,34,0,65,192,35,54,2,12,32,0,32,6,54,2,20,32,6,16,38,33,0,35,12,32,0,54,2,16,65,192,35,32,0,16,37,33,0,35,12,32,0,54,2,4,32,0,16,42,35,12,32,7,54,2,4,35,12,32,6,54,2,12,35,12,65,4,107,36,12,35,12,65,224,42,72,13,2,35,12,34,0,65,0,54,2,0,32,0,32,7,54,2,0,32,7,40,2,12,34,5,65,1,106,33,4,32,0,65,4,107,36,12,35,12,65,224,42,72,13,2,35,12,34,0,65,0,54,2,0,32,0,32,7,54,2,0,32,4,32,7,40,2,8,34,0,65,2,118,75,4,64,32,4,65,255,255,255,255,0,75,4,64,65,176,11,65,144,36,65,19,65,48,16,0,0,11,35,12,32,7,54,2,0,2,64,65,252,255,255,255,3,32,0,65,1,116,34,0,32,0,65,252,255,255,255,3,79,27,34,1,65,8,32,4,32,4,65,8,77,27,65,2,116,34,0,32,0,32,1,73,27,34,3,32,7,40,2,0,34,0,65,20,107,34,2,40,2,0,65,124,113,65,16,107,77,4,64,32,2,32,3,54,2,16,32,0,33,1,12,1,11,32,3,32,2,40,2,12,16,16,34,1,32,0,32,3,32,2,40,2,16,34,2,32,2,32,3,75,27,252,10,0,0,11,32,0,32,1,71,4,64,32,7,32,1,54,2,0,32,7,32,1,54,2,4,32,1,4,64,32,7,32,1,65,0,16,53,11,11,32,7,32,3,54,2,8,11,35,12,65,4,106,36,12,35,12,32,7,54,2,0,32,7,40,2,4,32,5,65,2,116,106,32,6,54,2,0,32,6,4,64,32,7,32,6,65,1,16,53,11,35,12,34,0,32,7,54,2,0,32,7,32,4,54,2,12,32,0,65,4,106,36,12,32,9,66,1,124,33,9,12,1,11,11,16,26,33,2,35,12,34,0,32,2,54,2,16,32,0,32,7,54,2,20,32,0,65,24,107,36,12,35,12,65,224,42,72,13,0,35,12,34,0,65,0,65,24,252,11,0,32,0,32,7,54,2,0,32,0,32,7,16,44,34,1,54,2,4,35,12,32,2,54,2,0,35,12,32,1,54,2,8,32,2,32,1,65,20,107,40,2,16,16,39,35,12,32,2,54,2,0,35,12,32,2,54,2,20,35,12,32,2,40,2,4,34,0,54,2,12,35,12,32,1,54,2,16,32,0,32,1,16,34,33,0,35,12,32,0,54,2,8,32,2,32,0,54,2,4,32,0,4,64,32,2,32,0,65,0,16,53,11,35,12,65,24,106,36,12,35,12,32,2,54,2,12,32,2,16,36,33,6,35,12,32,6,54,2,4,35,12,65,12,107,36,12,35,12,65,224,42,72,13,0,35,12,34,0,66,0,55,3,0,32,0,65,0,54,2,8,32,0,32,6,54,2,8,32,0,65,8,107,36,12,35,12,65,224,42,72,13,0,35,12,34,5,66,0,55,3,0,32,5,32,6,54,2,0,32,6,65,20,107,40,2,16,33,4,32,5,65,8,107,36,12,35,12,65,224,42,72,13,0,35,12,34,0,66,0,55,3,0,32,0,65,12,65,14,16,16,34,1,54,2,0,35,12,34,3,32,1,54,2,4,32,3,65,16,107,36,12,35,12,65,224,42,72,13,0,35,12,34,0,66,0,55,3,0,32,0,66,0,55,3,8,32,1,69,4,64,35,12,65,12,65,3,16,16,34,1,54,2,0,11,35,12,34,0,32,1,54,2,4,32,1,65,0,54,2,0,32,0,32,1,54,2,4,32,1,65,0,54,2,4,32,0,32,1,54,2,4,32,1,65,0,54,2,8,32,4,65,252,255,255,255,3,75,4,64,65,176,11,65,240,38,65,19,65,57,16,0,0,11,35,12,32,4,65,1,16,16,34,2,54,2,8,35,12,32,1,54,2,4,35,12,32,2,54,2,12,32,1,32,2,54,2,0,32,2,4,64,32,1,32,2,65,0,16,53,11,35,12,34,0,32,1,54,2,4,32,1,32,2,54,2,4,32,0,32,1,54,2,4,32,1,32,4,54,2,8,32,0,65,16,106,36,12,32,3,32,1,54,2,0,35,12,65,8,106,36,12,32,5,32,1,54,2,4,35,12,34,2,32,1,54,2,0,32,1,40,2,0,33,0,32,2,32,1,54,2,0,32,0,32,6,32,1,16,45,252,10,0,0,35,12,65,8,106,36,12,35,12,32,1,54,2,4,32,1,16,48,33,0,35,12,32,0,54,2,0,32,0,16,42,35,12,65,12,106,36,12,35,12,65,24,106,36,12,15,11,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,87,0,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,65,0,54,2,0,32,0,65,252,255,255,255,3,75,4,64,65,176,11,65,224,11,65,51,65,60,16,0,0,11,35,12,32,0,65,5,16,16,34,0,54,2,0,35,12,65,4,106,36,12,32,0,11,135,1,1,2,127,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,34,4,65,0,54,2,0,32,0,32,1,116,34,5,65,1,16,16,33,1,32,3,4,64,32,1,32,3,32,5,252,10,0,0,11,32,4,32,1,54,2,0,65,16,32,2,16,16,34,2,32,1,54,2,0,32,1,4,64,32,2,32,1,65,0,16,53,11,32,2,32,1,54,2,4,32,2,32,5,54,2,8,32,2,32,0,54,2,12,35,12,65,4,106,36,12,32,2,11,49,0,35,12,65,4,107,36,12,35,12,65,224,42,72,4,64,65,128,171,2,65,176,171,2,65,1,65,1,16,0,0,11,35,12,32,0,54,2,0,16,49,35,12,65,4,106,36,12,11,92,1,1,127,32,0,69,4,64,65,0,65,160,8,65,167,2,65,14,16,0,0,11,35,0,32,1,65,20,107,34,1,40,2,4,65,3,113,70,4,64,32,0,65,20,107,34,0,40,2,4,65,3,113,34,3,35,0,69,70,4,64,32,0,32,1,32,2,27,16,8,5,35,3,65,1,70,32,3,65,3,70,113,4,64,32,1,16,8,11,11,11,11,32,0,35,0,32,0,65,20,107,34,0,40,2,4,65,3,113,70,4,64,32,0,16,8,35,6,65,1,106,36,6,11,11,11,128,31,91,0,65,140,8,11,1,60,0,65,152,8,11,39,2,0,0,0,32,0,0,0,126,0,108,0,105,0,98,0,47,0,114,0,116,0,47,0,105,0,116,0,99,0,109,0,115,0,46,0,116,0,115,0,65,236,8,11,1,60,0,65,248,8,11,43,2,0,0,0,36,0,0,0,73,0,110,0,100,0,101,0,120,0,32,0,111,0,117,0,116,0,32,0,111,0,102,0,32,0,114,0,97,0,110,0,103,0,101,0,65,172,9,11,1,44,0,65,184,9,11,27,2,0,0,0,20,0,0,0,126,0,108,0,105,0,98,0,47,0,114,0,116,0,46,0,116,0,115,0,65,220,9,11,1,60,0,65,232,9,11,47,2,0,0,0,40,0,0,0,65,0,108,0,108,0,111,0,99,0,97,0,116,0,105,0,111,0,110,0,32,0,116,0,111,0,111,0,32,0,108,0,97,0,114,0,103,0,101,0,65,220,10,11,1,60,0,65,232,10,11,37,2,0,0,0,30,0,0,0,126,0,108,0,105,0,98,0,47,0,114,0,116,0,47,0,116,0,108,0,115,0,102,0,46,0,116,0,115,0,65,156,11,11,1,44,0,65,168,11,11,35,2,0,0,0,28,0,0,0,73,0,110,0,118,0,97,0,108,0,105,0,100,0,32,0,108,0,101,0,110,0,103,0,116,0,104,0,65,204,11,11,1,60,0,65,216,11,11,45,2,0,0,0,38,0,0,0,126,0,108,0,105,0,98,0,47,0,115,0,116,0,97,0,116,0,105,0,99,0,97,0,114,0,114,0,97,0,121,0,46,0,116,0,115,0,65,140,12,11,1,28,0,65,152,12,11,1,5,0,65,172,12,11,1,28,0,65,184,12,11,11,2,0,0,0,4,0,0,0,58,0,58,0,65,204,12,11,1,44,0,65,216,12,11,29,2,0,0,0,22,0,0,0,99,0,111,0,110,0,115,0,116,0,114,0,117,0,99,0,116,0,111,0,114,0,65,252,12,11,1,28,0,65,136,13,11,5,5,0,0,0,1,0,65,156,13,11,1,124,0,65,168,13,11,113,2,0,0,0,106,0,0,0,84,0,104,0,101,0,32,0,110,0,117,0,109,0,98,0,101,0,114,0,32,0,111,0,102,0,32,0,115,0,109,0,97,0,114,0,116,0,32,0,99,0,111,0,110,0,116,0,114,0,97,0,99,0,116,0,115,0,32,0,116,0,111,0,32,0,100,0,101,0,112,0,108,0,111,0,121,0,32,0,105,0,115,0,32,0,117,0,110,0,100,0,101,0,102,0,105,0,110,0,101,0,100,0,46,0,65,156,14,11,1,76,0,65,168,14,11,67,2,0,0,0,60,0,0,0,97,0,115,0,115,0,101,0,109,0,98,0,108,0,121,0,47,0,99,0,111,0,110,0,116,0,114,0,97,0,99,0,116,0,115,0,47,0,100,0,101,0,112,0,108,0,111,0,121,0,101,0,114,0,46,0,116,0,115,0,65,236,14,11,1,28,0,65,248,14,11,15,2,0,0,0,8,0,0,0,110,0,98,0,83,0,67,0,65,140,15,11,1,140,0,65,152,15,11,117,2,0,0,0,110,0,0,0,99,0,97,0,110,0,39,0,116,0,32,0,100,0,101,0,115,0,101,0,114,0,105,0,97,0,108,0,105,0,122,0,101,0,32,0,117,0,54,0,52,0,32,0,102,0,114,0,111,0,109,0,32,0,103,0,105,0,118,0,101,0,110,0,32,0,97,0,114,0,103,0,117,0,109,0,101,0,110,0,116,0,58,0,32,0,111,0,117,0,116,0,32,0,111,0,102,0,32,0,114,0,97,0,110,0,103,0,101,0,65,156,16,11,1,60,0,65,168,16,11,43,2,0,0,0,36,0,0,0,67,0,97,0,110,0,39,0,116,0,32,0,100,0,101,0,115,0,101,0,114,0,105,0,97,0,108,0,105,0,122,0,101,0,32,0,65,220,16,11,1,28,0,65,232,16,11,9,2,0,0,0,2,0,0,0,46,0,65,252,16,11,30,28,0,0,0,3,0,0,0,0,0,0,0,10,0,0,0,12,0,0,0,48,8,0,0,0,0,0,0,112,8,0,65,156,17,11,1,28,0,65,168,17,11,1,2,0,65,188,17,11,1,28,0,65,200,17,11,11,2,0,0,0,4,0,0,0,58,0,32,0,65,220,17,11,26,28,0,0,0,3,0,0,0,0,0,0,0,10,0,0,0,12,0,0,0,0,0,0,0,208,8,0,65,252,17,11,1,124,0,65,136,18,11,101,2,0,0,0,94,0,0,0,85,0,110,0,101,0,120,0,112,0,101,0,99,0,116,0,101,0,100,0,32,0,39,0,110,0,117,0,108,0,108,0,39,0,32,0,40,0,110,0,111,0,116,0,32,0,97,0,115,0,115,0,105,0,103,0,110,0,101,0,100,0,32,0,111,0,114,0,32,0,102,0,97,0,105,0,108,0,101,0,100,0,32,0,99,0,97,0,115,0,116,0,41,0,65,252,18,11,1,108,0,65,136,19,11,93,2,0,0,0,86,0,0,0,126,0,108,0,105,0,98,0,47,0,64,0,109,0,97,0,115,0,115,0,97,0,108,0,97,0,98,0,115,0,47,0,97,0,115,0,45,0,116,0,121,0,112,0,101,0,115,0,47,0,97,0,115,0,115,0,101,0,109,0,98,0,108,0,121,0,47,0,114,0,101,0,115,0,117,0,108,0,116,0,46,0,116,0,115,0,65,236,19,11,1,28,0,65,248,19,11,1,1,0,65,140,20,11,1,124,0,65,152,20,11,107,2,0,0,0,100,0,0,0,116,0,111,0,83,0,116,0,114,0,105,0,110,0,103,0,40,0,41,0,32,0,114,0,97,0,100,0,105,0,120,0,32,0,97,0,114,0,103,0,117,0,109,0,101,0,110,0,116,0,32,0,109,0,117,0,115,0,116,0,32,0,98,0,101,0,32,0,98,0,101,0,116,0,119,0,101,0,101,0,110,0,32,0,50,0,32,0,97,0,110,0,100,0,32,0,51,0,54,0,65,140,21,11,1,60,0,65,152,21,11,45,2,0,0,0,38,0,0,0,126,0,108,0,105,0,98,0,47,0,117,0,116,0,105,0,108,0,47,0,110,0,117,0,109,0,98,0,101,0,114,0,46,0,116,0,115,0,65,204,21,11,1,28,0,65,216,21,11,9,2,0,0,0,2,0,0,0,48,0,65,236,21,11,143,3,48,0,48,0,48,0,49,0,48,0,50,0,48,0,51,0,48,0,52,0,48,0,53,0,48,0,54,0,48,0,55,0,48,0,56,0,48,0,57,0,49,0,48,0,49,0,49,0,49,0,50,0,49,0,51,0,49,0,52,0,49,0,53,0,49,0,54,0,49,0,55,0,49,0,56,0,49,0,57,0,50,0,48,0,50,0,49,0,50,0,50,0,50,0,51,0,50,0,52,0,50,0,53,0,50,0,54,0,50,0,55,0,50,0,56,0,50,0,57,0,51,0,48,0,51,0,49,0,51,0,50,0,51,0,51,0,51,0,52,0,51,0,53,0,51,0,54,0,51,0,55,0,51,0,56,0,51,0,57,0,52,0,48,0,52,0,49,0,52,0,50,0,52,0,51,0,52,0,52,0,52,0,53,0,52,0,54,0,52,0,55,0,52,0,56,0,52,0,57,0,53,0,48,0,53,0,49,0,53,0,50,0,53,0,51,0,53,0,52,0,53,0,53,0,53,0,54,0,53,0,55,0,53,0,56,0,53,0,57,0,54,0,48,0,54,0,49,0,54,0,50,0,54,0,51,0,54,0,52,0,54,0,53,0,54,0,54,0,54,0,55,0,54,0,56,0,54,0,57,0,55,0,48,0,55,0,49,0,55,0,50,0,55,0,51,0,55,0,52,0,55,0,53,0,55,0,54,0,55,0,55,0,55,0,56,0,55,0,57,0,56,0,48,0,56,0,49,0,56,0,50,0,56,0,51,0,56,0,52,0,56,0,53,0,56,0,54,0,56,0,55,0,56,0,56,0,56,0,57,0,57,0,48,0,57,0,49,0,57,0,50,0,57,0,51,0,57,0,52,0,57,0,53,0,57,0,54,0,57,0,55,0,57,0,56,0,57,0,57,0,65,252,24,11,2,28,4,0,65,136,25,11,135,8,2,0,0,0,0,4,0,0,48,0,48,0,48,0,49,0,48,0,50,0,48,0,51,0,48,0,52,0,48,0,53,0,48,0,54,0,48,0,55,0,48,0,56,0,48,0,57,0,48,0,97,0,48,0,98,0,48,0,99,0,48,0,100,0,48,0,101,0,48,0,102,0,49,0,48,0,49,0,49,0,49,0,50,0,49,0,51,0,49,0,52,0,49,0,53,0,49,0,54,0,49,0,55,0,49,0,56,0,49,0,57,0,49,0,97,0,49,0,98,0,49,0,99,0,49,0,100,0,49,0,101,0,49,0,102,0,50,0,48,0,50,0,49,0,50,0,50,0,50,0,51,0,50,0,52,0,50,0,53,0,50,0,54,0,50,0,55,0,50,0,56,0,50,0,57,0,50,0,97,0,50,0,98,0,50,0,99,0,50,0,100,0,50,0,101,0,50,0,102,0,51,0,48,0,51,0,49,0,51,0,50,0,51,0,51,0,51,0,52,0,51,0,53,0,51,0,54,0,51,0,55,0,51,0,56,0,51,0,57,0,51,0,97,0,51,0,98,0,51,0,99,0,51,0,100,0,51,0,101,0,51,0,102,0,52,0,48,0,52,0,49,0,52,0,50,0,52,0,51,0,52,0,52,0,52,0,53,0,52,0,54,0,52,0,55,0,52,0,56,0,52,0,57,0,52,0,97,0,52,0,98,0,52,0,99,0,52,0,100,0,52,0,101,0,52,0,102,0,53,0,48,0,53,0,49,0,53,0,50,0,53,0,51,0,53,0,52,0,53,0,53,0,53,0,54,0,53,0,55,0,53,0,56,0,53,0,57,0,53,0,97,0,53,0,98,0,53,0,99,0,53,0,100,0,53,0,101,0,53,0,102,0,54,0,48,0,54,0,49,0,54,0,50,0,54,0,51,0,54,0,52,0,54,0,53,0,54,0,54,0,54,0,55,0,54,0,56,0,54,0,57,0,54,0,97,0,54,0,98,0,54,0,99,0,54,0,100,0,54,0,101,0,54,0,102,0,55,0,48,0,55,0,49,0,55,0,50,0,55,0,51,0,55,0,52,0,55,0,53,0,55,0,54,0,55,0,55,0,55,0,56,0,55,0,57,0,55,0,97,0,55,0,98,0,55,0,99,0,55,0,100,0,55,0,101,0,55,0,102,0,56,0,48,0,56,0,49,0,56,0,50,0,56,0,51,0,56,0,52,0,56,0,53,0,56,0,54,0,56,0,55,0,56,0,56,0,56,0,57,0,56,0,97,0,56,0,98,0,56,0,99,0,56,0,100,0,56,0,101,0,56,0,102,0,57,0,48,0,57,0,49,0,57,0,50,0,57,0,51,0,57,0,52,0,57,0,53,0,57,0,54,0,57,0,55,0,57,0,56,0,57,0,57,0,57,0,97,0,57,0,98,0,57,0,99,0,57,0,100,0,57,0,101,0,57,0,102,0,97,0,48,0,97,0,49,0,97,0,50,0,97,0,51,0,97,0,52,0,97,0,53,0,97,0,54,0,97,0,55,0,97,0,56,0,97,0,57,0,97,0,97,0,97,0,98,0,97,0,99,0,97,0,100,0,97,0,101,0,97,0,102,0,98,0,48,0,98,0,49,0,98,0,50,0,98,0,51,0,98,0,52,0,98,0,53,0,98,0,54,0,98,0,55,0,98,0,56,0,98,0,57,0,98,0,97,0,98,0,98,0,98,0,99,0,98,0,100,0,98,0,101,0,98,0,102,0,99,0,48,0,99,0,49,0,99,0,50,0,99,0,51,0,99,0,52,0,99,0,53,0,99,0,54,0,99,0,55,0,99,0,56,0,99,0,57,0,99,0,97,0,99,0,98,0,99,0,99,0,99,0,100,0,99,0,101,0,99,0,102,0,100,0,48,0,100,0,49,0,100,0,50,0,100,0,51,0,100,0,52,0,100,0,53,0,100,0,54,0,100,0,55,0,100,0,56,0,100,0,57,0,100,0,97,0,100,0,98,0,100,0,99,0,100,0,100,0,100,0,101,0,100,0,102,0,101,0,48,0,101,0,49,0,101,0,50,0,101,0,51,0,101,0,52,0,101,0,53,0,101,0,54,0,101,0,55,0,101,0,56,0,101,0,57,0,101,0,97,0,101,0,98,0,101,0,99,0,101,0,100,0,101,0,101,0,101,0,102,0,102,0,48,0,102,0,49,0,102,0,50,0,102,0,51,0,102,0,52,0,102,0,53,0,102,0,54,0,102,0,55,0,102,0,56,0,102,0,57,0,102,0,97,0,102,0,98,0,102,0,99,0,102,0,100,0,102,0,101,0,102,0,102,0,65,156,33,11,1,92,0,65,168,33,11,79,2,0,0,0,72,0,0,0,48,0,49,0,50,0,51,0,52,0,53,0,54,0,55,0,56,0,57,0,97,0,98,0,99,0,100,0,101,0,102,0,103,0,104,0,105,0,106,0,107,0,108,0,109,0,110,0,111,0,112,0,113,0,114,0,115,0,116,0,117,0,118,0,119,0,120,0,121,0,122,0,65,252,33,11,1,108,0,65,136,34,11,85,2,0,0,0,78,0,0,0,78,0,111,0,32,0,98,0,121,0,116,0,101,0,99,0,111,0,100,0,101,0,32,0,102,0,111,0,117,0,110,0,100,0,32,0,102,0,111,0,114,0,32,0,99,0,111,0,110,0,116,0,114,0,97,0,99,0,116,0,32,0,110,0,117,0,109,0,98,0,101,0,114,0,58,0,32,0,65,236,34,11,1,28,0,65,248,34,11,5,5,0,0,0,1,0,65,140,35,11,1,28,0,65,152,35,11,9,5,0,0,0,1,0,0,0,1,0,65,172,35,11,1,76,0,65,184,35,11,67,2,0,0,0,60,0,0,0,67,0,111,0,110,0,116,0,114,0,97,0,99,0,116,0,32,0,100,0,101,0,112,0,108,0,111,0,121,0,101,0,100,0,32,0,97,0,116,0,32,0,97,0,100,0,100,0,114,0,101,0,115,0,115,0,58,0,32,0,65,252,35,11,1,44,0,65,136,36,11,33,2,0,0,0,26,0,0,0,126,0,108,0,105,0,98,0,47,0,97,0,114,0,114,0,97,0,121,0,46,0,116,0,115,0,65,172,36,11,1,28,0,65,184,36,11,1,5,0,65,204,36,11,1,124,0,65,216,36,11,101,2,0,0,0,94,0,0,0,69,0,108,0,101,0,109,0,101,0,110,0,116,0,32,0,116,0,121,0,112,0,101,0,32,0,109,0,117,0,115,0,116,0,32,0,98,0,101,0,32,0,110,0,117,0,108,0,108,0,97,0,98,0,108,0,101,0,32,0,105,0,102,0,32,0,97,0,114,0,114,0,97,0,121,0,32,0,105,0,115,0,32,0,104,0,111,0,108,0,101,0,121,0,65,204,37,11,1,28,0,65,216,37,11,1,5,0,65,236,37,11,1,60,0,65,248,37,11,43,2,0,0,0,36,0,0,0,85,0,110,0,112,0,97,0,105,0,114,0,101,0,100,0,32,0,115,0,117,0,114,0,114,0,111,0,103,0,97,0,116,0,101,0,65,172,38,11,1,44,0,65,184,38,11,35,2,0,0,0,28,0,0,0,126,0,108,0,105,0,98,0,47,0,115,0,116,0,114,0,105,0,110,0,103,0,46,0,116,0,115,0,65,220,38,11,1,60,0,65,232,38,11,45,2,0,0,0,38,0,0,0,126,0,108,0,105,0,98,0,47,0,97,0,114,0,114,0,97,0,121,0,98,0,117,0,102,0,102,0,101,0,114,0,46,0,116,0,115,0,65,156,39,11,1,60,0,65,168,39,11,43,2,0,0,0,36,0,0,0,126,0,108,0,105,0,98,0,47,0,116,0,121,0,112,0,101,0,100,0,97,0,114,0,114,0,97,0,121,0,46,0,116,0,115,0,65,220,39,11,1,156,0,65,232,39,11,135,1,2,0,0,0,128,0,0,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72,0,73,0,74,0,75,0,76,0,77,0,78,0,79,0,80,0,81,0,82,0,83,0,84,0,85,0,86,0,87,0,88,0,89,0,90,0,97,0,98,0,99,0,100,0,101,0,102,0,103,0,104,0,105,0,106,0,107,0,108,0,109,0,110,0,111,0,112,0,113,0,114,0,115,0,116,0,117,0,118,0,119,0,120,0,121,0,122,0,48,0,49,0,50,0,51,0,52,0,53,0,54,0,55,0,56,0,57,0,43,0,47,0,65,252,40,11,1,28,0,65,136,41,11,9,2,0,0,0,2,0,0,0,61,0,65,156,41,11,1,60,0,65,168,41,11,49,2,0,0,0,42,0,0,0,79,0,98,0,106,0,101,0,99,0,116,0,32,0,97,0,108,0,114,0,101,0,97,0,100,0,121,0,32,0,112,0,105,0,110,0,110,0,101,0,100,0,65,220,41,11,1,60,0,65,232,41,11,47,2,0,0,0,40,0,0,0,79,0,98,0,106,0,101,0,99,0,116,0,32,0,105,0,115,0,32,0,110,0,111,0,116,0,32,0,112,0,105,0,110,0,110,0,101,0,100,0,65,160,42,11,13,15,0,0,0,32,0,0,0,32,0,0,0,32,0,65,184,42,11,37,100,0,0,0,2,1,0,0,0,0,0,0,66,0,0,0,2,9,0,0,4,65,0,0,0,0,0,0,32,0,0,0,2,65,0,0,65,0,37,16,115,111,117,114,99,101,77,97,112,112,105,110,103,85,82,76,19,46,47,100,101,112,108,111,121,101,114,46,119,97,115,109,46,109,97,112]); diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000..3d732c94 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,9 @@ +export * from './account' +export * from './smartContracts' +export * from './basicElements' +export * from './client' +export * from './utils' +export * from './operation' +export * from './provider' +export * from './contracts-wrappers' +export * from './events' diff --git a/src/operation/index.ts b/src/operation/index.ts new file mode 100644 index 00000000..2b82dd7a --- /dev/null +++ b/src/operation/index.ts @@ -0,0 +1,2 @@ +export * from './types' +export * from './operation' diff --git a/src/operation/operation.ts b/src/operation/operation.ts new file mode 100644 index 00000000..a06b33ee --- /dev/null +++ b/src/operation/operation.ts @@ -0,0 +1,136 @@ +import { Args, ArrayTypes } from '../basicElements' +import { SCEvent } from '../client' +import { Provider } from '../provider' +import { rawEventDecode } from '../utils' +import { OperationStatus } from './types' + +const DEFAULT_WAIT_TIMEOUT_MS = 60000 +const DEFAULT_WAIT_PERIOD_MS = 500 + +/** + * An operation object. + */ +export class Operation { + constructor( + public provider: Provider, + public id: string + ) {} + + /** + * Gets the status of the operation. + * + * @returns The status of the operation. + */ + async getStatus(): Promise { + return this.provider.getOperationStatus(this.id) + } + + /** + * Waits for the operation to reach a specific status. + * + * @param exitThreshold - The minimal status to wait for. + * @param timeout - The maximum time to wait. + * @param period - The time interval to check the status. + * + * @returns The status of the operation or NotFound if the timeout is reached. + */ + private wait( + exitThreshold: OperationStatus, + timeout = DEFAULT_WAIT_TIMEOUT_MS, + period = DEFAULT_WAIT_PERIOD_MS + ): Promise { + return new Promise((resolve) => { + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + let elapsedTime = 0 + const checkStatusInterval = setInterval(async () => { + const currentStatus = await this.getStatus() + if (currentStatus >= exitThreshold) { + clearInterval(checkStatusInterval) + resolve(currentStatus) + } else if (elapsedTime >= timeout) { + clearInterval(checkStatusInterval) + resolve(OperationStatus.NotFound) + } + elapsedTime += period + }, period) + }) + } + + /** + * Waits for the operation to be included in a block. + * + * @param timeout - The maximum time to wait. + * @param period - The time interval to check the status. + * + * @returns The status of the operation or NotFound if the timeout is reached. + */ + async waitSpeculativeExecution( + timeout?: number, + period?: number + ): Promise { + return this.wait(OperationStatus.SpeculativeSuccess, timeout, period) + } + + /** + * Waits for the block containing the operation to be final. + * + * @param timeout - The maximum time to wait. + * @param period - The time interval to check the status. + * + * @returns The status of the operation or NotFound if the timeout is reached. + */ + async waitFinalExecution( + timeout?: number, + period?: number + ): Promise { + return this.wait(OperationStatus.Success, timeout, period) + } + + /** + * Gets the events of the operation once the block reaches the final state. + * + * @returns The events of the operation. + */ + async getFinalEvents(): Promise { + if ((await this.waitFinalExecution()) === OperationStatus.NotFound) { + return Promise.reject(new Error('Operation not found')) + } + + return this.provider.getEvents({ operationId: this.id, isFinal: true }) + } + + /** + * Gets the events of the speculative execution of the operation. + * + * @returns The speculative events of the operation. + */ + async getSpeculativeEvents(): Promise { + if ((await this.waitSpeculativeExecution()) === OperationStatus.NotFound) { + return Promise.reject(new Error('Operation not found')) + } + + return this.provider.getEvents({ operationId: this.id, isFinal: false }) + } + + async getDeployedAddress(waitFinal = false): Promise { + const events = waitFinal + ? await this.getFinalEvents() + : await this.getSpeculativeEvents() + + const lastEvent = events.at(-1) + + if (!lastEvent) { + throw new Error('no event received.') + } + + if (lastEvent.context.is_error) { + const parsedData = JSON.parse(lastEvent.data) + throw new Error(parsedData.massa_execution_error) + } + + const contracts = new Args( + rawEventDecode(lastEvent.data) + ).nextArray(ArrayTypes.STRING) + return contracts[0] + } +} diff --git a/src/operation/operationManager.ts b/src/operation/operationManager.ts new file mode 100644 index 00000000..27194bde --- /dev/null +++ b/src/operation/operationManager.ts @@ -0,0 +1,245 @@ +import * as unsigned from '../utils/big-varint' +import { Address } from '../basicElements/address' +import { PrivateKey, PublicKey } from '../basicElements/keys' +import { PublicAPI } from '../client' +import { Signature } from '../basicElements/signature' +import varint from 'varint' +import { U64 } from '../basicElements/serializers' +import { + BaseOperation, + CallOperation, + ExecuteOperation, + OperationDetails, + OperationType, + RollOperation, + TransferOperation, +} from './types' + +export const PERIOD_TO_LIVE_DEFAULT = 9 +export const PERIOD_TO_LIVE_MAX = 9 +export const PERIOD_TO_LIVE_MIN = 1 + +/* + * A class regrouping operation functions. + */ +export class OperationManager { + constructor( + public privateKey: PrivateKey, + public blockchainClient?: PublicAPI + ) {} + + /** + * Serializes an operation according to the Massa protocol. + * + * @param operation - The operation to serialize. + * + * @returns A byte array representing the serialized operation. + */ + static serialize(operation: OperationDetails): Uint8Array { + const components = [ + unsigned.encode(operation.fee), + varint.encode(operation.expirePeriod), + varint.encode(operation.type), + ] + + switch (operation.type) { + case OperationType.Transaction: + operation = operation as TransferOperation + components.push(operation.recipientAddress.toBytes()) + components.push(unsigned.encode(operation.amount)) + break + case OperationType.RollBuy: + case OperationType.RollSell: + operation = operation as RollOperation + components.push(unsigned.encode(operation.amount)) + break + case OperationType.CallSmartContractFunction: + // @see https://docs.massa.net/docs/learn/operation-format-execution#callsc-operation-payload + operation = operation as CallOperation + components.push(unsigned.encode(operation.maxGas)) + components.push(unsigned.encode(operation.coins)) + components.push(Address.fromString(operation.address).toBytes()) + components.push(varint.encode(operation.func.length)) + components.push(Buffer.from(operation.func)) + components.push(varint.encode(operation.parameter.length)) + components.push(operation.parameter) + break + case OperationType.ExecuteSmartContractBytecode: + operation = operation as ExecuteOperation + components.push(unsigned.encode(operation.maxGas)) + components.push(unsigned.encode(operation.maxCoins)) + components.push( + unsigned.encode(U64.fromNumber(operation.contractDataBinary.length)) + ) + components.push(operation.contractDataBinary) + + operation.datastore = + operation.datastore || new Map() + components.push( + unsigned.encode(U64.fromNumber(operation.datastore.size)) + ) + + // length prefixed key-value pairs encoding + for (const [key, value] of operation.datastore) { + const keyBytes = Buffer.from(key) + const keyLen = unsigned.encode(U64.fromNumber(keyBytes.length)) + const valueBytes = Buffer.from(value) + const valueLen = unsigned.encode(U64.fromNumber(valueBytes.length)) + components.push(keyLen, keyBytes, valueLen, valueBytes) + } + break + default: + throw new Error('Operation type not supported') + } + + return Uint8Array.from( + components.flatMap((component) => Array.from(component)) + ) + } + + /** + * Deserializes an operation according to the Massa protocol. + * + * @param data - The byte array to deserialize. + * + * @returns An new instance of OperationDetails representing the deserialized operation. + */ + static deserialize(data: Uint8Array): OperationDetails { + let offset = 0 + + // eslint-disable-next-line func-style + const nextVarInt = (): bigint => { + const value = unsigned.decode(data, offset) + offset += unsigned.encodingLength(value) + return value + } + + const operationDetails: BaseOperation = { + fee: nextVarInt(), + expirePeriod: Number(nextVarInt()), + type: Number(nextVarInt()), + } + + switch (operationDetails.type) { + case OperationType.Transaction: { + const { data: addrBytes, length } = Address.extractFromBuffer( + data, + offset + ) + const recipientAddress = Address.fromBytes(addrBytes) + offset += length + return { + ...operationDetails, + recipientAddress, + amount: nextVarInt(), + } as TransferOperation + } + case OperationType.RollBuy: + case OperationType.RollSell: { + return { + ...operationDetails, + amount: nextVarInt(), + } as RollOperation + } + default: + throw new Error('Operation type not supported') + } + } + + /** + * Formats an operation for signing. + * + * @param chainId - The identifier of the blockchain network. + * @param operation - The operation to sign. + * @param key - The public key to sign the operation with. + * + * @returns The formatted operation ready for signing. + */ + static canonicalize( + chainId: bigint, + operation: OperationDetails, + key: PublicKey + ): Uint8Array { + // u64ToBytes is little endian + const networkId = new Uint8Array(U64.SIZE_BYTE) + const view = new DataView(networkId.buffer) + view.setBigUint64(0, chainId, false) + + const data = OperationManager.serialize(operation) + const publicKeyBytes = key.toBytes() + return Uint8Array.from([...networkId, ...publicKeyBytes, ...data]) + } + + /** + * Signs an operation for a given network. + * + * @remarks + * The chainId is used to counter replay attacks on a different chain. + * + * @param chainId - The identifier of the blockchain network. + * @param operation - The operation to sign. + * + * @returns A signature of the operation. + */ + async sign(chainId: bigint, operation: OperationDetails): Promise { + return this.privateKey.sign( + OperationManager.canonicalize( + chainId, + operation, + await this.privateKey.getPublicKey() + ) + ) + } + + /** + * Sends an operation to the blockchain. + * + * @param operation - The operation to send. + * + * @returns An operation Id. + */ + async send(operation: OperationDetails): Promise { + if (!this.blockchainClient) { + throw new Error('blockchainClient is mandatory to send operations') + } + const chainId = await this.blockchainClient.getChainId() + const signature = await this.sign(chainId, operation) + const data = OperationManager.serialize(operation) + const publicKey = await this.privateKey.getPublicKey() + + return this.blockchainClient.sendOperation({ + data, + publicKey: publicKey.toString(), + signature: signature.toString(), + }) + } +} + +/** + * Check the expire period validity. + * + * @remarks + * If the periodToLive is too big, the node will silently reject the operation. + * This is why the periodToLive is limited to an upper value. + * + * @param periodToLive - The period to live. + * + * @returns The expire period. + * @throws An error if the periodToLive is too low or too big. + */ +export function checkPeriodToLive(periodToLive = PERIOD_TO_LIVE_DEFAULT): void { + if (periodToLive < PERIOD_TO_LIVE_MIN || periodToLive > PERIOD_TO_LIVE_MAX) { + throw new Error( + `periodToLive must be between ${PERIOD_TO_LIVE_MIN} and ${PERIOD_TO_LIVE_MAX}.` + ) + } +} + +export async function getAbsoluteExpirePeriod( + client: PublicAPI, + periodToLive = PERIOD_TO_LIVE_DEFAULT +): Promise { + checkPeriodToLive(periodToLive) + const currentPeriod = await client.fetchPeriod() + return currentPeriod + periodToLive +} diff --git a/src/operation/types.ts b/src/operation/types.ts new file mode 100644 index 00000000..e0a260ef --- /dev/null +++ b/src/operation/types.ts @@ -0,0 +1,127 @@ +import { Address } from '../basicElements' +import { Mas } from '../basicElements/mas' +import { U64_t } from '../basicElements/serializers/number/u64' + +/** + * Operation status. + * + * @remarks + * This enumeration captures the lifecycle stages of a blockchain operation, from initiation to finalization. + * + * @privateRemarks + * Keeps the order of the stages in the lifecycle as it is used by the wait method. + */ +export enum OperationStatus { + /** + * The operation has not been found within the blockchain, either because it is not yet processed or does not exist. + */ + NotFound, + + /** + * The operation has been recognized and is awaiting inclusion in the blockchain ledger. + */ + PendingInclusion, + + /** + * The operation has executed successfully; however, the block containing it has not yet been confirmed as final. + */ + SpeculativeSuccess, + + /** + * The operation has failed; however, the block containing the failure has not yet been confirmed as final. + */ + SpeculativeError, + + /** + * The operation has executed successfully and the block containing it has been confirmed as final. + */ + Success, + + /** + * The operation has failed and the block containing the failure has been confirmed as final. + */ + Error, +} + +/** + * Operation types. + * + * @remarks + * The corresponding values are fixed by the node. + */ +export enum OperationType { + Transaction, + RollBuy, + RollSell, + ExecuteSmartContractBytecode, + CallSmartContractFunction, +} + +/** + * Operation options. + * + * @remarks + * Period to live is the number of periods the operation is valid for. + * This value must be positive and if it's too big, the node will (silently?) reject the operation. + * + * If no fee is provided, minimal fee of connected node is used. + * If no periodToLive is provided, the DefaultPeriodToLive is used. + */ +export type OperationOptions = { + fee?: U64_t + periodToLive?: number +} + +export type BaseOperation = { + fee: U64_t + expirePeriod: number + type: OperationType +} + +export type RollOperation = BaseOperation & { + type: OperationType.RollBuy | OperationType.RollSell + amount: U64_t +} + +export type TransferOperation = BaseOperation & { + type: OperationType.Transaction + amount: U64_t + recipientAddress: Address +} + +export type BaseSmartContractOperation = BaseOperation & { + maxGas: U64_t + coins: U64_t +} + +export type CallOperation = BaseSmartContractOperation & { + type: OperationType.CallSmartContractFunction + address: string + func: string + parameter: Uint8Array +} + +export type ReadOnlyParams = { + parameter: Uint8Array + coins?: Mas + fee?: Mas + maxGas?: U64_t + func: string + target: string + caller: string +} + +// @see https://docs.massa.net/docs/learn/operation-format-execution#executesc-operation-payload +export type ExecuteOperation = BaseOperation & { + maxGas: U64_t + maxCoins: U64_t + type: OperationType.ExecuteSmartContractBytecode + contractDataBinary: Uint8Array + datastore?: Map +} + +export type OperationDetails = + | RollOperation + | TransferOperation + | CallOperation + | ExecuteOperation diff --git a/src/provider/index.ts b/src/provider/index.ts new file mode 100644 index 00000000..82e42c1c --- /dev/null +++ b/src/provider/index.ts @@ -0,0 +1,3 @@ +export * from './types' +export * from './interface' +export * from './web3Provider' diff --git a/src/provider/interface.ts b/src/provider/interface.ts new file mode 100644 index 00000000..d5bb89cf --- /dev/null +++ b/src/provider/interface.ts @@ -0,0 +1,55 @@ +import { Address, EventFilter, Network, SCEvent, SmartContract } from '..' +import { Mas } from '../basicElements/mas' +import { Operation, OperationOptions, OperationStatus } from '../operation' +import { + CallSCParams, + DeploySCParams, + ReadSCData, + ReadSCParams, + SignedData, + NodeStatusInfo, +} from './' + +/** + * Defines the expected structure for a provider. + */ +export type Provider = { + /** Retrieves the account's address. */ + get address(): string + + /** Retrieves the provider's name associated with the account. */ + get accountName(): string + + /** Retrieves the account's name. */ + get providerName(): string + + /** Initiates a balance retrieval request for the account. */ + balance(final: boolean): Promise + networkInfos(): Promise + sign(data: Buffer | Uint8Array | string): Promise + buyRolls(amount: Mas, opts?: OperationOptions): Promise + sellRolls(amount: Mas, opts?: OperationOptions): Promise + transfer( + to: Address | string, + amount: Mas, + opts?: OperationOptions + ): Promise + callSC(params: CallSCParams): Promise + readSC(params: ReadSCParams): Promise + deploySC(params: DeploySCParams): Promise + getOperationStatus(opId: string): Promise + getEvents(filter: EventFilter): Promise + getNodeStatus(): Promise + + /** Storage */ + getStorageKeys( + address: string, + filter: Uint8Array | string, + final?: boolean + ): Promise + readStorage( + address: string, + keys: Uint8Array[] | string[], + final?: boolean + ): Promise +} diff --git a/src/provider/types.ts b/src/provider/types.ts new file mode 100644 index 00000000..6513a80f --- /dev/null +++ b/src/provider/types.ts @@ -0,0 +1,108 @@ +import { Args } from '../basicElements' +import { Mas } from '../basicElements/mas' +import { U64_t } from '../basicElements/serializers/number/u64' +import { SCEvent, Slot } from '../client' + +type CallSCCommons = { + parameter?: Args | Uint8Array + coins?: Mas + fee?: Mas + maxGas?: U64_t +} + +export type ReadSCParams = CallSCCommons & { + func: string + target: string + caller?: string +} + +export type CallSCParams = ReadSCParams & { + periodToLive?: number +} + +export type DeploySCParams = CallSCCommons & { + maxCoins?: Mas + byteCode: Uint8Array + periodToLive?: number + waitFinalExecution?: boolean +} + +export type ReadSCData = { + value: Uint8Array + info: { + error?: string + events: SCEvent[] + gasCost: number + } +} + +export type SignedData = { + /** Public key of the signer account */ + publicKey: string + /** Base58 encoded representation of the signature */ + signature: string +} + +export type NodeStatusInfo = { + config: Config + connectedNodes: Record + consensusStats: ConsensusStats + currentCycle: number + currentTime: number + currentCycleTime: number + nextCycleTime: number + lastSlot: Slot + nextSlot: Slot + networkStats: NetworkStats + nodeId: string + nodeIp?: null | string + poolStats: PoolStats + version: Version + executionStats: ExecutionStats + chainId: number + minimalFees?: string +} + +export type Config = { + blockReward: string + deltaF0: number + endTimestamp?: number | null + genesisTimestamp: number + maxBlockSize?: number + operationValidityPeriods: number + periodsPerCycle: number + rollPrice: string + t0: number + threadCount: number +} + +export type ConnectedNodes = Record + +export type ConsensusStats = { + cliqueCount: number + endTimespan: number + finalBlockCount: number + staleBlockCount: number + startTimespan: number +} + +export type NetworkStats = { + activeNodeCount: number + bannedPeerCount: number + inConnectionCount: number + knownPeerCount: number + outConnectionCount: number +} + +export type PoolStats = number[] + +export type Version = string + +export type ExecutionStats = { + timeWindowStart: number + timeWindowEnd: number + finalBlockCount: number + finalExecutedOperationsCount: number + activeCursor: Slot + finalCursor: Slot +} diff --git a/src/provider/web3Provider/constants.ts b/src/provider/web3Provider/constants.ts new file mode 100644 index 00000000..f6908074 --- /dev/null +++ b/src/provider/web3Provider/constants.ts @@ -0,0 +1 @@ +export const GAS_ESTIMATION_TOLERANCE = 20n // 20% diff --git a/src/provider/web3Provider/index.ts b/src/provider/web3Provider/index.ts new file mode 100644 index 00000000..a2cb4502 --- /dev/null +++ b/src/provider/web3Provider/index.ts @@ -0,0 +1,3 @@ +export * from './web3Provider' +export * from './constants' +export * from './smartContracts' diff --git a/src/provider/web3Provider/smartContracts.ts b/src/provider/web3Provider/smartContracts.ts new file mode 100644 index 00000000..7ba197c8 --- /dev/null +++ b/src/provider/web3Provider/smartContracts.ts @@ -0,0 +1,196 @@ +import { + Account, + DatastoreEntry, + minBigInt, + PublicAPI, + strToBytes, +} from '../..' +import { U64_t } from '../../basicElements/serializers/number/u64' +import { ErrorInsufficientBalance, ErrorMaxGas } from '../../errors' +import { MAX_GAS_CALL, MIN_GAS_CALL } from '../../smartContracts' +import { + CallSCParams, + DeploySCParams, + ReadSCParams, + GAS_ESTIMATION_TOLERANCE, + ReadSCData, +} from '..' +import * as StorageCost from '../../basicElements/storage' +import { populateDatastore } from '../../dataStore' +import { execute } from '../../basicElements/bytecode' +import { DEPLOYER_BYTECODE } from '../../generated/deployer-bytecode' +import { Mas } from '../../basicElements/mas' +import { CallOperation, OperationType } from '../../operation' +import { + getAbsoluteExpirePeriod, + OperationManager, +} from '../../operation/operationManager' + +export class SCProvider { + constructor( + public client: PublicAPI, + public account: Account + ) {} + + /** + * Reads smart contract function. + * @param params - readSCParams. + * @returns A promise that resolves to a ReadSCData. + */ + async readSC(params: ReadSCParams): Promise { + const args = params.parameter ?? new Uint8Array() + const caller = params.caller ?? this.account.address.toString() + const readOnlyParams = { + ...params, + caller, + parameter: + args instanceof Uint8Array ? args : Uint8Array.from(args.serialize()), + } + return this.client.executeReadOnlyCall(readOnlyParams) + } + + /** + * Executes a smart contract call operation + * @param params - callSCParams. + * @returns A promise that resolves to an Operation object representing the transaction. + */ + protected async call(params: CallSCParams): Promise { + const coins = params.coins ?? 0n + await this.checkAccountBalance(coins) + + const args = params.parameter ?? new Uint8Array() + const parameter = + args instanceof Uint8Array ? args : Uint8Array.from(args.serialize()) + + const fee = params.fee ?? (await this.client.getMinimalFee()) + + let maxGas = params.maxGas + if (!maxGas) { + maxGas = await this.getGasEstimation(params) + } else { + if (maxGas > MAX_GAS_CALL) { + throw new ErrorMaxGas({ isHigher: true, amount: MAX_GAS_CALL }) + } else if (maxGas < MIN_GAS_CALL) { + throw new ErrorMaxGas({ isHigher: false, amount: MIN_GAS_CALL }) + } + } + + const details: CallOperation = { + fee, + expirePeriod: await getAbsoluteExpirePeriod( + this.client, + params.periodToLive + ), + type: OperationType.CallSmartContractFunction, + coins, + maxGas, + address: params.target, + func: params.func, + parameter, + } + + const manager = new OperationManager(this.account.privateKey, this.client) + return manager.send(details) + } + + /** + * Returns the gas estimation for a given function. + * + * @remarks To avoid running out of gas, the gas estimation is increased by 20%. + * + * @param params - callSCParams. + * @throws If the read operation returns an error. + * @returns The gas estimation for the function. + */ + protected async getGasEstimation(params: CallSCParams): Promise { + const result = await this.readSC(params) + + if (result.info.error) { + throw new Error(result.info.error) + } + + const gasCost = BigInt(result.info.gasCost) + return minBigInt( + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + gasCost + (gasCost * GAS_ESTIMATION_TOLERANCE) / 100n, + MAX_GAS_CALL + ) + } + + protected async checkAccountBalance(coins: Mas): Promise { + if (coins > 0n) { + const balance = await this.client.getBalance( + this.account.address.toString() + ) + if (balance < coins) { + throw new ErrorInsufficientBalance({ + userBalance: balance, + neededBalance: coins, + }) + } + } + } + + /** + * Deploys a smart contract on the blockchain. + * + * @param params - Optional deployment details with defaults as follows: + * @param params.fee - Execution fee, auto-estimated if absent. + * @param params.maxCoins - Maximum number of coins to use, auto-estimated if absent. + * @param params.maxGas - Maximum execution gas, auto-estimated if absent. + * @param params.periodToLive - Duration in blocks before the transaction expires, defaults to 10. + * @param params.waitFinalExecution - Whether to wait for the transaction to be finalized, defaults to true. + * + * + * @returns The deployed smart contract. + * + * @throws If the account has insufficient balance to deploy the smart contract. + */ + protected async deploy(params: DeploySCParams): Promise { + const coins = params.coins ?? 0n + const totalCost = StorageCost.smartContract(params.byteCode.length) + coins + + await this.checkAccountBalance(totalCost) + + const args = params.parameter ?? new Uint8Array() + const parameter = + args instanceof Uint8Array ? args : Uint8Array.from(args.serialize()) + + const datastore = populateDatastore([ + { + data: params.byteCode, + args: parameter, + coins, + }, + ]) + + const fee = params.fee ?? (await this.client.getMinimalFee()) + + return execute(this.client, this.account.privateKey, DEPLOYER_BYTECODE, { + fee, + periodToLive: params.periodToLive, + maxCoins: params?.maxCoins ?? totalCost, + maxGas: params.maxGas, + datastore, + }) + } + + public async getStorageKeys( + address: string, + filter: Uint8Array | string = new Uint8Array(), + final = true + ): Promise { + const filterBytes: Uint8Array = + typeof filter === 'string' ? strToBytes(filter) : filter + return this.client.getDataStoreKeys(address, filterBytes, final) + } + + public async readStorage( + address: string, + keys: Uint8Array[] | string[], + final = true + ): Promise { + const entries: DatastoreEntry[] = keys.map((key) => ({ address, key })) + return this.client.getDatastoreEntries(entries, final) + } +} diff --git a/src/provider/web3Provider/web3Provider.ts b/src/provider/web3Provider/web3Provider.ts new file mode 100644 index 00000000..e85c6616 --- /dev/null +++ b/src/provider/web3Provider/web3Provider.ts @@ -0,0 +1,213 @@ +// a Web3Provider is the combination of a clientAPI and an private key account +import { + CallSCParams, + DeploySCParams, + NodeStatusInfo, + Provider, + SignedData, +} from '..' +import { SCProvider } from './smartContracts' +import { + Account, + Address, + CHAIN_ID, + EventFilter, + JsonRPCClient, + Network, + NetworkName, + PublicApiUrl, + SCEvent, + SmartContract, +} from '../..' +import { Mas } from '../../basicElements/mas' +import { + Operation, + OperationStatus, + OperationType, + OperationOptions, + RollOperation, + TransferOperation, +} from '../../operation' +import { + getAbsoluteExpirePeriod, + OperationManager, +} from '../../operation/operationManager' +import { formatNodeStatusObject } from '../../client/formatObjects' + +export class Web3Provider extends SCProvider implements Provider { + static fromRPCUrl(url: string, account: Account): Web3Provider { + return new Web3Provider(new JsonRPCClient(url), account) + } + + static mainnet(account: Account): Web3Provider { + return Web3Provider.fromRPCUrl(PublicApiUrl.Mainnet, account) + } + + static buildnet(account: Account): Web3Provider { + return Web3Provider.fromRPCUrl(PublicApiUrl.Buildnet, account) + } + + // eslint-disable-next-line @typescript-eslint/naming-convention + private readonly _providerName: string = 'Massa web3 provider' + + get accountName(): string { + return this.account.address.toString() + } + + get providerName(): string { + return this._providerName + } + + get address(): string { + return this.account.address.toString() + } + + async balance(final = true): Promise { + return this.client.getBalance(this.address.toString(), final) + } + + async networkInfos(): Promise { + const chainId = await this.client.getChainId() + let name = 'Unknown' + if (chainId === CHAIN_ID.Mainnet) { + name = NetworkName.Mainnet + } else if (chainId === CHAIN_ID.Buildnet) { + name = NetworkName.Buildnet + } + + return { + name, + chainId, + url: this.client.url, + minimalFee: await this.client.getMinimalFee(), + } + } + + private async rollOperation( + type: OperationType, + amount: Mas, + opts?: OperationOptions + ): Promise { + if (type !== OperationType.RollBuy && type !== OperationType.RollSell) { + throw new Error('Invalid roll operation type.') + } + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + if (amount <= 0) { + throw new Error('amount of rolls must be a positive non-zero value.') + } + + const operation = new OperationManager(this.account.privateKey, this.client) + const details: RollOperation = { + fee: opts?.fee ?? (await this.client.getMinimalFee()), + expirePeriod: await getAbsoluteExpirePeriod( + this.client, + opts?.periodToLive + ), + type, + amount, + } + const operationId = await operation.send(details) + return new Operation(this, operationId) + } + + /** + * Buys rolls. + * + * @param amount - The number of rolls to buy. + * @param opts - Optional operation details. + * + * @returns The ID of the operation. + * @throws If the amount of rolls is not a positive non-zero value. + */ + async buyRolls(amount: Mas, opts?: OperationOptions): Promise { + return this.rollOperation(OperationType.RollBuy, amount, opts) + } + + /** + * Sells rolls. + * + * @param amount - The number of rolls to sell. + * @param opts - Optional operation details. + * + * @returns The ID of the operation. + * @throws If the amount of rolls is not a positive non-zero value. + */ + async sellRolls(amount: Mas, opts?: OperationOptions): Promise { + return this.rollOperation(OperationType.RollSell, amount, opts) + } + + /** + * Transfers tokens. + * + * @param to - The address of the recipient. + * @param amount - The amount of tokens to transfer. + * @param opts - Optional operation details. + * + * @returns The ID of the operation. + * @throws If the amount of tokens is not a positive non-zero value. + */ + async transfer( + to: Address | string, + amount: Mas, + opts?: OperationOptions + ): Promise { + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + if (amount <= 0) { + throw new Error('amount to transfer must be a positive non-zero value.') + } + + if (typeof to === 'string') { + to = Address.fromString(to) + } + + const operation = new OperationManager(this.account.privateKey, this.client) + const details: TransferOperation = { + fee: opts?.fee ?? (await this.client.getMinimalFee()), + expirePeriod: await getAbsoluteExpirePeriod( + this.client, + opts?.periodToLive + ), + type: OperationType.Transaction, + amount, + recipientAddress: to, + } + const operationId = await operation.send(details) + return new Operation(this, operationId) + } + + // eslint-disable-next-line class-methods-use-this + public async sign( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + data: Buffer | Uint8Array | string + ): Promise { + throw new Error('not implemented') + } + + public async callSC(params: CallSCParams): Promise { + const operationId = await this.call(params) + return new Operation(this, operationId) + } + + public async deploySC(params: DeploySCParams): Promise { + const operationId = await this.deploy(params) + + const operation = new Operation(this, operationId) + const deployedAddress = await operation.getDeployedAddress( + params.waitFinalExecution + ) + return new SmartContract(this, deployedAddress) + } + + public async getOperationStatus(opId: string): Promise { + return this.client.getOperationStatus(opId) + } + + public async getEvents(filter: EventFilter): Promise { + return this.client.getEvents(filter) + } + + public async getNodeStatus(): Promise { + const status = await this.client.status() + return formatNodeStatusObject(status) + } +} diff --git a/src/smartContracts/constants.ts b/src/smartContracts/constants.ts new file mode 100644 index 00000000..18088fab --- /dev/null +++ b/src/smartContracts/constants.ts @@ -0,0 +1,3 @@ +export const MAX_GAS_CALL = 4294167295n +export const MIN_GAS_CALL = 2100000n +export const MAX_GAS_DEPLOYMENT = 3980167295n diff --git a/src/smartContracts/index.ts b/src/smartContracts/index.ts new file mode 100644 index 00000000..cb565866 --- /dev/null +++ b/src/smartContracts/index.ts @@ -0,0 +1,3 @@ +export * from './types' +export * from './smartContract' +export * from './constants' diff --git a/src/smartContracts/smartContract.ts b/src/smartContracts/smartContract.ts new file mode 100644 index 00000000..ad305032 --- /dev/null +++ b/src/smartContracts/smartContract.ts @@ -0,0 +1,86 @@ +import { Args } from '..' +import { Operation } from '../operation' +import { + CallSCParams, + DeploySCParams, + Provider, + ReadSCData, + ReadSCParams, +} from '../provider' +import { CallSCOptions, DeploySCOptions, ReadSCOptions } from './' + +/** + * A class to interact with a smart contract. + */ +export class SmartContract { + constructor( + public provider: Provider, + public address: string + ) {} + + /** + * Executes a smart contract call operation + * @param func - The smart contract function to be called. + * @param parameter - Parameters for the function call in Uint8Array or number[] format. + * @param options - Includes optional and required parameters like fee, maxGas, coins, and periodToLive. + * @returns A promise that resolves to an Operation object representing the transaction. + */ + async call( + func: string, + args: Args | Uint8Array = new Uint8Array(), + options: CallSCOptions = {} + ): Promise { + const callParams: CallSCParams = { + func, + parameter: args, + target: this.address, + ...options, + caller: this.provider.address, + } + + return this.provider.callSC(callParams) + } + + /** + * Executes a smart contract read operation + * @param func - The smart contract function to be called. + * @param args - Parameter for the function call in Uint8Array format. + * @param options - Includes optional parameters like fee, maxGas, coins, and periodToLive. + * @returns A promise that resolves to the result of the read operation. + */ + async read( + func: string, + args: Args | Uint8Array = new Uint8Array(), + options: ReadSCOptions = {} + ): Promise { + const readParams: ReadSCParams = { + func, + parameter: args, + target: this.address, + ...options, + } + return this.provider.readSC(readParams) + } + + /** + * Executes a smart contract read operation + * @param provider - Web3 provider. + * @param byteCode - Compiled SmartContract bytecode. + * @param constructorArgs - Parameter for call of constructor function. + * @param options - Includes optional parameters like fee, maxGas, coins, and periodToLive. + * @returns A promise that resolves to the result of the read operation. + */ + static async deploy( + provider: Provider, + byteCode: Uint8Array, + constructorArgs: Args | Uint8Array = new Uint8Array(), + options: DeploySCOptions = {} + ): Promise { + const deployParams: DeploySCParams = { + byteCode, + parameter: constructorArgs, + ...options, + } + return provider.deploySC(deployParams) + } +} diff --git a/src/smartContracts/types.ts b/src/smartContracts/types.ts new file mode 100644 index 00000000..b82b2811 --- /dev/null +++ b/src/smartContracts/types.ts @@ -0,0 +1,22 @@ +import { Mas } from '../basicElements/mas' +import { U64_t } from '../basicElements/serializers/number/u64' + +type CallSCCommons = { + coins?: Mas + fee?: Mas + maxGas?: U64_t +} + +export type DeploySCOptions = CallSCCommons & { + maxCoins?: Mas + waitFinalExecution?: boolean + periodToLive?: number +} + +export type CallSCOptions = CallSCCommons & { + periodToLive?: number +} + +export type ReadSCOptions = CallSCCommons & { + caller?: string +} diff --git a/src/utils/big-varint.ts b/src/utils/big-varint.ts new file mode 100644 index 00000000..56f79b25 --- /dev/null +++ b/src/utils/big-varint.ts @@ -0,0 +1,60 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +// This code was taken from the lib big-varint. https://github.com/joeltg/big-varint/blob/65346e5688245b20f05e5ce2dd8c784eb3ae3e15/src/unsigned.ts#L1C1-L58C2 +const LIMIT = 0x7fn + +export function encodingLength(value: bigint): number { + let i = 0 + + for (; value >= 0x80n; i++) { + value >>= 7n + } + + return i + 1 +} + +export function encode( + i: bigint, + buffer?: ArrayBuffer, + byteOffset?: number +): Uint8Array { + if (i < 0n) { + throw new RangeError('value must be unsigned') + } + + const byteLength = encodingLength(i) + buffer = buffer || new ArrayBuffer(byteLength) + byteOffset = byteOffset || 0 + if (buffer.byteLength < byteOffset + byteLength) { + throw new RangeError( + 'the buffer is too small to encode the number at the offset' + ) + } + + const array = new Uint8Array(buffer, byteOffset) + + let offset = 0 + while (LIMIT < i) { + array[offset++] = Number(i & LIMIT) | 0x80 + i >>= 7n + } + + array[offset] = Number(i) + + return array +} + +export function decode(data: Uint8Array, offset = 0): bigint { + let i = 0n + let n = 0 + let b: number + do { + b = data[offset + n] + if (b === undefined) { + throw new RangeError('offset out of range') + } + + i += BigInt(b & 0x7f) << BigInt(n * 7) + n++ + } while (0x80 <= b) + return i +} diff --git a/src/utils/events.ts b/src/utils/events.ts new file mode 100644 index 00000000..ce64d622 --- /dev/null +++ b/src/utils/events.ts @@ -0,0 +1,10 @@ +/** + * Decodes the raw event data from base64 to Uint8Array + * + * @param eventData - The raw event data in base64 format + * + * @returns The decoded raw event data + */ +export function rawEventDecode(eventData: string): Uint8Array { + return Uint8Array.from(Buffer.from(eventData, 'base64')) +} diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 00000000..374c7df1 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,5 @@ +export * from './isNode' +export * from './networks' +export * from './events' +export * from './maths' +export * from './numberFormat' diff --git a/src/utils/isNode.ts b/src/utils/isNode.ts new file mode 100644 index 00000000..b51b7e0f --- /dev/null +++ b/src/utils/isNode.ts @@ -0,0 +1,9 @@ +export function isNode(): boolean { + // inspired from secure-random.js + // we check for process.pid to prevent browserify from tricking us + return ( + typeof process !== 'undefined' && + typeof process.pid === 'number' && + typeof process.versions?.node === 'string' + ) +} diff --git a/src/utils/maths.ts b/src/utils/maths.ts new file mode 100644 index 00000000..0b571621 --- /dev/null +++ b/src/utils/maths.ts @@ -0,0 +1,3 @@ +export function minBigInt(a: bigint, b: bigint): bigint { + return a < b ? a : b +} diff --git a/src/utils/networks.ts b/src/utils/networks.ts new file mode 100644 index 00000000..8f7f4baf --- /dev/null +++ b/src/utils/networks.ts @@ -0,0 +1,26 @@ +/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/no-magic-numbers */ + +export enum PublicApiUrl { + Mainnet = 'https://mainnet.massa.net/api/v2', + Testnet = 'https://testnet.massa.net/api/v2', + Buildnet = 'https://buildnet.massa.net/api/v2', +} + +export enum NetworkName { + Mainnet = 'mainnet', + Testnet = 'testnet', + Buildnet = 'buildnet', +} + +export const CHAIN_ID = { + Mainnet: 77658377n, + Testnet: 77658376n, + Buildnet: 77658366n, +} + +export type Network = { + name: NetworkName | string + chainId: bigint + url?: string + minimalFee: bigint +} diff --git a/src/utils/numberFormat.ts b/src/utils/numberFormat.ts new file mode 100644 index 00000000..0d6ef6fe --- /dev/null +++ b/src/utils/numberFormat.ts @@ -0,0 +1,91 @@ +import { NB_DECIMALS } from '../basicElements/mas' + +/** + * Divides a number by a given exponent of base 10 (10exponent), and formats it into a string representation of the number. + * + * This code snippet is taken from the Viem SDK. + * - Docs: https://viem.sh/docs/utilities/formatUnits + * + * @example + * + * formatUnits(420000000000n, 9) + * // '420' + */ +export function formatUnits(value: bigint, decimals: number): string { + let display = value.toString() + + const negative = display.startsWith('-') + if (negative) display = display.slice(1) + + display = display.padStart(decimals, '0') + + // eslint-disable-next-line prefer-const + let [integer, fraction] = [ + display.slice(0, display.length - decimals), + display.slice(display.length - decimals), + ] + fraction = fraction.replace(/(0+)$/, '') + return `${negative ? '-' : ''}${integer || '0'}${ + fraction ? `.${fraction}` : '' + }` +} + +export function formatMas(value: bigint): string { + return formatUnits(value, NB_DECIMALS) +} + +/** + * Multiplies a string representation of a number by a given exponent of base 10 (10exponent). + * + * This code snippet is taken from the Viem SDK. + * - Docs: https://viem.sh/docs/utilities/parseUnits + * + * @example + * import { parseUnits } from 'viem' + * + * parseUnits('420', 9) + * // 420000000000n + */ +export function parseUnits(value: string, decimals: number): bigint { + let [integer, fraction = '0'] = value.split('.') + + const negative = integer.startsWith('-') + if (negative) integer = integer.slice(1) + + // trim trailing zeros. + fraction = fraction.replace(/(0+)$/, '') + + // round off if the fraction is larger than the number of decimals. + if (decimals === 0) { + if (Math.round(Number(`.${fraction}`)) === 1) + integer = `${BigInt(integer) + 1n}` + fraction = '' + } else if (fraction.length > decimals) { + const [left, unit, right] = [ + fraction.slice(0, decimals - 1), + fraction.slice(decimals - 1, decimals), + fraction.slice(decimals), + ] + + const rounded = Math.round(Number(`${unit}.${right}`)) + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + if (rounded > 9) + fraction = `${BigInt(left) + BigInt(1)}0`.padStart(left.length + 1, '0') + else fraction = `${left}${rounded}` + + if (fraction.length > decimals) { + fraction = fraction.slice(1) + integer = `${BigInt(integer) + 1n}` + } + + fraction = fraction.slice(0, decimals) + } else { + fraction = fraction.padEnd(decimals, '0') + } + + return BigInt(`${negative ? '-' : ''}${integer}${fraction}`) +} + +export function parseMas(value: string): bigint { + return parseUnits(value, NB_DECIMALS) +} diff --git a/test/generated/client-types-ti.ts b/test/generated/client-types-ti.ts new file mode 100644 index 00000000..9ee3cf3d --- /dev/null +++ b/test/generated/client-types-ti.ts @@ -0,0 +1,1193 @@ +/** + * This module was automatically generated by `ts-interface-builder` + */ +import * as t from "ts-interface-checker"; +// tslint:disable:object-literal-key-quotes + +export const NumberPsns2WbD = t.name("number"); + +export const Integer2AHOqbcQ = t.name("number"); + +export const UnorderedSetOfInteger2AHOqbcQjNvs9B0Z = t.array("Integer2AHOqbcQ"); + +export const Address = t.name("string"); + +export const UnorderedSetOfInteger2AHOqbcQtXvTMhya = t.array("Integer2AHOqbcQ"); + +export const BooleanHNwwo80P = t.name("boolean"); + +export const NumberZ1JdLCIz = t.name("number"); + +export const NumberSnYk3VhE = t.name("number"); + +export const ReadOnlyBytecodeExecution = t.iface([], { + "max_gas": "NumberPsns2WbD", + "bytecode": "UnorderedSetOfInteger2AHOqbcQjNvs9B0Z", + "address": t.opt("Address"), + "operation_datastore": t.opt("UnorderedSetOfInteger2AHOqbcQtXvTMhya"), + "is_final": t.opt("BooleanHNwwo80P"), + "coins": t.opt("NumberZ1JdLCIz"), + "fee": t.opt("NumberSnYk3VhE"), +}); + +export const StringYvGZTlwQ = t.name("string"); + +export const StringBtBJC5Iw = t.name("string"); + +export const UnorderedSetOfInteger2AHOqbcQzYHdsLoW = t.array("Integer2AHOqbcQ"); + +export const NullQu0Arl1F = t.name("null"); + +export const StringDoaGddGA = t.name("string"); + +export const OneOfNullQu0Arl1FStringDoaGddGAHzYKhN99 = t.union("NullQu0Arl1F", "StringDoaGddGA"); + +export const OneOfNullQu0Arl1FStringDoaGddGAEUSQB1KK = t.union("NullQu0Arl1F", "StringDoaGddGA"); + +export const OneOfNullQu0Arl1FStringDoaGddGANOhzhrxe = t.union("NullQu0Arl1F", "StringDoaGddGA"); + +export const ReadOnlyCall = t.iface([], { + "max_gas": "NumberPsns2WbD", + "target_address": "StringYvGZTlwQ", + "target_function": "StringBtBJC5Iw", + "parameter": "UnorderedSetOfInteger2AHOqbcQzYHdsLoW", + "caller_address": "OneOfNullQu0Arl1FStringDoaGddGAHzYKhN99", + "coins": "OneOfNullQu0Arl1FStringDoaGddGAEUSQB1KK", + "fee": "OneOfNullQu0Arl1FStringDoaGddGANOhzhrxe", +}); + +export const Boolean7Xei3MDX = t.name("boolean"); + +export const AddressFilter = t.iface([], { + "address": t.opt("Address"), + "is_final": t.opt("Boolean7Xei3MDX"), +}); + +export const BlockId = t.name("string"); + +export const NumberHo1ClIqD = t.name("number"); + +export const UnorderedSetOfInteger2AHOqbcQBha3UJIJ = t.array("Integer2AHOqbcQ"); + +export const DatastoreEntryInput = t.iface([], { + "address": "Address", + "key": "UnorderedSetOfInteger2AHOqbcQBha3UJIJ", +}); + +export const Slot = t.iface([], { + "period": "NumberHo1ClIqD", + "thread": "NumberHo1ClIqD", +}); + +export const String5J7NQ8B1 = t.name("string"); + +export const StringCc6XlKeq = t.name("string"); + +export const StringUcQL9QGN = t.name("string"); + +export const BooleanObf9WMA0 = t.name("boolean"); + +export const BooleanAXlyTrPe = t.name("boolean"); + +export const PrivateKey = t.name("string"); + +export const StringBBdNk2Ku = t.name("string"); + +export const StringOGpKXaCP = t.name("string"); + +export const PublicKey = t.name("string"); + +export const Signature = t.name("string"); + +export const UnorderedSetOfInteger2AHOqbcQarZIQlOy = t.array("Integer2AHOqbcQ"); + +export const OperationInput = t.iface([], { + "creator_public_key": "PublicKey", + "signature": "Signature", + "serialized_content": "UnorderedSetOfInteger2AHOqbcQarZIQlOy", +}); + +export const Pagination = t.iface([], { + "limit": "NumberHo1ClIqD", + "offset": "NumberHo1ClIqD", +}); + +export const ExecuteAt = t.iface([], { + "period": "NumberHo1ClIqD", + "thread": "NumberHo1ClIqD", +}); + +export const StringUJarsTOs = t.name("string"); + +export const UnorderedSetOfStringUJarsTOsgviiNMvH = t.array("StringUJarsTOs"); + +export const StringOz2F8Z2Y = t.name("string"); + +export const ReadOnlyResult = t.iface([], { + "Ok": t.opt("UnorderedSetOfStringUJarsTOsgviiNMvH"), + "Error": t.opt("StringOz2F8Z2Y"), +}); + +export const StringBt9L6T1F = t.name("string"); + +export const BooleanQYH7IQYB = t.name("boolean"); + +export const UnorderedSetOfAddressqhKJr2Tw = t.array("Address"); + +export const NumberHGt16B6Y = t.name("number"); + +export const OperationId = t.name("string"); + +export const BooleanSPcYqJj2 = t.name("boolean"); + +export const BooleanIqtEc7R0 = t.name("boolean"); + +export const EventExecutionContext = t.iface([], { + "slot": "Slot", + "block": t.opt("BlockId"), + "read_only": "BooleanQYH7IQYB", + "call_stack": "UnorderedSetOfAddressqhKJr2Tw", + "index_in_slot": "NumberHGt16B6Y", + "origin_operation_id": t.opt("OperationId"), + "is_final": "BooleanSPcYqJj2", + "is_error": t.opt("BooleanIqtEc7R0"), +}); + +export const SCOutputEvent = t.iface([], { + "data": "StringBt9L6T1F", + "context": "EventExecutionContext", +}); + +export const UnorderedSetOfSCOutputEventHwhiOmzE = t.array("SCOutputEvent"); + +export const NumberAIaYfWME = t.name("number"); + +export const ObjectD93Z4FAG = t.iface([], { + [t.indexKey]: "any", +}); + +export const ObjectHAgrRKSz = t.iface([], { + [t.indexKey]: "any", +}); + +export const UnorderedSetOfObjectHAgrRKSz46QV1Tyv = t.array("ObjectHAgrRKSz"); + +export const ObjectYWuwfL0B = t.iface([], { + [t.indexKey]: "any", +}); + +export const ObjectTK16EAH4 = t.iface([], { + [t.indexKey]: "any", +}); + +export const Object413CQ8L2 = t.iface([], { + [t.indexKey]: "any", +}); + +export const StringIytPJwYq = t.name("string"); + +export const StateChanges = t.iface([], { + "ledger_changes": "ObjectD93Z4FAG", + "async_pool_changes": "UnorderedSetOfObjectHAgrRKSz46QV1Tyv", + "pos_changes": "ObjectYWuwfL0B", + "executed_ops_changes": "ObjectTK16EAH4", + "executed_denunciations_changes": "Object413CQ8L2", + "execution_trail_hash_change": "StringIytPJwYq", +}); + +export const ExecuteReadOnlyResponse = t.iface([], { + "executed_at": "ExecuteAt", + "result": "ReadOnlyResult", + "output_events": "UnorderedSetOfSCOutputEventHwhiOmzE", + "gas_cost": "NumberAIaYfWME", + "state_changes": "StateChanges", +}); + +export const NumberSYJcvZVm = t.name("number"); + +export const StringFFlpWNJb = t.name("string"); + +export const NumberPAAsFK4N = t.name("number"); + +export const UnorderedSetOfNumberHo1ClIqDAokMKuEf = t.array("NumberHo1ClIqD"); + +export const UnorderedSetOfUnorderedSetOfNumberHo1ClIqDAokMKuEfIixaMtvV = t.array("UnorderedSetOfNumberHo1ClIqDAokMKuEf"); + +export const StringSZbUM3UB = t.name("string"); + +export const NumberUycrgn8X = t.name("number"); + +export const UnorderedSetOfUnorderedSetOfNumberHo1ClIqDAokMKuEfmvpf11Qe = t.array("UnorderedSetOfNumberHo1ClIqDAokMKuEf"); + +export const ObjectOfSlotStringDoaGddGAQZyvCcRS = t.iface([], { + "slot": t.opt("Slot"), + "amount": t.opt("StringDoaGddGA"), + [t.indexKey]: "any", +}); + +export const UnorderedSetOfObjectOfSlotStringDoaGddGAQZyvCcRS732D8Bc5 = t.array("ObjectOfSlotStringDoaGddGAQZyvCcRS"); + +export const UnorderedSetOfSlotpnXhUhWs = t.array("Slot"); + +export const ObjectOfSlotNumberHo1ClIqDMPMjgxrm = t.iface([], { + "slot": t.opt("Slot"), + "index": t.opt("NumberHo1ClIqD"), + [t.indexKey]: "any", +}); + +export const UnorderedSetOfObjectOfSlotNumberHo1ClIqDMPMjgxrm06Ae306Q = t.array("ObjectOfSlotNumberHo1ClIqDMPMjgxrm"); + +export const UnorderedSetOfBlockIdpdDCfi0P = t.array("BlockId"); + +export const UnorderedSetOfOperationId971EzIER = t.array("OperationId"); + +export const EndorsementId = t.name("string"); + +export const UnorderedSetOfEndorsementIdNN27ZC1J = t.array("EndorsementId"); + +export const BooleanVyG3AETh = t.name("boolean"); + +export const OneOfNullQu0Arl1FNumberHo1ClIqDKWtQwzS8 = t.union("NullQu0Arl1F", "NumberHo1ClIqD"); + +export const ExecutionAddressCycleInfo = t.iface([], { + "cycle": "NumberHo1ClIqD", + "is_final": "BooleanVyG3AETh", + "ok_count": "NumberHo1ClIqD", + "nok_count": "NumberHo1ClIqD", + "active_rolls": t.opt("OneOfNullQu0Arl1FNumberHo1ClIqDKWtQwzS8"), +}); + +export const UnorderedSetOfExecutionAddressCycleInfo8D3STgcL = t.array("ExecutionAddressCycleInfo"); + +export const AddressInfo = t.iface([], { + "address": "Address", + "thread": "NumberSYJcvZVm", + "final_balance": "StringFFlpWNJb", + "final_roll_count": "NumberPAAsFK4N", + "final_datastore_keys": "UnorderedSetOfUnorderedSetOfNumberHo1ClIqDAokMKuEfIixaMtvV", + "candidate_balance": "StringSZbUM3UB", + "candidate_roll_count": "NumberUycrgn8X", + "candidate_datastore_keys": "UnorderedSetOfUnorderedSetOfNumberHo1ClIqDAokMKuEfmvpf11Qe", + "deferred_credits": "UnorderedSetOfObjectOfSlotStringDoaGddGAQZyvCcRS732D8Bc5", + "next_block_draws": "UnorderedSetOfSlotpnXhUhWs", + "next_endorsement_draws": "UnorderedSetOfObjectOfSlotNumberHo1ClIqDMPMjgxrm06Ae306Q", + "created_blocks": "UnorderedSetOfBlockIdpdDCfi0P", + "created_operations": "UnorderedSetOfOperationId971EzIER", + "created_endorsements": "UnorderedSetOfEndorsementIdNN27ZC1J", + "cycle_infos": "UnorderedSetOfExecutionAddressCycleInfo8D3STgcL", +}); + +export const BooleanZxUVUy6M = t.name("boolean"); + +export const BooleanMazVJcyf = t.name("boolean"); + +export const BooleanHJvzO9WE = t.name("boolean"); + +export const BooleanHjqkwJfo = t.name("boolean"); + +export const NumberTbrodUsH = t.name("number"); + +export const OneOfNullQu0Arl1FNumberHo1ClIqD4U4GpKJM = t.union("NullQu0Arl1F", "NumberHo1ClIqD"); + +export const UnorderedSetOfStringDoaGddGADvj0XlFa = t.array("StringDoaGddGA"); + +export const EndorsementContent = t.iface([], { + "slot": "Slot", + "index": "NumberHo1ClIqD", + "endorsed_block": "BlockId", +}); + +export const ObjectOfStringDoaGddGAEndorsementIdPublicKeyAddressEndorsementContentWrpyYBUS = t.iface([], { + "content": t.opt("EndorsementContent"), + "signature": t.opt("StringDoaGddGA"), + "content_creator_pub_key": t.opt("PublicKey"), + "content_creator_address": t.opt("Address"), + "id": t.opt("EndorsementId"), + [t.indexKey]: "any", +}); + +export const UnorderedSetOfObjectOfStringDoaGddGAEndorsementIdPublicKeyAddressEndorsementContentWrpyYBUSwrpyYBUS = t.array("ObjectOfStringDoaGddGAEndorsementIdPublicKeyAddressEndorsementContentWrpyYBUS"); + +export const ObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUS = t.iface([], { + "public_key": t.opt("StringDoaGddGA"), + "slot": t.opt("Integer2AHOqbcQ"), + "index": t.opt("Integer2AHOqbcQ"), + "hash_1": t.opt("StringDoaGddGA"), + "hash_2": t.opt("StringDoaGddGA"), + "signature_1": t.opt("StringDoaGddGA"), + "signature_2": t.opt("StringDoaGddGA"), + [t.indexKey]: "any", +}); + +export const ObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUS = t.iface([], { + "public_key": t.opt("StringDoaGddGA"), + "slot": t.opt("Integer2AHOqbcQ"), + "hash_1": t.opt("StringDoaGddGA"), + "hash_2": t.opt("StringDoaGddGA"), + "signature_1": t.opt("StringDoaGddGA"), + "signature_2": t.opt("StringDoaGddGA"), + [t.indexKey]: "any", +}); + +export const OneOfObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUSObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUSGJLAASWC = t.union("ObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUS", "ObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUS"); + +export const UnorderedSetOfOneOfObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUSObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUSGJLAASWCwrpyYBUS = t.array("OneOfObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUSObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUSGJLAASWC"); + +export const Header = t.iface([], { + "current_version": t.opt("NumberTbrodUsH"), + "announced_version": t.opt("OneOfNullQu0Arl1FNumberHo1ClIqD4U4GpKJM"), + "operation_merkle_root": "StringDoaGddGA", + "parents": "UnorderedSetOfStringDoaGddGADvj0XlFa", + "slot": "Slot", + "endorsements": t.opt("UnorderedSetOfObjectOfStringDoaGddGAEndorsementIdPublicKeyAddressEndorsementContentWrpyYBUSwrpyYBUS"), + "denunciations": t.opt("UnorderedSetOfOneOfObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUSObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUSGJLAASWCwrpyYBUS"), +}); + +export const WrappedHeader = t.iface([], { + "content": "Header", + "signature": "Signature", + "content_creator_pub_key": "PublicKey", + "content_creator_address": "Address", + "id": t.opt("BlockId"), +}); + +export const UnorderedSetOfStringDoaGddGAucaTsQyS = t.array("StringDoaGddGA"); + +export const Block = t.iface([], { + "header": "WrappedHeader", + "operations": "UnorderedSetOfStringDoaGddGAucaTsQyS", +}); + +export const BlockInfoContent = t.iface([], { + "is_final": "BooleanZxUVUy6M", + "is_candidate": "BooleanMazVJcyf", + "is_discarded": t.opt("BooleanHJvzO9WE"), + "is_in_blockclique": "BooleanHjqkwJfo", + "block": "Block", +}); + +export const BlockInfo = t.iface([], { + "id": "StringDoaGddGA", + "content": t.opt("BlockInfoContent"), +}); + +export const UnorderedSetOfBlockId1V6I15AQ = t.array("BlockId"); + +export const Number7BVjpZ2Z = t.name("number"); + +export const BooleanXIboFXzF = t.name("boolean"); + +export const Clique = t.iface([], { + "block_ids": "UnorderedSetOfBlockId1V6I15AQ", + "fitness": "Number7BVjpZ2Z", + "is_blockclique": "BooleanXIboFXzF", +}); + +export const OneOfNullQu0Arl1FUnorderedSetOfInteger2AHOqbcQarZIQlOy81SHPJsX = t.union("UnorderedSetOfInteger2AHOqbcQarZIQlOy", "NullQu0Arl1F"); + +export const OneOfNullQu0Arl1FUnorderedSetOfInteger2AHOqbcQarZIQlOyGOQJrRPK = t.union("UnorderedSetOfInteger2AHOqbcQarZIQlOy", "NullQu0Arl1F"); + +export const DatastoreEntryOutput = t.iface([], { + "candidate_value": "OneOfNullQu0Arl1FUnorderedSetOfInteger2AHOqbcQarZIQlOy81SHPJsX", + "final_value": "OneOfNullQu0Arl1FUnorderedSetOfInteger2AHOqbcQarZIQlOyGOQJrRPK", +}); + +export const StringYVTrFSaQ = t.name("string"); + +export const StringZyWeUFZ8 = t.name("string"); + +export const IntegerCOVAu0Eq = t.name("number"); + +export const IntegerVC2Agt39 = t.name("number"); + +export const Object0XCk2T5H = t.iface([], { + [t.indexKey]: "any", +}); + +export const BooleanYDqyb5Vp = t.name("boolean"); + +export const NumberV8R93Gu7 = t.name("number"); + +export const StringUyVBK2CK = t.name("string"); + +export const Transfer = t.iface([], { + "from": "StringYVTrFSaQ", + "to": "StringZyWeUFZ8", + "amount": "IntegerCOVAu0Eq", + "effective_amount_received": "IntegerVC2Agt39", + "context": "Object0XCk2T5H", + "succeed": "BooleanYDqyb5Vp", + "fee": "NumberV8R93Gu7", + "block_id": "StringUyVBK2CK", +}); + +export const UnorderedSetOfTransferQEyQHpyL = t.array("Transfer"); + +export const UnorderedSetOfBlockId7G1Sy5Qv = t.array("BlockId"); + +export const Endorsement = t.iface([], { + "content": "EndorsementContent", + "content_creator_pub_key": "PublicKey", + "content_creator_address": t.opt("Address"), + "id": t.opt("EndorsementId"), + "signature": "StringDoaGddGA", +}); + +export const EndorsementInfo = t.iface([], { + "id": "EndorsementId", + "in_pool": "BooleanVyG3AETh", + "in_blocks": "UnorderedSetOfBlockId7G1Sy5Qv", + "is_final": "BooleanVyG3AETh", + "endorsement": "Endorsement", +}); + +export const StringVuVvWRdT = t.name("string"); + +export const StringU8LlHDu1 = t.name("string"); + +export const UnorderedSetOfStringDoaGddGAMZnHm9WS = t.array("StringDoaGddGA"); + +export const GraphInterval = t.iface([], { + "creator": "StringVuVvWRdT", + "id": "StringU8LlHDu1", + "is_final": "BooleanVyG3AETh", + "is_in_blockclique": "BooleanVyG3AETh", + "is_stale": "BooleanVyG3AETh", + "parents": "UnorderedSetOfStringDoaGddGAMZnHm9WS", + "slot": "Slot", +}); + +export const StringYTemzr68 = t.name("string"); + +export const UnorderedSetOfBlockIdyEy9Dvpn = t.array("BlockId"); + +export const BooleanSJ3TNusg = t.name("boolean"); + +export const OneOfBooleanVyG3AEThNullQu0Arl1FCuqCzoUJ = t.union("NullQu0Arl1F", "BooleanVyG3AETh"); + +export const NumberZoWtBk8U = t.name("number"); + +export const StringV3754ZDT = t.name("string"); + +export const NumberSbfeGjn7 = t.name("number"); + +export const StringNIrlyE1J = t.name("string"); + +export const Transaction = t.iface([], { + "amount": "StringNIrlyE1J", + "recipient_address": "StringDoaGddGA", +}); + +export const UnorderedSetOfNumberHo1ClIqDd5W02PgX = t.array("NumberHo1ClIqD"); + +export const NumberQUXtpAPK = t.name("number"); + +export const ObjectOfUnorderedSetOfInteger2AHOqbcQarZIQlOyUnorderedSetOfInteger2AHOqbcQarZIQlOyDbxIogvI = t.iface([], { + "entry": t.opt("UnorderedSetOfInteger2AHOqbcQarZIQlOy"), + "bytes": t.opt("UnorderedSetOfInteger2AHOqbcQarZIQlOy"), + [t.indexKey]: "any", +}); + +export const Datastore = t.iface([], { + [t.indexKey]: "any", +}); + +export const ExecuteSC = t.iface([], { + "data": "UnorderedSetOfNumberHo1ClIqDd5W02PgX", + "max_gas": "NumberQUXtpAPK", + "datastore": "Datastore", +}); + +export const String7HCIMJir = t.name("string"); + +export const StringSjIor0MV = t.name("string"); + +export const Number5Mo1HId6 = t.name("number"); + +export const CallSC = t.iface([], { + "target_addr": "Address", + "target_func": "String7HCIMJir", + "param": "StringSjIor0MV", + "max_gas": "NumberHo1ClIqD", + "coins": "Number5Mo1HId6", +}); + +export const NumberJdJmnq9D = t.name("number"); + +export const RollBuy = t.iface([], { + "roll_count": "NumberJdJmnq9D", +}); + +export const RollSell = t.iface([], { + "roll_count": "NumberJdJmnq9D", +}); + +export const OperationType = t.iface([], { + "Transaction": t.opt("Transaction"), + "ExecutSC": t.opt("ExecuteSC"), + "CallSC": t.opt("CallSC"), + "RollBuy": t.opt("RollBuy"), + "RollSell": t.opt("RollSell"), +}); + +export const Operation = t.iface([], { + "fee": "StringV3754ZDT", + "expire_period": "NumberSbfeGjn7", + "op": "OperationType", +}); + +export const WrappedOperation = t.iface([], { + "content": "Operation", + "signature": "Signature", + "content_creator_pub_key": t.opt("PublicKey"), + "content_creator_address": t.opt("Address"), + "id": t.opt("OperationId"), +}); + +export const OneOfBooleanVyG3AEThNullQu0Arl1FE3Qax0Os = t.union("NullQu0Arl1F", "BooleanVyG3AETh"); + +export const OperationInfo = t.iface([], { + "id": "StringYTemzr68", + "in_blocks": "UnorderedSetOfBlockIdyEy9Dvpn", + "in_pool": "BooleanSJ3TNusg", + "is_operation_final": "OneOfBooleanVyG3AEThNullQu0Arl1FCuqCzoUJ", + "thread": "NumberZoWtBk8U", + "operation": "WrappedOperation", + "op_exec_status": t.opt("OneOfBooleanVyG3AEThNullQu0Arl1FE3Qax0Os"), +}); + +export const ObjectOfAddressNumberHo1ClIqDFbgdJFtJ = t.iface([], { + "address": t.opt("Address"), + "active_rolls": t.opt("NumberHo1ClIqD"), + [t.indexKey]: "any", +}); + +export const Staker = t.iface([], { + [t.indexKey]: "any", +}); + +export const Number2A9FvvYh = t.name("number"); + +export const OneOfNullQu0Arl1FNumberHo1ClIqDXysINzQy = t.union("NullQu0Arl1F", "NumberHo1ClIqD"); + +export const NumberSgfzurLm = t.name("number"); + +export const NumberUwkWWxaa = t.name("number"); + +export const NumberTs6Cn6JQ = t.name("number"); + +export const NumberGrsxxfaH = t.name("number"); + +export const Number8ImKBhpQ = t.name("number"); + +export const NumberAxwlzLso = t.name("number"); + +export const Config = t.iface([], { + "block_reward": "StringNIrlyE1J", + "delta_f0": "Number2A9FvvYh", + "end_timestamp": t.opt("OneOfNullQu0Arl1FNumberHo1ClIqDXysINzQy"), + "genesis_timestamp": "NumberSgfzurLm", + "max_block_size": t.opt("NumberUwkWWxaa"), + "operation_validity_periods": "NumberTs6Cn6JQ", + "periods_per_cycle": "NumberGrsxxfaH", + "roll_price": "StringNIrlyE1J", + "t0": "Number8ImKBhpQ", + "thread_count": "NumberAxwlzLso", +}); + +export const ObjectOfStringDoaGddGAStringDoaGddGAXJdFCZe6 = t.iface([], { + "node_id": t.opt("StringDoaGddGA"), + "ip_address": t.opt("StringDoaGddGA"), + [t.indexKey]: "any", +}); + +export const ConnectedNodes = t.iface([], { + [t.indexKey]: "any", +}); + +export const NumberLpoULYcx = t.name("number"); + +export const ConsensusStats = t.iface([], { + "clique_count": "NumberHo1ClIqD", + "end_timespan": "NumberLpoULYcx", + "final_block_count": "NumberHo1ClIqD", + "stale_block_count": "NumberHo1ClIqD", + "start_timespan": "NumberLpoULYcx", +}); + +export const NumberSWFW9I8Z = t.name("number"); + +export const NumberYQZ1VVuw = t.name("number"); + +export const NumberQuWRP8Oa = t.name("number"); + +export const NumberSDEXjSo6 = t.name("number"); + +export const NumberWc2YJi2H = t.name("number"); + +export const NumberZdt4Udf4 = t.name("number"); + +export const NumberLgEVA2Rp = t.name("number"); + +export const NumberNw53IytE = t.name("number"); + +export const NumberXuleKeT9 = t.name("number"); + +export const NetworkStats = t.iface([], { + "active_node_count": "NumberWc2YJi2H", + "banned_peer_count": "NumberZdt4Udf4", + "in_connection_count": "NumberLgEVA2Rp", + "known_peer_count": "NumberNw53IytE", + "out_connection_count": "NumberXuleKeT9", +}); + +export const StringOFgZzVe7 = t.name("string"); + +export const OneOfNullQu0Arl1FStringDoaGddGANsst9HIR = t.union("NullQu0Arl1F", "StringDoaGddGA"); + +export const PoolStats = t.array("NumberHo1ClIqD"); + +export const Version = t.name("string"); + +export const NumberDk8ZmyGi = t.name("number"); + +export const NumberWbCeho3I = t.name("number"); + +export const NumberGCfSuERd = t.name("number"); + +export const NumberJ4Dz6P30 = t.name("number"); + +export const ExecutionStats = t.iface([], { + "time_window_start": "NumberDk8ZmyGi", + "time_window_end": "NumberWbCeho3I", + "final_block_count": "NumberGCfSuERd", + "final_executed_operations_count": "NumberJ4Dz6P30", + "active_cursor": "Slot", + "final_cursor": "Slot", +}); + +export const NumberBte4OVdF = t.name("number"); + +export const StringTXHumHoA = t.name("string"); + +export const AlwaysFalse = t.name("any"); + +export const IpAddress = t.name("string"); + +export const StringTPMT1Yxd = t.name("string"); + +export const StringXHbmHEWh = t.name("string"); + +export const UnorderedSetOfStakerX7P278VS = t.array("Staker"); + +export const ObjectOfNumberHo1ClIqDBlockIdHCnqqlza = t.iface([], { + "BlockId": t.opt("BlockId"), + "period": t.opt("NumberHo1ClIqD"), + [t.indexKey]: "any", +}); + +export const BlockParent = t.iface([], { + [t.indexKey]: "any", +}); + +export const Boolean4XbLtRCK = t.name("boolean"); + +export const UnorderedSetOfOperationInfowrpyYBUS = t.array("OperationInfo"); + +export const FilledBlock = t.iface([], { + "header": "WrappedHeader", + "operations": "UnorderedSetOfOperationInfowrpyYBUS", +}); + +export const FilledBlockInfoContent = t.iface([], { + "is_final": "BooleanZxUVUy6M", + "is_stale": "Boolean4XbLtRCK", + "is_in_blockclique": "BooleanHjqkwJfo", + "block": "FilledBlock", +}); + +export const UnorderedSetOfReadOnlyBytecodeExecutionK4Ht8Zdn = t.array("ReadOnlyBytecodeExecution"); + +export const UnorderedSetOfReadOnlyCallm6DMxyzd = t.array("ReadOnlyCall"); + +export const UnorderedSetOfAddressjJsnATCO = t.array("Address"); + +export const UnorderedSetOfAddressFilteraFrapw7X = t.array("AddressFilter"); + +export const UnorderedSetOfBlockIdZXK9XY8A = t.array("BlockId"); + +export const UnorderedSetOfDatastoreEntryInputBdlngHsZ = t.array("DatastoreEntryInput"); + +export const UnorderedSetOfSlotn0BdrHhh = t.array("Slot"); + +export const EventFilter = t.iface([], { + "start": t.opt("Slot"), + "end": t.opt("Slot"), + "emitter_address": t.opt("String5J7NQ8B1"), + "original_caller_address": t.opt("StringCc6XlKeq"), + "original_operation_id": t.opt("StringUcQL9QGN"), + "is_final": t.opt("BooleanObf9WMA0"), + "is_error": t.opt("BooleanAXlyTrPe"), +}); + +export const ObjectOfNumberHo1ClIqDNumberHo1ClIqDTmeT75Fq = t.iface([], { + "start": t.opt("NumberHo1ClIqD"), + "end": t.opt("NumberHo1ClIqD"), +}); + +export const UnorderedSetOfPrivateKeyG69QLiLP = t.array("PrivateKey"); + +export const UnorderedSetOfStringBBdNk2Kup3WUWKiM = t.array("StringBBdNk2Ku"); + +export const UnorderedSetOfStringOGpKXaCP4RgV7KAw = t.array("StringOGpKXaCP"); + +export const UnorderedSetOfOperationInput9XcIbRG1 = t.array("OperationInput"); + +export const ApiRequest = t.iface([], { + "page_request": t.opt("Pagination"), +}); + +export const UnorderedSetOfExecuteReadOnlyResponsewrpyYBUS = t.array("ExecuteReadOnlyResponse"); + +export const UnorderedSetOfAddressInfoCm3Tm6FQ = t.array("AddressInfo"); + +export const UnorderedSetOfStringUJarsTOsGY6FcFnU = t.array("StringUJarsTOs"); + +export const UnorderedSetOfBlockInfowrpyYBUS = t.array("BlockInfo"); + +export const UnorderedSetOfCliqueeS9LyMHx = t.array("Clique"); + +export const UnorderedSetOfDatastoreEntryOutputhcgFMMvn = t.array("DatastoreEntryOutput"); + +export const UnorderedSetOfUnorderedSetOfTransferQEyQHpyLoFgVJgXU = t.array("UnorderedSetOfTransferQEyQHpyL"); + +export const UnorderedSetOfEndorsementInfowrpyYBUS = t.array("EndorsementInfo"); + +export const UnorderedSetOfGraphIntervalwrpyYBUS = t.array("GraphInterval"); + +export const UnorderedSetOfOperationInfoMdPofISE = t.array("OperationInfo"); + +export const NodeStatus = t.iface([], { + "config": "Config", + "connected_nodes": "ConnectedNodes", + "consensus_stats": "ConsensusStats", + "current_cycle": "NumberSWFW9I8Z", + "current_time": "NumberYQZ1VVuw", + "current_cycle_time": "NumberQuWRP8Oa", + "next_cycle_time": "NumberSDEXjSo6", + "last_slot": "Slot", + "network_stats": "NetworkStats", + "next_slot": "Slot", + "node_id": "StringOFgZzVe7", + "node_ip": t.opt("OneOfNullQu0Arl1FStringDoaGddGANsst9HIR"), + "pool_stats": "PoolStats", + "version": "Version", + "execution_stats": "ExecutionStats", + "chain_id": "NumberBte4OVdF", + "minimal_fees": t.opt("StringTXHumHoA"), +}); + +export const UnorderedSetOfIpAddressWpGgzO6M = t.array("IpAddress"); + +export const PubkeySig = t.iface([], { + "public_key": "StringTPMT1Yxd", + "signature": "StringXHbmHEWh", +}); + +export const UnorderedSetOfOperationId5TxbV4NZ = t.array("OperationId"); + +export const PagedVecStaker = t.iface([], { + "content": t.opt("UnorderedSetOfStakerX7P278VS"), + "total_count": t.opt("NumberHo1ClIqD"), +}); + +export const UnorderedSetOfBlockParentxrssVm84 = t.array("BlockParent"); + +export const FilledBlockInfo = t.iface([], { + "id": "StringDoaGddGA", + "content": t.opt("FilledBlockInfoContent"), +}); + +export const AnyOfUnorderedSetOfReadOnlyBytecodeExecutionK4Ht8ZdnUnorderedSetOfReadOnlyCallm6DMxyzdUnorderedSetOfAddressjJsnATCOUnorderedSetOfAddressFilteraFrapw7XUnorderedSetOfBlockIdZXK9XY8ASlotUnorderedSetOfDatastoreEntryInputBdlngHsZUnorderedSetOfSlotn0BdrHhhUnorderedSetOfStringDoaGddGADvj0XlFaEventFilterObjectOfNumberHo1ClIqDNumberHo1ClIqDTmeT75FqUnorderedSetOfStringDoaGddGADvj0XlFaPaginationUnorderedSetOfPrivateKeyG69QLiLPUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringDoaGddGADvj0XlFaUnorderedSetOfStringDoaGddGADvj0XlFaUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfAddressjJsnATCOStringUJarsTOsUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringOGpKXaCP4RgV7KAwUnorderedSetOfOperationInput9XcIbRG1ApiRequestInteger2AHOqbcQInteger2AHOqbcQInteger2AHOqbcQInteger2AHOqbcQUnorderedSetOfExecuteReadOnlyResponsewrpyYBUSUnorderedSetOfExecuteReadOnlyResponsewrpyYBUSUnorderedSetOfAddressInfoCm3Tm6FQUnorderedSetOfStringUJarsTOsGY6FcFnUUnorderedSetOfBlockInfowrpyYBUSBlockUnorderedSetOfCliqueeS9LyMHxUnorderedSetOfDatastoreEntryOutputhcgFMMvnUnorderedSetOfUnorderedSetOfTransferQEyQHpyLoFgVJgXUUnorderedSetOfEndorsementInfowrpyYBUSUnorderedSetOfSCOutputEventHwhiOmzEUnorderedSetOfGraphIntervalwrpyYBUSUnorderedSetOfOperationInfoMdPofISEUnorderedSetOfStakerX7P278VSNodeStatusAlwaysFalseUnorderedSetOfAddressjJsnATCOAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseUnorderedSetOfIpAddressWpGgzO6MUnorderedSetOfIpAddressWpGgzO6MAlwaysFalseUnorderedSetOfIpAddressWpGgzO6MAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalsePubkeySigAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseUnorderedSetOfOperationId5TxbV4NZPagedVecStakerUnorderedSetOfBlockParentxrssVm84VersionBlockInfoWrappedHeaderFilledBlockInfoOperationBooleanVyG3AEThBooleanVyG3AEThBooleanVyG3AEThBooleanVyG3AETh = t.union("UnorderedSetOfReadOnlyBytecodeExecutionK4Ht8Zdn", "UnorderedSetOfReadOnlyCallm6DMxyzd", "UnorderedSetOfAddressjJsnATCO", "UnorderedSetOfAddressFilteraFrapw7X", "UnorderedSetOfBlockIdZXK9XY8A", "Slot", "UnorderedSetOfDatastoreEntryInputBdlngHsZ", "UnorderedSetOfSlotn0BdrHhh", "UnorderedSetOfStringDoaGddGADvj0XlFa", "EventFilter", "ObjectOfNumberHo1ClIqDNumberHo1ClIqDTmeT75Fq", "Pagination", "UnorderedSetOfPrivateKeyG69QLiLP", "UnorderedSetOfStringBBdNk2Kup3WUWKiM", "StringUJarsTOs", "UnorderedSetOfStringOGpKXaCP4RgV7KAw", "UnorderedSetOfOperationInput9XcIbRG1", "ApiRequest", "Integer2AHOqbcQ", "UnorderedSetOfExecuteReadOnlyResponsewrpyYBUS", "UnorderedSetOfAddressInfoCm3Tm6FQ", "UnorderedSetOfStringUJarsTOsGY6FcFnU", "UnorderedSetOfBlockInfowrpyYBUS", "Block", "UnorderedSetOfCliqueeS9LyMHx", "UnorderedSetOfDatastoreEntryOutputhcgFMMvn", "UnorderedSetOfUnorderedSetOfTransferQEyQHpyLoFgVJgXU", "UnorderedSetOfEndorsementInfowrpyYBUS", "UnorderedSetOfSCOutputEventHwhiOmzE", "UnorderedSetOfGraphIntervalwrpyYBUS", "UnorderedSetOfOperationInfoMdPofISE", "UnorderedSetOfStakerX7P278VS", "NodeStatus", "AlwaysFalse", "UnorderedSetOfIpAddressWpGgzO6M", "PubkeySig", "UnorderedSetOfOperationId5TxbV4NZ", "PagedVecStaker", "UnorderedSetOfBlockParentxrssVm84", "Version", "BlockInfo", "WrappedHeader", "FilledBlockInfo", "Operation", "BooleanVyG3AETh"); + +export const ExecuteReadOnlyBytecode = t.func("UnorderedSetOfExecuteReadOnlyResponsewrpyYBUS", t.param("ReadOnlyBytecodeExecution", "UnorderedSetOfReadOnlyBytecodeExecutionK4Ht8Zdn")); + +export const ExecuteReadOnlyCall = t.func("UnorderedSetOfExecuteReadOnlyResponsewrpyYBUS", t.param("ReadOnlyCall", "UnorderedSetOfReadOnlyCallm6DMxyzd")); + +export const GetAddresses = t.func("UnorderedSetOfAddressInfoCm3Tm6FQ", t.param("address", "UnorderedSetOfAddressjJsnATCO")); + +export const GetAddressesBytecode = t.func("UnorderedSetOfStringUJarsTOsGY6FcFnU", t.param("addressFilter", "UnorderedSetOfAddressFilteraFrapw7X")); + +export const GetBlocks = t.func("UnorderedSetOfBlockInfowrpyYBUS", t.param("blockId", "UnorderedSetOfBlockIdZXK9XY8A")); + +export const GetBlockcliqueBlockBySlot = t.func("Block", t.param("slot", "Slot")); + +export const GetCliques = t.func("UnorderedSetOfCliqueeS9LyMHx"); + +export const GetDatastoreEntries = t.func("UnorderedSetOfDatastoreEntryOutputhcgFMMvn", t.param("DatastoreEntryInputs", "UnorderedSetOfDatastoreEntryInputBdlngHsZ")); + +export const GetSlotsTransfers = t.func("UnorderedSetOfUnorderedSetOfTransferQEyQHpyLoFgVJgXU", t.param("slots", "UnorderedSetOfSlotn0BdrHhh")); + +export const GetEndorsements = t.func("UnorderedSetOfEndorsementInfowrpyYBUS", t.param("endorsementId", "UnorderedSetOfStringDoaGddGADvj0XlFa")); + +export const GetFilteredScOutputEvent = t.func("UnorderedSetOfSCOutputEventHwhiOmzE", t.param("EventFilter", "EventFilter")); + +export const GetGraphInterval = t.func("UnorderedSetOfGraphIntervalwrpyYBUS", t.param("TimeInterval", "ObjectOfNumberHo1ClIqDNumberHo1ClIqDTmeT75Fq")); + +export const GetOperations = t.func("UnorderedSetOfOperationInfoMdPofISE", t.param("operationId", "UnorderedSetOfStringDoaGddGADvj0XlFa")); + +export const GetStakers = t.func("UnorderedSetOfStakerX7P278VS", t.param("PageRequest", "Pagination")); + +export const GetStatus = t.func("NodeStatus"); + +export const AddStakingSecretKeys = t.func("AlwaysFalse", t.param("SecretKeys", "UnorderedSetOfPrivateKeyG69QLiLP")); + +export const GetStakingAddresses = t.func("UnorderedSetOfAddressjJsnATCO"); + +export const NodeAddToBootstrapBlacklist = t.func("AlwaysFalse", t.param("ip", "UnorderedSetOfStringBBdNk2Kup3WUWKiM")); + +export const NodeAddToBootstrapWhitelist = t.func("AlwaysFalse", t.param("ip", "UnorderedSetOfStringBBdNk2Kup3WUWKiM")); + +export const NodeAddToPeersWhitelist = t.func("AlwaysFalse", t.param("ip", "UnorderedSetOfStringBBdNk2Kup3WUWKiM")); + +export const NodeBanById = t.func("AlwaysFalse", t.param("id", "UnorderedSetOfStringDoaGddGADvj0XlFa")); + +export const NodeBanByIp = t.func("AlwaysFalse", t.param("ip", "UnorderedSetOfStringDoaGddGADvj0XlFa")); + +export const NodeBootstrapBlacklist = t.func("UnorderedSetOfIpAddressWpGgzO6M"); + +export const NodeBootstrapWhitelist = t.func("UnorderedSetOfIpAddressWpGgzO6M"); + +export const NodeBootstrapWhitelistAllowAll = t.func("AlwaysFalse"); + +export const NodePeersWhitelist = t.func("UnorderedSetOfIpAddressWpGgzO6M"); + +export const NodeRemoveFromBootstrapBlacklist = t.func("AlwaysFalse", t.param("ip", "UnorderedSetOfStringBBdNk2Kup3WUWKiM")); + +export const NodeRemoveFromBootstrapWhitelist = t.func("AlwaysFalse", t.param("ip", "UnorderedSetOfStringBBdNk2Kup3WUWKiM")); + +export const NodeRemoveFromPeersWhitelist = t.func("AlwaysFalse", t.param("ip", "UnorderedSetOfStringBBdNk2Kup3WUWKiM")); + +export const NodeRemoveFromWhitelist = t.func("AlwaysFalse", t.param("ip", "UnorderedSetOfStringBBdNk2Kup3WUWKiM")); + +export const RemoveStakingAddresses = t.func("AlwaysFalse", t.param("addresses", "UnorderedSetOfAddressjJsnATCO")); + +export const NodeSignMessage = t.func("PubkeySig", t.param("message", "StringUJarsTOs")); + +export const StopNode = t.func("AlwaysFalse"); + +export const NodeUnbanById = t.func("AlwaysFalse", t.param("id", "UnorderedSetOfStringBBdNk2Kup3WUWKiM")); + +export const NodeUnbanByIp = t.func("AlwaysFalse", t.param("ip", "UnorderedSetOfStringBBdNk2Kup3WUWKiM")); + +export const NodeWhitelist = t.func("AlwaysFalse", t.param("ip", "UnorderedSetOfStringOGpKXaCP4RgV7KAw")); + +export const SendOperations = t.func("UnorderedSetOfOperationId5TxbV4NZ", t.param("OperationInput", "UnorderedSetOfOperationInput9XcIbRG1")); + +export const GetLargestStakers = t.func("PagedVecStaker", t.param("ApiRequest", "ApiRequest")); + +export const GetNextBlockBestParents = t.func("UnorderedSetOfBlockParentxrssVm84"); + +export const GetVersion = t.func("Version"); + +export const SubscribeNewBlocks = t.func("BlockInfo"); + +export const SubscribeNewBlocksHeaders = t.func("WrappedHeader"); + +export const SubscribeNewFilledBlocks = t.func("FilledBlockInfo"); + +export const SubscribeNewOperations = t.func("Operation"); + +export const UnsubscribeNewBlocks = t.func("BooleanVyG3AETh", t.param("subscriptionId", "Integer2AHOqbcQ")); + +export const UnsubscribeNewBlocksHeaders = t.func("BooleanVyG3AETh", t.param("subscriptionId", "Integer2AHOqbcQ")); + +export const UnsubscribeNewFilledBlocks = t.func("BooleanVyG3AETh", t.param("subscriptionId", "Integer2AHOqbcQ")); + +export const UnsubscribeNewOperations = t.func("BooleanVyG3AETh", t.param("subscriptionId", "Integer2AHOqbcQ")); + +const exportedTypeSuite: t.ITypeSuite = { + NumberPsns2WbD, + Integer2AHOqbcQ, + UnorderedSetOfInteger2AHOqbcQjNvs9B0Z, + Address, + UnorderedSetOfInteger2AHOqbcQtXvTMhya, + BooleanHNwwo80P, + NumberZ1JdLCIz, + NumberSnYk3VhE, + ReadOnlyBytecodeExecution, + StringYvGZTlwQ, + StringBtBJC5Iw, + UnorderedSetOfInteger2AHOqbcQzYHdsLoW, + NullQu0Arl1F, + StringDoaGddGA, + OneOfNullQu0Arl1FStringDoaGddGAHzYKhN99, + OneOfNullQu0Arl1FStringDoaGddGAEUSQB1KK, + OneOfNullQu0Arl1FStringDoaGddGANOhzhrxe, + ReadOnlyCall, + Boolean7Xei3MDX, + AddressFilter, + BlockId, + NumberHo1ClIqD, + UnorderedSetOfInteger2AHOqbcQBha3UJIJ, + DatastoreEntryInput, + Slot, + String5J7NQ8B1, + StringCc6XlKeq, + StringUcQL9QGN, + BooleanObf9WMA0, + BooleanAXlyTrPe, + PrivateKey, + StringBBdNk2Ku, + StringOGpKXaCP, + PublicKey, + Signature, + UnorderedSetOfInteger2AHOqbcQarZIQlOy, + OperationInput, + Pagination, + ExecuteAt, + StringUJarsTOs, + UnorderedSetOfStringUJarsTOsgviiNMvH, + StringOz2F8Z2Y, + ReadOnlyResult, + StringBt9L6T1F, + BooleanQYH7IQYB, + UnorderedSetOfAddressqhKJr2Tw, + NumberHGt16B6Y, + OperationId, + BooleanSPcYqJj2, + BooleanIqtEc7R0, + EventExecutionContext, + SCOutputEvent, + UnorderedSetOfSCOutputEventHwhiOmzE, + NumberAIaYfWME, + ObjectD93Z4FAG, + ObjectHAgrRKSz, + UnorderedSetOfObjectHAgrRKSz46QV1Tyv, + ObjectYWuwfL0B, + ObjectTK16EAH4, + Object413CQ8L2, + StringIytPJwYq, + StateChanges, + ExecuteReadOnlyResponse, + NumberSYJcvZVm, + StringFFlpWNJb, + NumberPAAsFK4N, + UnorderedSetOfNumberHo1ClIqDAokMKuEf, + UnorderedSetOfUnorderedSetOfNumberHo1ClIqDAokMKuEfIixaMtvV, + StringSZbUM3UB, + NumberUycrgn8X, + UnorderedSetOfUnorderedSetOfNumberHo1ClIqDAokMKuEfmvpf11Qe, + ObjectOfSlotStringDoaGddGAQZyvCcRS, + UnorderedSetOfObjectOfSlotStringDoaGddGAQZyvCcRS732D8Bc5, + UnorderedSetOfSlotpnXhUhWs, + ObjectOfSlotNumberHo1ClIqDMPMjgxrm, + UnorderedSetOfObjectOfSlotNumberHo1ClIqDMPMjgxrm06Ae306Q, + UnorderedSetOfBlockIdpdDCfi0P, + UnorderedSetOfOperationId971EzIER, + EndorsementId, + UnorderedSetOfEndorsementIdNN27ZC1J, + BooleanVyG3AETh, + OneOfNullQu0Arl1FNumberHo1ClIqDKWtQwzS8, + ExecutionAddressCycleInfo, + UnorderedSetOfExecutionAddressCycleInfo8D3STgcL, + AddressInfo, + BooleanZxUVUy6M, + BooleanMazVJcyf, + BooleanHJvzO9WE, + BooleanHjqkwJfo, + NumberTbrodUsH, + OneOfNullQu0Arl1FNumberHo1ClIqD4U4GpKJM, + UnorderedSetOfStringDoaGddGADvj0XlFa, + EndorsementContent, + ObjectOfStringDoaGddGAEndorsementIdPublicKeyAddressEndorsementContentWrpyYBUS, + UnorderedSetOfObjectOfStringDoaGddGAEndorsementIdPublicKeyAddressEndorsementContentWrpyYBUSwrpyYBUS, + ObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUS, + ObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUS, + OneOfObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUSObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUSGJLAASWC, + UnorderedSetOfOneOfObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAInteger2AHOqbcQStringDoaGddGAStringDoaGddGAWrpyYBUSObjectOfInteger2AHOqbcQStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAStringDoaGddGAWrpyYBUSGJLAASWCwrpyYBUS, + Header, + WrappedHeader, + UnorderedSetOfStringDoaGddGAucaTsQyS, + Block, + BlockInfoContent, + BlockInfo, + UnorderedSetOfBlockId1V6I15AQ, + Number7BVjpZ2Z, + BooleanXIboFXzF, + Clique, + OneOfNullQu0Arl1FUnorderedSetOfInteger2AHOqbcQarZIQlOy81SHPJsX, + OneOfNullQu0Arl1FUnorderedSetOfInteger2AHOqbcQarZIQlOyGOQJrRPK, + DatastoreEntryOutput, + StringYVTrFSaQ, + StringZyWeUFZ8, + IntegerCOVAu0Eq, + IntegerVC2Agt39, + Object0XCk2T5H, + BooleanYDqyb5Vp, + NumberV8R93Gu7, + StringUyVBK2CK, + Transfer, + UnorderedSetOfTransferQEyQHpyL, + UnorderedSetOfBlockId7G1Sy5Qv, + Endorsement, + EndorsementInfo, + StringVuVvWRdT, + StringU8LlHDu1, + UnorderedSetOfStringDoaGddGAMZnHm9WS, + GraphInterval, + StringYTemzr68, + UnorderedSetOfBlockIdyEy9Dvpn, + BooleanSJ3TNusg, + OneOfBooleanVyG3AEThNullQu0Arl1FCuqCzoUJ, + NumberZoWtBk8U, + StringV3754ZDT, + NumberSbfeGjn7, + StringNIrlyE1J, + Transaction, + UnorderedSetOfNumberHo1ClIqDd5W02PgX, + NumberQUXtpAPK, + ObjectOfUnorderedSetOfInteger2AHOqbcQarZIQlOyUnorderedSetOfInteger2AHOqbcQarZIQlOyDbxIogvI, + Datastore, + ExecuteSC, + String7HCIMJir, + StringSjIor0MV, + Number5Mo1HId6, + CallSC, + NumberJdJmnq9D, + RollBuy, + RollSell, + OperationType, + Operation, + WrappedOperation, + OneOfBooleanVyG3AEThNullQu0Arl1FE3Qax0Os, + OperationInfo, + ObjectOfAddressNumberHo1ClIqDFbgdJFtJ, + Staker, + Number2A9FvvYh, + OneOfNullQu0Arl1FNumberHo1ClIqDXysINzQy, + NumberSgfzurLm, + NumberUwkWWxaa, + NumberTs6Cn6JQ, + NumberGrsxxfaH, + Number8ImKBhpQ, + NumberAxwlzLso, + Config, + ObjectOfStringDoaGddGAStringDoaGddGAXJdFCZe6, + ConnectedNodes, + NumberLpoULYcx, + ConsensusStats, + NumberSWFW9I8Z, + NumberYQZ1VVuw, + NumberQuWRP8Oa, + NumberSDEXjSo6, + NumberWc2YJi2H, + NumberZdt4Udf4, + NumberLgEVA2Rp, + NumberNw53IytE, + NumberXuleKeT9, + NetworkStats, + StringOFgZzVe7, + OneOfNullQu0Arl1FStringDoaGddGANsst9HIR, + PoolStats, + Version, + NumberDk8ZmyGi, + NumberWbCeho3I, + NumberGCfSuERd, + NumberJ4Dz6P30, + ExecutionStats, + NumberBte4OVdF, + StringTXHumHoA, + AlwaysFalse, + IpAddress, + StringTPMT1Yxd, + StringXHbmHEWh, + UnorderedSetOfStakerX7P278VS, + ObjectOfNumberHo1ClIqDBlockIdHCnqqlza, + BlockParent, + Boolean4XbLtRCK, + UnorderedSetOfOperationInfowrpyYBUS, + FilledBlock, + FilledBlockInfoContent, + UnorderedSetOfReadOnlyBytecodeExecutionK4Ht8Zdn, + UnorderedSetOfReadOnlyCallm6DMxyzd, + UnorderedSetOfAddressjJsnATCO, + UnorderedSetOfAddressFilteraFrapw7X, + UnorderedSetOfBlockIdZXK9XY8A, + UnorderedSetOfDatastoreEntryInputBdlngHsZ, + UnorderedSetOfSlotn0BdrHhh, + EventFilter, + ObjectOfNumberHo1ClIqDNumberHo1ClIqDTmeT75Fq, + UnorderedSetOfPrivateKeyG69QLiLP, + UnorderedSetOfStringBBdNk2Kup3WUWKiM, + UnorderedSetOfStringOGpKXaCP4RgV7KAw, + UnorderedSetOfOperationInput9XcIbRG1, + ApiRequest, + UnorderedSetOfExecuteReadOnlyResponsewrpyYBUS, + UnorderedSetOfAddressInfoCm3Tm6FQ, + UnorderedSetOfStringUJarsTOsGY6FcFnU, + UnorderedSetOfBlockInfowrpyYBUS, + UnorderedSetOfCliqueeS9LyMHx, + UnorderedSetOfDatastoreEntryOutputhcgFMMvn, + UnorderedSetOfUnorderedSetOfTransferQEyQHpyLoFgVJgXU, + UnorderedSetOfEndorsementInfowrpyYBUS, + UnorderedSetOfGraphIntervalwrpyYBUS, + UnorderedSetOfOperationInfoMdPofISE, + NodeStatus, + UnorderedSetOfIpAddressWpGgzO6M, + PubkeySig, + UnorderedSetOfOperationId5TxbV4NZ, + PagedVecStaker, + UnorderedSetOfBlockParentxrssVm84, + FilledBlockInfo, + AnyOfUnorderedSetOfReadOnlyBytecodeExecutionK4Ht8ZdnUnorderedSetOfReadOnlyCallm6DMxyzdUnorderedSetOfAddressjJsnATCOUnorderedSetOfAddressFilteraFrapw7XUnorderedSetOfBlockIdZXK9XY8ASlotUnorderedSetOfDatastoreEntryInputBdlngHsZUnorderedSetOfSlotn0BdrHhhUnorderedSetOfStringDoaGddGADvj0XlFaEventFilterObjectOfNumberHo1ClIqDNumberHo1ClIqDTmeT75FqUnorderedSetOfStringDoaGddGADvj0XlFaPaginationUnorderedSetOfPrivateKeyG69QLiLPUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringDoaGddGADvj0XlFaUnorderedSetOfStringDoaGddGADvj0XlFaUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfAddressjJsnATCOStringUJarsTOsUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringBBdNk2Kup3WUWKiMUnorderedSetOfStringOGpKXaCP4RgV7KAwUnorderedSetOfOperationInput9XcIbRG1ApiRequestInteger2AHOqbcQInteger2AHOqbcQInteger2AHOqbcQInteger2AHOqbcQUnorderedSetOfExecuteReadOnlyResponsewrpyYBUSUnorderedSetOfExecuteReadOnlyResponsewrpyYBUSUnorderedSetOfAddressInfoCm3Tm6FQUnorderedSetOfStringUJarsTOsGY6FcFnUUnorderedSetOfBlockInfowrpyYBUSBlockUnorderedSetOfCliqueeS9LyMHxUnorderedSetOfDatastoreEntryOutputhcgFMMvnUnorderedSetOfUnorderedSetOfTransferQEyQHpyLoFgVJgXUUnorderedSetOfEndorsementInfowrpyYBUSUnorderedSetOfSCOutputEventHwhiOmzEUnorderedSetOfGraphIntervalwrpyYBUSUnorderedSetOfOperationInfoMdPofISEUnorderedSetOfStakerX7P278VSNodeStatusAlwaysFalseUnorderedSetOfAddressjJsnATCOAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseUnorderedSetOfIpAddressWpGgzO6MUnorderedSetOfIpAddressWpGgzO6MAlwaysFalseUnorderedSetOfIpAddressWpGgzO6MAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalsePubkeySigAlwaysFalseAlwaysFalseAlwaysFalseAlwaysFalseUnorderedSetOfOperationId5TxbV4NZPagedVecStakerUnorderedSetOfBlockParentxrssVm84VersionBlockInfoWrappedHeaderFilledBlockInfoOperationBooleanVyG3AEThBooleanVyG3AEThBooleanVyG3AEThBooleanVyG3AETh, + ExecuteReadOnlyBytecode, + ExecuteReadOnlyCall, + GetAddresses, + GetAddressesBytecode, + GetBlocks, + GetBlockcliqueBlockBySlot, + GetCliques, + GetDatastoreEntries, + GetSlotsTransfers, + GetEndorsements, + GetFilteredScOutputEvent, + GetGraphInterval, + GetOperations, + GetStakers, + GetStatus, + AddStakingSecretKeys, + GetStakingAddresses, + NodeAddToBootstrapBlacklist, + NodeAddToBootstrapWhitelist, + NodeAddToPeersWhitelist, + NodeBanById, + NodeBanByIp, + NodeBootstrapBlacklist, + NodeBootstrapWhitelist, + NodeBootstrapWhitelistAllowAll, + NodePeersWhitelist, + NodeRemoveFromBootstrapBlacklist, + NodeRemoveFromBootstrapWhitelist, + NodeRemoveFromPeersWhitelist, + NodeRemoveFromWhitelist, + RemoveStakingAddresses, + NodeSignMessage, + StopNode, + NodeUnbanById, + NodeUnbanByIp, + NodeWhitelist, + SendOperations, + GetLargestStakers, + GetNextBlockBestParents, + GetVersion, + SubscribeNewBlocks, + SubscribeNewBlocksHeaders, + SubscribeNewFilledBlocks, + SubscribeNewOperations, + UnsubscribeNewBlocks, + UnsubscribeNewBlocksHeaders, + UnsubscribeNewFilledBlocks, + UnsubscribeNewOperations, +}; +export default exportedTypeSuite; diff --git a/test/integration/MRC20.spec.ts b/test/integration/MRC20.spec.ts new file mode 100644 index 00000000..8ce2e238 --- /dev/null +++ b/test/integration/MRC20.spec.ts @@ -0,0 +1,83 @@ +import { MRC20 } from '../../src/contracts-wrappers' +import { provider } from './setup' + +describe('Generic token wrapper tests', () => { + let usdcContract: MRC20 + const USDC = 'AS12k8viVmqPtRuXzCm6rKXjLgpQWqbuMjc37YHhB452KSUUb9FgL' + + beforeAll(async () => { + usdcContract = new MRC20(provider, USDC) + }) + + test('version', async () => { + const version = await usdcContract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await usdcContract.name() + expect(name).toBe('Sepolia USDC') + }) + + test('symbol', async () => { + const symbol = await usdcContract.symbol() + expect(symbol).toBe('USDC.s') + }) + + test('decimals', async () => { + const decimals = await usdcContract.decimals() + expect(decimals).toBe(6) + }) + + test('totalSupply', async () => { + const totalSupply = await usdcContract.totalSupply() + expect(totalSupply).toBeGreaterThan(0n) + }) + + test('transfer', async () => { + const amount = 1_000n + const balance = await usdcContract.balanceOf(provider.address) + + const operation = await usdcContract.transfer( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53', + amount + ) + await operation.waitSpeculativeExecution() + + const newBalance = await usdcContract.balanceOf(provider.address) + expect(newBalance).toBe(balance - amount) + }) + + test('allowance', async () => { + const previousAllowance = await usdcContract.allowance( + provider.address, + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ) + + const amount = 123_000_000n + let operation = await usdcContract.increaseAllowance( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53', + amount + ) + await operation.waitSpeculativeExecution() + + let newAllowance = await usdcContract.allowance( + provider.address, + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ) + + expect(newAllowance).toBe(previousAllowance + amount) + + operation = await usdcContract.decreaseAllowance( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53', + amount + ) + await operation.waitSpeculativeExecution() + + newAllowance = await usdcContract.allowance( + provider.address, + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ) + expect(newAllowance).toBe(previousAllowance) + }) +}) diff --git a/test/integration/accountOperation.spec.ts b/test/integration/accountOperation.spec.ts new file mode 100644 index 00000000..961ad8d3 --- /dev/null +++ b/test/integration/accountOperation.spec.ts @@ -0,0 +1,24 @@ +import { OperationStatus } from '../../src/operation' +import { provider } from './setup' + +describe('AccountOperation tests', () => { + test('transfer', async () => { + const op = await provider.transfer( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53', + 1n + ) + expect(await op.getStatus()).toBe(OperationStatus.NotFound) + }) + + test('not enough fee', async () => { + expect( + provider.transfer( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53', + 1n, + { fee: 1n } + ) + ).rejects.toThrow( + 'Bad request: fee is too low provided: 0.000000001 , minimal_fees required: 0.01' + ) + }) +}) diff --git a/test/integration/contracts/scTest.ts b/test/integration/contracts/scTest.ts new file mode 100644 index 00000000..e8a510ce --- /dev/null +++ b/test/integration/contracts/scTest.ts @@ -0,0 +1,57 @@ +// The entry file of your WebAssembly module. +import { Context, Storage, generateEvent } from '@massalabs/massa-as-sdk' +import { Args, stringToBytes } from '@massalabs/as-types' + +/** + * This function is meant to be called only one time: when the contract is deployed. + * + * @param binaryArgs - Arguments serialized with Args + */ +export function constructor(binaryArgs: StaticArray): StaticArray { + // This line is important. It ensures that this function can't be called in the future. + // If you remove this check, someone could call your constructor function and reset your smart contract. + if (!Context.isDeployingContract()) { + return [] + } + + const argsDeser = new Args(binaryArgs) + const name = argsDeser + .nextString() + .expect('Name argument is missing or invalid') + generateEvent(`Constructor called with name ${name}`) + return [] +} + +/** + * @param _ - not used + * @returns the emitted event serialized in bytes + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function event(_: StaticArray): StaticArray { + const message = "I'm an event!" + generateEvent(message) + return stringToBytes(message) +} + +export function setValueToKey(_args: StaticArray): void { + const args = new Args(_args) + const key = args.nextString().expect('Key argument is missing or invalid') + const value = args.nextString().expect('Value argument is missing or invalid') + + // event the value + Storage.set(key, value) + + generateEvent(`Set value ${value.toString()} to key ${key.toString()}`) +} + +export function getValueFromKey(_args: StaticArray): StaticArray { + const args = new Args(_args) + const key = args.nextString().expect('Key argument is missing or invalid') + const value = Storage.get(key) + return stringToBytes(value) +} +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function sendCoins(_: StaticArray): void { + const coinAmount = Context.transferredCoins() + generateEvent(`Received ${coinAmount.toString()} coins`) +} diff --git a/test/integration/contracts/scTest.wasm b/test/integration/contracts/scTest.wasm new file mode 100644 index 00000000..341d970d Binary files /dev/null and b/test/integration/contracts/scTest.wasm differ diff --git a/test/integration/events.spec.ts b/test/integration/events.spec.ts new file mode 100644 index 00000000..6a963147 --- /dev/null +++ b/test/integration/events.spec.ts @@ -0,0 +1,96 @@ +import { EventFilter, EventPoller, SCEvent } from '../../src' +import { MRC20 } from '../../src/contracts-wrappers' +import { provider } from './setup' +import waitForExpect from 'wait-for-expect' + +const USDC = 'AS12k8viVmqPtRuXzCm6rKXjLgpQWqbuMjc37YHhB452KSUUb9FgL' + +let usdcContract: MRC20 + +describe('SC Event tests', () => { + beforeAll(async () => { + usdcContract = new MRC20(provider, USDC) + }) + + test('poll transfer event from caller and contract addr', async () => { + const amount = 1_000n + const currentSlot = await provider.client.getCurrentSlot() + const operation = await usdcContract.transfer( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53', + amount + ) + await operation.waitSpeculativeExecution() + + let events: SCEvent[] = [] + + const filter = { + smartContractAddress: USDC, + callerAddress: provider.address, + start: currentSlot, + } + + const { stopPolling } = EventPoller.start(provider, filter, (data) => { + events = data + }) + + await waitForExpect(() => { + expect(events.length).toEqual(1) + expect(events[0].data).toEqual('TRANSFER SUCCESS') + }) + stopPolling() + }) + + test('poll transfer event from operationId', async () => { + const amount = 1_000n + const { lastSlot: currentSlot } = await provider.getNodeStatus() + + const operation = await usdcContract.transfer( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53', + amount + ) + await operation.waitSpeculativeExecution() + + let events: SCEvent[] = [] + + const filter: EventFilter = { + operationId: operation.id, + start: currentSlot, + } + + const { stopPolling } = EventPoller.start(provider, filter, (data) => { + events = data + }) + + await waitForExpect(() => { + expect(events.length).toEqual(1) + expect(events[0].data).toEqual('TRANSFER SUCCESS') + }) + stopPolling() + }) + + test('poll transfer event without start slot', async () => { + const amount = 1_000n + + const operation = await usdcContract.transfer( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53', + amount + ) + await operation.waitSpeculativeExecution() + + let events: SCEvent[] = [] + + const filter: EventFilter = { + operationId: operation.id, + } + + const { stopPolling } = EventPoller.start(provider, filter, (data) => { + events = data + }) + + await waitForExpect(() => { + expect(events.length).toEqual(1) + expect(events[0].data).toEqual('TRANSFER SUCCESS') + }) + stopPolling() + }) +}) diff --git a/test/integration/mns.spec.ts b/test/integration/mns.spec.ts new file mode 100644 index 00000000..ce92d8cf --- /dev/null +++ b/test/integration/mns.spec.ts @@ -0,0 +1,52 @@ +import { MNS } from '../../src' +import { provider } from './setup' + +describe('MNS tests', () => { + let mns: MNS + + // The syntra MNS ownership has been renounced, so the associated contract will not change. + const syntraContract = 'AS1hyi3cyBocobFtFZHhTs84mTLhThDK4KvCkj6bijbtHEi3d8Vv' + + beforeAll(async () => { + mns = MNS.buildnet(provider) + }) + + test('resolve', async () => { + const res = await mns.resolve('syntra') + expect(res).toBe(syntraContract) + }) + + test('from address', async () => { + const res = await mns.fromAddress(syntraContract) + expect(res).toEqual(['syntra']) + }) + + test('alloc, update target and free', async () => { + const domain = 'trloloooooooooooooooololololzss' + let operation = await mns.alloc(domain, provider.address, { + coins: 1049000000n, + }) + await operation.waitFinalExecution() + + // check resolution + let res = await mns.resolve(domain) + expect(res).toBe(provider.address) + + // update target + const newTarget = 'bonjour' + operation = await mns.updateTarget(domain, newTarget) + await operation.waitFinalExecution() + + // check new resolution + res = await mns.resolve(domain) + expect(res).toBe(newTarget) + + // free domain + operation = await mns.free(domain) + await operation.waitFinalExecution() + + // check domain has been freed + res = await mns.resolve(domain) + expect(res).toBe('') + }, 300000) +}) diff --git a/test/integration/provider.spec.ts b/test/integration/provider.spec.ts new file mode 100644 index 00000000..89e4146e --- /dev/null +++ b/test/integration/provider.spec.ts @@ -0,0 +1,35 @@ +import { CHAIN_ID, NetworkName } from '../../src' +import { provider } from './setup' + +describe('Provider tests', () => { + test('networkInfos', async () => { + const infos = await provider.networkInfos() + expect(infos).toEqual({ + name: NetworkName.Buildnet, + minimalFee: 10000000n, + chainId: CHAIN_ID.Buildnet, + url: 'https://buildnet.massa.net/api/v2', + }) + }) + + test('Node Status', async () => { + const status = await provider.getNodeStatus() + expect(status.config).toBeDefined() + expect(status.connectedNodes).toBeDefined() + expect(status.consensusStats).toBeDefined() + expect(status.currentCycle).toBeDefined() + expect(status.currentTime).toBeDefined() + expect(status.currentCycleTime).toBeDefined() + expect(status.nextCycleTime).toBeDefined() + expect(status.lastSlot).toBeDefined() + expect(status.nextSlot).toBeDefined() + expect(status.networkStats).toBeDefined() + expect(status.nodeId).toBeDefined() + expect(status.nodeIp).toBeDefined() + expect(status.poolStats).toBeDefined() + expect(status.version).toBeDefined() + expect(status.executionStats).toBeDefined() + expect(status.chainId).toBeDefined() + expect(status.minimalFees).toBeDefined() + }) +}) diff --git a/test/integration/publicAPI.spec.ts b/test/integration/publicAPI.spec.ts new file mode 100644 index 00000000..3679014a --- /dev/null +++ b/test/integration/publicAPI.spec.ts @@ -0,0 +1,271 @@ +import { + AddressFilter, + ReadOnlyBytecodeExecution, + ReadOnlyCall, + Slot, +} from '../../src/generated/client-types' +import { createCheckers } from 'ts-interface-checker' +import validator from '../generated/client-types-ti' +import { EventFilter, PublicAPI } from '../../src/client' +import { MAX_GAS_CALL } from '../../src/smartContracts' +import { bytesToStr, strToBytes } from '../../src/basicElements' +import { provider } from './setup' + +const { + NodeStatus, + AddressInfo, + EndorsementInfo, + Clique, + GraphInterval, + Staker, + Block, + BlockInfo, + OperationInfo, + SCOutputEvent, + ExecuteReadOnlyResponse, +} = createCheckers(validator) + +let lastSlot: Slot = { period: 0, thread: 0 } +let someEndorsement: string[] +let someBlockIds: string[] +let operationId: string + +const TEST_USER = 'AU12dG5xP1RDEB5ocdHkymNVvvSJmUL9BgHwCksDowqmGWxfpm93x' +// Hello contract from toolkit +const NAME_KEY = 'name_key' +const NAME_VAL = 'Massa' +const TEST_CONTRACT = 'AS12N5DvTVwvaLbaniMgDJqKwJ3uXBGwzzGuB1f6fjeSx3nhhahTE' + +let client: PublicAPI +beforeAll(() => { + client = provider.client +}) + +describe('client tests', () => { + test('getStatus', async () => { + const status = await client.status() + lastSlot.period = status.last_slot.period + lastSlot.thread = status.last_slot.thread + NodeStatus.check(status) + }) + + test('getAddressInfo', async () => { + const info = await client.getAddressInfo( + 'AU1Fp7uBP2TXxDty2HdTE3ZE3XQ4cNXnG3xuo8TkQLJtyxC7FKhx' + ) + AddressInfo.strictCheck(info) + }) + + test('getCliques', async () => { + const cliques = await client.getCliques() + someBlockIds = cliques[0].block_ids + cliques.forEach((c) => Clique.strictCheck(c)) + }) + + test('getGraphInterval', async () => { + const now = Date.now() + const interval = await client.getGraphInterval(now - 2000, now) + interval.forEach((i) => GraphInterval.strictCheck(i)) + }) + + test('getStakers', async () => { + const stakers = await client.getStakers({ limit: 5, offset: 0 }) + stakers.forEach((s) => Staker.strictCheck(s)) + expect(stakers.length).toBeGreaterThan(0) + }) + + test('getBlockcliqueBlock', async () => { + const block = await client.getBlockcliqueBlock(lastSlot) + if (block.header.content.endorsements) { + someEndorsement = block.header.content.endorsements.map((e) => e.id!) + } + Block.strictCheck(block) + }) + + test('getBlock', async () => { + const block = await client.getBlock(someBlockIds[0]) + BlockInfo.strictCheck(block) + expect(block).toHaveProperty('content.block.header.content.endorsements') + }) + + test('getMultipleBlocks', async () => { + const blocks = await client.getMultipleBlocks(someBlockIds.slice(0, 2)) + BlockInfo.strictCheck(blocks[0]) + }) + + test('getEndorsement', async () => { + const endorsement = await client.getEndorsement(someEndorsement[0]!) + EndorsementInfo.strictCheck(endorsement) + }) + + test('getMultipleEndorsements', async () => { + const endorsements = await client.getMultipleEndorsements([ + someEndorsement[1]!, + someEndorsement[2]!, + ]) + endorsements.forEach((e) => EndorsementInfo.strictCheck(e)) + }) + + test('getDataStoreKeys', async () => { + const keys = await client.getDataStoreKeys(TEST_CONTRACT) + expect(keys).toHaveLength(1) + expect(bytesToStr(keys[0])).toBe(NAME_KEY) + }) + + test('getDataStoreKeys with filter', async () => { + const keys = await client.getDataStoreKeys( + TEST_CONTRACT, + strToBytes(NAME_KEY) + ) + expect(keys).toHaveLength(1) + expect(bytesToStr(keys[0])).toBe(NAME_KEY) + }) + + test('getDatastoreEntry', async () => { + const entry = await client.getDatastoreEntry(NAME_KEY, TEST_CONTRACT) + expect(bytesToStr(entry)).toBe(NAME_VAL) + }) + + test('getDatastoreEntry speculative', async () => { + const entry = await client.getDatastoreEntry(NAME_KEY, TEST_CONTRACT, false) + expect(bytesToStr(entry)).toBe(NAME_VAL) + }) + + test('getDatastoreEntries', async () => { + const entries = await client.getDatastoreEntries([ + { + address: TEST_CONTRACT, + key: strToBytes(NAME_KEY), + }, + ]) + + expect(entries).toHaveLength(1) + expect(bytesToStr(entries[0])).toBe(NAME_VAL) + }) + + test.skip('sendOperations', async () => { + const operations = await client.sendMultipleOperations([ + { + creator_public_key: + 'P12QDzMvr1SNNwJWmdpA9XQY9PqCDqdLaqiQDFZKQh8dPGSxagTh', + signature: + '1JhEaikbcebpJKPd7q6VsA2iWcnuL1iho6vcbpAsJJkp5SjFo7nD8xCJwxTXh7oiKH3bQ95DH7DK1kNzu5Xw5somQxbeiA', + serialized_content: [ + 128, 173, 226, 4, 160, 194, 30, 0, 0, 0, 159, 203, 100, 23, 219, 54, + 253, 245, 197, 164, 216, 135, 68, 99, 245, 229, 167, 22, 210, 46, 194, + 89, 114, 243, 208, 0, 237, 205, 111, 189, 24, 65, 0, + ], + }, + ]) + expect(operations).toHaveLength(1) + operationId = operations[0] + }) + + test.skip('sendOperation', async () => { + const operation = await client.sendOperation({ + publicKey: 'P12QDzMvr1SNNwJWmdpA9XQY9PqCDqdLaqiQDFZKQh8dPGSxagTh', + signature: + '1JhEaikbcebpJKPd7q6VsA2iWcnuL1iho6vcbpAsJJkp5SjFo7nD8xCJwxTXh7oiKH3bQ95DH7DK1kNzu5Xw5somQxbeiA', + data: Uint8Array.from([ + 128, 173, 226, 4, 160, 194, 30, 0, 0, 0, 159, 203, 100, 23, 219, 54, + 253, 245, 197, 164, 216, 135, 68, 99, 245, 229, 167, 22, 210, 46, 194, + 89, 114, 243, 208, 0, 237, 205, 111, 189, 24, 65, 0, + ]), + }) + expect(operation.length > 0) + }) + + test.skip('getOperation', async () => { + const operation = await client.getOperation(operationId) + OperationInfo.strictCheck(operation) + }) + + test.skip('getMultipleOperations', async () => { + const operations = await client.getOperations([operationId, operationId]) + expect(operations).toHaveLength(2) + }) + + test('getMultipleAddressInfo', async () => { + const info = await client.getMultipleAddressInfo([TEST_CONTRACT]) + expect(info).toHaveLength(1) + AddressInfo.strictCheck(info[0]) + }) + + test.skip('getEvents', async () => { + const event = await client.getEvents({ + smartTEST_CONTRACT: TEST_CONTRACT, + } as EventFilter) + expect(event.length > 1).toBeTruthy() + SCOutputEvent.strictCheck(event[0]) + }) + + test('executeReadOnlyBytecode', async () => { + const response = await client.executeReadOnlyBytecode({ + max_gas: 100000, + bytecode: [65, 66], + address: TEST_USER, + }) + ExecuteReadOnlyResponse.strictCheck(response) + }) + + test('executeMultipleReadOnlyBytecode', async () => { + const req = { + max_gas: 100000, + bytecode: [65, 66], + address: TEST_USER, + } as ReadOnlyBytecodeExecution + const responses = await client.executeMultipleReadOnlyBytecode([req, req]) + expect(responses).toHaveLength(2) + }) + + test.skip('getAddressesBytecode', async () => { + const bytecode = await client.getAddressesBytecode({ + address: TEST_CONTRACT, + is_final: true, + } as AddressFilter) + expect(bytecode.length > 1).toBeTruthy() + }) + + test.skip('executeMultipleGetAddressesBytecode', async () => { + const req = { + address: TEST_CONTRACT, + is_final: true, + } as AddressFilter + const bytecodes = await client.executeMultipleGetAddressesBytecode([ + req, + req, + ]) + expect(bytecodes).toHaveLength(2) + }) + + test('executeReadOnlyCall', async () => { + let arg = { + func: 'hello', + caller: TEST_USER, + target: TEST_CONTRACT, + maxGas: MAX_GAS_CALL, + parameter: new Uint8Array(), + } + + const response = await client.executeReadOnlyCall(arg) + expect(response).toHaveProperty('value') + + expect(bytesToStr(response.value)).toBe(`Hello, ${NAME_VAL}!`) + }) + + test('executeMultipleReadOnlyCall', async () => { + let arg = { + max_gas: 1000000, + target_address: TEST_USER, + target_function: 'hello', + parameter: [], + caller_address: null, + coins: null, + fee: null, + } as ReadOnlyCall + const responses = await client.executeMultipleReadOnlyCall([arg, arg]) + expect(responses).toHaveLength(2) + ExecuteReadOnlyResponse.strictCheck(responses[0]) + ExecuteReadOnlyResponse.strictCheck(responses[1]) + }) +}) diff --git a/test/integration/setup.ts b/test/integration/setup.ts new file mode 100644 index 00000000..6d1d4630 --- /dev/null +++ b/test/integration/setup.ts @@ -0,0 +1,24 @@ +import 'dotenv/config' +import { Account } from '../../src/account' +import { Mas } from '../../src/basicElements' +import { Web3Provider } from '../../src/provider' + +export let account: Account +export let provider: Web3Provider +export let mainnetProvider: Web3Provider + +jest.setTimeout(120_000) + +beforeAll(async () => { + account = await Account.fromEnv() + provider = Web3Provider.buildnet(account) + mainnetProvider = Web3Provider.mainnet(account) + + // eslint-disable-next-line no-console + console.log( + 'Using account:', + provider.address, + 'with balance:', + Mas.toString(await provider.balance()) + ) +}) diff --git a/test/integration/smartContract.spec.ts b/test/integration/smartContract.spec.ts new file mode 100644 index 00000000..cd7f2815 --- /dev/null +++ b/test/integration/smartContract.spec.ts @@ -0,0 +1,209 @@ +import path from 'path' +import fs from 'fs' +import { + DeploySCOptions, + MAX_GAS_CALL, + MAX_GAS_DEPLOYMENT, + MIN_GAS_CALL, + SmartContract, +} from '../../src/smartContracts' +import { provider } from './setup' +import { Address, Args, bytesToStr, Mas } from '../../src/basicElements' + +import { execute } from '../../src/basicElements/bytecode' +import { Operation } from '../../src/operation' + +const INSUFFICIENT_MAX_GAS = MIN_GAS_CALL - 1n +const contractPath = path.join(__dirname, './contracts/scTest.wasm') + +describe('Smart Contract', () => { + describe('ByteCode', () => { + test('execute', async () => { + const byteCode = new Uint8Array([1, 2, 3, 4]) + const opts = { + periodToLive: 2, + coins: 3n, + maxGas: 4n, + } + + const opId = await execute( + provider.client, + provider.account.privateKey, + byteCode, + opts + ) + const operation = new Operation(provider, opId) + expect(await operation.getSpeculativeEvents()).toHaveLength(1) + }) + + test('not enough fee', async () => { + const byteCode = new Uint8Array([1, 2, 3, 4]) + const opts = { + fee: Mas.fromString('0.000000001'), + periodToLive: 2, + coins: 3n, + maxGas: 4n, + } + + await expect( + execute(provider.client, provider.account.privateKey, byteCode, opts) + ).rejects.toMatchObject({ + message: expect.stringMatching(/fee is too low/), + }) + }) + }) + + describe('SmartContract - Call ', () => { + let contractTest: SmartContract + + beforeAll(async () => { + const byteCode = fs.readFileSync(contractPath) + const constructorArgs = new Args().addString('myName') + + const deployOptions: DeploySCOptions = { + periodToLive: 2, + maxGas: MAX_GAS_DEPLOYMENT, + coins: Mas.fromString('0.0016'), + } + + contractTest = await SmartContract.deploy( + provider, + byteCode, + constructorArgs, + deployOptions + ) + + expect(Address.fromString(contractTest.address).isEOA).toBeFalsy() + }) + + test('minimal call', async () => { + const op = await contractTest.call('event') + const events = await op.getSpeculativeEvents() + const firstEvent = events[0].data + expect(firstEvent).toBe("I'm an event!") + }) + + test('call that set a value in the datastore', async () => { + const key = 'myKey' + const value = 'myValue' + const parameter = new Args().addString(key).addString(value).serialize() + + const op = await contractTest.call('setValueToKey', parameter, { + coins: Mas.fromString('0.0016'), + }) + + const events = await op.getSpeculativeEvents() + const firstEvent = events[0].data + expect(firstEvent).toBe(`Set value ${value} to key ${key}`) + }) + + test('call with send coins', async () => { + const coinAmount = Mas.fromString('1') + + const op = await contractTest.call('sendCoins', new Uint8Array(), { + coins: coinAmount, + }) + + const events = await op.getSpeculativeEvents() + const firstEvent = events[0].data + + expect(firstEvent).toBe(`Received ${coinAmount.toString()} coins`) + }) + + test('Attempt to call with maxGas value that is below the minimum required limit', async () => { + const call = contractTest.call('event', undefined, { + maxGas: INSUFFICIENT_MAX_GAS, + }) + + expect(call).rejects.toThrow( + `The gas limit for the operation was below the minimum amount of ${MIN_GAS_CALL}` + ) + }) + + test('Attempt to call with maxGas value that exceeds the maximum limit', async () => { + const call = contractTest.call('event', undefined, { + maxGas: MAX_GAS_CALL + 1n, + }) + + expect(call).rejects.toThrow( + `The gas limit for the operation was higher than the maximum amount of ${MAX_GAS_CALL}` + ) + }) + + test('Read only call', async () => { + const result = await contractTest.read( + 'getValueFromKey', + new Args().addString('myKey').serialize() + ) + + const value = bytesToStr(result.value) + + expect(value).toBe('myValue') + }) + + test('Read only call with not serialized args', async () => { + const result = await contractTest.read( + 'getValueFromKey', + new Args().addString('myKey') + ) + + const value = bytesToStr(result.value) + + expect(value).toBe('myValue') + }) + + test('Read only call with invalid function name', async () => { + const result = await contractTest.read('invalidFunction') + + expect(result.info.error).toContain('Missing export invalidFunction') + }) + + // Read with fee + test('Read only call with fee', async () => { + const result = await contractTest.read( + 'getValueFromKey', + new Args().addString('myKey').serialize(), + { + caller: provider.account.address.toString(), + } + ) + + const value = bytesToStr(result.value) + expect(value).toBe('myValue') + }) + + test('Read only call with fee and no callerAddress', async () => { + const result = await contractTest.read( + 'getValueFromKey', + new Args().addString('myKey').serialize() + ) + + const value = bytesToStr(result.value) + expect(value).toBe('myValue') + }) + + test('Read only call with coins', async () => { + const coinAmount = Mas.fromString('1') + const result = await contractTest.read('sendCoins', undefined, { + coins: coinAmount, + }) + + expect(result.info.events[0].data).toBe( + `Received ${coinAmount.toString()} coins` + ) + }) + + test('Read only call with maxGas', async () => { + const result = await contractTest.read( + 'getValueFromKey', + new Args().addString('myKey').serialize(), + { + maxGas: MAX_GAS_CALL, + } + ) + + const value = bytesToStr(result.value) + expect(value).toBe('myValue') + }) + }) +}) diff --git a/test/integration/tokens/DAIe.spec.ts b/test/integration/tokens/DAIe.spec.ts new file mode 100644 index 00000000..45cb6e5f --- /dev/null +++ b/test/integration/tokens/DAIe.spec.ts @@ -0,0 +1,29 @@ +import { DAIe } from '../../../src/contracts-wrappers' +import { mainnetProvider } from './../setup' + +describe('DAIe wrapper tests', () => { + let contract: DAIe + beforeAll(async () => { + contract = new DAIe(mainnetProvider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('Dai Stablecoin') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('DAI.e') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(18) + }) +}) diff --git a/test/integration/tokens/DAIs.spec.ts b/test/integration/tokens/DAIs.spec.ts new file mode 100644 index 00000000..f9c07784 --- /dev/null +++ b/test/integration/tokens/DAIs.spec.ts @@ -0,0 +1,29 @@ +import { DAIs } from '../../../src/contracts-wrappers' +import { provider } from './../setup' + +describe('DAIs wrapper tests', () => { + let contract: DAIs + beforeAll(async () => { + contract = new DAIs(provider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('Sepolia tDAI') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('tDAI.s') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(18) + }) +}) diff --git a/test/integration/tokens/PUR.spec.ts b/test/integration/tokens/PUR.spec.ts new file mode 100644 index 00000000..872bcab5 --- /dev/null +++ b/test/integration/tokens/PUR.spec.ts @@ -0,0 +1,29 @@ +import { PUR } from '../../../src/contracts-wrappers' +import { mainnetProvider } from './../setup' + +describe('PUR wrapper tests', () => { + let contract: PUR + beforeAll(async () => { + contract = new PUR(mainnetProvider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('Purrfect Universe') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('PUR') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(18) + }) +}) diff --git a/test/integration/tokens/USDCe.spec.ts b/test/integration/tokens/USDCe.spec.ts new file mode 100644 index 00000000..4b223b42 --- /dev/null +++ b/test/integration/tokens/USDCe.spec.ts @@ -0,0 +1,29 @@ +import { USDCe } from '../../../src/contracts-wrappers' +import { mainnetProvider } from './../setup' + +describe('USDCe wrapper tests', () => { + let contract: USDCe + beforeAll(async () => { + contract = new USDCe(mainnetProvider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('USD Coin') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('USDC.e') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(6) + }) +}) diff --git a/test/integration/tokens/USDCs.spec.ts b/test/integration/tokens/USDCs.spec.ts new file mode 100644 index 00000000..9b0370d9 --- /dev/null +++ b/test/integration/tokens/USDCs.spec.ts @@ -0,0 +1,29 @@ +import { USDCs } from '../../../src/contracts-wrappers' +import { provider } from './../setup' + +describe('USDCs wrapper tests', () => { + let contract: USDCs + beforeAll(async () => { + contract = new USDCs(provider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('Sepolia USDC') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('USDC.s') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(6) + }) +}) diff --git a/test/integration/tokens/USDTb.spec.ts b/test/integration/tokens/USDTb.spec.ts new file mode 100644 index 00000000..e61d022f --- /dev/null +++ b/test/integration/tokens/USDTb.spec.ts @@ -0,0 +1,29 @@ +import { USDTb } from '../../../src/contracts-wrappers' +import { mainnetProvider } from './../setup' + +describe('USDTb wrapper tests', () => { + let contract: USDTb + beforeAll(async () => { + contract = new USDTb(mainnetProvider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('Bsc USDT') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('USDT.b') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(18) + }) +}) diff --git a/test/integration/tokens/USDTbt.spec.ts b/test/integration/tokens/USDTbt.spec.ts new file mode 100644 index 00000000..0cb78a1c --- /dev/null +++ b/test/integration/tokens/USDTbt.spec.ts @@ -0,0 +1,29 @@ +import { USDTbt } from '../../../src/contracts-wrappers' +import { provider } from './../setup' + +describe('USDTbt wrapper tests', () => { + let contract: USDTbt + beforeAll(async () => { + contract = new USDTbt(provider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('Binance-peg USD') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('USDT.bt') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(18) + }) +}) diff --git a/test/integration/tokens/WETHb.spec.ts b/test/integration/tokens/WETHb.spec.ts new file mode 100644 index 00000000..6aeb8591 --- /dev/null +++ b/test/integration/tokens/WETHb.spec.ts @@ -0,0 +1,29 @@ +import { WETHb } from '../../../src/contracts-wrappers' +import { mainnetProvider } from './../setup' + +describe('WETH.b wrapper tests', () => { + let contract: WETHb + beforeAll(async () => { + contract = new WETHb(mainnetProvider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('Bsc ETH') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('WETH.b') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(18) + }) +}) diff --git a/test/integration/tokens/WETHbt.spec.ts b/test/integration/tokens/WETHbt.spec.ts new file mode 100644 index 00000000..b0095aad --- /dev/null +++ b/test/integration/tokens/WETHbt.spec.ts @@ -0,0 +1,29 @@ +import { WETHbt } from '../../../src/contracts-wrappers' +import { provider } from './../setup' + +describe('WETHbt wrapper tests', () => { + let contract: WETHbt + beforeAll(async () => { + contract = new WETHbt(provider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('bsc testnet WETH') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('WETH.bt') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(18) + }) +}) diff --git a/test/integration/tokens/WETHe.spec.ts b/test/integration/tokens/WETHe.spec.ts new file mode 100644 index 00000000..50c09602 --- /dev/null +++ b/test/integration/tokens/WETHe.spec.ts @@ -0,0 +1,29 @@ +import { WETHe } from '../../../src/contracts-wrappers' +import { mainnetProvider } from './../setup' + +describe('WETH.e wrapper tests', () => { + let contract: WETHe + beforeAll(async () => { + contract = new WETHe(mainnetProvider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('Wrapped Ether') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('WETH.e') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(18) + }) +}) diff --git a/test/integration/tokens/WETHs.spec.ts b/test/integration/tokens/WETHs.spec.ts new file mode 100644 index 00000000..07e0e86a --- /dev/null +++ b/test/integration/tokens/WETHs.spec.ts @@ -0,0 +1,29 @@ +import { WETHs } from '../../../src/contracts-wrappers' +import { provider } from './../setup' + +describe('WETHs wrapper tests', () => { + let contract: WETHs + beforeAll(async () => { + contract = new WETHs(provider) + }) + + test('version', async () => { + const version = await contract.version() + expect(version).toBe('0.0.1') + }) + + test('name', async () => { + const name = await contract.name() + expect(name).toBe('sepolia WETH') + }) + + test('symbol', async () => { + const symbol = await contract.symbol() + expect(symbol).toBe('WETH.s') + }) + + test('decimals', async () => { + const decimals = await contract.decimals() + expect(decimals).toBe(18) + }) +}) diff --git a/test/unit/account.spec.ts b/test/unit/account.spec.ts new file mode 100644 index 00000000..37b99179 --- /dev/null +++ b/test/unit/account.spec.ts @@ -0,0 +1,170 @@ +import { readFileSync } from 'fs' +import { load } from 'js-yaml' +import { Account, AccountKeyStore } from '../../src/account' +import { Version } from '../../src/crypto/interfaces/versioner' +import path from 'path' + +describe('Account tests', () => { + test('from private key', async () => { + const account = await Account.fromPrivateKey( + 'S12jWf59Yzf2LimL89soMnAP2VEBDBpfCbZLoEFo36CxEL3j92rZ' + ) + expect(account.address.toString()).toBe( + 'AU126tkwrhXn9gEG5JPtrNy8NNLbVMwywokgLKshSYyzP8qusqXZL' + ) + expect(account.publicKey.toString()).toBe( + 'P126AtzfcSJwdi6xsAmXbzXhhwVhS9d1hRjFNT4PfrDogt3nAihj' + ) + expect(account.version).toBe(Version.V1) + expect(account.address.version).toBe(Version.V0) + expect(account.address.isEOA).toBe(true) + + const ks = await account.toKeyStore( + 'unsecurePassword', + new Uint8Array([ + 146, 63, 151, 136, 93, 135, 105, 113, 124, 41, 189, 207, 86, 124, 17, + 152, + ]), + new Uint8Array([250, 104, 81, 250, 235, 79, 110, 84, 243, 225, 144, 242]) + ) + expect(ks.Version).toBe(Version.V1) + expect(ks.Address).toBe( + 'AU126tkwrhXn9gEG5JPtrNy8NNLbVMwywokgLKshSYyzP8qusqXZL' + ) + expect(ks.Nonce).toStrictEqual( + new Uint8Array([250, 104, 81, 250, 235, 79, 110, 84, 243, 225, 144, 242]) + ) + expect(ks.Salt).toStrictEqual( + new Uint8Array([ + 146, 63, 151, 136, 93, 135, 105, 113, 124, 41, 189, 207, 86, 124, 17, + 152, + ]) + ) + expect(ks.PublicKey).toStrictEqual([ + 0, 143, 111, 199, 160, 227, 187, 57, 238, 223, 80, 251, 169, 64, 21, 116, + 165, 95, 187, 192, 76, 97, 33, 64, 208, 119, 99, 182, 139, 174, 219, 61, + 109, + ]) + expect(ks.CipheredData).toStrictEqual([ + 191, 181, 5, 198, 76, 145, 242, 89, 253, 215, 151, 10, 245, 32, 241, 9, + 171, 181, 76, 103, 121, 184, 33, 16, 227, 83, 53, 133, 194, 38, 20, 217, + 34, 61, 169, 108, 156, 217, 196, 74, 34, 127, 129, 33, 103, 215, 117, 66, + 78, + ]) + const account2 = await Account.fromKeyStore(ks, 'unsecurePassword') + const ks2 = await account2.toKeyStore('unsecurePassword', ks.Salt, ks.Nonce) + expect(ks).toStrictEqual(ks2) + }) + + test('Account - from keystore', async () => { + const walletPath = path.join(__dirname, 'wallet_test_version_1.yaml') + const ks = load(readFileSync(walletPath, 'utf8')) as AccountKeyStore + + expect(ks.Version).toBe(Version.V1) + expect(ks.Address).toBe( + 'AU126tkwrhXn9gEG5JPtrNy8NNLbVMwywokgLKshSYyzP8qusqXZL' + ) + + const account = await Account.fromKeyStore(ks, 'unsecurePassword') + expect(account.address.toString()).toBe( + 'AU126tkwrhXn9gEG5JPtrNy8NNLbVMwywokgLKshSYyzP8qusqXZL' + ) + expect(account.publicKey.toString()).toBe( + 'P126AtzfcSJwdi6xsAmXbzXhhwVhS9d1hRjFNT4PfrDogt3nAihj' + ) + expect(account.version).toBe(Version.V1) + expect(account.address.version).toBe(Version.V0) + expect(account.address.isEOA).toBe(true) + }) + + test('Account - to and from keystore (V0)', async () => { + const accountv0 = await Account.fromPrivateKey( + 'S12jWf59Yzf2LimL89soMnAP2VEBDBpfCbZLoEFo36CxEL3j92rZ', + Version.V0 + ) + + const ks = await accountv0.toKeyStore( + 'unsecurePassword', + new Uint8Array([ + 146, 63, 151, 136, 93, 135, 105, 113, 124, 41, 189, 207, 86, 124, 17, + 152, + ]), + new Uint8Array([250, 104, 81, 250, 235, 79, 110, 84, 243, 225, 144, 242]) + ) + expect(ks.Version).toBe(Version.V0) + expect(ks.Address).toBe( + 'AU126tkwrhXn9gEG5JPtrNy8NNLbVMwywokgLKshSYyzP8qusqXZL' + ) + expect(ks.Nonce).toStrictEqual( + new Uint8Array([250, 104, 81, 250, 235, 79, 110, 84, 243, 225, 144, 242]) + ) + expect(ks.Salt).toStrictEqual( + new Uint8Array([ + 146, 63, 151, 136, 93, 135, 105, 113, 124, 41, 189, 207, 86, 124, 17, + 152, + ]) + ) + expect(ks.PublicKey).toStrictEqual([ + 0, 143, 111, 199, 160, 227, 187, 57, 238, 223, 80, 251, 169, 64, 21, 116, + 165, 95, 187, 192, 76, 97, 33, 64, 208, 119, 99, 182, 139, 174, 219, 61, + 109, + ]) + expect(ks.CipheredData).toStrictEqual([ + 191, 181, 5, 198, 76, 145, 242, 89, 253, 215, 151, 10, 245, 32, 241, 9, + 171, 181, 76, 103, 121, 184, 33, 16, 227, 83, 53, 133, 194, 38, 20, 217, + 34, 61, 169, 108, 156, 217, 196, 74, 34, 127, 129, 33, 103, 215, 117, 66, + 78, + ]) + + const account = await Account.fromKeyStore(ks, 'unsecurePassword') + + expect(account).toBeDefined() + expect(account.privateKey).toBeDefined() + expect(account.publicKey).toBeDefined() + expect(account.address).toBeDefined() + expect(account.version).toBe(Version.V0) + expect(account.address.version).toBe(Version.V0) + expect(account.address.isEOA).toBe(true) + }) + + // test('Account - from yaml file', async () => { + // const walletPath = path.join(__dirname, 'wallet_test_version_1.yaml') + + // const account = await Account.fromYaml(walletPath, 'unsecurePassword') + // expect(account.address.toString()).toBe( + // 'AU126tkwrhXn9gEG5JPtrNy8NNLbVMwywokgLKshSYyzP8qusqXZL' + // ) + // expect(account.publicKey.toString()).toBe( + // 'P126AtzfcSJwdi6xsAmXbzXhhwVhS9d1hRjFNT4PfrDogt3nAihj' + // ) + // expect(account.version).toBe(Version.V1) + // expect(account.address.version).toBe(Version.V0) + // expect(account.address.isEOA).toBe(true) + // }) + + test('Account - from environment variables', async () => { + process.env.PRIVATE_KEY = + 'S12jWf59Yzf2LimL89soMnAP2VEBDBpfCbZLoEFo36CxEL3j92rZ' + + const account = await Account.fromEnv() + + expect(account).toBeDefined() + expect(account.address.toString()).toBe( + 'AU126tkwrhXn9gEG5JPtrNy8NNLbVMwywokgLKshSYyzP8qusqXZL' + ) + expect(account.publicKey.toString()).toBe( + 'P126AtzfcSJwdi6xsAmXbzXhhwVhS9d1hRjFNT4PfrDogt3nAihj' + ) + expect(account.version).toBe(Version.V1) + expect(account.address.isEOA).toBe(true) + }) + + test('Account - sign message and verify signature', async () => { + const account = await Account.fromPrivateKey( + 'S12jWf59Yzf2LimL89soMnAP2VEBDBpfCbZLoEFo36CxEL3j92rZ' + ) + const message = new Uint8Array([1, 2, 3]) + const signature = await account.sign(message) + expect(account.verify(message, signature)).toBeTruthy() + }) +}) diff --git a/test/unit/address.spec.ts b/test/unit/address.spec.ts new file mode 100644 index 00000000..d0e6805f --- /dev/null +++ b/test/unit/address.spec.ts @@ -0,0 +1,70 @@ +import { Account } from '../../src/account' +import { Address } from '../../src/basicElements' + +const contractAddress = 'AS1eK3SEXGDAWN6pZhdr4Q7WJv6UHss55EB14hPy4XqBpiktfPu6' + +describe('Address tests', () => { + let account: Account + + beforeAll(async () => { + account = await Account.generate() + }) + + test('serialization and deserialization', async () => { + const address = Address.fromString( + 'AU1tY57YPhHyCTDhJP4gdNqHeqzRd37TDB4VB8MUJFFaQPrq57do' + ) + const bytes = address.toBytes() + + // serialization + expect(bytes).toStrictEqual( + new Uint8Array([ + 0, 0, 117, 4, 163, 189, 244, 68, 52, 227, 126, 40, 61, 243, 206, 212, + 58, 106, 9, 96, 74, 130, 69, 47, 38, 49, 139, 36, 117, 249, 22, 212, 63, + 104, + ]) + ) + + // deserialization + expect(Address.fromBytes(bytes)).toStrictEqual(address) + }) + + test('fromString throws error for invalid address string', () => { + expect(() => Address.fromString('invalid_address_string')).toThrow( + /invalid address string:/ + ) + }) + + test('toString returns string with user prefix for EOA', () => { + const address = Address.fromPublicKey(account.publicKey) + expect(address.toString()).toMatch(/^AU/) + }) + + test('toString returns string with contract prefix for contract account', () => { + const address = Address.fromString(contractAddress) + expect(address.toString()).toMatch(/^AS/) + }) + + test('toBytes returns bytes with EOA prefix for EOA', () => { + const address = Address.fromPublicKey(account.publicKey) + const bytes = address.toBytes() + // The first byte should be 0 for EOA + expect(bytes[0]).toBe(0) + }) + + test('toBytes returns bytes with contract prefix for contract account', () => { + const address = Address.fromString(contractAddress) + const bytes = address.toBytes() + // The first byte should be 1 for contract account + expect(bytes[0]).toBe(1) + }) + + test('extractFromBuffer returns extracted address bytes', () => { + const address = Address.fromPublicKey(account.publicKey) + const buffer = Uint8Array.from([...address.toBytes(), 1, 2, 3, 4]) + const { data, length } = Address.extractFromBuffer(buffer) + + expect(data).toStrictEqual(address.toBytes()) + expect(length).toStrictEqual(address.toBytes().length) + }) +}) diff --git a/test/unit/base.spec.ts b/test/unit/base.spec.ts new file mode 100644 index 00000000..4c76e469 --- /dev/null +++ b/test/unit/base.spec.ts @@ -0,0 +1,35 @@ +import { ErrorBase } from '../../src/errors/base' +import { ErrorCodes } from '../../src/errors/utils/codes' + +test('ErrorBase', () => { + expect(new ErrorBase('An error occurred.').message).toBe(`An error occurred.`) + + expect( + new ErrorBase('An error occurred.', { details: 'Some details' }).message + ).toBe(`An error occurred. + +Details: Some details`) + + expect( + new ErrorBase('An error occurred.', { + metaMessages: ['Some meta message'], + }).message + ).toBe(`An error occurred. + +Meta: Some meta message`) + + expect( + new ErrorBase('An error occurred.', { + docsPath: 'https://example.com/docs', + }).message + ).toBe(`An error occurred. + +Docs: see https://example.com/docs for more information.`) +}) + +test('ErrorBase with code', () => { + const errorBase = new ErrorBase('An error occurred.', { + code: ErrorCodes.UnknownError, + }) + expect(errorBase.code).toBe(ErrorCodes.UnknownError) +}) diff --git a/test/unit/events-utils.spec.ts b/test/unit/events-utils.spec.ts new file mode 100644 index 00000000..d1c5fc88 --- /dev/null +++ b/test/unit/events-utils.spec.ts @@ -0,0 +1,16 @@ +import { Args } from '../../src/basicElements' +import { rawEventDecode } from '../../src/utils/events' + +describe('Events utils', () => { + describe('rawEventDecode', () => { + test('decode', () => { + const message = 'test' + const rawData = new Args().addString('test').serialize() + const dataBase64Encoded = Buffer.from(rawData).toString('base64') + const rawEvent = rawEventDecode(dataBase64Encoded) + const event = new Args(rawEvent).nextString() + + expect(event).toEqual(message) + }) + }) +}) diff --git a/test/unit/internal.spec.ts b/test/unit/internal.spec.ts new file mode 100644 index 00000000..e7f9303c --- /dev/null +++ b/test/unit/internal.spec.ts @@ -0,0 +1,35 @@ +import { + extractData, + mustExtractPrefix, +} from '../../src/basicElements/internal' +import Base58 from '../../src/crypto/base58' +import VarintVersioner from '../../src/crypto/varintVersioner' +import { Version } from '../../src/crypto/interfaces/versioner' + +describe('Internal functions tests', () => { + const serializer = new Base58() + const versioner = new VarintVersioner() + + test('extractData throws error for invalid version', () => { + const data = serializer.serialize(Uint8Array.from([0, 1, 2, 3, 4])) + expect(() => extractData(serializer, versioner, data, Version.V1)).toThrow( + 'invalid version: 0. 1 was expected.' + ) + }) + + test('extractData returns correct data for valid version', () => { + const data = serializer.serialize(Uint8Array.from([0, 1, 2, 3, 4])) + const extractedData = extractData(serializer, versioner, data, Version.V0) + expect(extractedData).toEqual(Uint8Array.from([1, 2, 3, 4])) + }) + + test('mustExtractPrefix throws error for invalid prefix', () => { + expect(() => mustExtractPrefix('IP_invalid_prefix', 'AS')).toThrow( + 'invalid prefix: IP. AS was expected.' + ) + + expect(() => mustExtractPrefix('IP_invalid_prefix', 'AS', 'AU')).toThrow( + 'invalid prefix: IP. one of AS or AU was expected.' + ) + }) +}) diff --git a/test/unit/key.spec.ts b/test/unit/key.spec.ts new file mode 100644 index 00000000..3d99f449 --- /dev/null +++ b/test/unit/key.spec.ts @@ -0,0 +1,96 @@ +import { Address } from '../../src/basicElements/address' +import { PrivateKey, PublicKey } from '../../src/basicElements/keys' + +describe('PrivateKey and PublicKey tests', () => { + let privateKey: PrivateKey + let publicKey: PublicKey + + beforeAll(async () => { + privateKey = PrivateKey.generate() + publicKey = await PublicKey.fromPrivateKey(privateKey) + }) + + describe('Conversion to and from Bytes', () => { + test('PublicKey toBytes and fromBytes', async () => { + const publicKey = await PublicKey.fromPrivateKey(privateKey) + const newPubKeyBytes = PublicKey.fromBytes(publicKey.toBytes()) + expect(newPubKeyBytes.toBytes()).toEqual(publicKey.toBytes()) + }) + + test('PrivateKey toBytes and fromBytes', async () => { + const privateKey = PrivateKey.generate() + const newPKeyBytes = PrivateKey.fromBytes(privateKey.toBytes()) + expect(newPKeyBytes.toBytes()).toEqual(privateKey.toBytes()) + }) + }) + + describe('Address Generation', () => { + test('PublicKey getAddress', async () => { + const privKey = PrivateKey.fromString( + 'S1eK3SEXGDAWN6pZhdr4Q7WJv6UHss55EB14hPy4XqBpiktfPu6' + ) + const pubKey = await PublicKey.fromPrivateKey(privKey) + const address = Address.fromPublicKey(pubKey) + + expect(address.toString()).toBe( + 'AU12Set6aygzt1k7ZkDwrkStYovVBzeGs8VgaZogy11s7fQzaytv3' + ) + }) + }) + + describe('Signing and Verification', () => { + test('PrivateKey sign and PublicKey verify', async () => { + const message = new TextEncoder().encode('Hello, world!') + const signature = await privateKey.sign(message) + const isValid = await publicKey.verify(message, signature) + + expect(isValid).toBe(true) + }) + }) + + describe('From String', () => { + test('fromString returns PrivateKey when valid private key string', () => { + const privateKeyString = privateKey.toString() + const key = PrivateKey.fromString(privateKeyString) + expect(key).toBeInstanceOf(PrivateKey) + expect(key.toString()).toBe(privateKey.toString()) + }) + + test('fromString returns PublicKey when valid public key string', () => { + const publicKeyString = publicKey.toString() + const key = PublicKey.fromString(publicKeyString) + expect(key).toBeInstanceOf(PublicKey) + expect(key.toString()).toBe(publicKey.toString()) + }) + + test('fromString throws error for invalid private key string', () => { + const invalidPrivateKeyString = 'invalidPrivateKey' + expect(() => PrivateKey.fromString(invalidPrivateKeyString)).toThrow( + /invalid private key string/ + ) + }) + + test('fromString throws error for invalid public key string', () => { + const invalidPublicKeyString = 'invalidPublicKey' + + expect(() => PublicKey.fromString(invalidPublicKeyString)).toThrow( + /invalid public key string/ + ) + }) + }) + + describe('From Environment Variables', () => { + test('fromEnv returns PrivateKey when PRIVATE_KEY environment variable set', () => { + process.env.PRIVATE_KEY = privateKey.toString() + const key = PrivateKey.fromEnv() + expect(key.toString()).toBe(privateKey.toString()) + }) + + test('fromEnv throws error when PRIVATE_KEY environment variable is not set', () => { + delete process.env.PRIVATE_KEY + expect(() => PrivateKey.fromEnv()).toThrow( + 'missing `PRIVATE_KEY` environment variable' + ) + }) + }) +}) diff --git a/test/unit/mas.spec.ts b/test/unit/mas.spec.ts new file mode 100644 index 00000000..95eb3603 --- /dev/null +++ b/test/unit/mas.spec.ts @@ -0,0 +1,40 @@ +import { Mas } from '../../src/basicElements' + +describe('amount conversion', () => { + it('converts from integer', () => { + expect(Mas.fromMas(1n)).toStrictEqual(1_000_000_000n) + expect(Mas.fromMas(1234n)).toStrictEqual(1_234_000_000_000n) + expect(() => Mas.fromMas(BigInt(1) << BigInt(256))).toThrow() + + expect(Mas.fromMilliMas(1n)).toStrictEqual(1_000_000n) + expect(Mas.fromMilliMas(1234n)).toStrictEqual(1_234_000_000n) + + expect(Mas.fromMicroMas(1n)).toStrictEqual(1_000n) + expect(Mas.fromMicroMas(1234n)).toStrictEqual(1_234_000n) + + expect(Mas.fromNanoMas(1n)).toStrictEqual(1n) + expect(Mas.fromNanoMas(1234n)).toStrictEqual(1_234n) + }) + + it('converts from string', () => { + expect(Mas.fromString('1')).toStrictEqual(1_000_000_000n) + expect(Mas.fromString('1.1')).toStrictEqual(1_100_000_000n) + expect(Mas.fromString('01234.56789')).toStrictEqual(1_234_567_890_000n) + expect(Mas.fromString('01234.567890000')).toStrictEqual(1_234_567_890_000n) + expect(() => Mas.fromString('1.1.1')).toThrow() + expect(() => Mas.fromString('0.1234567890')).toThrow() + expect(() => + Mas.fromString((BigInt(1) << BigInt(256)).toString()) + ).toThrow() + }) + + it('converts to string', () => { + expect(Mas.toString(1_000_000_000n)).toStrictEqual('1') + expect(Mas.toString(1_100_000_000n)).toStrictEqual('1.1') + expect(Mas.toString(1_234_567_890_000n)).toStrictEqual('1234.56789') + expect(Mas.toString(100_000n)).toStrictEqual('0.0001') + expect(Mas.toString(1_234_567_890_000n, 2)).toStrictEqual('1234.57') + expect(Mas.toString(1_234_567_890_000n, 3)).toStrictEqual('1234.568') + expect(Mas.toString(1_234_567_890_000n, 6)).toStrictEqual('1234.567890') + }) +}) diff --git a/test/unit/mock/blockchainClient.mock.ts b/test/unit/mock/blockchainClient.mock.ts new file mode 100644 index 00000000..e878a8fa --- /dev/null +++ b/test/unit/mock/blockchainClient.mock.ts @@ -0,0 +1,21 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { PublicAPI, SCEvent } from '../../../src/client' +import { NodeStatus } from '../../../src/generated/client-types' + +export const blockchainClientMock = { + sendOperation: jest.fn().mockResolvedValue('operationId'), + fetchPeriod: jest.fn().mockResolvedValue(1), + getOperationStatus: jest.fn(), + getBalance: jest.fn().mockResolvedValue(123_456_789n), + getEvents: jest.fn().mockResolvedValue([] as SCEvent[]), + getChainId: jest.fn().mockResolvedValue(1n), + getMinimalFee: jest.fn().mockResolvedValue(100_000n), + executeReadOnlyCall: jest.fn().mockResolvedValue({ + value: new Uint8Array(), + info: { + events: [], + stateChanges: {}, + }, + }), + status: jest.fn().mockResolvedValue({} as NodeStatus), +} as any as PublicAPI diff --git a/test/unit/mock/provider.mock.ts b/test/unit/mock/provider.mock.ts new file mode 100644 index 00000000..291c4518 --- /dev/null +++ b/test/unit/mock/provider.mock.ts @@ -0,0 +1,7 @@ +import { Provider } from '../../../src/provider' +import { blockchainClientMock } from './blockchainClient.mock' + +export const providerMock = { + getOperationStatus: blockchainClientMock.getOperationStatus, + getEvents: blockchainClientMock.getEvents, +} as any as Provider diff --git a/test/unit/operation.spec.ts b/test/unit/operation.spec.ts new file mode 100644 index 00000000..feaed6c0 --- /dev/null +++ b/test/unit/operation.spec.ts @@ -0,0 +1,113 @@ +import { Operation } from '../../src/operation' +import { EventExecutionContext } from '../../src/generated/client-types' +import { OperationStatus } from '../../src/operation' +import { blockchainClientMock } from './mock/blockchainClient.mock' +import { providerMock } from './mock/provider.mock' +import { SCEvent } from '../../src' + +const OPERATION_ID = 'testOperationID' +const operation = new Operation(providerMock, OPERATION_ID) + +describe('Operation tests', () => { + test('get success operation status', async () => { + jest + .spyOn(providerMock, 'getOperationStatus') + .mockResolvedValueOnce(OperationStatus.Success) + const status = await operation.getStatus() + + expect(blockchainClientMock.getOperationStatus).toHaveBeenCalledWith( + OPERATION_ID + ) + expect(status).toBe(OperationStatus.Success) + }) + + test('get SpeculativeSuccess operation status', async () => { + jest + .spyOn(providerMock, 'getOperationStatus') + .mockResolvedValueOnce(OperationStatus.SpeculativeSuccess) + const status = await operation.getStatus() + + expect(blockchainClientMock.getOperationStatus).toHaveBeenCalledWith( + OPERATION_ID + ) + expect(status).toBe(OperationStatus.SpeculativeSuccess) + }) + + test('get operation status not found', async () => { + jest + .spyOn(providerMock, 'getOperationStatus') + .mockResolvedValueOnce(OperationStatus.NotFound) + const status = await operation.getStatus() + + expect(blockchainClientMock.getOperationStatus).toHaveBeenCalledWith( + OPERATION_ID + ) + expect(status).toBe(OperationStatus.NotFound) + }) + + test('get speculative events', async () => { + const dummyEvents = [ + { + data: 'theData', + context: {} as EventExecutionContext, + }, + { + data: 'moreData', + context: {} as EventExecutionContext, + }, + ] as SCEvent[] + + jest + .spyOn(blockchainClientMock, 'getOperationStatus') + .mockResolvedValueOnce(OperationStatus.SpeculativeSuccess) + jest + .spyOn(blockchainClientMock, 'getEvents') + .mockResolvedValueOnce(dummyEvents) + + const events = await operation.getSpeculativeEvents() + + expect(blockchainClientMock.getEvents).toHaveBeenCalledWith({ + operationId: OPERATION_ID, + isFinal: false, + }) + expect(events).toStrictEqual(dummyEvents) + }) + + test('get final events', async () => { + const dummyEvents = [ + { + data: 'theData', + context: {} as EventExecutionContext, + }, + { + data: 'moreData', + context: {} as EventExecutionContext, + }, + ] as SCEvent[] + + jest + .spyOn(blockchainClientMock, 'getOperationStatus') + .mockResolvedValueOnce(OperationStatus.Success) + jest + .spyOn(blockchainClientMock, 'getEvents') + .mockResolvedValueOnce(dummyEvents) + + const events = await operation.getFinalEvents() + + expect(blockchainClientMock.getEvents).toHaveBeenCalledWith({ + operationId: OPERATION_ID, + isFinal: true, + }) + expect(events).toStrictEqual(dummyEvents) + }) + + test('get events of not found', async () => { + jest + .spyOn(operation, 'waitFinalExecution') + .mockResolvedValueOnce(OperationStatus.NotFound) + + await expect(operation.getFinalEvents()).rejects.toThrow( + 'Operation not found' + ) + }) +}) diff --git a/test/unit/operationManager.spec.ts b/test/unit/operationManager.spec.ts new file mode 100644 index 00000000..f3e99f94 --- /dev/null +++ b/test/unit/operationManager.spec.ts @@ -0,0 +1,272 @@ +import { blockchainClientMock } from './mock/blockchainClient.mock' +import { Signature, PrivateKey, Address } from '../../src/' + +import 'dotenv/config' +import { + ExecuteOperation, + OperationType, + RollOperation, + TransferOperation, +} from '../../src/operation' +import { + getAbsoluteExpirePeriod, + OperationManager, + PERIOD_TO_LIVE_DEFAULT, + PERIOD_TO_LIVE_MAX, + PERIOD_TO_LIVE_MIN, +} from '../../src/operation/operationManager' + +describe('Operation manager tests', () => { + test('serialize - transfer', async () => { + const transfer: TransferOperation = { + fee: 1n, + type: OperationType.Transaction, + expirePeriod: 2, + amount: 3n, + recipientAddress: Address.fromString( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ), + } + + expect(OperationManager.serialize(transfer)).toEqual( + new Uint8Array([ + 1, 2, 0, 0, 0, 123, 112, 231, 120, 210, 147, 6, 222, 60, 132, 122, 220, + 63, 36, 111, 216, 72, 248, 161, 29, 104, 213, 241, 70, 172, 217, 243, + 24, 153, 171, 29, 50, 3, + ]) + ) + }) + + test('serialize - sell roll', async () => { + const sellRoll: RollOperation = { + type: OperationType.RollSell, + expirePeriod: 2, + fee: 1n, + amount: 3n, + } + + expect(OperationManager.serialize(sellRoll)).toEqual( + new Uint8Array([1, 2, 2, 3]) + ) + }) + + test('serialize - execute', async () => { + const execute: ExecuteOperation = { + fee: 1n, + type: OperationType.ExecuteSmartContractBytecode, + expirePeriod: 2, + maxGas: 3n, + maxCoins: 4n, + contractDataBinary: new Uint8Array([1, 2, 3, 4]), + datastore: new Map([ + [new Uint8Array([1, 2, 3, 4]), new Uint8Array([1, 2, 3, 4])], + ]), + } + + expect(OperationManager.serialize(execute)).toEqual( + new Uint8Array([ + 1, 2, 3, 3, 4, 4, 1, 2, 3, 4, 1, 4, 1, 2, 3, 4, 4, 1, 2, 3, 4, + ]) + ) + }) + + test('serialize - throw if OperationType is not supported', async () => { + const operation = { + type: -1, + } + + expect(() => + OperationManager.serialize(operation as ExecuteOperation) + ).toThrow('Operation type not supported') + }) + + test('canonicalize', async () => { + const transfer: TransferOperation = { + fee: 1n, + type: OperationType.Transaction, + expirePeriod: 2, + amount: 3n, + recipientAddress: Address.fromString( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ), + } + + const publicKey = await PrivateKey.fromString( + 'S1edybaAp8cYXwXtchW3nfyPwwh9tvoWgSdkxK2uJwWo9zZrCH9' + ).getPublicKey() + + expect(OperationManager.canonicalize(1n, transfer, publicKey)).toEqual( + new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 1, 0, 80, 4, 30, 211, 241, 1, 3, 219, 6, 32, 235, + 244, 186, 4, 239, 84, 155, 62, 17, 45, 68, 245, 236, 88, 141, 50, 82, + 254, 9, 151, 4, 167, 1, 2, 0, 0, 0, 123, 112, 231, 120, 210, 147, 6, + 222, 60, 132, 122, 220, 63, 36, 111, 216, 72, 248, 161, 29, 104, 213, + 241, 70, 172, 217, 243, 24, 153, 171, 29, 50, 3, + ]) + ) + }) + + test('canonicalize - execute', async () => { + const execute: ExecuteOperation = { + fee: 1n, + type: OperationType.ExecuteSmartContractBytecode, + expirePeriod: 2, + maxGas: 3n, + maxCoins: 4n, + contractDataBinary: new Uint8Array([1, 2, 3, 4]), + datastore: new Map([ + [new Uint8Array([1, 2, 3, 4]), new Uint8Array([1, 2, 3, 4])], + ]), + } + + const publicKey = await PrivateKey.fromString( + 'S1edybaAp8cYXwXtchW3nfyPwwh9tvoWgSdkxK2uJwWo9zZrCH9' + ).getPublicKey() + + expect(OperationManager.canonicalize(1n, execute, publicKey)).toEqual( + new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 1, 0, 80, 4, 30, 211, 241, 1, 3, 219, 6, 32, 235, + 244, 186, 4, 239, 84, 155, 62, 17, 45, 68, 245, 236, 88, 141, 50, 82, + 254, 9, 151, 4, 167, 1, 2, 3, 3, 4, 4, 1, 2, 3, 4, 1, 4, 1, 2, 3, 4, 4, + 1, 2, 3, 4, + ]) + ) + }) + + test('deserialize - transfer', async () => { + const transfer: TransferOperation = { + fee: 1n, + type: OperationType.Transaction, + expirePeriod: 2, + amount: 3n, + recipientAddress: Address.fromString( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ), + } + + const serialized = OperationManager.serialize(transfer) + const deserialized = OperationManager.deserialize(serialized) + + expect(deserialized).toEqual(transfer) + }) + + test('deserialize - roll sell', async () => { + const sellRoll: RollOperation = { + type: OperationType.RollSell, + expirePeriod: 2, + fee: 1n, + amount: 3n, + } + + const serialized = OperationManager.serialize(sellRoll) + const deserialized = OperationManager.deserialize(serialized) + + expect(deserialized).toEqual(sellRoll) + }) + + test('sign', async () => { + const transfer: TransferOperation = { + fee: 1n, + type: OperationType.Transaction, + expirePeriod: 2, + amount: 3n, + recipientAddress: Address.fromString( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ), + } + + const privateKey = await PrivateKey.generate() + const operationManager = new OperationManager(privateKey) + const signature = await operationManager.sign(1n, transfer) + + expect(signature).toBeInstanceOf(Signature) + }) + + test('send throw if blockchainClient is not defined', async () => { + const transfer: TransferOperation = { + fee: 1n, + type: OperationType.Transaction, + expirePeriod: 2, + amount: 3n, + recipientAddress: Address.fromString( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ), + } + + const privateKey = await PrivateKey.generate() + const operationManager = new OperationManager(privateKey) + + await expect(operationManager.send(transfer)).rejects.toThrow( + 'blockchainClient is mandatory to send operations' + ) + }) + + test('send', async () => { + const transfer: TransferOperation = { + fee: 1n, + type: OperationType.Transaction, + expirePeriod: 2, + amount: 3n, + recipientAddress: Address.fromString( + 'AU1wN8rn4SkwYSTDF3dHFY4U28KtsqKL1NnEjDZhHnHEy6cEQm53' + ), + } + + const privateKey = await PrivateKey.generate() + + const operationManager = new OperationManager( + privateKey, + blockchainClientMock + ) + + const operationId = await operationManager.send(transfer) + + expect(blockchainClientMock.getChainId).toHaveBeenCalled() + expect(blockchainClientMock.sendOperation).toHaveBeenCalledWith({ + data: OperationManager.serialize(transfer), + publicKey: (await privateKey.getPublicKey()).toString(), + signature: (await operationManager.sign(1n, transfer)).toString(), + }) + expect(operationId).toBe('operationId') + }) +}) + +describe('Expire Period', () => { + let currentPeriod: number + beforeAll(async () => { + currentPeriod = await blockchainClientMock.fetchPeriod() + }) + + test('returns correct expire period', async () => { + const periodToLive = 5 + const expectedExpirePeriod = currentPeriod + periodToLive + const expirePeriod = await getAbsoluteExpirePeriod( + blockchainClientMock, + periodToLive + ) + expect(expirePeriod).toBe(expectedExpirePeriod) + }) + + test('returns default expire period', async () => { + const expirePeriod = await getAbsoluteExpirePeriod(blockchainClientMock) + expect(expirePeriod).toBe(currentPeriod + PERIOD_TO_LIVE_DEFAULT) + }) + + test('throws error if periodToLive is less than PERIOD_TO_LIVE_MIN', () => { + const periodToLive = 0 + expect( + getAbsoluteExpirePeriod(blockchainClientMock, periodToLive) + ).rejects.toThrow( + `periodToLive must be between ${PERIOD_TO_LIVE_MIN} and ${PERIOD_TO_LIVE_MAX}.` + ) + }) + + test('throws error if periodToLive is greater than PERIOD_TO_LIVE_MAX', () => { + const periodToLive = 101 + expect( + getAbsoluteExpirePeriod(blockchainClientMock, periodToLive) + ).rejects.toThrow( + `periodToLive must be between ${PERIOD_TO_LIVE_MIN} and ${PERIOD_TO_LIVE_MAX}.` + ) + }) +}) diff --git a/test/unit/passwordSeal.spec.ts b/test/unit/passwordSeal.spec.ts new file mode 100644 index 00000000..c44e5fda --- /dev/null +++ b/test/unit/passwordSeal.spec.ts @@ -0,0 +1,19 @@ +import { PasswordSeal } from '../../src/crypto/passwordSeal' +import randomUint8Array from 'secure-random' + +describe('Password Seal tests', () => { + test('creates Sealer from env variable', async () => { + process.env.PASSWORD = 'unsecurePassword' + process.env.SALT = Buffer.from(randomUint8Array(16)).toString('base64') + process.env.NONCE = Buffer.from(randomUint8Array(12)).toString('base64') + + const sealer = PasswordSeal.fromEnv() + expect(sealer).toBeDefined() + + const originalData = Uint8Array.from([1, 2, 3, 4, 5]) + const encryptedData = await sealer.seal(originalData) + const decryptedData = await sealer.unseal(encryptedData) + + expect(originalData).toEqual(Uint8Array.from(decryptedData)) + }) +}) diff --git a/test/unit/serializedInteger.spec.ts b/test/unit/serializedInteger.spec.ts new file mode 100644 index 00000000..74660e89 --- /dev/null +++ b/test/unit/serializedInteger.spec.ts @@ -0,0 +1,778 @@ +import { + U8, + U16, + U32, + U64, + U128, + U256, + I8, + I16, + I32, + I64, + I128, + I256, +} from '../../src/basicElements' + +describe('Integer serialization', () => { + test('U8', async () => { + expect(U8.SIZE_BIT).toBe(8) + expect(U8.MAX).toBe(255n) + + expect(U8.fromNumber(255)).toBe(255n) + expect(U8.fromNumber(0)).toBe(0n) + expect(() => U8.fromNumber(256)).toThrow( + 'value 256 is too large for an U8.' + ) + expect(() => U8.fromNumber(-1)).toThrow( + "negative value can't be serialized as unsigned integer." + ) + expect(() => U8.fromNumber(1.1)).toThrow('value 1.1 is not a safe integer.') + + expect(U8.fromBytes(new Uint8Array([255]))).toBe(255n) + expect(U8.fromBytes(new Uint8Array([0]))).toBe(0n) + expect(() => U8.fromBytes(new Uint8Array())).toThrow( + 'not enough bytes to read the value.' + ) + + expect(U8.toBytes(255n)).toEqual(Uint8Array.from([255])) + expect(U8.toBytes(0n)).toEqual(Uint8Array.from([0])) + + expect(U8.fromBuffer(new Uint8Array([255]), 0)).toEqual({ + value: 255n, + offset: 1, + }) + expect(U8.fromBuffer(new Uint8Array([0]), 0)).toEqual({ + value: 0n, + offset: 1, + }) + expect(U8.fromBuffer(new Uint8Array([255, 0]), 0)).toEqual({ + value: 255n, + offset: 1, + }) + expect(U8.fromBuffer(new Uint8Array([255, 0]), 1)).toEqual({ + value: 0n, + offset: 2, + }) + expect(() => U8.fromBuffer(new Uint8Array(), 0)).toThrow( + 'not enough bytes to read the value.' + ) + expect(() => U8.fromBuffer(new Uint8Array([255, 0]), 2)).toThrow( + 'not enough bytes to read the value.' + ) + }) + + test('U16', async () => { + expect(U16.SIZE_BIT).toBe(16) + expect(U16.MAX).toBe(65_535n) + + expect(U16.fromNumber(65_535)).toBe(65_535n) + expect(U16.fromNumber(0)).toBe(0n) + expect(() => U16.fromNumber(65536)).toThrow( + 'value 65536 is too large for an U16.' + ) + expect(() => U16.fromNumber(-1)).toThrow( + "negative value can't be serialized as unsigned integer." + ) + expect(() => U16.fromNumber(1.1)).toThrow( + 'value 1.1 is not a safe integer.' + ) + + expect(U16.fromBytes(new Uint8Array([255, 0]))).toBe(255n) + expect(U16.fromBytes(new Uint8Array([0, 0]))).toBe(0n) + expect(() => U16.fromBytes(new Uint8Array([255]))).toThrow( + 'not enough bytes to read the value.' + ) + + expect(U16.toBytes(65_535n)).toEqual(Uint8Array.from([255, 255])) + expect(U16.toBytes(255n)).toEqual(Uint8Array.from([255, 0])) + expect(U16.toBytes(0n)).toEqual(Uint8Array.from([0, 0])) + + expect(U16.fromBuffer(new Uint8Array([255, 255, 0]), 0)).toEqual({ + value: 65_535n, + offset: 2, + }) + expect(U16.fromBuffer(new Uint8Array([255, 255, 0]), 1)).toEqual({ + value: 255n, + offset: 3, + }) + expect(() => U16.fromBuffer(new Uint8Array([255]), 0)).toThrow( + 'not enough bytes to read the value.' + ) + expect(() => U16.fromBuffer(new Uint8Array([255, 255, 0]), 2)).toThrow( + 'not enough bytes to read the value.' + ) + }) + + test('U32', async () => { + expect(U32.SIZE_BIT).toBe(32) + expect(U32.MAX).toBe(4_294_967_295n) + + expect(U32.fromNumber(4_294_967_295)).toBe(4_294_967_295n) + expect(U32.fromNumber(0)).toBe(0n) + expect(() => U32.fromNumber(4_294_967_296)).toThrow( + 'value 4294967296 is too large for an U32.' + ) + expect(() => U32.fromNumber(-1)).toThrow( + "negative value can't be serialized as unsigned integer." + ) + expect(() => U32.fromNumber(1.1)).toThrow( + 'value 1.1 is not a safe integer.' + ) + + expect(U32.fromBytes(new Uint8Array([255, 255, 255, 255]))).toBe( + 4294967295n + ) + expect(U32.fromBytes(new Uint8Array([0, 0, 0, 0]))).toBe(0n) + expect(() => U32.fromBytes(new Uint8Array([255, 255, 255]))).toThrow( + 'not enough bytes to read the value.' + ) + + expect(U32.toBytes(4_294_967_295n)).toEqual( + Uint8Array.from([255, 255, 255, 255]) + ) + expect(U32.toBytes(65_535n)).toEqual(Uint8Array.from([255, 255, 0, 0])) + expect(U32.toBytes(255n)).toEqual(Uint8Array.from([255, 0, 0, 0])) + expect(U32.toBytes(0n)).toEqual(Uint8Array.from([0, 0, 0, 0])) + + expect(U32.fromBuffer(new Uint8Array([255, 255, 255, 255, 0]), 0)).toEqual({ + value: 4_294_967_295n, + offset: 4, + }) + expect(U32.fromBuffer(new Uint8Array([255, 255, 255, 255, 0]), 1)).toEqual({ + value: 16_777_215n, + offset: 5, + }) + expect(() => U32.fromBuffer(new Uint8Array([255, 255, 255]), 0)).toThrow( + 'not enough bytes to read the value.' + ) + expect(() => + U32.fromBuffer(new Uint8Array([255, 255, 255, 255, 0]), 4) + ).toThrow('not enough bytes to read the value.') + }) + + test('U64', async () => { + expect(U64.SIZE_BIT).toBe(64) + expect(U64.MAX).toBe(18_446_744_073_709_551_615n) + + expect(U64.fromNumber(Number.MAX_SAFE_INTEGER)).toBe(9_007_199_254_740_991n) + expect(U64.fromNumber(18_446_744_073_709_551_615n)).toBe( + 18_446_744_073_709_551_615n + ) + expect(U64.fromNumber(0)).toBe(0n) + expect(() => U64.fromNumber(Number.MAX_SAFE_INTEGER + 1)).toThrow( + 'value 9007199254740992 is not a safe integer.' + ) + expect(() => U64.fromNumber(18_446_744_073_709_551_616n)).toThrow( + 'value 18446744073709551616 is too large for an U64.' + ) + expect(() => U64.fromNumber(-1)).toThrow( + "negative value can't be serialized as unsigned integer." + ) + expect(() => U64.fromNumber(1.1)).toThrow( + 'value 1.1 is not a safe integer.' + ) + + expect( + U64.fromBytes(new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255])) + ).toBe(18_446_744_073_709_551_615n) + expect(U64.fromBytes(new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]))).toBe(0n) + expect(() => + U64.fromBytes(new Uint8Array([255, 255, 255, 255, 255, 255, 255])) + ).toThrow('not enough bytes to read the value.') + + expect(U64.toBytes(18_446_744_073_709_551_615n)).toEqual( + Uint8Array.from([255, 255, 255, 255, 255, 255, 255, 255]) + ) + expect(U64.toBytes(4_294_967_295n)).toEqual( + Uint8Array.from([255, 255, 255, 255, 0, 0, 0, 0]) + ) + expect(U64.toBytes(65_535n)).toEqual( + Uint8Array.from([255, 255, 0, 0, 0, 0, 0, 0]) + ) + expect(U64.toBytes(255n)).toEqual( + Uint8Array.from([255, 0, 0, 0, 0, 0, 0, 0]) + ) + expect(U64.toBytes(0n)).toEqual(Uint8Array.from([0, 0, 0, 0, 0, 0, 0, 0])) + }) + + test('U128', async () => { + expect(U128.SIZE_BIT).toBe(128) + expect(U128.MAX).toBe(340282366920938463463374607431768211455n) + + expect(U128.fromNumber(Number.MAX_SAFE_INTEGER)).toBe(9007199254740991n) + expect(U128.fromNumber(340282366920938463463374607431768211455n)).toBe( + 340282366920938463463374607431768211455n + ) + expect(U128.fromNumber(0)).toBe(0n) + expect(() => U128.fromNumber(Number.MAX_SAFE_INTEGER + 1)).toThrow( + 'value 9007199254740992 is not a safe integer.' + ) + expect(() => + U128.fromNumber(340282366920938463463374607431768211456n) + ).toThrow( + 'value 340282366920938463463374607431768211456 is too large for an U128.' + ) + expect(() => U128.fromNumber(-1)).toThrow( + "negative value can't be serialized as unsigned integer." + ) + expect(() => U128.fromNumber(1.1)).toThrow( + 'value 1.1 is not a safe integer.' + ) + + expect( + U128.fromBytes( + new Uint8Array([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, + ]) + ) + ).toBe(U128.MAX) + expect( + U128.fromBytes( + new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + ) + ).toBe(0n) + expect(() => + U128.fromBytes( + new Uint8Array([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, + ]) + ) + ).toThrow('not enough bytes to read the value.') + + expect( + U128.fromBuffer( + new Uint8Array([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, + ]), + 0 + ) + ).toEqual({ offset: 16, value: U128.MAX }) + + expect(U128.toBytes(U128.MAX)).toEqual( + Uint8Array.from([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, + ]) + ) + expect(U128.toBytes(4294967295n)).toEqual( + Uint8Array.from([255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + ) + expect(U128.toBytes(65535n)).toEqual( + Uint8Array.from([255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + ) + expect(U128.toBytes(255n)).toEqual( + Uint8Array.from([255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + ) + expect(U128.toBytes(0n)).toEqual( + Uint8Array.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + ) + }) + + test('U256', async () => { + expect(U256.SIZE_BIT).toBe(256) + expect(U256.MAX).toBe( + 115792089237316195423570985008687907853269984665640564039457584007913129639935n + ) + + expect(U256.fromNumber(Number.MAX_SAFE_INTEGER)).toBe(9007199254740991n) + expect( + U256.fromNumber( + 115792089237316195423570985008687907853269984665640564039457584007913129639935n + ) + ).toBe( + 115792089237316195423570985008687907853269984665640564039457584007913129639935n + ) + expect(U256.fromNumber(0)).toBe(0n) + expect(() => U256.fromNumber(Number.MAX_SAFE_INTEGER + 1)).toThrow( + 'value 9007199254740992 is not a safe integer.' + ) + expect(() => + U256.fromNumber( + 115792089237316195423570985008687907853269984665640564039457584007913129639936n + ) + ).toThrow( + 'value 115792089237316195423570985008687907853269984665640564039457584007913129639936 is too large for an U256.' + ) + expect(() => U256.fromNumber(-1)).toThrow( + "negative value can't be serialized as unsigned integer." + ) + expect(() => U256.fromNumber(1.1)).toThrow( + 'value 1.1 is not a safe integer.' + ) + + expect( + U256.fromBytes( + new Uint8Array([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, + ]) + ) + ).toBe( + 115792089237316195423570985008687907853269984665640564039457584007913129639935n + ) + expect( + U256.fromBytes( + new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]) + ) + ).toBe(0n) + expect(() => + U256.fromBytes( + new Uint8Array([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, + ]) + ) + ).toThrow('not enough bytes to read the value.') + + expect( + U256.toBytes( + 115792089237316195423570985008687907853269984665640564039457584007913129639935n + ) + ).toEqual( + Uint8Array.from([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, + ]) + ) + expect(U256.toBytes(4294967295n)).toEqual( + Uint8Array.from([ + 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]) + ) + + expect(U256.toBytes(65535n)).toEqual( + Uint8Array.from([ + 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]) + ) + expect(U256.toBytes(255n)).toEqual( + Uint8Array.from([ + 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]) + ) + expect(U256.toBytes(0n)).toEqual( + Uint8Array.from([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + ]) + ) + + expect( + U256.fromBuffer( + new Uint8Array([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, + ]), + 0 + ) + ).toEqual({ + value: + 115792089237316195423570985008687907853269984665640564039457584007913129639935n, + offset: 32, + }) + + expect( + U256.fromBuffer( + new Uint8Array([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 0, + ]), + 1 + ) + ).toEqual({ + value: + 115792089237316195423570985008687907853269984665640564039457584007913129639935n >> + 8n, + offset: 33, + }) + + expect(() => U256.fromBuffer(new Uint8Array([255, 255, 255]), 0)).toThrow( + 'not enough bytes to read the value.' + ) + expect(() => + U256.fromBuffer( + new Uint8Array([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 0, + ]), + 16 + ) + ).toThrow('not enough bytes to read the value.') + }) + + test('I8', async () => { + expect(I8.SIZE_BIT).toBe(8) + expect(I8.MAX).toBe(127n) + expect(I8.MIN).toBe(-128n) + + expect(I8.fromNumber(127)).toBe(127n) + expect(I8.fromNumber(-128)).toBe(-128n) + expect(I8.fromNumber(0)).toBe(0n) + expect(() => I8.fromNumber(128)).toThrow( + 'value 128 is out of range for an I8.' + ) + expect(() => I8.fromNumber(-129)).toThrow( + 'value -129 is out of range for an I8.' + ) + expect(() => I8.fromNumber(1.1)).toThrow('value 1.1 is not a safe integer.') + + expect(I8.fromBytes(new Uint8Array([127]))).toBe(127n) + expect(I8.fromBytes(new Uint8Array([0]))).toBe(0n) + expect(I8.fromBytes(new Uint8Array([128]))).toBe(-128n) + expect(() => I8.fromBytes(new Uint8Array())).toThrow( + 'not enough bytes to read the value.' + ) + + expect(I8.toBytes(127n)).toEqual(Uint8Array.from([127])) + expect(I8.toBytes(0n)).toEqual(Uint8Array.from([0])) + expect(I8.toBytes(-128n)).toEqual(Uint8Array.from([128])) + + expect(I8.fromBuffer(new Uint8Array([127]), 0)).toEqual({ + value: 127n, + offset: 1, + }) + expect(I8.fromBuffer(new Uint8Array([0]), 0)).toEqual({ + value: 0n, + offset: 1, + }) + expect(I8.fromBuffer(new Uint8Array([128]), 0)).toEqual({ + value: -128n, + offset: 1, + }) + expect(() => I8.fromBuffer(new Uint8Array(), 0)).toThrow( + 'not enough bytes to read the value.' + ) + }) + + test('I16', async () => { + expect(I16.SIZE_BIT).toBe(16) + expect(I16.MAX).toBe(32767n) + expect(I16.MIN).toBe(-32768n) + + expect(I16.fromNumber(32767)).toBe(32767n) + expect(I16.fromNumber(-32768)).toBe(-32768n) + expect(I16.fromNumber(0)).toBe(0n) + expect(() => I16.fromNumber(32768)).toThrow( + 'value 32768 is out of range for an I16.' + ) + expect(() => I16.fromNumber(-32769)).toThrow( + 'value -32769 is out of range for an I16.' + ) + expect(() => I16.fromNumber(1.1)).toThrow( + 'value 1.1 is not a safe integer.' + ) + + expect(I16.fromBytes(new Uint8Array([255, 127]))).toBe(32767n) + expect(I16.fromBytes(new Uint8Array([0, 0]))).toBe(0n) + expect(I16.fromBytes(new Uint8Array([0, 128]))).toBe(-32768n) + expect(() => I16.fromBytes(new Uint8Array([255]))).toThrow( + 'not enough bytes to read the value.' + ) + + expect(I16.toBytes(32767n)).toEqual(Uint8Array.from([255, 127])) + expect(I16.toBytes(0n)).toEqual(Uint8Array.from([0, 0])) + expect(I16.toBytes(-32768n)).toEqual(Uint8Array.from([0, 128])) + + expect(I16.fromBuffer(new Uint8Array([255, 127]), 0)).toEqual({ + value: 32767n, + offset: 2, + }) + expect(I16.fromBuffer(new Uint8Array([0, 0]), 0)).toEqual({ + value: 0n, + offset: 2, + }) + expect(I16.fromBuffer(new Uint8Array([0, 128]), 0)).toEqual({ + value: -32768n, + offset: 2, + }) + expect(() => I16.fromBuffer(new Uint8Array([255]), 0)).toThrow( + 'not enough bytes to read the value.' + ) + }) + + test('I32', async () => { + expect(I32.SIZE_BIT).toBe(32) + expect(I32.MAX).toBe(2147483647n) + expect(I32.MIN).toBe(-2147483648n) + + expect(I32.fromNumber(2147483647)).toBe(2147483647n) + expect(I32.fromNumber(-2147483648)).toBe(-2147483648n) + expect(I32.fromNumber(0)).toBe(0n) + expect(() => I32.fromNumber(2147483648)).toThrow( + 'value 2147483648 is out of range for an I32.' + ) + expect(() => I32.fromNumber(-2147483649)).toThrow( + 'value -2147483649 is out of range for an I32.' + ) + expect(() => I32.fromNumber(1.1)).toThrow( + 'value 1.1 is not a safe integer.' + ) + + expect(I32.fromBytes(new Uint8Array([255, 255, 255, 127]))).toBe( + 2147483647n + ) + expect(I32.fromBytes(new Uint8Array([0, 0, 0, 0]))).toBe(0n) + expect(I32.fromBytes(new Uint8Array([0, 0, 0, 128]))).toBe(-2147483648n) + expect(() => I32.fromBytes(new Uint8Array([255, 255, 255]))).toThrow( + 'not enough bytes to read the value.' + ) + + expect(I32.toBytes(2147483647n)).toEqual( + Uint8Array.from([255, 255, 255, 127]) + ) + expect(I32.toBytes(0n)).toEqual(Uint8Array.from([0, 0, 0, 0])) + expect(I32.toBytes(-2147483648n)).toEqual(Uint8Array.from([0, 0, 0, 128])) + + expect(I32.fromBuffer(new Uint8Array([255, 255, 255, 127]), 0)).toEqual({ + value: 2147483647n, + offset: 4, + }) + expect(I32.fromBuffer(new Uint8Array([0, 0, 0, 0]), 0)).toEqual({ + value: 0n, + offset: 4, + }) + expect(I32.fromBuffer(new Uint8Array([0, 0, 0, 128]), 0)).toEqual({ + value: -2147483648n, + offset: 4, + }) + expect(() => I32.fromBuffer(new Uint8Array([255, 255, 255]), 0)).toThrow( + 'not enough bytes to read the value.' + ) + }) + + test('I64', async () => { + expect(I64.SIZE_BIT).toBe(64) + expect(I64.MAX).toBe(9223372036854775807n) + expect(I64.MIN).toBe(-9223372036854775808n) + + expect(I64.fromNumber(Number.MAX_SAFE_INTEGER)).toBe(9_007_199_254_740_991n) + expect(I64.fromNumber(-Number.MAX_SAFE_INTEGER)).toBe( + -9_007_199_254_740_991n + ) + expect(I64.fromNumber(0)).toBe(0n) + expect(() => I64.fromNumber(9223372036854775808n)).toThrow( + 'value 9223372036854775808 is out of range for an I64.' + ) + expect(() => I64.fromNumber(-9223372036854775809n)).toThrow( + 'value -9223372036854775809 is out of range for an I64.' + ) + expect(() => I64.fromNumber(1.1)).toThrow( + 'value 1.1 is not a safe integer.' + ) + + expect( + I64.fromBytes(new Uint8Array([255, 255, 255, 255, 255, 255, 255, 127])) + ).toBe(9223372036854775807n) + expect(I64.fromBytes(new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]))).toBe(0n) + expect(I64.fromBytes(new Uint8Array([0, 0, 0, 0, 0, 0, 0, 128]))).toBe( + -9223372036854775808n + ) + expect(() => + I64.fromBytes(new Uint8Array([255, 255, 255, 255, 255, 255, 255])) + ).toThrow('not enough bytes to read the value.') + + expect(I64.toBytes(9223372036854775807n)).toEqual( + Uint8Array.from([255, 255, 255, 255, 255, 255, 255, 127]) + ) + expect(I64.toBytes(0n)).toEqual(Uint8Array.from([0, 0, 0, 0, 0, 0, 0, 0])) + expect(I64.toBytes(-9223372036854775808n)).toEqual( + Uint8Array.from([0, 0, 0, 0, 0, 0, 0, 128]) + ) + + expect( + I64.fromBuffer( + new Uint8Array([255, 255, 255, 255, 255, 255, 255, 127]), + 0 + ) + ).toEqual({ + value: 9223372036854775807n, + offset: 8, + }) + expect(I64.fromBuffer(new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]), 0)).toEqual( + { + value: 0n, + offset: 8, + } + ) + expect( + I64.fromBuffer(new Uint8Array([0, 0, 0, 0, 0, 0, 0, 128]), 0) + ).toEqual({ + value: -9223372036854775808n, + offset: 8, + }) + expect(() => + I64.fromBuffer(new Uint8Array([255, 255, 255, 255, 255, 255, 255]), 0) + ).toThrow('not enough bytes to read the value.') + }) + + test('I128', async () => { + expect(I128.SIZE_BIT).toBe(128) + expect(I128.MAX).toBe(170141183460469231731687303715884105727n) + expect(I128.MIN).toBe(-170141183460469231731687303715884105728n) + + expect(I128.fromNumber(170141183460469231731687303715884105727n)).toBe( + 170141183460469231731687303715884105727n + ) + expect(I128.fromNumber(-170141183460469231731687303715884105728n)).toBe( + -170141183460469231731687303715884105728n + ) + expect(I128.fromNumber(0)).toBe(0n) + expect(() => + I128.fromNumber(170141183460469231731687303715884105728n) + ).toThrow( + 'value 170141183460469231731687303715884105728 is out of range for an I128.' + ) + expect(() => + I128.fromNumber(-170141183460469231731687303715884105729n) + ).toThrow( + 'value -170141183460469231731687303715884105729 is out of range for an I128.' + ) + expect(() => I128.fromNumber(1.1)).toThrow( + 'value 1.1 is not a safe integer.' + ) + + const maxBytes = new Uint8Array([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 127, + ]) + const minBytes = new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, + ]) + expect(I128.fromBytes(maxBytes)).toBe( + 170141183460469231731687303715884105727n + ) + expect(I128.fromBytes(new Uint8Array(16))).toBe(0n) + expect(I128.fromBytes(minBytes)).toBe( + -170141183460469231731687303715884105728n + ) + expect(() => I128.fromBytes(new Uint8Array(15))).toThrow( + 'not enough bytes to read the value.' + ) + + expect(I128.toBytes(170141183460469231731687303715884105727n)).toEqual( + maxBytes + ) + expect(I128.toBytes(0n)).toEqual(new Uint8Array(16)) + expect(I128.toBytes(-170141183460469231731687303715884105728n)).toEqual( + minBytes + ) + + expect(I128.fromBuffer(maxBytes, 0)).toEqual({ + value: 170141183460469231731687303715884105727n, + offset: 16, + }) + expect(I128.fromBuffer(new Uint8Array(16), 0)).toEqual({ + value: 0n, + offset: 16, + }) + expect(I128.fromBuffer(minBytes, 0)).toEqual({ + value: -170141183460469231731687303715884105728n, + offset: 16, + }) + expect(() => I128.fromBuffer(new Uint8Array(15), 0)).toThrow( + 'not enough bytes to read the value.' + ) + }) + + test('I256', async () => { + expect(I256.SIZE_BIT).toBe(256) + expect(I256.MAX).toBe( + 57896044618658097711785492504343953926634992332820282019728792003956564819967n + ) + expect(I256.MIN).toBe( + -57896044618658097711785492504343953926634992332820282019728792003956564819968n + ) + + expect( + I256.fromNumber( + 5789604461865809771178549250434395392663499233282028201972879200395656481n + ) + ).toBe( + 5789604461865809771178549250434395392663499233282028201972879200395656481n + ) + expect( + I256.fromNumber( + -57896044618658097711785492504343953926634992332820282019728792003956564n + ) + ).toBe( + -57896044618658097711785492504343953926634992332820282019728792003956564n + ) + expect(I256.fromNumber(0)).toBe(0n) + expect(() => + I256.fromNumber( + 115792089237316195423570985008687907853269984665640564039457584007913129639936n + ) + ).toThrow( + 'value 115792089237316195423570985008687907853269984665640564039457584007913129639936 is out of range for an I256.' + ) + expect(() => + I256.fromNumber( + -115792089237316195423570985008687907853269984665640564039457584007913129639937n + ) + ).toThrow( + 'value -115792089237316195423570985008687907853269984665640564039457584007913129639937 is out of range for an I256.' + ) + expect(() => I256.fromNumber(1.1)).toThrow( + 'value 1.1 is not a safe integer.' + ) + + const maxBytes = new Uint8Array(32).fill(255) + maxBytes[31] = 127 + const minBytes = new Uint8Array(32).fill(0) + minBytes[31] = 128 + expect(I256.fromBytes(maxBytes)).toBe( + 57896044618658097711785492504343953926634992332820282019728792003956564819967n + ) + expect(I256.fromBytes(new Uint8Array(32))).toBe(0n) + expect(I256.fromBytes(minBytes)).toBe( + -57896044618658097711785492504343953926634992332820282019728792003956564819968n + ) + expect(() => I256.fromBytes(new Uint8Array(31))).toThrow( + 'not enough bytes to read the value.' + ) + + expect( + I256.toBytes( + 57896044618658097711785492504343953926634992332820282019728792003956564819967n + ) + ).toEqual(maxBytes) + expect(I256.toBytes(0n)).toEqual(new Uint8Array(32)) + expect( + I256.toBytes( + -57896044618658097711785492504343953926634992332820282019728792003956564819968n + ) + ).toEqual(minBytes) + + expect(I256.fromBuffer(maxBytes, 0)).toEqual({ + value: + 57896044618658097711785492504343953926634992332820282019728792003956564819967n, + offset: 32, + }) + expect(I256.fromBuffer(new Uint8Array(32), 0)).toEqual({ + value: 0n, + offset: 32, + }) + expect(I256.fromBuffer(minBytes, 0)).toEqual({ + value: + -57896044618658097711785492504343953926634992332820282019728792003956564819968n, + offset: 32, + }) + expect(() => I256.fromBuffer(new Uint8Array(31), 0)).toThrow( + 'not enough bytes to read the value.' + ) + }) +}) diff --git a/packages/web3-utils/test/serializers.spec.ts b/test/unit/serializers/array.spec.ts similarity index 52% rename from packages/web3-utils/test/serializers.spec.ts rename to test/unit/serializers/array.spec.ts index 16bfd72c..f7708cbf 100644 --- a/packages/web3-utils/test/serializers.spec.ts +++ b/test/unit/serializers/array.spec.ts @@ -1,18 +1,19 @@ -import { expect, it, describe } from '@jest/globals' -import * as ser from '../src' -import { asTests } from './utils/fixtures/as-serializer' -import { Args, ArrayTypes } from '../src/arguments' +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import { Args, ArrayTypes } from '../../../src/basicElements/args' +import { + ISerializable, + IDeserializedResult, +} from '../../../src/basicElements/serializers/interface/ISerializable' +import { U8, U32, U64, I128, I32 } from '../../../src/basicElements/serializers' import { - deserializeObj, - getDatatypeSize, - serializableObjectsArrayToBytes, arrayToBytes, bytesToArray, bytesToSerializableObjectArray, -} from '../src/serializers/arrays' -import { IDeserializedResult, ISerializable } from '../src/interfaces' + deserializeObj, + getDatatypeSize, + serializableObjectsArrayToBytes, +} from '../../../src/basicElements/serializers/arrays' -// Implement a simple serializable class for testing. class TestSerializable implements ISerializable { value: number @@ -33,217 +34,6 @@ class TestSerializable implements ISerializable { } } -describe('Serialization tests', () => { - it('ser/deser with emojis', () => { - const str = 'Hello world ๐Ÿ™‚' - expect(ser.bytesToStr(ser.strToBytes(str))).toEqual(str) - }) - it('ser/deser Ascii', () => { - const str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' - expect(ser.bytesToStr(ser.strToBytes(str))).toEqual(str) - }) - it('ser/deser utf16 char', () => { - const str = String.fromCharCode(0xd83d, 0xde42) - expect(ser.bytesToStr(ser.strToBytes(str))).toEqual('๐Ÿ™‚') - }) - it('ser/deser bool', () => { - let val = false - expect(ser.byteToBool(ser.boolToByte(val))).toEqual(val) - val = true - expect(ser.byteToBool(ser.boolToByte(val))).toEqual(val) - }) - it('ser/deser u8', () => { - const val = 123 - expect(ser.byteToU8(ser.u8toByte(val))).toEqual(val) - }) - it('throws an error when trying to serialize a negative Uint8 value', () => { - const negativeValue = -1 - const args = new Args() - - expect(() => args.addU8(negativeValue)).toThrow( - `Unable to serialize invalid Uint8 value ${negativeValue}` - ) - }) - it('throws an error when trying to serialize a Uint8 value greater than 255', () => { - const largeValue = 256 - const args = new Args() - - expect(() => args.addU8(largeValue)).toThrow( - `Unable to serialize invalid Uint8 value ${largeValue}` - ) - }) - it('ser/deser u32', () => { - const val = 666 - expect(ser.bytesToU32(ser.u32ToBytes(val))).toEqual(val) - }) - it('throws an error when trying to serialize a negative u32 value', () => { - const negativeValue = -1 - const args = new Args() - - expect(() => args.addU32(negativeValue)).toThrow( - `Unable to serialize invalid Uint32 value ${negativeValue}` - ) - }) - it('throws an error when trying to serialize a Uint32 value greater than 4294967295', () => { - const largeValue = 4294967296 - const args = new Args() - - expect(() => args.addU32(largeValue)).toThrow( - `Unable to serialize invalid Uint32 value ${largeValue}` - ) - }) - it('ser/deser u64', () => { - const val = BigInt(666) - expect(ser.bytesToU64(ser.u64ToBytes(val))).toEqual(val) - }) - it('throws an error when trying to serialize a negative u64 value', () => { - const negativeValue = BigInt(-1) - const args = new Args() - - expect(() => args.addU64(negativeValue)).toThrow( - `Unable to serialize invalid Uint64 value ${negativeValue}` - ) - }) - it('throws an error when trying to serialize a u64 value greater than 18446744073709551615', () => { - const largeValue = BigInt('18446744073709551616') - const args = new Args() - - expect(() => args.addU64(largeValue)).toThrow( - `Unable to serialize invalid Uint64 value ${largeValue}` - ) - }) - it('ser/deser i128', () => { - const val = -123456789123456789n - expect(ser.bytesToI128(ser.i128ToBytes(val))).toEqual(val) - }) - it('ser/deser i128', () => { - const val = ser.I128_MAX - expect(ser.bytesToI128(ser.i128ToBytes(val))).toEqual(val) - }) - it('ser/deser i128', () => { - const val = ser.I128_MIN - expect(ser.bytesToI128(ser.i128ToBytes(val))).toEqual(val) - }) - it('ser/deser u128', () => { - const val = 123456789123456789n - expect(ser.bytesToU128(ser.u128ToBytes(val))).toEqual(val) - }) - it('throws an error when trying to serialize a negative u128 value', () => { - const negativeValue = BigInt(-1) - const args = new Args() - - expect(() => args.addU128(negativeValue)).toThrow( - `Unable to serialize invalid Uint128 value ${negativeValue}` - ) - }) - it('throws an error when trying to serialize a u128 value greater than U128_MAX', () => { - const largeValue = ser.U128_MAX + 1n - const args = new Args() - - expect(() => args.addU128(largeValue)).toThrow( - `Unable to serialize invalid Uint128 value ${largeValue}` - ) - }) - it('ser/deser u256', () => { - const val = 123456789012345678901234567890n - expect(ser.bytesToU256(ser.u256ToBytes(val))).toEqual(val) - }) - it('throws an error when trying to serialize a negative u256 value', () => { - const negativeValue = BigInt(-1) - const args = new Args() - - expect(() => args.addU256(negativeValue)).toThrow( - `Unable to serialize invalid Uint256 value ${negativeValue}` - ) - }) - it('throws an error when trying to serialize a u256 value greater than U256_MAX', () => { - const largeValue = ser.U256_MAX + 1n - const args = new Args() - - expect(() => args.addU256(largeValue)).toThrow( - `Unable to serialize invalid Uint256 value ${largeValue}` - ) - }) - it('ser/deser i32', () => { - const val = -666 - expect(ser.bytesToI32(ser.i32ToBytes(val))).toEqual(val) - }) - it('throws an error when trying to serialize an invalid int32 value', () => { - const invalidValue = Math.pow(2, 31) - const args = new Args() - - expect(() => args.addI32(invalidValue)).toThrow( - `Unable to serialize invalid int32 value ${invalidValue}` - ) - }) - it('ser/deser i64', () => { - const val = BigInt(-666) - expect(ser.bytesToI64(ser.i64ToBytes(val))).toEqual(val) - }) - it('throws an error when trying to serialize an invalid int64 value', () => { - const invalidValue = BigInt('9223372036854775808') - const args = new Args() - - expect(() => args.addI64(invalidValue)).toThrow( - `Unable to serialize invalid int64 value ${invalidValue.toString()}` - ) - }) - it('ser/deser f32', () => { - const val = -666.666 - expect(ser.bytesToF32(ser.f32ToBytes(val))).toBeCloseTo(val, 0.001) - }) - it('ser/deser f64', () => { - const val = -666.666 - expect(ser.bytesToF64(ser.f64ToBytes(val))).toEqual(val) - }) - it('ser/deser f64 max val', () => { - const val = Number.MAX_VALUE - expect(ser.bytesToF64(ser.f64ToBytes(val))).toEqual(val) - }) - it('ser/deser empty string', () => { - const str = '' - expect(ser.bytesToStr(ser.strToBytes(str))).toEqual(str) - }) - it('ser/deser empty Uint8Array', () => { - const arr = new Uint8Array(0) - expect(ser.bytesToStr(arr)).toEqual('') - }) -}) - -describe('Test against assemblyscript serializer', () => { - for (const test of asTests) { - it(`AS tests ${test.name}: serialize`, () => { - expect(ser[test.ser](test.val)).toEqual(new Uint8Array(test.serialized)) - }) - - it(`AS tests ${test.name}: deserialize`, () => { - if (test.deser === 'bytesToF32') { - // Special case for 32bits floats - expect(ser[test.deser](new Uint8Array(test.serialized))).toBeCloseTo( - test.val as number, - 0.001 - ) - } else { - expect(ser[test.deser](new Uint8Array(test.serialized))).toEqual( - test.val - ) - } - }) - } - - it(`AS tests Array`, () => { - const input = ['Hello', 'World', '๐Ÿ™‚'] - const serialized = [ - 26, 0, 0, 0, 5, 0, 0, 0, 72, 101, 108, 108, 111, 5, 0, 0, 0, 87, 111, 114, - 108, 100, 4, 0, 0, 0, 240, 159, 153, 130, - ] - expect(new Args().addArray(input, ArrayTypes.STRING).serialize()).toEqual( - serialized - ) - expect(new Args(serialized).nextArray(ArrayTypes.STRING)).toEqual(input) - }) -}) - describe('array.ts functions', () => { describe('getDatatypeSize tests', () => { it('returns the correct size for BOOL', () => { @@ -352,14 +142,26 @@ describe('array.ts functions', () => { }) it('converts a U8 array to bytes and back correctly', () => { - const dataArray = [1, 2, 3, 4, 5] + const dataArray = [ + U8.fromNumber(1), + U8.fromNumber(2), + U8.fromNumber(3), + U8.fromNumber(4), + U8.fromNumber(5), + ] const byteArray = arrayToBytes(dataArray, ArrayTypes.U8) const arrayBack = bytesToArray(byteArray, ArrayTypes.U8) expect(arrayBack).toEqual(dataArray) }) it('converts a U32 array to bytes and back correctly', () => { - const dataArray = [10, 20, 30, 40, 50] + const dataArray = [ + U32.fromNumber(10), + U32.fromNumber(20), + U32.fromNumber(30), + U32.fromNumber(40), + U32.fromNumber(50), + ] const byteArray = arrayToBytes(dataArray, ArrayTypes.U32) const arrayBack = bytesToArray(byteArray, ArrayTypes.U32) expect(arrayBack).toEqual(dataArray) @@ -367,11 +169,11 @@ describe('array.ts functions', () => { it('converts a U64 array to bytes and back correctly', () => { const dataArray = [ - BigInt(10), - BigInt(20), - BigInt(30), - BigInt(40), - BigInt(50), + U64.fromNumber(10), + U64.fromNumber(20), + U64.fromNumber(30), + U64.fromNumber(40), + U64.fromNumber(50), ] const byteArray = arrayToBytes(dataArray, ArrayTypes.U64) const arrayBack = bytesToArray(byteArray, ArrayTypes.U64) @@ -395,8 +197,8 @@ describe('array.ts functions', () => { 123456789123456789n, -123456789123456789n, 0n, - ser.I128_MAX, - ser.I128_MIN, + I128.MAX, + I128.MIN, -123456789123456789n, ] @@ -419,7 +221,7 @@ describe('array.ts functions', () => { }) it('converts a I32 array to bytes and back correctly', () => { - const dataArray = [-10, -20, -30, -40, -50] + const dataArray = [-10, -20, -30, -40, -50].map(I32.fromNumber) const byteArray = arrayToBytes(dataArray, ArrayTypes.I32) const arrayBack = bytesToArray(byteArray, ArrayTypes.I32) expect(arrayBack).toEqual(dataArray) @@ -464,7 +266,7 @@ describe('array.ts functions', () => { const arrayBack = bytesToArray(byteArray, ArrayTypes.F32) arrayBack.forEach((value, index) => { - expect(value).toBeCloseTo(dataArray[index], 5) // 5 is the precision (number of digits after the decimal point) + expect(value).toBeCloseTo(dataArray[index], 5) }) }) it('converts a F64 array to bytes and back correctly', () => { @@ -473,7 +275,7 @@ describe('array.ts functions', () => { const arrayBack = bytesToArray(byteArray, ArrayTypes.F64) arrayBack.forEach((value, index) => { - expect(value).toBeCloseTo(dataArray[index], 5) // 5 is the precision (number of digits after the decimal point) + expect(value).toBeCloseTo(dataArray[index], 5) }) }) it('throws an error when an unsupported type is used', () => { @@ -485,5 +287,15 @@ describe('array.ts functions', () => { `Unsupported type: ${unsupportedType}` ) }) + + it('string array', () => { + const dataArray = ['bonjour', 'hello', 'hola', 'hallo', 'ciao'] + const byteArray = new Args() + .addArray(dataArray, ArrayTypes.STRING) + .serialize() + const arrayBack = new Args(byteArray).nextArray(ArrayTypes.STRING) + + expect(arrayBack).toEqual(dataArray) + }) }) }) diff --git a/test/unit/serializers/serializers.spec.ts b/test/unit/serializers/serializers.spec.ts new file mode 100644 index 00000000..26d7866a --- /dev/null +++ b/test/unit/serializers/serializers.spec.ts @@ -0,0 +1,216 @@ +import { Args } from '../../../src/basicElements/args' +import { + U8, + U16, + U32, + U64, + U128, + U256, + I8, + I16, + I32, + I64, + I128, + I256, + boolToByte, + byteToBool, + bytesToF32, + bytesToF64, + bytesToStr, + f32ToBytes, + f64ToBytes, + strToBytes, +} from '../../../src/basicElements/serializers' + +describe('Serialization tests', () => { + it('ser/deser with emojis', () => { + const str = 'Hello world ๐Ÿ™‚' + expect(bytesToStr(strToBytes(str))).toEqual(str) + }) + it('ser/deser Ascii', () => { + const str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' + expect(bytesToStr(strToBytes(str))).toEqual(str) + }) + it('ser/deser utf16 char', () => { + const str = String.fromCharCode(0xd83d, 0xde42) + expect(bytesToStr(strToBytes(str))).toEqual('๐Ÿ™‚') + }) + it('ser/deser bool', () => { + let val = false + expect(byteToBool(boolToByte(val))).toEqual(val) + val = true + expect(byteToBool(boolToByte(val))).toEqual(val) + }) + // Duplicate of serializedInteger.spec.ts? + it('ser/deser u8', () => { + const val = 123 + expect(U8.fromBytes(U8.toBytes(U8.fromNumber(val)))).toEqual(BigInt(val)) + }) + it('throws an error when trying to serialize a negative Uint8 value', () => { + const negativeValue = -1n + const args = new Args() + + expect(() => args.addU8(negativeValue)).toThrow( + `negative value can't be serialized as unsigned integer.` + ) + }) + it('throws an error when trying to serialize a Uint8 value greater than 255', () => { + const largeValue = 256n + const args = new Args() + + expect(() => args.addU8(largeValue)).toThrow( + `value ${largeValue} is too large for an U8.` + ) + }) + // Duplicate of serializedInteger.spec.ts? + it('ser/deser u16', () => { + const val = 123 + expect(U16.fromBytes(U16.toBytes(U16.fromNumber(val)))).toEqual(BigInt(val)) + }) + it('ser/deser i16', () => { + const val = 123 + expect(I16.fromBytes(I16.toBytes(I16.fromNumber(val)))).toEqual(BigInt(val)) + }) + // Duplicate of serializedInteger.spec.ts? + it('ser/deser u32', () => { + const val = 666 + expect(U32.fromBytes(U32.toBytes(U32.fromNumber(val)))).toEqual(BigInt(val)) + }) + it('throws an error when trying to serialize a negative u32 value', () => { + const negativeValue = -1n + const args = new Args() + + expect(() => args.addU32(negativeValue)).toThrow( + `negative value can't be serialized as unsigned integer.` + ) + }) + it('throws an error when trying to serialize a Uint32 value greater than 4294967295', () => { + const largeValue = 4294967296n + const args = new Args() + + expect(() => args.addU32(largeValue)).toThrow( + `value ${largeValue} is too large for an U32.` + ) + }) + // Duplicate of serializedInteger.spec.ts? + it('ser/deser u64', () => { + const val = BigInt(666) + expect(U64.fromBytes(U64.toBytes(U64.fromNumber(val)))).toEqual(val) + }) + it('throws an error when trying to serialize a negative u64 value', () => { + const negativeValue = BigInt(-1) + const args = new Args() + + expect(() => args.addU64(negativeValue)).toThrow( + `negative value can't be serialized as unsigned integer.` + ) + }) + it('throws an error when trying to serialize a u64 value greater than 18446744073709551615', () => { + const largeValue = BigInt('18446744073709551616') + const args = new Args() + + expect(() => args.addU64(largeValue)).toThrow( + `value ${largeValue} is too large for an U64.` + ) + }) + + it('ser/deser i128', () => { + const val = -123456789123456789n + expect(I128.fromBytes(I128.toBytes(I128.fromNumber(val)))).toEqual(val) + }) + it('ser/deser i128', () => { + const val = I128.MAX + expect(I128.fromBytes(I128.toBytes(I128.fromNumber(val)))).toEqual(val) + }) + it('ser/deser i128', () => { + const val = I128.MIN + expect(I128.fromBytes(I128.toBytes(I128.fromNumber(val)))).toEqual(val) + }) + + it('ser/deser u128', () => { + const val = BigInt('123456789123456789123456789') + expect(U128.fromBytes(U128.toBytes(U128.fromNumber(val)))).toEqual(val) + }) + + it('throws an error when trying to serialize a negative u128 value', () => { + const negativeValue = BigInt(-1) + const args = new Args() + + expect(() => args.addU128(negativeValue)).toThrow( + `negative value can't be serialized as unsigned integer.` + ) + }) + + it('throws an error when trying to serialize a u128 value greater than U128_MAX', () => { + const largeValue = U128.MAX + 1n + const args = new Args() + + expect(() => args.addU128(largeValue)).toThrow( + `value ${largeValue} is too large for an U128.` + ) + }) + it('ser/deser u256', () => { + const val = 123456789012345678901234567890n + expect(U256.fromBytes(U256.toBytes(val))).toEqual(val) + }) + it('throws an error when trying to serialize a negative u256 value', () => { + const negativeValue = BigInt(-1) + const args = new Args() + + expect(() => args.addU256(negativeValue)).toThrow( + `negative value can't be serialized as unsigned integer.` + ) + }) + it('throws an error when trying to serialize a u256 value greater than U256_MAX', () => { + const largeValue = U256.MAX + 1n + const args = new Args() + + expect(() => args.addU256(largeValue)).toThrow( + `value ${largeValue} is too large for an U256.` + ) + }) + it('ser/deser i32', () => { + const val = -666 + expect(I32.fromBytes(I32.toBytes(I32.fromNumber(val)))).toEqual(BigInt(val)) + }) + it('throws an error when trying to serialize an invalid int32 value', () => { + const invalidValue = Math.pow(2, 31) + const args = new Args() + + expect(() => args.addI32(I32.fromNumber(invalidValue))).toThrow( + `value ${invalidValue} is out of range for an I32.` + ) + }) + it('ser/deser i64', () => { + const val = BigInt(-666) + expect(I64.fromBytes(I64.toBytes(I64.fromNumber(val)))).toEqual(val) + }) + it('throws an error when trying to serialize an invalid int64 value', () => { + const invalidValue = BigInt('9223372036854775808') + const args = new Args() + + expect(() => args.addI64(invalidValue)).toThrow( + `value ${invalidValue} is out of range for an I64.` + ) + }) + it('ser/deser f32', () => { + const val = -666.666 + expect(bytesToF32(f32ToBytes(val))).toBeCloseTo(val, 0.001) + }) + it('ser/deser f64', () => { + const val = -666.666 + expect(bytesToF64(f64ToBytes(val))).toEqual(val) + }) + it('ser/deser f64 max val', () => { + const val = Number.MAX_VALUE + expect(bytesToF64(f64ToBytes(val))).toEqual(val) + }) + it('ser/deser empty string', () => { + const str = '' + expect(bytesToStr(strToBytes(str))).toEqual(str) + }) + it('ser/deser empty Uint8Array', () => { + const arr = new Uint8Array(0) + expect(bytesToStr(arr)).toEqual('') + }) +}) diff --git a/test/unit/storage.spec.ts b/test/unit/storage.spec.ts new file mode 100644 index 00000000..ccd08bcd --- /dev/null +++ b/test/unit/storage.spec.ts @@ -0,0 +1,37 @@ +import * as Mas from '../../src/basicElements/mas' +import * as StorageCost from '../../src/basicElements/storage' + +const STORAGE_BYTE_COST = Mas.fromString('0.0001') +const BASE_ACCOUNT_CREATION_COST = Mas.fromString('0.001') + +describe('StorageCost', () => { + describe('bytes', () => { + it('should calculate the cost of a given number of bytes', () => { + const numberOfBytes = 10 + const expectedCost = BigInt(numberOfBytes) * STORAGE_BYTE_COST + expect(StorageCost.bytes(numberOfBytes)).toEqual(expectedCost) + }) + }) + + describe('account', () => { + it('should calculate the cost of creating a new account', () => { + expect(StorageCost.account()).toEqual(BASE_ACCOUNT_CREATION_COST) + }) + }) + + describe('smartContract', () => { + it('should calculate the cost of deploying a smart contract', () => { + const numberOfBytes = 10 + const expectedCost = + StorageCost.bytes(numberOfBytes) + StorageCost.account() + expect(StorageCost.smartContract(numberOfBytes)).toEqual(expectedCost) + }) + }) + + describe('newEntry', () => { + it('should calculate the cost of creating a new entry in the datastore', () => { + const expectedCost = StorageCost.bytes(4) + expect(StorageCost.newEntry()).toEqual(expectedCost) + }) + }) +}) diff --git a/test/unit/wallet_test_version_1.yaml b/test/unit/wallet_test_version_1.yaml new file mode 100644 index 00000000..c71ee3cd --- /dev/null +++ b/test/unit/wallet_test_version_1.yaml @@ -0,0 +1,94 @@ +Version: 1 +Nickname: test_version_1 +Address: AU126tkwrhXn9gEG5JPtrNy8NNLbVMwywokgLKshSYyzP8qusqXZL +Salt: + [146, 63, 151, 136, 93, 135, 105, 113, 124, 41, 189, 207, 86, 124, 17, 152] +Nonce: [250, 104, 81, 250, 235, 79, 110, 84, 243, 225, 144, 242] +CipheredData: + [ + 191, + 181, + 5, + 198, + 76, + 145, + 242, + 89, + 253, + 215, + 151, + 10, + 245, + 32, + 241, + 9, + 171, + 181, + 76, + 103, + 121, + 184, + 33, + 16, + 227, + 83, + 53, + 133, + 194, + 38, + 20, + 217, + 34, + 61, + 169, + 108, + 156, + 217, + 196, + 74, + 34, + 127, + 129, + 33, + 103, + 215, + 117, + 66, + 78, + ] +PublicKey: + [ + 0, + 143, + 111, + 199, + 160, + 227, + 187, + 57, + 238, + 223, + 80, + 251, + 169, + 64, + 21, + 116, + 165, + 95, + 187, + 192, + 76, + 97, + 33, + 64, + 208, + 119, + 99, + 182, + 139, + 174, + 219, + 61, + 109, + ] diff --git a/packages/massa-web3/tsconfig.commonjs.json b/tsconfig.commonjs.json similarity index 100% rename from packages/massa-web3/tsconfig.commonjs.json rename to tsconfig.commonjs.json diff --git a/packages/massa-web3/tsconfig.esm.json b/tsconfig.esm.json similarity index 100% rename from packages/massa-web3/tsconfig.esm.json rename to tsconfig.esm.json diff --git a/tsconfig.base.json b/tsconfig.json similarity index 70% rename from tsconfig.base.json rename to tsconfig.json index 08bb124f..159dc896 100644 --- a/tsconfig.base.json +++ b/tsconfig.json @@ -16,6 +16,7 @@ "skipLibCheck": true, "esModuleInterop": true, "outDir": "./dist", + "strictNullChecks": true, "types": [ "node", "jest" @@ -25,21 +26,13 @@ "esnext" ], "baseUrl": ".", - "paths": { - "@massalabs/massa-web3/*": [ - "packages/massa-web3/src/*" - ], - "@massalabs/web3-utils/*": [ - "packages/web3-utils/src/*" - ] - } }, "include": [ - "packages/**/src/**/*.ts" - ], + "./src/**/*.ts" + ], "exclude": [ "node_modules", - "packages/**/node_modules", - "packages/**/dist" + "dist", + "**/*.spec.ts" ] } \ No newline at end of file diff --git a/packages/massa-web3/tsdoc.json b/tsdoc.json similarity index 100% rename from packages/massa-web3/tsdoc.json rename to tsdoc.json diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 00000000..b52e1903 --- /dev/null +++ b/typedoc.json @@ -0,0 +1,9 @@ +{ + "navigation": { + "includeGroups": true + }, + "navigationLinks": { + "Main documentation": "https://docs.massa.net/" + }, + "entryPoints": ["src"] +} \ No newline at end of file