diff --git a/.depcheckrc.json b/.depcheckrc.json new file mode 100644 index 00000000..fa091274 --- /dev/null +++ b/.depcheckrc.json @@ -0,0 +1,22 @@ +{ + "ignores": [ + "@arethetypeswrong/cli", + "@lavamoat/allow-scripts", + "@lavamoat/preinstall-always-fail", + "@metamask/auto-changelog", + "@metamask/eslint-config", + "@metamask/eslint-config-*", + "@types/*", + "@typescript-eslint/utils", + "@vitest/coverage-istanbul", + "@vitest/eslint-plugin", + "@yarnpkg/types", + "eslint-config-*", + "eslint-import-resolver-typescript", + "eslint-plugin-*", + "prettier-plugin-packagejson", + "ts-node", + "typedoc", + "typescript-eslint" + ] +} diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index c9b7a2f3..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = { - root: true, - - extends: ['@metamask/eslint-config'], - - overrides: [ - { - files: ['*.ts'], - extends: ['@metamask/eslint-config-typescript'], - rules: { - // TODO: Move this to our shared config - 'no-invalid-this': 'off', - '@typescript-eslint/no-invalid-this': ['error'], - }, - }, - - { - files: ['*.js'], - extends: ['@metamask/eslint-config-nodejs'], - }, - - { - files: ['*.test.ts', './tests/setupAfterEnv.ts'], - extends: ['@metamask/eslint-config-jest'], - }, - ], - - ignorePatterns: ['!.eslintrc.js', '!.prettierrc.js', 'dist/'], -}; diff --git a/.gitattributes b/.gitattributes index bf5e085f..524151a2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,8 @@ * text=auto yarn.lock linguist-generated=false + +# yarn v3 +# See: https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored +/.yarn/releases/** binary +/.yarn/plugins/** binary diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 50bea790..77e1abab 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # Lines starting with '#' are comments. # Each line is a file pattern followed by one or more owners. -* @MetaMask/devs +* @MetaMask/core-platform diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..5fc5feac --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,11 @@ + diff --git a/.github/workflows/build-lint-test.yml b/.github/workflows/build-lint-test.yml new file mode 100644 index 00000000..6a3c122d --- /dev/null +++ b/.github/workflows/build-lint-test.yml @@ -0,0 +1,50 @@ +name: Build, Lint, and Test + +on: + workflow_call: + +jobs: + build-lint-test: + name: Build, Lint, and Test + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18.x, 20.x, 22.x] + steps: + - uses: actions/checkout@v4 + - name: Install Corepack via Node + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + - name: Install Yarn + run: corepack enable + - name: Install Node.js ${{ matrix.node-version }} and restore Yarn cache + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'yarn' + - name: Install dependencies via Yarn + run: yarn --immutable + - run: yarn build + - run: yarn lint + - run: yarn test + - name: Validate RC changelog + if: ${{ startsWith(github.head_ref, 'release/') }} + run: yarn auto-changelog validate --rc --prettier + - name: Validate changelog + if: ${{ !startsWith(github.head_ref, 'release/') }} + run: yarn auto-changelog validate --prettier + - name: Require clean working directory + shell: bash + run: | + if ! git diff --exit-code; then + echo "Working tree dirty after building" + exit 1 + fi + all-jobs-pass: + name: All jobs pass + runs-on: ubuntu-latest + needs: + - build-lint-test + steps: + - run: echo "Great success!" diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml deleted file mode 100644 index ee0bc302..00000000 --- a/.github/workflows/build-test.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Build, Lint, and Test - -on: - push: - branches: [main] - pull_request: - -jobs: - build-lint-test: - name: Build, Lint, and Test - runs-on: ubuntu-20.04 - strategy: - matrix: - node-version: [14.x, 16.x] - steps: - - uses: actions/checkout@v2 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node-version }} - - name: Get Yarn cache directory - run: echo "::set-output name=YARN_CACHE_DIR::$(yarn cache dir)" - id: yarn-cache-dir - - name: Get Yarn version - run: echo "::set-output name=YARN_VERSION::$(yarn --version)" - id: yarn-version - - name: Cache yarn dependencies - uses: actions/cache@v2 - with: - path: ${{ steps.yarn-cache-dir.outputs.YARN_CACHE_DIR }} - key: yarn-cache-${{ runner.os }}-${{ steps.yarn-version.outputs.YARN_VERSION }}-${{ hashFiles('yarn.lock') }} - - run: yarn --frozen-lockfile - - run: yarn allow-scripts - - run: yarn build - - run: yarn lint - - run: yarn test - - name: Validate RC changelog - if: ${{ startsWith(github.head_ref, 'release/') }} - run: yarn auto-changelog validate --rc - - name: Validate changelog - if: ${{ !startsWith(github.head_ref, 'release/') }} - run: yarn auto-changelog validate - - name: Require clean working directory - shell: bash - run: | - if ! git diff --exit-code; then - echo "Working tree dirty after building" - exit 1 - fi - all-jobs-pass: - name: All jobs pass - runs-on: ubuntu-20.04 - needs: - - build-lint-test - steps: - - run: echo "Great success!" diff --git a/.github/workflows/create-release-pr.yml b/.github/workflows/create-release-pr.yml index e843833d..730e1b65 100644 --- a/.github/workflows/create-release-pr.yml +++ b/.github/workflows/create-release-pr.yml @@ -21,7 +21,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: # This is to guarantee that the most recent tag is fetched. # This can be configured to a more reasonable value by consumers. @@ -29,22 +29,12 @@ jobs: # We check out the specified branch, which will be used as the base # branch for all git operations and the release PR. ref: ${{ github.event.inputs.base-branch }} - - name: Get Node.js version - id: nvm - run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc) - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v4 with: - node-version: ${{ steps.nvm.outputs.NODE_VERSION }} - - uses: MetaMask/action-create-release-pr@v1 + node-version-file: .nvmrc + - uses: MetaMask/action-create-release-pr@v3 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: release-type: ${{ github.event.inputs.release-type }} release-version: ${{ github.event.inputs.release-version }} - artifacts-path: gh-action__release-authors - # Upload the release author artifact for use in subsequent workflows - - uses: actions/upload-artifact@v2 - with: - name: release-authors - path: gh-action__release-authors - if-no-files-found: error diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..21493f84 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,93 @@ +name: Main + +on: + push: + branches: [main] + pull_request: + +jobs: + check-workflows: + name: Check workflows + runs-on: ubuntu-latest + steps: + - name: Checkout and setup environment + uses: MetaMask/action-checkout-and-setup@v1 + with: + is-high-risk-environment: false + - name: Download actionlint + id: download-actionlint + run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/7fdc9630cc360ea1a469eed64ac6d78caeda1234/scripts/download-actionlint.bash) 1.6.23 + shell: bash + - name: Check workflow files + run: ${{ steps.download-actionlint.outputs.executable }} -color + shell: bash + + analyse-code: + name: Code scanner + needs: check-workflows + uses: ./.github/workflows/security-code-scanner.yml + permissions: + actions: read + contents: read + security-events: write + secrets: + SECURITY_SCAN_METRICS_TOKEN: ${{ secrets.SECURITY_SCAN_METRICS_TOKEN }} + APPSEC_BOT_SLACK_WEBHOOK: ${{ secrets.APPSEC_BOT_SLACK_WEBHOOK }} + + build-lint-test: + name: Build, lint, and test + uses: ./.github/workflows/build-lint-test.yml + + all-jobs-completed: + name: All jobs completed + runs-on: ubuntu-latest + needs: + - check-workflows + - analyse-code + - build-lint-test + outputs: + PASSED: ${{ steps.set-output.outputs.PASSED }} + steps: + - name: Set PASSED output + id: set-output + run: echo "PASSED=true" >> "$GITHUB_OUTPUT" + + all-jobs-pass: + name: All jobs pass + if: ${{ always() }} + runs-on: ubuntu-latest + needs: all-jobs-completed + steps: + - name: Check that all jobs have passed + run: | + passed="${{ needs.all-jobs-completed.outputs.PASSED }}" + if [[ $passed != "true" ]]; then + exit 1 + fi + + is-release: + # Filtering by `push` events ensures that we only release from the `main` branch, which is a + # requirement for our npm publishing environment. + # The commit author should always be 'github-actions' for releases created by the + # 'create-release-pr' workflow, so we filter by that as well to prevent accidentally + # triggering a release. + if: github.event_name == 'push' && startsWith(github.event.head_commit.author.name, 'github-actions') + needs: all-jobs-pass + outputs: + IS_RELEASE: ${{ steps.is-release.outputs.IS_RELEASE }} + runs-on: ubuntu-latest + steps: + - uses: MetaMask/action-is-release@v1 + id: is-release + + publish-release: + needs: is-release + if: needs.is-release.outputs.IS_RELEASE == 'true' + name: Publish release + permissions: + contents: write + uses: ./.github/workflows/publish-release.yml + secrets: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + PUBLISH_DOCS_TOKEN: ${{ secrets.PUBLISH_DOCS_TOKEN }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 31484ac4..46587154 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -1,29 +1,80 @@ name: Publish Release on: - pull_request: - types: [closed] - + workflow_call: + secrets: + NPM_TOKEN: + required: true + SLACK_WEBHOOK_URL: + required: true + PUBLISH_DOCS_TOKEN: + required: true jobs: publish-release: permissions: contents: write - if: | - github.event.pull_request.merged == true && - startsWith(github.event.pull_request.head.ref, 'release/') runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - with: - # We check out the release pull request's base branch, which will be - # used as the base branch for all git operations. - ref: ${{ github.event.pull_request.base.ref }} - - name: Get Node.js version - id: nvm - run: echo ::set-output name=NODE_VERSION::$(cat .nvmrc) - - uses: actions/setup-node@v2 - with: - node-version: ${{ steps.nvm.outputs.NODE_VERSION }} - - uses: MetaMask/action-publish-release@v1 + - name: Checkout and setup environment + uses: MetaMask/action-checkout-and-setup@v1 + with: + is-high-risk-environment: true + ref: ${{ github.sha }} + - uses: MetaMask/action-publish-release@v3 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - run: yarn build + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: publish-release-artifacts-${{ github.sha }} + retention-days: 4 + include-hidden-files: true + path: | + ./dist + ./node_modules/.yarn-state.yml + + publish-npm-dry-run: + needs: publish-release + runs-on: ubuntu-latest + steps: + - name: Checkout and setup environment + uses: MetaMask/action-checkout-and-setup@v1 + with: + is-high-risk-environment: true + ref: ${{ github.sha }} + - name: Restore build artifacts + uses: actions/download-artifact@v4 + with: + name: publish-release-artifacts-${{ github.sha }} + - name: Dry Run Publish + # omit npm-token token to perform dry run publish + uses: MetaMask/action-npm-publish@v5 + with: + slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} + subteam: S042S7RE4AE # @metamask-npm-publishers + env: + SKIP_PREPACK: true + + publish-npm: + needs: publish-npm-dry-run + runs-on: ubuntu-latest + environment: npm-publish + steps: + - name: Checkout and setup environment + uses: MetaMask/action-checkout-and-setup@v1 + with: + is-high-risk-environment: true + ref: ${{ github.sha }} + - name: Restore build artifacts + uses: actions/download-artifact@v4 + with: + name: publish-release-artifacts-${{ github.sha }} + - name: Publish + uses: MetaMask/action-npm-publish@v5 + with: + # This `NPM_TOKEN` needs to be manually set per-repository. + # Look in the repository settings under "Environments", and set this token in the `npm-publish` environment. + npm-token: ${{ secrets.NPM_TOKEN }} + env: + SKIP_PREPACK: true diff --git a/.github/workflows/require-additional-reviewer.yml b/.github/workflows/require-additional-reviewer.yml deleted file mode 100644 index 1ea1c062..00000000 --- a/.github/workflows/require-additional-reviewer.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Require Additional Reviewer for Releases - -on: - pull_request: - pull_request_review: - -jobs: - require-additional-reviewer: - permissions: - actions: read - contents: read - pull-requests: read - statuses: write - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - # If the base branch has been merged into the release branch, we - # need to find the earliest common ancestor commit of the base and - # release branches. - fetch-depth: 0 - # We want the head / feature branch to be checked out, and we will - # compare it to the base branch in the action. - ref: ${{ github.event.pull_request.head.ref }} - - uses: MetaMask/action-require-additional-reviewer@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - read-org-token: ${{ secrets.ORG_READER }} diff --git a/.github/workflows/security-code-scanner.yml b/.github/workflows/security-code-scanner.yml new file mode 100644 index 00000000..ababbbeb --- /dev/null +++ b/.github/workflows/security-code-scanner.yml @@ -0,0 +1,47 @@ +name: MetaMask Security Code Scanner + +on: + workflow_call: + secrets: + SECURITY_SCAN_METRICS_TOKEN: + required: false + APPSEC_BOT_SLACK_WEBHOOK: + required: false + workflow_dispatch: + +jobs: + run-security-scan: + name: Run security scan + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + steps: + - name: Analyse code + uses: MetaMask/action-security-code-scanner@v1 + with: + repo: ${{ github.repository }} + paths_ignored: | + .storybook/ + '**/__snapshots__/' + '**/*.snap' + '**/*.stories.js' + '**/*.stories.tsx' + '**/*.test.browser.ts*' + '**/*.test.js*' + '**/*.test.ts*' + '**/fixtures/' + '**/jest.config.js' + '**/jest.environment.js' + '**/mocks/' + '**/test*/' + docs/ + e2e/ + merged-packages/ + node_modules + storybook/ + test*/ + rules_excluded: example + project_metrics_token: ${{ secrets.SECURITY_SCAN_METRICS_TOKEN }} + slack_webhook: ${{ secrets.APPSEC_BOT_SLACK_WEBHOOK }} diff --git a/.gitignore b/.gitignore index 174c7d59..d54c2ba0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store dist/ coverage/ +docs/ # Logs logs @@ -66,9 +67,12 @@ node_modules/ # Stores VSCode versions used for testing VSCode extensions .vscode-test -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz +# yarn v3 (w/o zero-install) +# See: https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored .pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions diff --git a/.nvmrc b/.nvmrc index 958b5a36..b009dfb9 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v14 +lts/* diff --git a/.prettierrc.js b/.prettierrc.mjs similarity index 67% rename from .prettierrc.js rename to .prettierrc.mjs index b2d98d2e..3322d030 100644 --- a/.prettierrc.js +++ b/.prettierrc.mjs @@ -1,8 +1,11 @@ // All of these are defaults except singleQuote, but we specify them // for explicitness -module.exports = { +const config = { quoteProps: 'as-needed', singleQuote: true, tabWidth: 2, trailingComma: 'all', + plugins: ['prettier-plugin-packagejson'], }; + +export default config; diff --git a/.yarn/plugins/@yarnpkg/plugin-allow-scripts.cjs b/.yarn/plugins/@yarnpkg/plugin-allow-scripts.cjs new file mode 100644 index 00000000..e4acaee3 --- /dev/null +++ b/.yarn/plugins/@yarnpkg/plugin-allow-scripts.cjs @@ -0,0 +1,9 @@ +/* eslint-disable */ +//prettier-ignore +module.exports = { +name: "@yarnpkg/plugin-allow-scripts", +factory: function (require) { +var plugin=(()=>{var l=Object.defineProperty;var s=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var p=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(o,e)=>(typeof require<"u"?require:o)[e]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+t+'" is not supported')});var u=(t,o)=>{for(var e in o)l(t,e,{get:o[e],enumerable:!0})},f=(t,o,e,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let i of a(o))!c.call(t,i)&&i!==e&&l(t,i,{get:()=>o[i],enumerable:!(r=s(o,i))||r.enumerable});return t};var m=t=>f(l({},"__esModule",{value:!0}),t);var g={};u(g,{default:()=>d});var n=p("@yarnpkg/shell"),x={hooks:{afterAllInstalled:async()=>{let t=await(0,n.execute)("yarn run allow-scripts");t!==0&&process.exit(t)}}},d=x;return m(g);})(); +return plugin; +} +}; diff --git a/.yarnrc b/.yarnrc deleted file mode 100644 index 5455c6c5..00000000 --- a/.yarnrc +++ /dev/null @@ -1 +0,0 @@ -ignore-scripts true diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 00000000..6e38e4ba --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,17 @@ +compressionLevel: mixed + +enableGlobalCache: false + +enableScripts: false + +enableTelemetry: 0 + +logFilters: + - code: YN0004 + level: discard + +nodeLinker: node-modules + +plugins: + - path: .yarn/plugins/@yarnpkg/plugin-allow-scripts.cjs + spec: "https://raw.githubusercontent.com/LavaMoat/LavaMoat/main/packages/yarn-plugin-allow-scripts/bundles/@yarnpkg/plugin-allow-scripts.js" diff --git a/CHANGELOG.md b/CHANGELOG.md index 87aa0994..d97b44a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # Changelog + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), @@ -6,8 +7,201 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [13.0.0] + +### Changed + +- **BREAKING:** Distribute separate CommonJS and ESM files ([#351](https://github.com/MetaMask/eth-block-tracker/pull/351)) + - Use the `exports` field of `package.json`, breaking some previously valid imports. + +## [12.2.1] + +### Fixed + +- `PollingBlockTracker.checkForLatestBlock()` and `getLatestBlock()` now clear the cached block after `blockReset` duration when called and the `PollingBlockTracker` is not polling. ([#348](https://github.com/MetaMask/eth-block-tracker/pull/348)) + +## [12.2.0] + +### Changed + +- `PollingBlockTracker.getLatestBlock()` now accepts an optional parameter `useCache` ([#340](https://github.com/MetaMask/eth-block-tracker/pull/340)) + - This option defaults to `true`, but when `false`, it ignores the cached block number and instead updates and returns a new block number, ensuring that the frequency of requests is limited to the `pollingInterval` period + +## [12.1.0] + +### Changed + +- Bump `@metamask/eth-json-rpc-provider` from `^4.1.5` to `^5.0.0` ([#334](https://github.com/MetaMask/eth-block-tracker/pull/334)) + +## [12.0.1] + +### Fixed + +- Fixed hanging `getLatestBlock()` promises when block tracker is stopped before request completion ([#320](https://github.com/MetaMask/eth-block-tracker/pull/320)) + - Pending `getLatestBlock()` requests are now properly rejected with "Block tracker destroyed" error when the tracker is stopped + +## [12.0.0] + +### Changed + +- Errors that occur while polling are no longer wrapped ([#310](https://github.com/MetaMask/eth-block-tracker/pull/310)) + +### Removed + +- **BREAKING:** Remove `SubscribeBlockTracker` ([#309](https://github.com/MetaMask/eth-block-tracker/pull/309)) + - Although we continue to maintain this, we have not used it internally for quite some time. In general we have found a polling-based approval to be reliable than a subscription-based approach. We recommend using `PollingBlockTracker` instead. + +### Fixed + +- Fix `PollingBlockTracker.getLatestBlock` so that it throws an error encountered while making the request instead of hanging, regardless of whether the request occurs inside or outside of a polling loop ([#313](https://github.com/MetaMask/eth-block-tracker/pull/313)) +- Fix `PollingBlockTracker.getLatestBlock` so that if invoked while a previous invocation is pending, it will throw if that invocation also throws ([#313](https://github.com/MetaMask/eth-block-tracker/pull/313)) + +## [11.0.4] + +### Changed + +- Bump `@metamask/utils` from `^9.1.0` to `^11.0.1` ([#297](https://github.com/MetaMask/eth-block-tracker/pull/297)) + +## [11.0.3] + +### Fixed + +- Avoid risk of infinite retry loops when fetching new blocks ([#284](https://github.com/MetaMask/eth-block-tracker/pull/284)) + - When the provider returns an error and `PollingBlockTracker` or `SubscribeBlockTracker` is destroyed, the promise returned by the `getLatestBlock` method will be rejected. + +## [11.0.2] + +### Fixed + +- Bump `@metamask/eth-json-rpc-provider` from `^4.1.1` to `^4.1.5` ([#273](https://github.com/MetaMask/eth-block-tracker/pull/273)) + +## [11.0.1] + +### Changed + +- Bump `@metamask/eth-json-rpc-provider` from `^4.1.0` to `^4.1.1` ([#261](https://github.com/MetaMask/eth-block-tracker/pull/261)) +- Bump `@metamask/safe-event-emitter` from `^3.0.0` to `^3.1.1` ([#261](https://github.com/MetaMask/eth-block-tracker/pull/261)) +- Bump `@metamask/utils` from `^8.1.0` to `^9.1.0` ([#261](https://github.com/MetaMask/eth-block-tracker/pull/261)) + +## [11.0.0] + +### Changed + +- **BREAKING**: Adapt to EIP-1193 provider changes by using `request` method of provider instead of `sendAsync` ([#252](https://github.com/MetaMask/eth-block-tracker/pull/252)) + - This change included in `10.1.0` was mistakenly categorised as a non-breaking change. + - This requires provider object to have the `request` method. You need to upgrade to minimum `4.1.0` of `@metamask/eth-json-rpc-provider` so that the `request` method is available. + +## [10.1.0] [DEPRECATED] + +### Changed + +- Adapt to EIP-1193 provider changes ([#252](https://github.com/MetaMask/eth-block-tracker/pull/252)) + - Deprecated `sendAsync` method is replaced with `request` method +- Bump `@metamask/eth-json-rpc-provider` from `^4.0.0` to `^4.1.0` ([#252](https://github.com/MetaMask/eth-block-tracker/pull/252)) + +## [10.0.0] + +### Changed + +- BREAKING: Drop support for Node.js v16; add support for Node.js v20, v22 ([#245](https://github.com/MetaMask/eth-block-tracker/pull/245)) +- Update `@metamask/eth-json-rpc-provider` from `^3.0.2` to `^4.0.0` ([#247](https://github.com/MetaMask/eth-block-tracker/pull/247)) + +## [9.0.3] + +### Fixed + +- Update dependency `@metamask/eth-json-rpc-engine` from `^7.1.1` to `^8.0.2` ([#235](https://github.com/MetaMask/eth-block-tracker/pull/235)) +- Update dependency `@metamask/eth-json-rpc-provider` from `^2.3.1` to `^3.0.2` ([#235](https://github.com/MetaMask/eth-block-tracker/pull/235)) + +## [9.0.2] + +### Fixed + +- Put back missing empty `params` to `eth_blockNumber` call removed in 9.0.1 ([#198](https://github.com/MetaMask/eth-block-tracker/pull/198)) + +## [9.0.1] + +### Fixed + +- Concurrency fix: Prevent multiple simultaneous polling loops ([#208](https://github.com/MetaMask/eth-block-tracker/pull/208)) +- Bump `@metamask/eth-json-rpc-provider` from `^2.1.0` to `^2.3.1` ([#198](https://github.com/MetaMask/eth-block-tracker/pull/198)) ([#217](https://github.com/MetaMask/eth-block-tracker/pull/217)) + +## [9.0.0] + +### Changed + +- Rename package from `eth-block-tracker` to `@metamask/eth-block-tracker` ([#183](https://github.com/MetaMask/eth-block-tracker/pull/183)) + +## [8.1.0] + +### Changed + +- Typescript: Add `checkForLatestBlock` function to `BlockTracker` interface ([#184](https://github.com/MetaMask/eth-block-tracker/pull/184)) + +## [8.0.0] + +### Changed + +- Bump @metamask/utils from ^5.0.2 to ^8.1.0 ([#178](https://github.com/MetaMask/eth-block-tracker/pull/178)) +- **BREAKING**: Bump @metamask/eth-json-rpc-provider from ^1.0.0 to ^2.1.0 ([#174](https://github.com/MetaMask/eth-block-tracker/pull/174)) +- **BREAKING**: Increase minimum Node.js version to 16 ([#173](https://github.com/MetaMask/eth-block-tracker/pull/173)) + +## [7.2.0] + +### Added + +- Typescript: Export `BlockTracker` interface ([#168](https://github.com/MetaMask/eth-block-tracker/pull/168)) + +### Changed + +- Dependency Updates: ([#165](https://github.com/MetaMask/eth-block-tracker/pull/165)) + - Bump pify from ^3.0.0 to ^5.0.0 + - Bump @metamask/utils from ^5.0.1 to ^5.0.2 + +## [7.1.0] + +### Added + +- Add `usePastBlocks` to constructor ([#151](https://github.com/MetaMask/eth-block-tracker/pull/151)) + - Optional flag. When set to true, it allows blocks less than the current block number to be cached and returned. + +## [7.0.1] + +### Changed + +- Dependency updates: + - Bump @metamask/utils from 5.0.1 to 5.0.2 + - [#141](https://github.com/MetaMask/eth-block-tracker/pull/141) + - [#144](https://github.com/MetaMask/eth-block-tracker/pull/144) + - Bump @metamask/safe-event-emitter from 2.0.0 to 3.0.0 ([#143](https://github.com/MetaMask/eth-block-tracker/pull/143)) + +## [7.0.0] + +### Changed + +- **BREAKING:** The type of the `provider` option for `PollingBlockTracker` and `SubscribeBlockTracker` has changed ([#130](https://github.com/MetaMask/eth-block-tracker/pull/130)) + - The `provider` option must be compatible with the `SafeEventEmitterProvider` type from `@metamask/eth-json-rpc-middleware`. + - The new provider type should be mostly equivalent, except that it's now expected to have a `send` method. We don't use that `send` method in this package though. + +### Removed + +- **BREAKING:** Remove the `Provider` exported type ([#130](https://github.com/MetaMask/eth-block-tracker/pull/130)) + - We now use `@metamask/eth-json-rpc-provider` for this instead, so there was no need to re-export it. + +## [6.1.0] + +### Added + +- Add back Provider type that was accidentally removed in 6.0.0 ([#117](https://github.com/MetaMask/eth-block-tracker/pull/117)) + +### Fixed + +- Align Provider type with `eth-json-rpc-middleware` to prevent typecasting ([#117](https://github.com/MetaMask/eth-block-tracker/pull/117)) + ## [6.0.0] + ### Added + - Add logging ([#112](https://github.com/MetaMask/eth-block-tracker/pull/112)) - You will not be able to see log messages by default, but you can turn them on for this library by setting the `DEBUG` environment variable to `metamask:eth-block-tracker:*` or `metamask:*`. - Add `destroy` method to block tracker classes ([#106](https://github.com/MetaMask/eth-block-tracker/pull/106)) @@ -15,6 +209,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Expose types that represent options to PollingBlockTracker and SubscribeBlockTracker constructors ([#103](https://github.com/MetaMask/eth-block-tracker/pull/103)) ### Changed + - **BREAKING:** Require Node >= 14 ([#113](https://github.com/MetaMask/eth-block-tracker/pull/113)) - **BREAKING:** Make BaseBlockTracker abstract ([#103](https://github.com/MetaMask/eth-block-tracker/pull/103)) - If you are using this class directly, you must only use PollingBlockTracker or SubscribeBlockTracker. @@ -28,45 +223,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - This change was made because OpenEthereum does not support this parameter. While we've done our best to confirm that this will not be a breaking change for other Ethereum implementations, you will want to confirm no breakages for yours. ### Security + - Add `@lavamoat/allow-scripts` to ensure that install scripts are opt-in for dependencies ([#97](https://github.com/MetaMask/eth-block-tracker/pull/97)) ## [5.0.1] - 2021-03-25 + ### Fixed + - Add missing `types` field to `package.json` ([#75](https://github.com/MetaMask/eth-block-tracker/pull/75)) ## [5.0.0] - 2021-03-25 + ### Changed + - **(BREAKING)** Refactor exports ([#71](https://github.com/MetaMask/eth-block-tracker/pull/71)) - **(BREAKING)** Target ES2017, remove ES5 builds ([#71](https://github.com/MetaMask/eth-block-tracker/pull/71)) - Migrate to TypeScript ([#71](https://github.com/MetaMask/eth-block-tracker/pull/71)) - Update various dependencies ([#44](https://github.com/MetaMask/eth-block-tracker/pull/44), [#49](https://github.com/MetaMask/eth-block-tracker/pull/49), [#54](https://github.com/MetaMask/eth-block-tracker/pull/54), [#59](https://github.com/MetaMask/eth-block-tracker/pull/59), [#61](https://github.com/MetaMask/eth-block-tracker/pull/61), [#62](https://github.com/MetaMask/eth-block-tracker/pull/62), [#63](https://github.com/MetaMask/eth-block-tracker/pull/63), [#70](https://github.com/MetaMask/eth-block-tracker/pull/70), [#72](https://github.com/MetaMask/eth-block-tracker/pull/72)) ### Removed + - Remove unused production dependencies ([#60](https://github.com/MetaMask/eth-block-tracker/pull/60), [#68](https://github.com/MetaMask/eth-block-tracker/pull/68)) ## [4.4.3] - 2019-08-30 + ### Added + - Add SubscribeBlockTracker ### Changed + - Change events so that they now only return the block number (internal polling is done via `eth_blockNumber`) - Add `retryTimeout` and `keepEventLoopActive` to constructor - Update block trackers to inherit from `safe-event-emitter` rather than EventEmitter ### Removed + - Remove `block` event - Please use `latest` or `sync`. ## [4.0.0] - 2018-04-26 + ### Added + - Add isRunning method - Add `error` event ### Changed + - Significantly rewrite `eth-block-tracker` (primarily due to optimizing network IO) - Rename `awaitCurrentBlock` to `getLatestBlock` ### Removed + - Remove `stop`/`start` methods from BlockTrackers - BlockTrackers now automatically start and stop based on listener count for the `latest` and `sync` events. You can force a stop by calling the `EventEmitter` method `removeAllListeners`. - Remove tx body from block @@ -75,7 +284,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Remove test/util/testBlockMiddleware ## [3.0.0] - 2018-04-16 + ### Changed + - Update published version so main module now exports unprocessed source - Module includes dist: - Bundle: `dist/EthBlockTracker.js` @@ -85,19 +296,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - It no longer provides a callback to event handlers. ### Fixed + - Fix `awaitCurrentBlock` return value ## [2.0.0] - 2017-06-14 + ### Added + - Expose EventEmitter interface (via `async-eventemitter`) - Add `getTrackingBlock`, `getCurrentBlock`, `start`, and `stop` - Add events: `block`, `latest`, `sync` ## [1.0.0] - 2017-02-03 + ### Added + - Add RpcBlockTracker -[Unreleased]: https://github.com/MetaMask/eth-block-tracker/compare/v6.0.0...HEAD +[Unreleased]: https://github.com/MetaMask/eth-block-tracker/compare/v13.0.0...HEAD +[13.0.0]: https://github.com/MetaMask/eth-block-tracker/compare/v12.2.1...v13.0.0 +[12.2.1]: https://github.com/MetaMask/eth-block-tracker/compare/v12.2.0...v12.2.1 +[12.2.0]: https://github.com/MetaMask/eth-block-tracker/compare/v12.1.0...v12.2.0 +[12.1.0]: https://github.com/MetaMask/eth-block-tracker/compare/v12.0.1...v12.1.0 +[12.0.1]: https://github.com/MetaMask/eth-block-tracker/compare/v12.0.0...v12.0.1 +[12.0.0]: https://github.com/MetaMask/eth-block-tracker/compare/v11.0.4...v12.0.0 +[11.0.4]: https://github.com/MetaMask/eth-block-tracker/compare/v11.0.3...v11.0.4 +[11.0.3]: https://github.com/MetaMask/eth-block-tracker/compare/v11.0.2...v11.0.3 +[11.0.2]: https://github.com/MetaMask/eth-block-tracker/compare/v11.0.1...v11.0.2 +[11.0.1]: https://github.com/MetaMask/eth-block-tracker/compare/v11.0.0...v11.0.1 +[11.0.0]: https://github.com/MetaMask/eth-block-tracker/compare/v10.1.0...v11.0.0 +[10.1.0]: https://github.com/MetaMask/eth-block-tracker/compare/v10.0.0...v10.1.0 +[10.0.0]: https://github.com/MetaMask/eth-block-tracker/compare/v9.0.3...v10.0.0 +[9.0.3]: https://github.com/MetaMask/eth-block-tracker/compare/v9.0.2...v9.0.3 +[9.0.2]: https://github.com/MetaMask/eth-block-tracker/compare/v9.0.1...v9.0.2 +[9.0.1]: https://github.com/MetaMask/eth-block-tracker/compare/v9.0.0...v9.0.1 +[9.0.0]: https://github.com/MetaMask/eth-block-tracker/compare/v8.1.0...v9.0.0 +[8.1.0]: https://github.com/MetaMask/eth-block-tracker/compare/v8.0.0...v8.1.0 +[8.0.0]: https://github.com/MetaMask/eth-block-tracker/compare/v7.2.0...v8.0.0 +[7.2.0]: https://github.com/MetaMask/eth-block-tracker/compare/v7.1.0...v7.2.0 +[7.1.0]: https://github.com/MetaMask/eth-block-tracker/compare/v7.0.1...v7.1.0 +[7.0.1]: https://github.com/MetaMask/eth-block-tracker/compare/v7.0.0...v7.0.1 +[7.0.0]: https://github.com/MetaMask/eth-block-tracker/compare/v6.1.0...v7.0.0 +[6.1.0]: https://github.com/MetaMask/eth-block-tracker/compare/v6.0.0...v6.1.0 [6.0.0]: https://github.com/MetaMask/eth-block-tracker/compare/v5.0.1...v6.0.0 [5.0.1]: https://github.com/MetaMask/eth-block-tracker/compare/v5.0.0...v5.0.1 [5.0.0]: https://github.com/MetaMask/eth-block-tracker/compare/v4.4.3...v5.0.0 diff --git a/README.md b/README.md index 55d08113..90461c63 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,36 @@ -# eth-block-tracker +# @metamask/eth-block-tracker + + + + + +
+

⚠️ PLEASE READ ⚠️

+

+ This package has been migrated to our + core + monorepo, and this repository has been archived. Please note that all + future development and feature releases will take place in the + core + repository. +

+
This module walks the Ethereum blockchain, keeping track of the latest block. It uses a web3 provider as a data source and will continuously poll for the next block. ## Installation -`yarn add eth-block-tracker` +`yarn add @metamask/eth-block-tracker` or -`npm install eth-block-tracker` +`npm install @metamask/eth-block-tracker` ## Usage ```js -const createInfuraProvider = require('eth-json-rpc-infura'); -const { PollingBlockTracker } = require('eth-block-tracker'); +const createInfuraProvider = require('@metamask/eth-json-rpc-infura'); +const { PollingBlockTracker } = require('@metamask/eth-block-tracker'); const provider = createInfuraProvider({ network: 'mainnet', @@ -35,9 +51,12 @@ blockTracker.on('sync', ({ newBlock, oldBlock }) => { ### Methods -#### new PollingBlockTracker({ provider, pollingInterval, retryTimeout, keepEventLoopActive }) +#### new PollingBlockTracker({ provider, pollingInterval, retryTimeout, keepEventLoopActive, usePastBlocks }) -Creates a new block tracker with `provider` as a data source and `pollingInterval` (ms) timeout between polling for the latest block. If an error is encountered when fetching blocks, it will wait `retryTimeout` (ms) before attempting again. If `keepEventLoopActive` is false, in Node.js it will [unref the polling timeout](https://nodejs.org/api/timers.html#timers_timeout_unref), allowing the process to exit during the polling interval. Defaults to `true`, meaning the process will be kept alive. +- Creates a new block tracker with `provider` as a data source and `pollingInterval` (ms) timeout between polling for the latest block. +- If an error is encountered when fetching blocks, it will wait `retryTimeout` (ms) before attempting again. +- If `keepEventLoopActive` is `false`, in Node.js it will [unref the polling timeout](https://nodejs.org/api/timers.html#timers_timeout_unref), allowing the process to exit during the polling interval. Defaults to `true`, meaning the process will be kept alive. +- If `usePastBlocks` is `true`, block numbers less than the current block number can used and emitted. Defaults to `false`, meaning that only block numbers greater than the current block number will be used and emitted. #### getCurrentBlock() @@ -87,11 +106,10 @@ blockTracker.on('error', (err) => console.error(err)); ### Setup -- Install [Node.js](https://nodejs.org) version 14 - - If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm use` will automatically choose the right node version for you. -- Install [Yarn v1](https://yarnpkg.com/en/docs/install) -- Run `yarn setup` to install dependencies and run any requried post-install scripts - - **Warning:** Do not use the `yarn` / `yarn install` command directly. Use `yarn setup` instead. The normal install command will skip required post-install scripts, leaving your development environment in an invalid state. +- Install the current LTS version of [Node.js](https://nodejs.org) + - If you are using [nvm](https://github.com/creationix/nvm#installation) (recommended) running `nvm install` will install the latest version and running `nvm use` will automatically choose the right node version for you. +- Install [Yarn](https://yarnpkg.com) v4 via [Corepack](https://github.com/nodejs/corepack?tab=readme-ov-file#how-to-install) +- Run `yarn install` to install dependencies and run any required post-install scripts ### Testing and Linting @@ -104,35 +122,28 @@ Run `yarn lint` to run the linter, or run `yarn lint:fix` to run the linter and The project follows the same release process as the other libraries in the MetaMask organization. The GitHub Actions [`action-create-release-pr`](https://github.com/MetaMask/action-create-release-pr) and [`action-publish-release`](https://github.com/MetaMask/action-publish-release) are used to automate the release process; see those repositories for more information about how they work. 1. Choose a release version. - - The release version should be chosen according to SemVer. Analyze the changes to see whether they include any breaking changes, new features, or deprecations, then choose the appropriate SemVer version. See [the SemVer specification](https://semver.org/) for more information. 2. If this release is backporting changes onto a previous release, then ensure there is a major version branch for that version (e.g. `1.x` for a `v1` backport release). - - The major version branch should be set to the most recent release with that major version. For example, when backporting a `v1.0.2` release, you'd want to ensure there was a `1.x` branch that was set to the `v1.0.1` tag. 3. Trigger the [`workflow_dispatch`](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch) event [manually](https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow) for the `Create Release Pull Request` action to create the release PR. - - For a backport release, the base branch should be the major version branch that you ensured existed in step 2. For a normal release, the base branch should be the main branch for that repository (which should be the default value). - This should trigger the [`action-create-release-pr`](https://github.com/MetaMask/action-create-release-pr) workflow to create the release PR. 4. Update the changelog to move each change entry into the appropriate change category ([See here](https://keepachangelog.com/en/1.0.0/#types) for the full list of change categories, and the correct ordering), and edit them to be more easily understood by users of the package. - - Generally any changes that don't affect consumers of the package (e.g. lockfile changes or development environment changes) are omitted. Exceptions may be made for changes that might be of interest despite not having an effect upon the published package (e.g. major test improvements, security improvements, improved documentation, etc.). - Try to explain each change in terms that users of the package would understand (e.g. avoid referencing internal variables/concepts). - Consolidate related changes into one change entry if it makes it easier to explain. - - Run `yarn auto-changelog validate --rc` to check that the changelog is correctly formatted. + - Run `yarn auto-changelog validate --rc --prettier` to check that the changelog is correctly formatted. 5. Review and QA the release. - - If changes are made to the base branch, the release branch will need to be updated with these changes and review/QA will need to restart again. As such, it's probably best to avoid merging other PRs into the base branch while review is underway. 6. Squash & Merge the release. - - This should trigger the [`action-publish-release`](https://github.com/MetaMask/action-publish-release) workflow to tag the final release commit and publish the release on GitHub. 7. Publish the release on npm. - - Be very careful to use a clean local environment to publish the release, and follow exactly the same steps used during CI. - Use `npm publish --dry-run` to examine the release contents to ensure the correct files are included. Compare to previous releases if necessary (e.g. using `https://unpkg.com/browse/[package name]@[package version]/`). - Once you are confident the release contents are correct, publish the release using `npm publish`. diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..80405bd1 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,60 @@ +import base, { createConfig } from '@metamask/eslint-config'; +import jest from '@metamask/eslint-config-jest'; +import nodejs from '@metamask/eslint-config-nodejs'; +import typescript from '@metamask/eslint-config-typescript'; + +const config = createConfig([ + { + ignores: ['dist/', 'docs/', '.yarn/'], + }, + + { + extends: base, + + languageOptions: { + sourceType: 'module', + parserOptions: { + tsconfigRootDir: import.meta.dirname, + project: ['./tsconfig.json'], + }, + }, + + settings: { + 'import-x/extensions': ['.js', '.mjs'], + }, + }, + + { + files: ['**/*.ts'], + extends: typescript, + rules: { + // TODO: These should perhaps be enabled + '@typescript-eslint/prefer-nullish-coalescing': 'off', + 'no-restricted-syntax': 'off', + // TODO: Thise should definitely be enabled + '@typescript-eslint/naming-convention': 'warn', + '@typescript-eslint/unbound-method': 'warn', + '@typescript-eslint/consistent-type-definitions': 'warn', + '@typescript-eslint/explicit-function-return-type': 'warn', + }, + }, + + { + files: ['**/*.js', '**/*.cjs'], + extends: nodejs, + + languageOptions: { + sourceType: 'script', + }, + }, + + { + files: ['./test/**/*', '**/*.test.ts', '**/*.test.js'], + extends: [jest, nodejs], + rules: { + 'import-x/no-nodejs-modules': 'off', + }, + }, +]); + +export default config; diff --git a/jest.config.ts b/jest.config.ts index 9ad3b271..2daa0720 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -137,7 +137,7 @@ const config: Config.InitialOptions = { // setupFiles: [], // A list of paths to modules that run some code to configure or set up the testing framework before each test - setupFilesAfterEnv: ['./tests/setupAfterEnv.ts'], + setupFilesAfterEnv: ['./test/setupAfterEnv.ts'], // The number of seconds after which a test is considered as slow and reported as such in the results. // slowTestThreshold: 5, diff --git a/package.json b/package.json index 6302610f..1bf9dc71 100644 --- a/package.json +++ b/package.json @@ -1,67 +1,96 @@ { - "name": "eth-block-tracker", - "version": "6.0.0", - "description": "A block tracker for the Ethereum blockchain. Keeps track of the latest block.", + "name": "@metamask/eth-block-tracker", + "version": "13.0.0", + "description": "A block tracker for the Ethereum blockchain. Keeps track of the latest block", + "homepage": "https://github.com/MetaMask/eth-block-tracker#readme", + "bugs": { + "url": "https://github.com/MetaMask/eth-block-tracker/issues" + }, "repository": { "type": "git", "url": "https://github.com/MetaMask/eth-block-tracker.git" }, "license": "MIT", - "main": "dist/index.js", - "types": "dist/index.d.ts", + "sideEffects": false, + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + }, + "./package.json": "./package.json" + }, + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.cts", "files": [ - "dist/" + "dist" ], "scripts": { - "build": "tsc --project tsconfig.build.json", + "build": "ts-bridge --project tsconfig.build.json --clean", "build:clean": "rimraf dist && yarn build", - "lint": "yarn lint:eslint && yarn lint:misc --check", - "lint:eslint": "eslint . --cache --ext js,ts", - "lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write", - "lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' --ignore-path .gitignore --no-error-on-unmatched-pattern", - "prepublishOnly": "yarn build:clean && yarn lint && yarn test", - "setup": "yarn install && yarn allow-scripts", - "test": "jest", + "build:docs": "typedoc", + "lint": "yarn lint:eslint && yarn lint:constraints && yarn lint:misc --check && yarn lint:dependencies --check && yarn lint:changelog", + "lint:changelog": "auto-changelog validate --prettier", + "lint:constraints": "yarn constraints", + "lint:dependencies": "depcheck && yarn dedupe --check", + "lint:dependencies:fix": "depcheck && yarn dedupe", + "lint:eslint": "eslint . --cache", + "lint:fix": "yarn lint:eslint --fix && yarn lint:constraints --fix && yarn lint:misc --write && yarn lint:dependencies:fix && yarn lint:changelog", + "lint:misc": "prettier '**/*.json' '**/*.md' '**/*.yml' '!.yarnrc.yml' --ignore-path .gitignore --no-error-on-unmatched-pattern", + "prepack": "./scripts/prepack.sh", + "test": "jest && attw --pack", "test:watch": "jest --watch" }, "dependencies": { - "@metamask/safe-event-emitter": "^2.0.0", - "@metamask/utils": "^3.0.1", - "json-rpc-random-id": "^1.0.1", - "pify": "^3.0.0" + "@metamask/eth-json-rpc-provider": "^5.0.0", + "@metamask/safe-event-emitter": "^3.1.1", + "@metamask/utils": "^11.0.1", + "json-rpc-random-id": "^1.0.1" }, "devDependencies": { - "@lavamoat/allow-scripts": "^2.0.2", - "@metamask/auto-changelog": "^2.5.0", - "@metamask/eslint-config": "^9.0.0", - "@metamask/eslint-config-jest": "^9.0.0", - "@metamask/eslint-config-nodejs": "^9.0.0", - "@metamask/eslint-config-typescript": "^9.0.1", + "@arethetypeswrong/cli": "^0.15.3", + "@jest/types": "^27.5.1", + "@lavamoat/allow-scripts": "^3.0.4", + "@metamask/auto-changelog": "^3.4.4", + "@metamask/eslint-config": "^14.0.0", + "@metamask/eslint-config-jest": "^14.0.0", + "@metamask/eslint-config-nodejs": "^14.0.0", + "@metamask/eslint-config-typescript": "^14.0.0", + "@metamask/json-rpc-engine": "^10.0.0", + "@ts-bridge/cli": "^0.6.3", "@types/jest": "^27.4.1", "@types/json-rpc-random-id": "^1.0.1", - "@types/node": "^17.0.23", - "@types/pify": "^5.0.1", - "@typescript-eslint/eslint-plugin": "^4.20.0", - "@typescript-eslint/parser": "^4.20.0", - "eslint": "^7.23.0", - "eslint-config-prettier": "^8.1.0", - "eslint-import-resolver-typescript": "^2.7.1", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jest": "^24.1.3", - "eslint-plugin-jsdoc": "^36.1.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^3.3.1", + "@types/node": "^18.18", + "@yarnpkg/types": "^4.0.1", + "depcheck": "^1.4.3", + "eslint": "^9.11.0", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-import-x": "^4.3.0", + "eslint-plugin-jest": "^28.8.3", + "eslint-plugin-jsdoc": "^50.2.4", + "eslint-plugin-n": "^17.10.3", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-promise": "^7.1.0", "jest": "^27.5.1", - "json-rpc-engine": "^6.1.0", - "prettier": "^2.2.1", - "prettier-plugin-packagejson": "^2.2.11", + "prettier": "^3.3.3", + "prettier-plugin-packagejson": "^2.5.8", "rimraf": "^3.0.2", "ts-jest": "^27.1.4", - "ts-node": "^10.7.0", - "typescript": "~4.4.0" + "ts-node": "^10.9.1", + "typedoc": "^0.24.8", + "typescript": "~5.2.2", + "typescript-eslint": "^8.7.0" }, + "packageManager": "yarn@4.5.3", "engines": { - "node": ">=14.0.0" + "node": "^18.16 || ^20 || >=22" }, "publishConfig": { "access": "public", @@ -69,7 +98,8 @@ }, "lavamoat": { "allowScripts": { - "@lavamoat/preinstall-always-fail": false + "@lavamoat/preinstall-always-fail": false, + "eslint-plugin-import-x>unrs-resolver": false } } } diff --git a/scripts/get.sh b/scripts/get.sh new file mode 100755 index 00000000..9c988bb8 --- /dev/null +++ b/scripts/get.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +set -e +set -u +set -o pipefail + +if [[ ${RUNNER_DEBUG:-0} == 1 ]]; then + set -x +fi + +KEY="${1}" +OUTPUT="${2}" + +if [[ -z $KEY ]]; then + echo "Error: KEY not specified." + exit 1 +fi + +if [[ -z $OUTPUT ]]; then + echo "Error: OUTPUT not specified." + exit 1 +fi + +echo "$OUTPUT=$(jq --raw-output "$KEY" package.json)" >> "$GITHUB_OUTPUT" diff --git a/scripts/prepack.sh b/scripts/prepack.sh new file mode 100755 index 00000000..ad99af58 --- /dev/null +++ b/scripts/prepack.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +if [[ -n $SKIP_PREPACK ]]; then + echo "Notice: skipping prepack." + exit 0 +fi + +yarn build diff --git a/src/BaseBlockTracker.ts b/src/BaseBlockTracker.ts deleted file mode 100644 index bd7b9903..00000000 --- a/src/BaseBlockTracker.ts +++ /dev/null @@ -1,204 +0,0 @@ -import SafeEventEmitter from '@metamask/safe-event-emitter'; -import { JsonRpcRequest, JsonRpcResponse } from 'json-rpc-engine'; - -const sec = 1000; - -const calculateSum = (accumulator: number, currentValue: number) => - accumulator + currentValue; -const blockTrackerEvents: (string | symbol)[] = ['sync', 'latest']; - -export interface Provider extends SafeEventEmitter { - sendAsync: ( - req: JsonRpcRequest, - cb: (err: Error, response: JsonRpcResponse) => void, - ) => void; -} - -interface BaseBlockTrackerArgs { - blockResetDuration?: number; -} - -export abstract class BaseBlockTracker extends SafeEventEmitter { - protected _isRunning: boolean; - - private _blockResetDuration: number; - - private _currentBlock: string | null; - - private _blockResetTimeout?: ReturnType; - - constructor(opts: BaseBlockTrackerArgs) { - super(); - - // config - this._blockResetDuration = opts.blockResetDuration || 20 * sec; - // state - this._currentBlock = null; - this._isRunning = false; - - // bind functions for internal use - this._onNewListener = this._onNewListener.bind(this); - this._onRemoveListener = this._onRemoveListener.bind(this); - this._resetCurrentBlock = this._resetCurrentBlock.bind(this); - - // listen for handler changes - this._setupInternalEvents(); - } - - async destroy() { - this._cancelBlockResetTimeout(); - await this._maybeEnd(); - super.removeAllListeners(); - } - - isRunning(): boolean { - return this._isRunning; - } - - getCurrentBlock(): string | null { - return this._currentBlock; - } - - async getLatestBlock(): Promise { - // return if available - if (this._currentBlock) { - return this._currentBlock; - } - // wait for a new latest block - const latestBlock: string = await new Promise((resolve) => - this.once('latest', resolve), - ); - // return newly set current block - return latestBlock; - } - - // dont allow module consumer to remove our internal event listeners - removeAllListeners(eventName?: string | symbol) { - // perform default behavior, preserve fn arity - if (eventName) { - super.removeAllListeners(eventName); - } else { - super.removeAllListeners(); - } - - // re-add internal events - this._setupInternalEvents(); - // trigger stop check just in case - this._onRemoveListener(); - - return this; - } - - /** - * To be implemented in subclass. - */ - protected abstract _start(): Promise; - - /** - * To be implemented in subclass. - */ - protected abstract _end(): Promise; - - private _setupInternalEvents(): void { - // first remove listeners for idempotence - this.removeListener('newListener', this._onNewListener); - this.removeListener('removeListener', this._onRemoveListener); - // then add them - this.on('newListener', this._onNewListener); - this.on('removeListener', this._onRemoveListener); - } - - private _onNewListener(eventName: string | symbol): void { - // `newListener` is called *before* the listener is added - if (blockTrackerEvents.includes(eventName)) { - this._maybeStart(); - } - } - - private _onRemoveListener(): void { - // `removeListener` is called *after* the listener is removed - if (this._getBlockTrackerEventCount() > 0) { - return; - } - this._maybeEnd(); - } - - private async _maybeStart(): Promise { - if (this._isRunning) { - return; - } - this._isRunning = true; - // cancel setting latest block to stale - this._cancelBlockResetTimeout(); - await this._start(); - this.emit('_started'); - } - - private async _maybeEnd(): Promise { - if (!this._isRunning) { - return; - } - this._isRunning = false; - this._setupBlockResetTimeout(); - await this._end(); - this.emit('_ended'); - } - - private _getBlockTrackerEventCount(): number { - return blockTrackerEvents - .map((eventName) => this.listenerCount(eventName)) - .reduce(calculateSum); - } - - protected _newPotentialLatest(newBlock: string): void { - const currentBlock = this._currentBlock; - // only update if blok number is higher - if (currentBlock && hexToInt(newBlock) <= hexToInt(currentBlock)) { - return; - } - this._setCurrentBlock(newBlock); - } - - private _setCurrentBlock(newBlock: string): void { - const oldBlock = this._currentBlock; - this._currentBlock = newBlock; - this.emit('latest', newBlock); - this.emit('sync', { oldBlock, newBlock }); - } - - private _setupBlockResetTimeout(): void { - // clear any existing timeout - this._cancelBlockResetTimeout(); - // clear latest block when stale - this._blockResetTimeout = setTimeout( - this._resetCurrentBlock, - this._blockResetDuration, - ); - - // nodejs - dont hold process open - if (this._blockResetTimeout.unref) { - this._blockResetTimeout.unref(); - } - } - - private _cancelBlockResetTimeout(): void { - if (this._blockResetTimeout) { - clearTimeout(this._blockResetTimeout); - } - } - - private _resetCurrentBlock(): void { - this._currentBlock = null; - } -} - -/** - * Converts a number represented as a string in hexadecimal format into a native - * number. - * - * @param hexInt - The hex string. - * @returns The number. - */ -function hexToInt(hexInt: string): number { - return Number.parseInt(hexInt, 16); -} diff --git a/src/BlockTracker.ts b/src/BlockTracker.ts new file mode 100644 index 00000000..399f05c3 --- /dev/null +++ b/src/BlockTracker.ts @@ -0,0 +1,13 @@ +import type SafeEventEmitter from '@metamask/safe-event-emitter'; + +export type BlockTracker = SafeEventEmitter & { + destroy(): Promise; + + isRunning(): boolean; + + getCurrentBlock(): string | null; + + getLatestBlock(): Promise; + + checkForLatestBlock(): Promise; +}; diff --git a/src/PollingBlockTracker.test.ts b/src/PollingBlockTracker.test.ts index f213df76..bcb2cfd1 100644 --- a/src/PollingBlockTracker.test.ts +++ b/src/PollingBlockTracker.test.ts @@ -1,13 +1,13 @@ -import EMPTY_FUNCTION from '../tests/emptyFunction'; -import recordCallsToSetTimeout from '../tests/recordCallsToSetTimeout'; -import { withPollingBlockTracker } from '../tests/withBlockTracker'; -import buildDeferred from '../tests/buildDeferred'; import { PollingBlockTracker } from '.'; +import buildDeferred from '../test/buildDeferred'; +import EMPTY_FUNCTION from '../test/emptyFunction'; +import recordCallsToSetTimeout from '../test/recordCallsToSetTimeout'; +import { withPollingBlockTracker } from '../test/withBlockTracker'; -interface Sync { +type Sync = { oldBlock: string; newBlock: string; -} +}; const METHODS_TO_ADD_LISTENER = ['on', 'addListener'] as const; const METHODS_TO_REMOVE_LISTENER = ['off', 'removeListener'] as const; @@ -66,9 +66,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -80,7 +78,7 @@ describe('PollingBlockTracker', () => { await new Promise((resolve) => { blockTracker.on('_waitingForNextIteration', resolve); }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); blockTracker.removeAllListeners(); expect( setTimeoutRecorder.calls.some((call) => { @@ -99,7 +97,7 @@ describe('PollingBlockTracker', () => { await new Promise((resolve) => originalSetTimeout(resolve, blockTrackerOptions.blockResetDuration), ); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); }, ); }); @@ -117,9 +115,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -131,7 +127,7 @@ describe('PollingBlockTracker', () => { await new Promise((resolve) => { blockTracker.on('_waitingForNextIteration', resolve); }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); blockTracker.removeAllListeners(); await setTimeoutRecorder.nextMatchingDuration( blockTrackerOptions.blockResetDuration, @@ -146,141 +142,215 @@ describe('PollingBlockTracker', () => { }); describe('getLatestBlock', () => { - it('should start the block tracker immediately after being called', async () => { - recordCallsToSetTimeout(); + describe('when the block tracker is not running', () => { + describe('if no other concurrent call exists', () => { + describe('if the latest block number has already been fetched once', () => { + it('returns the block number', async () => { + recordCallsToSetTimeout(); - await withPollingBlockTracker(async ({ blockTracker }) => { - const promiseToGetLatestBlock = blockTracker.getLatestBlock(); - expect(blockTracker.isRunning()).toBe(true); - // We have to wait for the promise to resolve after the assertion - // because by the time this promise resolves, the block tracker isn't - // running anymore - await promiseToGetLatestBlock; - }); - }); + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + ], + }, + }, + async ({ blockTracker }) => { + await blockTracker.getLatestBlock(); + const block = await blockTracker.getLatestBlock(); + expect(block).toBe('0x1'); + }, + ); + }); + }); - it('should stop the block tracker automatically after its promise is fulfilled', async () => { - recordCallsToSetTimeout(); + describe('if the latest block number has not been fetched yet', () => { + it('does not start the block tracker', async () => { + recordCallsToSetTimeout(); - await withPollingBlockTracker(async ({ blockTracker }) => { - await blockTracker.getLatestBlock(); - expect(blockTracker.isRunning()).toBe(false); + await withPollingBlockTracker(async ({ blockTracker }) => { + expect(blockTracker.isRunning()).toBe(false); + await blockTracker.getLatestBlock(); + expect(blockTracker.isRunning()).toBe(false); + }); + }); + + describe('if the latest block number is successfully fetched', () => { + it('returns the fetched latest block number', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker(async ({ blockTracker }) => { + const block = await blockTracker.getLatestBlock(); + expect(block).toBe('0x0'); + }); + }); + + it('should start a timer to clear the current block number later', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout(); + const blockResetDuration = 1000; + + await withPollingBlockTracker( + { + blockTracker: { + blockResetDuration, + }, + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + }, + async ({ blockTracker }) => { + const block = await blockTracker.getLatestBlock(); + expect(block).toBe('0x0'); + await setTimeoutRecorder.nextMatchingDuration( + blockResetDuration, + ); + expect(blockTracker.getCurrentBlock()).toBeNull(); + }, + ); + }); + }); + + describe('if an error occurs while fetching the latest block number', () => { + it('re-throws the error', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + error: new Error('boom'), + }, + ], + }, + }, + async ({ blockTracker }) => { + await expect(blockTracker.getLatestBlock()).rejects.toThrow( + 'boom', + ); + }, + ); + }); + + it('does not emit "error"', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + error: new Error('boom'), + }, + ], + }, + }, + async ({ blockTracker }) => { + const errorListener = jest.fn(); + blockTracker.on('error', errorListener); + await expect(blockTracker.getLatestBlock()).rejects.toThrow( + 'boom', + ); + expect(errorListener).not.toHaveBeenCalled(); + }, + ); + }); + }); + }); }); - }); - it('should fetch the latest block number', async () => { - recordCallsToSetTimeout(); + describe('if already called concurrently', () => { + describe('if the latest block number is successfully fetched', () => { + it('returns the block number that the other call returns', async () => { + recordCallsToSetTimeout(); - await withPollingBlockTracker( - { - provider: { - stubs: [ + await withPollingBlockTracker(async ({ blockTracker }) => { + const promise1 = blockTracker.getLatestBlock(); + const promise2 = blockTracker.getLatestBlock(); + const [block1, block2] = await Promise.all([promise1, promise2]); + expect(block1).toBe(block2); + }); + }); + }); + + describe('if an error occurs while fetching the latest block number', () => { + it('throws the error that the other call throws', async () => { + const thrownError = new Error('boom'); + recordCallsToSetTimeout(); + + await withPollingBlockTracker( { - methodName: 'eth_blockNumber', - response: { - result: '0x0', + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + error: thrownError, + }, + ], }, }, - ], - }, - }, - async ({ blockTracker }) => { - const latestBlockNumber = await blockTracker.getLatestBlock(); - expect(latestBlockNumber).toStrictEqual('0x0'); - }, - ); - }); + async ({ blockTracker }) => { + const promise1 = blockTracker.getLatestBlock(); + const promise2 = blockTracker.getLatestBlock(); + await expect(promise1).rejects.toThrow(thrownError); + await expect(promise2).rejects.toThrow(thrownError); + }, + ); + }); + }); + }); - it('request the latest block number with `skipCache: true` if the block tracker was initialized with `setSkipCacheFlag: true`', async () => { - recordCallsToSetTimeout(); + it('request the latest block number with `skipCache: true` if the block tracker was initialized with `setSkipCacheFlag: true`', async () => { + recordCallsToSetTimeout(); - await withPollingBlockTracker( - { blockTracker: { setSkipCacheFlag: true } }, - async ({ provider, blockTracker }) => { - jest.spyOn(provider, 'sendAsync'); + await withPollingBlockTracker( + { blockTracker: { setSkipCacheFlag: true } }, + async ({ provider, blockTracker }) => { + jest.spyOn(provider, 'request'); - await blockTracker.getLatestBlock(); + await blockTracker.getLatestBlock(); - expect(provider.sendAsync).toHaveBeenCalledWith( - { + expect(provider.request).toHaveBeenCalledWith({ jsonrpc: '2.0' as const, id: expect.any(Number), method: 'eth_blockNumber' as const, params: [], skipCache: true, - }, - expect.any(Function), - ); - }, - ); - }); - - it('should not ask for a new block number while the current block number is cached', async () => { - recordCallsToSetTimeout(); - - await withPollingBlockTracker(async ({ provider, blockTracker }) => { - const sendAsyncSpy = jest.spyOn(provider, 'sendAsync'); - await blockTracker.getLatestBlock(); - await blockTracker.getLatestBlock(); - const requestsForLatestBlock = sendAsyncSpy.mock.calls.filter( - (args) => { - return args[0].method === 'eth_blockNumber'; + }); }, ); - expect(requestsForLatestBlock).toHaveLength(1); }); - }); - it('should ask for a new block number after the cached one is cleared', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockTrackerOptions = { - pollingInterval: 100, - blockResetDuration: 200, - }; + it('should not ask for a new block number while the current block number is cached', async () => { + recordCallsToSetTimeout(); - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, - }, - ], - }, - blockTracker: blockTrackerOptions, - }, - async ({ provider, blockTracker }) => { - const sendAsyncSpy = jest.spyOn(provider, 'sendAsync'); + await withPollingBlockTracker(async ({ provider, blockTracker }) => { + const requestSpy = jest.spyOn(provider, 'request'); await blockTracker.getLatestBlock(); - // When the block tracker stops, there may be two `setTimeout`s in - // play: one to go to the next iteration of the block tracker - // loop, another to expire the current block number cache. We don't - // know which one has been added first, so we have to find it. - await setTimeoutRecorder.nextMatchingDuration( - blockTrackerOptions.blockResetDuration, - ); await blockTracker.getLatestBlock(); - const requestsForLatestBlock = sendAsyncSpy.mock.calls.filter( + const requestsForLatestBlock = requestSpy.mock.calls.filter( (args) => { return args[0].method === 'eth_blockNumber'; }, ); - expect(requestsForLatestBlock).toHaveLength(2); - }, - ); + expect(requestsForLatestBlock).toHaveLength(1); + }); + }); }); - METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if the request for the latest block number returns an error response`, async () => { + describe('when the block tracker is already started', () => { + it('should return a promise that rejects if the request for the block number fails and the block tracker is then stopped', async () => { recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -289,37 +359,27 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + error: new Error('boom'), }, ], }, }, async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); + blockTracker.on('latest', EMPTY_FUNCTION); - const promiseForLatestBlock = await blockTracker.getLatestBlock(); + const latestBlockPromise = blockTracker.getLatestBlock(); - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: PollingBlockTracker - encountered error fetching block:\nboom/u, + expect(blockTracker.isRunning()).toBe(true); + await blockTracker.destroy(); + await expect(latestBlockPromise).rejects.toThrow( + 'Block tracker destroyed', ); - const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); + expect(blockTracker.isRunning()).toBe(false); }, ); }); - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider throws an Error`, async () => { + it('should not retry failed requests after the block tracker is stopped', async () => { recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -328,37 +388,34 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + error: new Error('boom'), }, ], }, }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); + async ({ blockTracker, provider }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + const requestSpy = jest.spyOn(provider, 'request'); - const promiseForLatestBlock = blockTracker.getLatestBlock(); + const latestBlockPromise = blockTracker.getLatestBlock(); + await blockTracker.destroy(); - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom\n/u, + await expect(latestBlockPromise).rejects.toThrow( + 'Block tracker destroyed', ); - const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); + expect(requestSpy).toHaveBeenCalledTimes(1); + expect(requestSpy).toHaveBeenCalledWith({ + jsonrpc: '2.0', + id: expect.any(Number), + method: 'eth_blockNumber', + params: [], + }); }, ); }); - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider throws a string`, async () => { + it('should log an error if, while making a request for the latest block number, the provider throws and there is nothing listening to "error"', async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -368,36 +425,30 @@ describe('PollingBlockTracker', () => { { methodName: 'eth_blockNumber', implementation: () => { - throw 'boom'; - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', + throw thrownError; }, }, ], }, }, async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); + blockTracker.on('latest', EMPTY_FUNCTION); + jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); - const promiseForLatestBlock = blockTracker.getLatestBlock(); + await expect(blockTracker.getLatestBlock()).rejects.toThrow('boom'); + await new Promise((resolve) => { + blockTracker.on('_waitingForNextIteration', resolve); + }); - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nboom/u, + expect(console.error).toHaveBeenCalledWith( + 'Error updating latest block: boom', ); - const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); }, ); }); - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider rejects with an error`, async () => { + it('should log an error if, while requesting the latest block number, the provider rejects and there is nothing listening to "error"', async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -406,233 +457,729 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - error: 'boom', - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + error: thrownError, }, ], }, }, async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); + blockTracker.on('latest', EMPTY_FUNCTION); + jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); - const promiseForLatestBlock = await blockTracker.getLatestBlock(); + await expect(blockTracker.getLatestBlock()).rejects.toThrow('boom'); + await new Promise((resolve) => { + blockTracker.on('_waitingForNextIteration', resolve); + }); - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, + expect(console.error).toHaveBeenCalledWith( + 'Error updating latest block: boom', ); - const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); }, ); }); - }); - it('should log an error if the request for the latest block number returns an error response and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); + it('should update the current block number', async () => { + recordCallsToSetTimeout(); - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', }, - }, - ], + ], + }, }, - }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); - - blockTracker.getLatestBlock(); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); - }); - - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: PollingBlockTracker - encountered error fetching block:\nboom/u, - ), - }), - ); - }, - ); - }); + async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + await blockTracker.getLatestBlock(); + const currentBlockNumber = blockTracker.getCurrentBlock(); + expect(currentBlockNumber).toBe('0x0'); + }, + ); + }); - it('should log an error if, while making a request for the latest block number, the provider throws an Error and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); + it('should not start a timer to clear the current block number later', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout(); + const blockTrackerOptions = { + pollingInterval: 100, + blockResetDuration: 200, + }; - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + await blockTracker.getLatestBlock(); + const currentBlockNumber = blockTracker.getCurrentBlock(); + expect(currentBlockNumber).toBe('0x0'); + + const blockResetTimeouts = setTimeoutRecorder.calls.filter( + (call) => { + return call.duration === blockTrackerOptions.blockResetDuration; }, - ], + ); + expect(blockResetTimeouts).toHaveLength(0); }, - }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); + ); + }); - blockTracker.getLatestBlock(); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); - }); + describe('if no other concurrent call exists', () => { + describe('if the latest block number has already been fetched once', () => { + it('returns the block number', async () => { + recordCallsToSetTimeout(); - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ), - }), - ); - }, - ); - }); + await withPollingBlockTracker(async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + await blockTracker.getLatestBlock(); + const block = await blockTracker.getLatestBlock(); + expect(block).toBe('0x0'); + }); + }); + }); - it('should log an error the request for the latest block number throws a string and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); + describe('if the latest block number has not been fetched yet', () => { + describe('if the latest block number is successfully fetched on the next poll iteration', () => { + it('returns the fetched latest block number', async () => { + recordCallsToSetTimeout(); - await withPollingBlockTracker( - { - provider: { - stubs: [ + await withPollingBlockTracker(async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + const block = await blockTracker.getLatestBlock(); + expect(block).toBe('0x0'); + }); + }); + + it('does not stop the block tracker once complete', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker(async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + await blockTracker.getLatestBlock(); + expect(blockTracker.isRunning()).toBe(true); + }); + }); + }); + + describe('if an error occurs while fetching the latest block number on the next poll iteration', () => { + it('emits "error" if anything is listening to "error"', async () => { + const thrownError = new Error('boom'); + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + error: thrownError, + }, + ], + }, + }, + async ({ blockTracker }) => { + const errorListener = jest.fn(); + blockTracker.on('error', errorListener); + blockTracker.on('latest', EMPTY_FUNCTION); + await expect(blockTracker.getLatestBlock()).rejects.toThrow( + 'boom', + ); + expect(errorListener).toHaveBeenCalledWith(thrownError); + }, + ); + }); + + it('logs an error if nothing is listening to "error"', async () => { + const thrownError = new Error('boom'); + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + error: thrownError, + }, + ], + }, + }, + async ({ blockTracker }) => { + jest + .spyOn(console, 'error') + .mockImplementation(EMPTY_FUNCTION); + blockTracker.on('latest', EMPTY_FUNCTION); + await expect(blockTracker.getLatestBlock()).rejects.toThrow( + 'boom', + ); + expect(console.error).toHaveBeenCalledWith( + 'Error updating latest block: boom', + ); + }, + ); + }); + + it('does not stop the block tracker once complete', async () => { + const thrownError = new Error('boom'); + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + error: thrownError, + }, + ], + }, + }, + async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + try { + await blockTracker.getLatestBlock(); + } catch { + // do nothing + } + expect(blockTracker.isRunning()).toBe(true); + }, + ); + }); + }); + }); + }); + + describe('if already called concurrently', () => { + describe('if the latest block number is successfully fetched on the next poll iteration', () => { + it('returns the block number that the other call returns', async () => { + recordCallsToSetTimeout(); + await withPollingBlockTracker(async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + const promise1 = blockTracker.getLatestBlock(); + const promise2 = blockTracker.getLatestBlock(); + const [block1, block2] = await Promise.all([promise1, promise2]); + expect(block1).toBe(block2); + }); + }); + + it('does not stop the block tracker once complete', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker(async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + await blockTracker.getLatestBlock(); + expect(blockTracker.isRunning()).toBe(true); + }); + }); + }); + + describe('if an error occurs while fetching the latest block number on the next poll iteration', () => { + it('throws the error that the other call throws', async () => { + const thrownError = new Error('boom'); + recordCallsToSetTimeout(); + + await withPollingBlockTracker( { - methodName: 'eth_blockNumber', - implementation: () => { - throw 'boom'; + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + error: thrownError, + }, + ], }, }, - ], - }, - }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); - - blockTracker.getLatestBlock(); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); + async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + const promise1 = blockTracker.getLatestBlock(); + const promise2 = blockTracker.getLatestBlock(); + await expect(promise1).rejects.toThrow(thrownError); + await expect(promise2).rejects.toThrow(thrownError); + }, + ); }); - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nboom/u, - ), - }), - ); - }, - ); - }); + it('emits "error" only once if anything is listening to "error"', async () => { + const thrownError = new Error('boom'); + recordCallsToSetTimeout(); - it('should log an error if, while requesting the latest block number, the provider rejects with an error and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + error: thrownError, + }, + ], + }, + }, + async ({ blockTracker }) => { + const errorListener = jest.fn(); + blockTracker.on('error', errorListener); + blockTracker.on('latest', EMPTY_FUNCTION); + const promise1 = blockTracker.getLatestBlock(); + const promise2 = blockTracker.getLatestBlock(); + await Promise.allSettled([promise1, promise2]); + expect(errorListener).toHaveBeenCalledTimes(1); + }, + ); + }); - await withPollingBlockTracker( - { - provider: { - stubs: [ + it('logs an error only once if nothing is listening to "error"', async () => { + const thrownError = new Error('boom'); + recordCallsToSetTimeout(); + + await withPollingBlockTracker( { - methodName: 'eth_blockNumber', - error: 'boom', + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + error: thrownError, + }, + ], + }, }, - ], - }, - }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); + async ({ blockTracker }) => { + jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); + blockTracker.on('latest', EMPTY_FUNCTION); + const promise1 = blockTracker.getLatestBlock(); + const promise2 = blockTracker.getLatestBlock(); + await Promise.allSettled([promise1, promise2]); + expect(console.error).toHaveBeenCalledTimes(1); + }, + ); + }); - blockTracker.getLatestBlock(); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); + it('does not stop the block tracker once complete', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker(async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + await blockTracker.getLatestBlock(); + expect(blockTracker.isRunning()).toBe(true); + }); }); + }); + }); - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ), - }), + METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { + it(`should throw and emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request for the latest block number, the provider throws`, async () => { + const thrownError = new Error('boom'); + recordCallsToSetTimeout({ numAutomaticCalls: 1 }); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + implementation: () => { + throw thrownError; + }, + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + }, + async ({ blockTracker }) => { + blockTracker[methodToAddListener]('latest', EMPTY_FUNCTION); + const errorListener = jest.fn(); + expect(blockTracker.isRunning()).toBe(true); + blockTracker[methodToAddListener]('error', errorListener); + await expect(blockTracker.getLatestBlock()).rejects.toThrow( + 'boom', + ); + expect(errorListener).toHaveBeenCalledWith(thrownError); + const latestBlock = await blockTracker.getLatestBlock(); + expect(latestBlock).toBe('0x0'); + }, ); - }, - ); - }); + }); - it('should update the current block number', async () => { - recordCallsToSetTimeout(); + it(`should throw and emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request for the latest block number, the provider rejects with an error`, async () => { + const thrownError = new Error('boom'); + recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + error: thrownError, + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + }, + async ({ blockTracker }) => { + blockTracker[methodToAddListener]('latest', EMPTY_FUNCTION); + const errorListener = jest.fn(); + expect(blockTracker.isRunning()).toBe(true); + blockTracker[methodToAddListener]('error', errorListener); + await expect(blockTracker.getLatestBlock()).rejects.toThrow( + 'boom', + ); + expect(errorListener).toHaveBeenCalledWith(thrownError); + const latestBlock = await blockTracker.getLatestBlock(); + expect(latestBlock).toBe('0x0'); + }, + ); + }); + }); + + it('should reject pending latest block request if block tracker is stopped before fetch completes on second getLatestBlock call', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout(); + const blockTrackerOptions = { + pollingInterval: 100, + blockResetDuration: 200, + }; + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', result: '0x0', }, - }, - ], + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: blockTrackerOptions, }, - }, - async ({ blockTracker }) => { - await blockTracker.getLatestBlock(); - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); - }, - ); - }); + async ({ blockTracker }) => { + // Step 1: Start the block tracker + blockTracker.on('latest', EMPTY_FUNCTION); - it('should clear the current block number some time after being called', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockTrackerOptions = { - pollingInterval: 100, - blockResetDuration: 200, - }; + // Step 2: Wait for the first block update to resolve + await new Promise((resolve) => { + blockTracker.on('sync', resolve); + }); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); + expect(blockTracker.isRunning()).toBe(true); - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { + // Clear the current block to force a new request for the next getLatestBlock + // When the block tracker stops, there may be two `setTimeout`s in + // play: one to go to the next iteration of the block tracker + // loop, another to expire the current block number cache. We don't + // know which one has been added first, so we have to find it. + blockTracker.removeAllListeners(); + await setTimeoutRecorder.nextMatchingDuration( + blockTrackerOptions.blockResetDuration, + ); + expect(blockTracker.getCurrentBlock()).toBeNull(); + + // Restart the tracker for the second call + blockTracker.on('latest', EMPTY_FUNCTION); + + // Step 3: Immediately after, call getLatestBlock + const secondBlockPromise = blockTracker.getLatestBlock(); + + // Step 4: Immediately after, stop the block tracker + blockTracker.removeAllListeners(); + + // Verify block tracker state + expect(blockTracker.isRunning()).toBe(false); + expect(blockTracker.getCurrentBlock()).toBeNull(); + + // The call to getLatestBlock would then never resolve (should be rejected) + await expect(secondBlockPromise).rejects.toThrow( + 'Block tracker destroyed', + ); + + // Verify that the block reset timeout is set up + expect( + setTimeoutRecorder.calls.some((call) => { + return call.duration === blockTrackerOptions.blockResetDuration; + }), + ).toBe(true); + + // Wait for the block reset timeout to complete + await setTimeoutRecorder.nextMatchingDuration( + blockTrackerOptions.blockResetDuration, + ); + + // Verify that the current block is still null after the timeout + expect(blockTracker.getCurrentBlock()).toBeNull(); + }, + ); + }); + + it('should reject pending latest block request if block tracker is destroyed before fetch completes on second getLatestBlock call', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout(); + const blockTrackerOptions = { + pollingInterval: 100, + blockResetDuration: 200, + }; + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', result: '0x0', }, - }, - ], + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: blockTrackerOptions, }, - blockTracker: blockTrackerOptions, - }, - async ({ blockTracker }) => { - await blockTracker.getLatestBlock(); - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); + async ({ blockTracker }) => { + // Step 1: Start the block tracker + blockTracker.on('latest', EMPTY_FUNCTION); + + // Step 2: Wait for the first block update to resolve + await new Promise((resolve) => { + blockTracker.on('sync', resolve); + }); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); + expect(blockTracker.isRunning()).toBe(true); + + // Clear the current block to force a new request for the next getLatestBlock + // When the block tracker stops, there may be two `setTimeout`s in + // play: one to go to the next iteration of the block tracker + // loop, another to expire the current block number cache. We don't + // know which one has been added first, so we have to find it. + blockTracker.removeAllListeners(); + await setTimeoutRecorder.nextMatchingDuration( + blockTrackerOptions.blockResetDuration, + ); + expect(blockTracker.getCurrentBlock()).toBeNull(); + + // Restart the tracker for the second call + blockTracker.on('latest', EMPTY_FUNCTION); + + // Step 3: Immediately after, call getLatestBlock + const secondBlockPromise = blockTracker.getLatestBlock(); + + // Step 4: Immediately after, destroy the block tracker + await blockTracker.destroy(); + + // Verify block tracker state + expect(blockTracker.isRunning()).toBe(false); + expect(blockTracker.getCurrentBlock()).toBeNull(); + + // The call to getLatestBlock would then never resolve (should be rejected) + await expect(secondBlockPromise).rejects.toThrow( + 'Block tracker destroyed', + ); + + // Verify that the block reset timeout is set up + expect( + setTimeoutRecorder.calls.some((call) => { + return call.duration === blockTrackerOptions.blockResetDuration; + }), + ).toBe(true); + + // Wait for the block reset timeout to complete + await setTimeoutRecorder.nextMatchingDuration( + blockTrackerOptions.blockResetDuration, + ); + + // Verify that the current block is still null after the timeout + expect(blockTracker.getCurrentBlock()).toBeNull(); + }, + ); + }); + }); + + describe('with useCache: false and a block number is already cached', () => { + describe('when the block tracker is not running', () => { + it('should not fetch a new block even if less than the polling interval time has passed since the last call', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x2', + }, + ], + }, + }, + async ({ blockTracker }) => { + await blockTracker.getLatestBlock(); + const block = await blockTracker.getLatestBlock({ + useCache: false, + }); + expect(block).toBe('0x1'); + expect(blockTracker.isRunning()).toBe(false); + }, + ); + }); + + it('should fetch a new block even if more than the polling interval time has passed since the last call', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout(); + const blockTrackerOptions = { + pollingInterval: 100, + blockResetDuration: 200, + }; + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x2', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + await blockTracker.getLatestBlock(); + await setTimeoutRecorder.nextMatchingDuration( + blockTrackerOptions.pollingInterval, + ); + const block = await blockTracker.getLatestBlock({ + useCache: false, + }); + expect(block).toBe('0x2'); + expect(blockTracker.isRunning()).toBe(false); + }, + ); + }); + }); + + describe('when the block tracker is already started', () => { + it('should wait for the next block event', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x2', + }, + { + methodName: 'eth_blockNumber', + result: '0x3', + }, + ], + }, + }, + + async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + await new Promise((resolve) => { + blockTracker.once('_waitingForNextIteration', resolve); + }); + + const blockPromise1 = blockTracker.getLatestBlock({ + useCache: false, + }); + const pollingLoopPromise1 = new Promise((resolve) => { + blockTracker.once('_waitingForNextIteration', resolve); + }); + await setTimeoutRecorder.next(); + await pollingLoopPromise1; + const block1 = await blockPromise1; + expect(block1).toBe('0x2'); + + const pollingLoopPromise2 = new Promise((resolve) => { + blockTracker.once('_waitingForNextIteration', resolve); + }); + const blockPromise2 = blockTracker.getLatestBlock({ + useCache: false, + }); + await setTimeoutRecorder.next(); + await pollingLoopPromise2; + const block2 = await blockPromise2; + expect(block2).toBe('0x3'); + }, + ); + }); + + it('should handle concurrent calls', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x2', + }, + ], + }, + }, + async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + await new Promise((resolve) => { + blockTracker.once('_waitingForNextIteration', resolve); + }); - // When the block tracker stops, there may be two `setTimeout`s in - // play: one to go to the next iteration of the block tracker - // loop, another to expire the current block number cache. We don't - // know which one has been added first, so we have to find it. - await setTimeoutRecorder.nextMatchingDuration( - blockTrackerOptions.blockResetDuration, + const blockPromise1 = blockTracker.getLatestBlock({ + useCache: false, + }); + const blockPromise2 = blockTracker.getLatestBlock({ + useCache: false, + }); + + const pollingLoopPromise = new Promise((resolve) => { + blockTracker.once('_waitingForNextIteration', resolve); + }); + await setTimeoutRecorder.next(); + await pollingLoopPromise; + + const block1 = await blockPromise1; + const block2 = await blockPromise2; + expect(block1).toBe('0x2'); + expect(block2).toBe('0x2'); + }, ); - expect(blockTracker.getCurrentBlock()).toBeNull(); - }, - ); + }); + }); }); }); @@ -646,21 +1193,17 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, { methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, + result: '0x1', }, ], }, }, async ({ blockTracker }) => { - blockTracker.checkForLatestBlock(); + await blockTracker.checkForLatestBlock(); await new Promise((resolve) => { blockTracker.on('latest', resolve); }); @@ -678,55 +1221,56 @@ describe('PollingBlockTracker', () => { }); }); - it('should fetch the latest block number', async () => { - recordCallsToSetTimeout(); - + it('should return the same promise if called multiple times', async () => { await withPollingBlockTracker( { provider: { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x1', }, ], }, }, async ({ blockTracker }) => { - const latestBlockNumber = await blockTracker.checkForLatestBlock(); - expect(latestBlockNumber).toStrictEqual('0x0'); + const promiseToCheckLatestBlock1 = blockTracker.checkForLatestBlock(); + const promiseToCheckLatestBlock2 = blockTracker.checkForLatestBlock(); + + expect(promiseToCheckLatestBlock1).toStrictEqual( + promiseToCheckLatestBlock2, + ); }, ); }); - it('request the latest block number with `skipCache: true` if the block tracker was initialized with `setSkipCacheFlag: true`', async () => { + it('should fetch the latest block number', async () => { recordCallsToSetTimeout(); await withPollingBlockTracker( - { blockTracker: { setSkipCacheFlag: true } }, - async ({ provider, blockTracker }) => { - jest.spyOn(provider, 'sendAsync'); - - await blockTracker.checkForLatestBlock(); - - expect(provider.sendAsync).toHaveBeenCalledWith( - { - jsonrpc: '2.0' as const, - id: expect.any(Number), - method: 'eth_blockNumber' as const, - params: [], - skipCache: true, - }, - expect.any(Function), - ); + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + }, + async ({ blockTracker }) => { + const latestBlockNumber = await blockTracker.checkForLatestBlock(); + expect(latestBlockNumber).toBe('0x0'); }, ); }); - it(`should not emit the "error" event, but should throw instead if the request for the latest block number returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); + it('should update the current block number', async () => { + recordCallsToSetTimeout(); await withPollingBlockTracker( { @@ -734,18 +1278,36 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, + result: '0x0', }, ], }, }, async ({ blockTracker }) => { - const promiseForLatestBlock = blockTracker.checkForLatestBlock(); - await expect(promiseForLatestBlock).rejects.toThrow( - 'PollingBlockTracker - encountered error fetching block:\nboom', - ); + await blockTracker.checkForLatestBlock(); + const currentBlockNumber = blockTracker.getCurrentBlock(); + expect(currentBlockNumber).toBe('0x0'); + }, + ); + }); + + it('request the latest block number with `skipCache: true` if the block tracker was initialized with `setSkipCacheFlag: true`', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { blockTracker: { setSkipCacheFlag: true } }, + async ({ provider, blockTracker }) => { + jest.spyOn(provider, 'request'); + + await blockTracker.checkForLatestBlock(); + + expect(provider.request).toHaveBeenCalledWith({ + jsonrpc: '2.0' as const, + id: expect.any(Number), + method: 'eth_blockNumber' as const, + params: [], + skipCache: true, + }); }, ); }); @@ -760,13 +1322,11 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - error: 'boom', + error: new Error('boom'), }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -778,31 +1338,34 @@ describe('PollingBlockTracker', () => { ); }); - it('should update the current block number', async () => { - recordCallsToSetTimeout(); + it('should start a timer to clear the current block number later if the block tracker is not running', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout(); + const blockResetDuration = 1000; await withPollingBlockTracker( { + blockTracker: { + blockResetDuration, + }, provider: { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, }, async ({ blockTracker }) => { await blockTracker.checkForLatestBlock(); - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); + await setTimeoutRecorder.nextMatchingDuration(blockResetDuration); + expect(blockTracker.getCurrentBlock()).toBeNull(); }, ); }); - it('should never start a timer to clear the current block number later', async () => { + it('should not start a timer to clear the current block number later if the block tracker is running', async () => { const setTimeoutRecorder = recordCallsToSetTimeout(); const blockResetDuration = 1000; @@ -815,24 +1378,256 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { + result: '0x0', + }, + ], + }, + }, + async ({ blockTracker }) => { + blockTracker.on('latest', EMPTY_FUNCTION); + await blockTracker.checkForLatestBlock(); + + const blockResetTimeouts = setTimeoutRecorder.calls.filter((call) => { + return call.duration === blockResetDuration; + }); + expect(blockResetTimeouts).toHaveLength(0); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); + }, + ); + }); + + describe.each([ + ['not initialized with `usePastBlocks`', {}], + ['initialized with `usePastBlocks: false`', { usePastBlocks: false }], + ] as const)( + 'after a block number is cached if the block tracker was %s', + (_description, blockTrackerOptions) => { + it('should return the fetched block number if the fetched block number is greater than the current block number', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + const blockNumber1 = await blockTracker.checkForLatestBlock(); + expect(blockNumber1).toBe('0x0'); + const blockNumber2 = await blockTracker.checkForLatestBlock(); + expect(blockNumber2).toBe('0x1'); + }, + ); + }); + + it('should update the current block number if the fetched block number is greater than the current block number', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + await blockTracker.checkForLatestBlock(); + await blockTracker.checkForLatestBlock(); + const currentBlockNumber = blockTracker.getCurrentBlock(); + expect(currentBlockNumber).toBe('0x1'); + }, + ); + }); + + it('should return the current block number if the fetched block number is less than the current block number', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + const blockNumber1 = await blockTracker.checkForLatestBlock(); + expect(blockNumber1).toBe('0x1'); + const blockNumber2 = await blockTracker.checkForLatestBlock(); + expect(blockNumber2).toBe('0x1'); + }, + ); + }); + + it('should not update the current block number if the fetched block number is less than the current block number', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + await blockTracker.checkForLatestBlock(); + await blockTracker.checkForLatestBlock(); + const currentBlockNumber = blockTracker.getCurrentBlock(); + expect(currentBlockNumber).toBe('0x1'); + }, + ); + }); + }, + ); + + describe('after a block number is cached if the block tracker was initialized with `usePastBlocks: true`', () => { + it('should return the fetched block number if the fetched block number is greater than the current block number', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + ], + }, + blockTracker: { usePastBlocks: true }, + }, + async ({ blockTracker }) => { + const blockNumber1 = await blockTracker.checkForLatestBlock(); + expect(blockNumber1).toBe('0x0'); + const blockNumber2 = await blockTracker.checkForLatestBlock(); + expect(blockNumber2).toBe('0x1'); + }, + ); + }); + + it('should update the current block number if the fetched block number is greater than the current block number', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + ], + }, + blockTracker: { usePastBlocks: true }, + }, + async ({ blockTracker }) => { + await blockTracker.checkForLatestBlock(); + await blockTracker.checkForLatestBlock(); + const currentBlockNumber = blockTracker.getCurrentBlock(); + expect(currentBlockNumber).toBe('0x1'); + }, + ); + }); + + it('should return the fetched block number if the fetched block number is less than the current block number', async () => { + recordCallsToSetTimeout(); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', result: '0x0', }, - }, - ], + ], + }, + blockTracker: { usePastBlocks: true }, }, - }, - async ({ blockTracker }) => { - await blockTracker.checkForLatestBlock(); + async ({ blockTracker }) => { + const blockNumber1 = await blockTracker.checkForLatestBlock(); + expect(blockNumber1).toBe('0x1'); + const blockNumber2 = await blockTracker.checkForLatestBlock(); + expect(blockNumber2).toBe('0x0'); + }, + ); + }); - await new Promise((resolve) => - originalSetTimeout(resolve, blockResetDuration), - ); + it('should update the current block number if the fetched block number is less than the current block number', async () => { + recordCallsToSetTimeout(); - expect(setTimeoutRecorder.calls).toHaveLength(0); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); - }, - ); + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: { usePastBlocks: true }, + }, + async ({ blockTracker }) => { + await blockTracker.checkForLatestBlock(); + await blockTracker.checkForLatestBlock(); + const currentBlockNumber = blockTracker.getCurrentBlock(); + expect(currentBlockNumber).toBe('0x0'); + }, + ); + }); }); }); @@ -858,9 +1653,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -869,15 +1662,13 @@ describe('PollingBlockTracker', () => { const latestBlockNumber = await new Promise((resolve) => { blockTracker[methodToAddListener]('latest', resolve); }); - expect(latestBlockNumber).toStrictEqual('0x0'); + expect(latestBlockNumber).toBe('0x0'); }, ); }); - it('should emit "latest" periodically afterward', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout({ - numAutomaticCalls: 1, - }); + it('should update the current block number', async () => { + recordCallsToSetTimeout(); await withPollingBlockTracker( { @@ -885,34 +1676,17 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, + result: '0x0', }, ], }, }, async ({ blockTracker }) => { - const receivedBlockNumbers: string[] = []; - - await new Promise((resolve) => { - setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); - - blockTracker[methodToAddListener]( - 'latest', - (blockNumber: string) => { - receivedBlockNumbers.push(blockNumber); - }, - ); + await new Promise((resolve) => { + blockTracker[methodToAddListener]('latest', resolve); }); - - expect(receivedBlockNumbers).toStrictEqual(['0x0', '0x1']); + const currentBlockNumber = blockTracker.getCurrentBlock(); + expect(currentBlockNumber).toBe('0x0'); }, ); }); @@ -931,15 +1705,11 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, { methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, + result: '0x1', }, ], }, @@ -957,55 +1727,12 @@ describe('PollingBlockTracker', () => { return call.duration === blockTrackerOptions.pollingInterval; }, ); - expect(nextIterationTimeout).not.toBeUndefined(); + expect(nextIterationTimeout).toBeDefined(); expect(nextIterationTimeout?.timeout.hasRef()).toBe(false); }, ); }); - it('should not emit "latest" if the newly fetched block number is less than the current block number', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout({ - numAutomaticCalls: 1, - }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const receivedBlockNumbers: string[] = []; - - await new Promise((resolve) => { - setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); - - blockTracker[methodToAddListener]( - 'latest', - (blockNumber: string) => { - receivedBlockNumbers.push(blockNumber); - }, - ); - }); - - expect(receivedBlockNumbers).toStrictEqual(['0x1']); - }, - ); - }); - it('should re-throw any error out of band that occurs in the listener', async () => { await withPollingBlockTracker(async ({ blockTracker }) => { const thrownError = new Error('boom'); @@ -1015,10 +1742,11 @@ describe('PollingBlockTracker', () => { interceptCallback: (callback, stopPassingThroughCalls) => { return async () => { try { - await callback(); + return await callback(); } catch (error: unknown) { resolve(error); stopPassingThroughCalls(); + return undefined; } }; }, @@ -1040,109 +1768,25 @@ describe('PollingBlockTracker', () => { await withPollingBlockTracker( { blockTracker: { setSkipCacheFlag: true } }, async ({ provider, blockTracker }) => { - jest.spyOn(provider, 'sendAsync'); + jest.spyOn(provider, 'request'); await new Promise((resolve) => { blockTracker[methodToAddListener]('latest', resolve); }); - expect(provider.sendAsync).toHaveBeenCalledWith( - { - jsonrpc: '2.0' as const, - id: expect.any(Number), - method: 'eth_blockNumber' as const, - params: [], - skipCache: true, - }, - expect.any(Function), - ); - }, - ); - }); - - it(`should emit the "error" event and should not kill the block tracker if the request for the latest block number returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: PollingBlockTracker - encountered error fetching block:\nboom/u, - ); - const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); - }, - ); - }); - - it(`should emit the "error" event and should not kill the block tracker if, while making the request for the latest block number, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); + expect(provider.request).toHaveBeenCalledWith({ + jsonrpc: '2.0' as const, + id: expect.any(Number), + method: 'eth_blockNumber' as const, + params: [], + skipCache: true, }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom\n/u, - ); - const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); }, ); }); - it(`should emit the "error" event and should not kill the block tracker if, while making the request for the latest block number, the provider throws a string`, async () => { + it(`should emit the "error" event and should not kill the block tracker if, while making the request for the latest block number, the provider throws`, async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -1152,38 +1796,33 @@ describe('PollingBlockTracker', () => { { methodName: 'eth_blockNumber', implementation: () => { - throw 'boom'; + throw thrownError; }, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, }, async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); + const errorListener = jest.fn(); + blockTracker[methodToAddListener]('error', errorListener); const promiseForLatestBlock = new Promise((resolve) => { blockTracker[methodToAddListener]('latest', resolve); }); - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nboom/u, - ); const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); + expect(errorListener).toHaveBeenCalledWith(thrownError); + expect(latestBlock).toBe('0x0'); }, ); }); it(`should emit the "error" event and should not kill the block tracker if, while making the request for the latest block number, the provider rejects with an error`, async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -1192,37 +1831,32 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - error: 'boom', + error: thrownError, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, }, async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); + const errorListener = jest.fn(); + blockTracker[methodToAddListener]('error', errorListener); const promiseForLatestBlock = new Promise((resolve) => { blockTracker[methodToAddListener]('latest', resolve); }); - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ); const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); + expect(errorListener).toHaveBeenCalledWith(thrownError); + expect(latestBlock).toBe('0x0'); }, ); }); - it('should log an error if the request for the latest block number returns an error response and there is nothing listening to "error"', async () => { + it('should log an error if, while making a request for the latest block number, the provider throws and there is nothing listening to "error"', async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -1231,15 +1865,13 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - error: 'boom', + implementation: () => { + throw thrownError; }, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -1253,17 +1885,14 @@ describe('PollingBlockTracker', () => { }); expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: PollingBlockTracker - encountered error fetching block:\nboom/u, - ), - }), + 'Error updating latest block: boom', ); }, ); }); - it('should log an error if, while making a request for the latest block number, the provider throws an Error and there is nothing listening to "error"', async () => { + it('should log an error if, while making the request for the latest block number, the provider rejects with an error and there is nothing listening to "error"', async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -1272,15 +1901,11 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, + error: thrownError, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -1294,120 +1919,260 @@ describe('PollingBlockTracker', () => { }); expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ), - }), + 'Error updating latest block: boom', ); }, ); }); - it('should log an error if, while making a request for the latest block number, the provider throws a string and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); + describe.each([ + ['not initialized with `usePastBlocks`', {}], + ['initialized with `usePastBlocks: false`', { usePastBlocks: false }], + ] as const)( + 'after a block number is cached if the block tracker was %s', + (_description, blockTrackerOptions) => { + it('should emit "latest" if the fetched block number is greater than the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw 'boom'; - }, - }, - { - methodName: 'eth_blockNumber', - response: { + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + const receivedBlockNumbers: string[] = []; + + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); + + blockTracker[methodToAddListener]( + 'latest', + (blockNumber: string) => { + receivedBlockNumbers.push(blockNumber); + }, + ); + }); + + expect(receivedBlockNumbers).toStrictEqual(['0x0', '0x1']); + }, + ); + }); + + it('should not emit "latest" if the fetched block number is less than the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + const receivedBlockNumbers: string[] = []; + + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); + + blockTracker[methodToAddListener]( + 'latest', + (blockNumber: string) => { + receivedBlockNumbers.push(blockNumber); + }, + ); + }); + + expect(receivedBlockNumbers).toStrictEqual(['0x1']); + }, + ); + }); + + it('should not emit "latest" if the fetched block number is the same as the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + const receivedBlockNumbers: string[] = []; + + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); + + blockTracker[methodToAddListener]( + 'latest', + (blockNumber: string) => { + receivedBlockNumbers.push(blockNumber); + }, + ); + }); + + expect(receivedBlockNumbers).toStrictEqual(['0x0']); + }, + ); + }); + }, + ); + + describe('after a block number is cached if the block tracker was initialized with `usePastBlocks: true`', () => { + it('should emit "latest" if the fetched block number is greater than the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', result: '0x0', }, - }, - ], + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + ], + }, + blockTracker: { usePastBlocks: true }, }, - }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); + async ({ blockTracker }) => { + const receivedBlockNumbers: string[] = []; - blockTracker[methodToAddListener]('latest', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); - }); + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nboom/u, - ), - }), - ); - }, - ); - }); + blockTracker[methodToAddListener]( + 'latest', + (blockNumber: string) => { + receivedBlockNumbers.push(blockNumber); + }, + ); + }); - it('should log an error if, while making the request for the latest block number, the provider rejects with an error and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); + expect(receivedBlockNumbers).toStrictEqual(['0x0', '0x1']); + }, + ); + }); + + it('should emit "latest" if the fetched block number is less than the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - error: 'boom', - }, - { - methodName: 'eth_blockNumber', - response: { + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', result: '0x0', }, - }, - ], + ], + }, + blockTracker: { usePastBlocks: true }, }, - }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); + async ({ blockTracker }) => { + const receivedBlockNumbers: string[] = []; - blockTracker[methodToAddListener]('latest', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); - }); + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ), - }), - ); - }, - ); - }); + blockTracker[methodToAddListener]( + 'latest', + (blockNumber: string) => { + receivedBlockNumbers.push(blockNumber); + }, + ); + }); - it('should update the current block number', async () => { - recordCallsToSetTimeout(); + expect(receivedBlockNumbers).toStrictEqual(['0x1', '0x0']); + }, + ); + }); - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { + it('should not emit "latest" if the fetched block number is the same as the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', result: '0x0', }, - }, - ], + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: { usePastBlocks: true }, }, - }, - async ({ blockTracker }) => { - await new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); - }, - ); + async ({ blockTracker }) => { + const receivedBlockNumbers: string[] = []; + + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); + + blockTracker[methodToAddListener]( + 'latest', + (blockNumber: string) => { + receivedBlockNumbers.push(blockNumber); + }, + ); + }); + + expect(receivedBlockNumbers).toStrictEqual(['0x0']); + }, + ); + }); }); }); @@ -1431,9 +2196,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -1447,10 +2210,8 @@ describe('PollingBlockTracker', () => { ); }); - it('should emit "sync" periodically afterward', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout({ - numAutomaticCalls: 1, - }); + it('should update the current block number', async () => { + recordCallsToSetTimeout(); await withPollingBlockTracker( { @@ -1458,34 +2219,17 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, + result: '0x0', }, ], }, }, async ({ blockTracker }) => { - const syncs: Sync[] = []; - - await new Promise((resolve) => { - setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); - - blockTracker[methodToAddListener]('sync', (sync: Sync) => { - syncs.push(sync); - }); + await new Promise((resolve) => { + blockTracker[methodToAddListener]('sync', resolve); }); - - expect(syncs).toStrictEqual([ - { oldBlock: null, newBlock: '0x0' }, - { oldBlock: '0x0', newBlock: '0x1' }, - ]); + const currentBlockNumber = blockTracker.getCurrentBlock(); + expect(currentBlockNumber).toBe('0x0'); }, ); }); @@ -1504,15 +2248,11 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, { methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, + result: '0x1', }, ], }, @@ -1530,54 +2270,12 @@ describe('PollingBlockTracker', () => { return call.duration === blockTrackerOptions.pollingInterval; }, ); - expect(nextIterationTimeout).not.toBeUndefined(); + expect(nextIterationTimeout).toBeDefined(); expect(nextIterationTimeout?.timeout.hasRef()).toBe(false); }, ); }); - it('should not emit "sync" if the newly fetched block number is less than the current block number', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout({ - numAutomaticCalls: 1, - }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const syncs: Sync[] = []; - - await new Promise((resolve) => { - setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); - - blockTracker[methodToAddListener]('sync', (sync: Sync) => { - syncs.push(sync); - }); - }); - - expect(syncs).toStrictEqual([ - { oldBlock: null, newBlock: '0x1' }, - ]); - }, - ); - }); - it('should re-throw any error out of band that occurs in the listener', async () => { await withPollingBlockTracker(async ({ blockTracker }) => { const thrownError = new Error('boom'); @@ -1587,10 +2285,11 @@ describe('PollingBlockTracker', () => { interceptCallback: (callback, stopPassingThroughCalls) => { return async () => { try { - await callback(); + return await callback(); } catch (error: unknown) { resolve(error); stopPassingThroughCalls(); + return undefined; } }; }, @@ -1612,109 +2311,25 @@ describe('PollingBlockTracker', () => { await withPollingBlockTracker( { blockTracker: { setSkipCacheFlag: true } }, async ({ provider, blockTracker }) => { - jest.spyOn(provider, 'sendAsync'); + jest.spyOn(provider, 'request'); await new Promise((resolve) => { blockTracker[methodToAddListener]('sync', resolve); }); - expect(provider.sendAsync).toHaveBeenCalledWith( - { - jsonrpc: '2.0' as const, - id: expect.any(Number), - method: 'eth_blockNumber' as const, - params: [], - skipCache: true, - }, - expect.any(Function), - ); - }, - ); - }); - - it(`should emit the "error" event and should not kill the block tracker if the request for the latest block number returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: PollingBlockTracker - encountered error fetching block:\nboom/u, - ); - const sync = await promiseForSync; - expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); - }, - ); - }); - - it(`should emit the "error" event and should not kill the block tracker if, while making the request for the latest block number, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); + expect(provider.request).toHaveBeenCalledWith({ + jsonrpc: '2.0' as const, + id: expect.any(Number), + method: 'eth_blockNumber' as const, + params: [], + skipCache: true, }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom\n/u, - ); - const sync = await promiseForSync; - expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); }, ); }); - it(`should emit the "error" event and should not kill the block tracker if, while making the request for the latest block number, the provider throws a string`, async () => { + it(`should emit the "error" event and should not kill the block tracker if, while making the request for the latest block number, the provider throws`, async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -1724,112 +2339,33 @@ describe('PollingBlockTracker', () => { { methodName: 'eth_blockNumber', implementation: () => { - throw 'boom'; - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nboom/u, - ); - const sync = await promiseForSync; - expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); - }, - ); - }); - - it(`should emit the "error" event and should not kill the block tracker if, while making the request for the latest block number, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - error: 'boom', - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', + throw thrownError; }, }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ); - const sync = await promiseForSync; - expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); - }, - ); - }); - - it('should log an error if the request for the latest block number returns an error response and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ { methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, + result: '0x0', }, ], }, }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); - - blockTracker[methodToAddListener]('sync', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); + async ({ blockTracker }) => { + const errorListener = jest.fn(); + blockTracker[methodToAddListener]('error', errorListener); + + const promiseForSync = new Promise((resolve) => { + blockTracker[methodToAddListener]('sync', resolve); }); - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: PollingBlockTracker - encountered error fetching block:\nboom/u, - ), - }), - ); + const sync = await promiseForSync; + expect(errorListener).toHaveBeenCalledWith(thrownError); + expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); }, ); }); - it('should log an error if, while making a request for the latest block number, the provider throws an Error and there is nothing listening to "error"', async () => { + it(`should emit the "error" event and should not kill the block tracker if, while making the request for the latest block number, the provider rejects with an error`, async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -1838,33 +2374,32 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, + error: new Error('boom'), + }, + { + methodName: 'eth_blockNumber', + result: '0x0', }, ], }, }, async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); + const errorListener = jest.fn(); + blockTracker[methodToAddListener]('error', errorListener); - blockTracker[methodToAddListener]('sync', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); + const promiseForSync = new Promise((resolve) => { + blockTracker[methodToAddListener]('sync', resolve); }); - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ), - }), - ); + const sync = await promiseForSync; + expect(errorListener).toHaveBeenCalledWith(thrownError); + expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); }, ); }); - it('should log an error if, while making a request for the latest block number, the provider throws a string and there is nothing listening to "error"', async () => { + it('should log an error if, while making a request for the latest block number, the provider throws and there is nothing listening to "error"', async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -1874,7 +2409,7 @@ describe('PollingBlockTracker', () => { { methodName: 'eth_blockNumber', implementation: () => { - throw 'boom'; + throw thrownError; }, }, ], @@ -1889,17 +2424,14 @@ describe('PollingBlockTracker', () => { }); expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nboom/u, - ), - }), + 'Error updating latest block: boom', ); }, ); }); it('should log an error if, while making the request for the latest block number, the provider rejects with an error and there is nothing listening to "error"', async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -1908,7 +2440,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - error: 'boom', + error: thrownError, }, ], }, @@ -1922,40 +2454,257 @@ describe('PollingBlockTracker', () => { }); expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ), - }), + 'Error updating latest block: boom', ); }, ); }); - it('should update the current block number', async () => { - recordCallsToSetTimeout(); + describe.each([ + ['not initialized with `usePastBlocks`', {}], + ['initialized with `usePastBlocks: false`', { usePastBlocks: false }], + ] as const)( + 'after a block number is cached if the block tracker was %s', + (_description, blockTrackerOptions) => { + it('should emit "sync" if the fetched block number is greater than the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + const syncs: Sync[] = []; + + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); + + blockTracker[methodToAddListener]('sync', (sync: Sync) => { + syncs.push(sync); + }); + }); + + expect(syncs).toStrictEqual([ + { oldBlock: null, newBlock: '0x0' }, + { oldBlock: '0x0', newBlock: '0x1' }, + ]); + }, + ); + }); + + it('should not emit "sync" if the fetched block number is less than the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + const syncs: Sync[] = []; + + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); + + blockTracker[methodToAddListener]('sync', (sync: Sync) => { + syncs.push(sync); + }); + }); + + expect(syncs).toStrictEqual([ + { oldBlock: null, newBlock: '0x1' }, + ]); + }, + ); + }); + + it('should not emit "sync" if the fetched block number is the same as the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + const syncs: Sync[] = []; + + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); + + blockTracker[methodToAddListener]('sync', (sync: Sync) => { + syncs.push(sync); + }); + }); + + expect(syncs).toStrictEqual([ + { oldBlock: null, newBlock: '0x0' }, + ]); + }, + ); + }); + }, + ); + + describe('after a block number is cached if the block tracker was initialized with `usePastBlocks: true`', () => { + it('should emit "sync" if the fetched block number is greater than the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', result: '0x0', }, - }, - ], + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + ], + }, + blockTracker: { usePastBlocks: true }, }, - }, - async ({ blockTracker }) => { - await new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); - }, - ); + async ({ blockTracker }) => { + const syncs: Sync[] = []; + + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); + + blockTracker[methodToAddListener]('sync', (sync: Sync) => { + syncs.push(sync); + }); + }); + + expect(syncs).toStrictEqual([ + { oldBlock: null, newBlock: '0x0' }, + { oldBlock: '0x0', newBlock: '0x1' }, + ]); + }, + ); + }); + + it('should emit "sync" if the fetched block number is less than the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: { usePastBlocks: true }, + }, + async ({ blockTracker }) => { + const syncs: Sync[] = []; + + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); + + blockTracker[methodToAddListener]('sync', (sync: Sync) => { + syncs.push(sync); + }); + }); + + expect(syncs).toStrictEqual([ + { oldBlock: null, newBlock: '0x1' }, + { oldBlock: '0x1', newBlock: '0x0' }, + ]); + }, + ); + }); + + it('should not emit "sync" if the fetched block number is the same as the current block number', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout({ + numAutomaticCalls: 1, + }); + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + ], + }, + blockTracker: { usePastBlocks: true }, + }, + async ({ blockTracker }) => { + const syncs: Sync[] = []; + + await new Promise((resolve) => { + setTimeoutRecorder.onNumAutomaticCallsExhausted(resolve); + + blockTracker[methodToAddListener]('sync', (sync: Sync) => { + syncs.push(sync); + }); + }); + + expect(syncs).toStrictEqual([ + { oldBlock: null, newBlock: '0x0' }, + ]); + }, + ); + }); }); }); @@ -1979,9 +2728,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -2036,9 +2783,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -2053,7 +2798,7 @@ describe('PollingBlockTracker', () => { blockTracker.on('latest', listener2); await promiseForLatestBlock; const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); + expect(currentBlockNumber).toBe('0x0'); blockTracker[methodToRemoveListener]('latest', listener1); blockTracker[methodToRemoveListener]('latest', listener2); @@ -2069,6 +2814,60 @@ describe('PollingBlockTracker', () => { }, ); }); + + it('should cancel polling timeout and prevent multiple synchronize loops', async () => { + const setTimeoutRecorder = recordCallsToSetTimeout(); + + const blockTrackerOptions = { + pollingInterval: 100, + blockResetDuration: 200, + }; + + await withPollingBlockTracker( + { + provider: { + stubs: [ + { + methodName: 'eth_blockNumber', + result: '0x0', + }, + { + methodName: 'eth_blockNumber', + result: '0x1', + }, + { + methodName: 'eth_blockNumber', + result: '0x2', + }, + ], + }, + blockTracker: blockTrackerOptions, + }, + async ({ blockTracker }) => { + const listener = EMPTY_FUNCTION; + + for (let i = 0; i < 3; i++) { + blockTracker.on('latest', listener); + + expect(blockTracker.isRunning()).toBe(true); + + await new Promise((resolve) => { + blockTracker.on('_waitingForNextIteration', resolve); + }); + + blockTracker[methodToRemoveListener]('latest', listener); + + expect(blockTracker.isRunning()).toBe(false); + } + + expect( + setTimeoutRecorder.findCallsMatchingDuration( + blockTrackerOptions.pollingInterval, + ), + ).toHaveLength(0); + }, + ); + }); }); describe('"sync"', () => { @@ -2105,9 +2904,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -2122,7 +2919,7 @@ describe('PollingBlockTracker', () => { blockTracker.on('sync', listener2); await promiseForLatestBlock; const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); + expect(currentBlockNumber).toBe('0x0'); blockTracker[methodToRemoveListener]('sync', listener1); blockTracker[methodToRemoveListener]('sync', listener2); @@ -2196,34 +2993,30 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, { methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, + result: '0x1', }, ], }, blockTracker: blockTrackerOptions, }, async ({ blockTracker }) => { - blockTracker.once('latest', EMPTY_FUNCTION); + const { promise, resolve: listener } = buildDeferred(); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); - }); + blockTracker.once('latest', listener); - const nextIterationTimeout = setTimeoutRecorder.calls.find( - (call) => { - return call.duration === blockTrackerOptions.pollingInterval; - }, - ); - expect(nextIterationTimeout).not.toBeUndefined(); - expect(nextIterationTimeout?.timeout.hasRef()).toBe(false); + await promise; + + // Once the listener has fired the block tracker should stop, + // meaning there should be no timeouts. + expect( + setTimeoutRecorder.findCallsMatchingDuration( + blockTrackerOptions.pollingInterval, + ), + ).toHaveLength(0); }, ); }); @@ -2241,9 +3034,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -2253,7 +3044,7 @@ describe('PollingBlockTracker', () => { await new Promise((resolve) => { blockTracker.once('latest', resolve); }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); // When the block tracker stops, there may be two `setTimeout`s in // play: one to go to the next iteration of the block tracker @@ -2264,93 +3055,12 @@ describe('PollingBlockTracker', () => { ); expect(blockTracker.getCurrentBlock()).toBeNull(); }, - ); - }); - - METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if the request for the latest block number returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: PollingBlockTracker - encountered error fetching block:\nboom/u, - ); - const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom\n/u, - ); - const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); - }, - ); - }); + ); + }); - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider throws a string`, async () => { + METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { + it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider throws`, async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -2360,38 +3070,33 @@ describe('PollingBlockTracker', () => { { methodName: 'eth_blockNumber', implementation: () => { - throw 'boom'; + throw thrownError; }, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, }, async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); + const errorListener = jest.fn(); + blockTracker[methodToAddListener]('error', errorListener); const promiseForLatestBlock = new Promise((resolve) => { blockTracker.once('latest', resolve); }); - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nboom/u, - ); const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); + expect(errorListener).toHaveBeenCalledWith(thrownError); + expect(latestBlock).toBe('0x0'); }, ); }); it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider rejects with an error`, async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -2400,120 +3105,33 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - error: 'boom', + error: thrownError, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, }, async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); + const errorListener = jest.fn(); + blockTracker[methodToAddListener]('error', errorListener); const promiseForLatestBlock = new Promise((resolve) => { blockTracker.once('latest', resolve); }); - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ); const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toStrictEqual('0x0'); + expect(errorListener).toHaveBeenCalledWith(thrownError); + expect(latestBlock).toBe('0x0'); }, ); }); }); - it('should log an error if the request for the latest block number returns an error response and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); - - blockTracker.once('latest', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); - }); - - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: PollingBlockTracker - encountered error fetching block:\nboom/u, - ), - }), - ); - }, - ); - }); - - it('should log an error if, while making a request for the latest block number, the provider throws an Error and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); - - blockTracker.once('latest', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); - }); - - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ), - }), - ); - }, - ); - }); - - it('should log an error if, while making a request for the latest block number, the provider throws a string and there is nothing listening to "error"', async () => { + it('should log an error if, while making a request for the latest block number, the provider throws and there is nothing listening to "error"', async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -2523,14 +3141,12 @@ describe('PollingBlockTracker', () => { { methodName: 'eth_blockNumber', implementation: () => { - throw 'boom'; + throw thrownError; }, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -2544,17 +3160,14 @@ describe('PollingBlockTracker', () => { }); expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nboom/u, - ), - }), + 'Error updating latest block: boom', ); }, ); }); it('should log an error if, while making the request for the latest block number, the provider rejects with an error and there is nothing listening to "error"', async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -2563,13 +3176,11 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - error: 'boom', + error: thrownError, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -2583,11 +3194,7 @@ describe('PollingBlockTracker', () => { }); expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ), - }), + 'Error updating latest block: boom', ); }, ); @@ -2624,9 +3231,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -2636,7 +3241,7 @@ describe('PollingBlockTracker', () => { await new Promise((resolve) => { blockTracker.once('sync', resolve); }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); // When the block tracker stops, there may be two `setTimeout`s in // play: one to go to the next iteration of the block tracker @@ -2651,89 +3256,8 @@ describe('PollingBlockTracker', () => { }); METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if the request for the latest block number returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: PollingBlockTracker - encountered error fetching block:\nboom/u, - ); - const sync = await promiseForSync; - expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom\n/u, - ); - const sync = await promiseForSync; - expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider throws a string`, async () => { + it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider throws`, async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -2743,38 +3267,33 @@ describe('PollingBlockTracker', () => { { methodName: 'eth_blockNumber', implementation: () => { - throw 'boom'; + throw thrownError; }, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, }, async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); + const errorListener = jest.fn(); + blockTracker[methodToAddListener]('error', errorListener); const promiseForSync = new Promise((resolve) => { blockTracker.once('sync', resolve); }); - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nboom/u, - ); const sync = await promiseForSync; + expect(errorListener).toHaveBeenCalledWith(thrownError); expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); }, ); }); it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not throw if, while making the request for the latest block number, the provider rejects with an error`, async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -2783,120 +3302,33 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - error: 'boom', + error: thrownError, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, }, async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); + const errorListener = jest.fn(); + blockTracker[methodToAddListener]('error', errorListener); const promiseForSync = new Promise((resolve) => { blockTracker.once('sync', resolve); }); - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toMatch( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ); const sync = await promiseForSync; + expect(errorListener).toHaveBeenCalledWith(thrownError); expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); }, ); }); }); - it('should log an error if the request for the latest block number returns an error response and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); - - blockTracker.once('sync', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); - }); - - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: PollingBlockTracker - encountered error fetching block:\nboom/u, - ), - }), - ); - }, - ); - }); - - it('should log an error if, while making a request for the latest block number, the provider throws an Error and there is nothing listening to "error"', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withPollingBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - jest.spyOn(console, 'error').mockImplementation(EMPTY_FUNCTION); - - blockTracker.once('sync', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('_waitingForNextIteration', resolve); - }); - - expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ), - }), - ); - }, - ); - }); - - it('should log an error if, while making a request for the latest block number, the provider throws a string and there is nothing listening to "error"', async () => { + it('should log an error if, while making a request for the latest block number, the provider throws and there is nothing listening to "error"', async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -2906,14 +3338,12 @@ describe('PollingBlockTracker', () => { { methodName: 'eth_blockNumber', implementation: () => { - throw 'boom'; + throw thrownError; }, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -2927,17 +3357,14 @@ describe('PollingBlockTracker', () => { }); expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nboom/u, - ), - }), + 'Error updating latest block: boom', ); }, ); }); it('should log an error if, while making the request for the latest block number, the provider rejects with an error and there is nothing listening to "error"', async () => { + const thrownError = new Error('boom'); recordCallsToSetTimeout({ numAutomaticCalls: 1 }); await withPollingBlockTracker( @@ -2946,13 +3373,11 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - error: 'boom', + error: thrownError, }, { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -2966,11 +3391,7 @@ describe('PollingBlockTracker', () => { }); expect(console.error).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringMatching( - /^PollingBlockTracker - encountered an error while attempting to update latest block:\nError: boom/u, - ), - }), + 'Error updating latest block: boom', ); }, ); @@ -3002,9 +3423,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -3047,9 +3466,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -3060,7 +3477,7 @@ describe('PollingBlockTracker', () => { await new Promise((resolve) => { blockTracker.on('sync', resolve); }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); blockTracker.removeAllListeners(); // When the block tracker stops, there may be two `setTimeout`s in @@ -3106,9 +3523,7 @@ describe('PollingBlockTracker', () => { stubs: [ { methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, + result: '0x0', }, ], }, @@ -3119,7 +3534,7 @@ describe('PollingBlockTracker', () => { await new Promise((resolve) => { blockTracker.on('sync', resolve); }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); + expect(blockTracker.getCurrentBlock()).toBe('0x0'); blockTracker.removeAllListeners('latest'); blockTracker.removeAllListeners('sync'); diff --git a/src/PollingBlockTracker.ts b/src/PollingBlockTracker.ts index 48bbb737..f0e658b9 100644 --- a/src/PollingBlockTracker.ts +++ b/src/PollingBlockTracker.ts @@ -1,36 +1,69 @@ +import type { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider'; +import SafeEventEmitter from '@metamask/safe-event-emitter'; +import { + createDeferredPromise, + type DeferredPromise, + getErrorMessage, + type JsonRpcRequest, +} from '@metamask/utils'; import getCreateRandomId from 'json-rpc-random-id'; -import pify from 'pify'; -import { JsonRpcRequest } from 'json-rpc-engine'; -import { BaseBlockTracker, Provider } from './BaseBlockTracker'; + +import type { BlockTracker } from './BlockTracker'; import { projectLogger, createModuleLogger } from './logging-utils'; const log = createModuleLogger(projectLogger, 'polling-block-tracker'); const createRandomId = getCreateRandomId(); const sec = 1000; -export interface PollingBlockTrackerOptions { - provider?: Provider; +const blockTrackerEvents: (string | symbol)[] = ['sync', 'latest']; + +export type PollingBlockTrackerOptions = { + provider?: SafeEventEmitterProvider; pollingInterval?: number; retryTimeout?: number; keepEventLoopActive?: boolean; setSkipCacheFlag?: boolean; blockResetDuration?: number; -} + usePastBlocks?: boolean; +}; -interface ExtendedJsonRpcRequest extends JsonRpcRequest { +type ExtendedJsonRpcRequest = { skipCache?: boolean; -} +} & JsonRpcRequest<[]>; + +type InternalListener = (value: string) => void; + +export class PollingBlockTracker + extends SafeEventEmitter + implements BlockTracker +{ + private _isRunning: boolean; + + private readonly _blockResetDuration: number; + + private readonly _usePastBlocks: boolean; -export class PollingBlockTracker extends BaseBlockTracker { - private _provider: Provider; + private _currentBlock: string | null; - private _pollingInterval: number; + private _blockResetTimeout?: ReturnType; - private _retryTimeout: number; + private _pollingTimeout?: ReturnType; - private _keepEventLoopActive: boolean; + private readonly _provider: SafeEventEmitterProvider; - private _setSkipCacheFlag: boolean; + private readonly _pollingInterval: number; + + private readonly _retryTimeout: number; + + private readonly _keepEventLoopActive: boolean; + + private readonly _setSkipCacheFlag: boolean; + + readonly #internalEventListeners: InternalListener[] = []; + + #pendingLatestBlock?: Omit, 'resolve'>; + + #pendingFetch?: Omit, 'resolve'>; constructor(opts: PollingBlockTrackerOptions = {}) { // parse + validate args @@ -38,9 +71,22 @@ export class PollingBlockTracker extends BaseBlockTracker { throw new Error('PollingBlockTracker - no provider specified.'); } - super({ - blockResetDuration: opts.blockResetDuration ?? opts.pollingInterval, - }); + super(); + + // config + this._blockResetDuration = opts.blockResetDuration || 20 * sec; + this._usePastBlocks = opts.usePastBlocks || false; + // state + this._currentBlock = null; + this._isRunning = false; + + // bind functions for internal use + this._onNewListener = this._onNewListener.bind(this); + this._onRemoveListener = this._onRemoveListener.bind(this); + this._resetCurrentBlock = this._resetCurrentBlock.bind(this); + + // listen for handler changes + this._setupInternalEvents(); // config this._provider = opts.provider; @@ -51,92 +97,355 @@ export class PollingBlockTracker extends BaseBlockTracker { this._setSkipCacheFlag = opts.setSkipCacheFlag || false; } - // trigger block polling - async checkForLatestBlock() { - await this._updateLatestBlock(); - return await this.getLatestBlock(); + async destroy() { + this._cancelBlockResetTimeout(); + super.removeAllListeners(); + this._maybeEnd(); } - protected async _start(): Promise { - this._synchronize(); + isRunning(): boolean { + return this._isRunning; } - protected async _end(): Promise { - // No-op + getCurrentBlock(): string | null { + return this._currentBlock; } - private async _synchronize(): Promise { - while (this._isRunning) { + async getLatestBlock({ + useCache = true, + }: { useCache?: boolean } = {}): Promise { + // return if available + if (this._currentBlock && useCache) { + return this._currentBlock; + } + + if (this.#pendingLatestBlock) { + return await this.#pendingLatestBlock.promise; + } + + const { promise, resolve, reject } = createDeferredPromise({ + suppressUnhandledRejection: true, + }); + this.#pendingLatestBlock = { reject, promise }; + + if (this._isRunning) { + try { + // If tracker is running, wait for next block with timeout + const onLatestBlock = (value: string) => { + this.#removeInternalListener(onLatestBlock); + this.removeListener('latest', onLatestBlock); + resolve(value); + }; + + this.#addInternalListener(onLatestBlock); + this.once('latest', onLatestBlock); + + return await promise; + } catch (error) { + reject(error); + throw error; + } finally { + this.#pendingLatestBlock = undefined; + } + } else { + // If tracker isn't running, just fetch directly try { - await this._updateLatestBlock(); - const promise = timeout( - this._pollingInterval, - !this._keepEventLoopActive, - ); - this.emit('_waitingForNextIteration'); - await promise; - } catch (err: any) { - const newErr = new Error( - `PollingBlockTracker - encountered an error while attempting to update latest block:\n${ - err.stack ?? err - }`, - ); - try { - this.emit('error', newErr); - } catch (emitErr) { - console.error(newErr); - } - const promise = timeout(this._retryTimeout, !this._keepEventLoopActive); - this.emit('_waitingForNextIteration'); - await promise; + const latestBlock = await this._updateLatestBlock(); + resolve(latestBlock); + return latestBlock; + } catch (error) { + reject(error); + throw error; + } finally { + // We want to rate limit calls to this method if we made a direct fetch + // for the block number because the BlockTracker was not running. We + // achieve this by delaying the unsetting of the #pendingLatestBlock promise. + setTimeout(() => { + this.#pendingLatestBlock = undefined; + }, this._pollingInterval); } } } - private async _updateLatestBlock(): Promise { + // dont allow module consumer to remove our internal event listeners + removeAllListeners(eventName?: string | symbol) { + // perform default behavior, preserve fn arity + if (eventName) { + super.removeAllListeners(eventName); + } else { + super.removeAllListeners(); + } + + // re-add internal events + this._setupInternalEvents(); + // trigger stop check just in case + this._onRemoveListener(); + + return this; + } + + private _setupInternalEvents(): void { + // first remove listeners for idempotence + this.removeListener('newListener', this._onNewListener); + this.removeListener('removeListener', this._onRemoveListener); + // then add them + this.on('newListener', this._onNewListener); + this.on('removeListener', this._onRemoveListener); + } + + private _onNewListener(eventName: string | symbol): void { + // `newListener` is called *before* the listener is added + if (blockTrackerEvents.includes(eventName)) { + // TODO: Handle dangling promise + this._maybeStart(); + } + } + + private _onRemoveListener(): void { + // `removeListener` is called *after* the listener is removed + if (this._getBlockTrackerEventCount() > 0) { + return; + } + this._maybeEnd(); + } + + private _maybeStart() { + if (this._isRunning) { + return; + } + + this._isRunning = true; + // cancel setting latest block to stale + this._cancelBlockResetTimeout(); + this._start(); + this.emit('_started'); + } + + private _maybeEnd() { + if (!this._isRunning) { + return; + } + + this._isRunning = false; + this._setupBlockResetTimeout(); + this._end(); + this.#rejectPendingLatestBlock(new Error('Block tracker destroyed')); + this.emit('_ended'); + } + + private _getBlockTrackerEventCount(): number { + return ( + blockTrackerEvents + .map((eventName) => this.listeners(eventName)) + .flat() + // internal listeners are not included in the count + .filter((listener) => + this.#internalEventListeners.every( + (internalListener) => !Object.is(internalListener, listener), + ), + ).length + ); + } + + private _shouldUseNewBlock(newBlock: string) { + const currentBlock = this._currentBlock; + if (!currentBlock) { + return true; + } + const newBlockInt = hexToInt(newBlock); + const currentBlockInt = hexToInt(currentBlock); + + return ( + (this._usePastBlocks && newBlockInt < currentBlockInt) || + newBlockInt > currentBlockInt + ); + } + + private _newPotentialLatest(newBlock: string): void { + if (!this._shouldUseNewBlock(newBlock)) { + return; + } + this._setCurrentBlock(newBlock); + } + + private _setCurrentBlock(newBlock: string): void { + const oldBlock = this._currentBlock; + this._currentBlock = newBlock; + this.emit('latest', newBlock); + this.emit('sync', { oldBlock, newBlock }); + } + + private _setupBlockResetTimeout(): void { + // clear any existing timeout + this._cancelBlockResetTimeout(); + // clear latest block when stale + this._blockResetTimeout = setTimeout( + this._resetCurrentBlock, + this._blockResetDuration, + ); + + // nodejs - dont hold process open + if (this._blockResetTimeout.unref) { + this._blockResetTimeout.unref(); + } + } + + private _cancelBlockResetTimeout(): void { + if (this._blockResetTimeout) { + clearTimeout(this._blockResetTimeout); + } + } + + private _resetCurrentBlock(): void { + this._currentBlock = null; + } + + /** + * Checks for the latest block, updates the internal state, and returns the + * value immediately rather than waiting for the next polling interval. + * + * @deprecated Use {@link getLatestBlock} instead. + * @returns A promise that resolves to the latest block number. + */ + async checkForLatestBlock() { + await this._updateLatestBlock(); + return await this.getLatestBlock(); + } + + private _start() { + // Intentionally not awaited as this starts the polling via a timeout chain. + // eslint-disable-next-line @typescript-eslint/no-floating-promises + this._updateAndQueue(); + } + + private _end() { + this._clearPollingTimeout(); + } + + private async _updateLatestBlock(): Promise { // fetch + set latest block const latestBlock = await this._fetchLatestBlock(); this._newPotentialLatest(latestBlock); + + if (!this._isRunning) { + // Ensure the one-time update is eventually reset once it's stale + this._setupBlockResetTimeout(); + } + + // _newPotentialLatest() ensures that this._currentBlock is not null + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return this._currentBlock!; } private async _fetchLatestBlock(): Promise { - const req: ExtendedJsonRpcRequest<[]> = { - jsonrpc: '2.0', - id: createRandomId(), - method: 'eth_blockNumber', - params: [], - }; - if (this._setSkipCacheFlag) { - req.skipCache = true; - } - - log('Making request', req); - const res = await pify((cb) => this._provider.sendAsync(req, cb))(); - log('Got response', res); - if (res.error) { - throw new Error( - `PollingBlockTracker - encountered error fetching block:\n${res.error.message}`, - ); - } - return res.result; + // If there's already a pending fetch, reuse it + if (this.#pendingFetch) { + return await this.#pendingFetch.promise; + } + + // Create a new deferred promise for this request + const { promise, resolve, reject } = createDeferredPromise({ + suppressUnhandledRejection: true, + }); + this.#pendingFetch = { reject, promise }; + + try { + const req: ExtendedJsonRpcRequest = { + jsonrpc: '2.0', + id: createRandomId(), + method: 'eth_blockNumber', + params: [] as [], + }; + if (this._setSkipCacheFlag) { + req.skipCache = true; + } + + log('Making request', req); + const result = await this._provider.request<[], string>(req); + log('Got result', result); + resolve(result); + return result; + } catch (error) { + log('Encountered error fetching block', getErrorMessage(error)); + reject(error); + this.#rejectPendingLatestBlock(error); + throw error; + } finally { + this.#pendingFetch = undefined; + } + } + + /** + * The core polling function that runs after each interval. + * Updates the latest block and then queues the next update. + */ + private async _updateAndQueue() { + let interval = this._pollingInterval; + + try { + await this._updateLatestBlock(); + } catch (error: unknown) { + try { + this.emit('error', error); + } catch { + console.error(`Error updating latest block: ${getErrorMessage(error)}`); + } + + interval = this._retryTimeout; + } + + if (!this._isRunning) { + return; + } + + this._clearPollingTimeout(); + + const timeoutRef = setTimeout(() => { + // Intentionally not awaited as this just continues the polling loop. + // eslint-disable-next-line @typescript-eslint/no-floating-promises + this._updateAndQueue(); + }, interval); + + if (timeoutRef.unref && !this._keepEventLoopActive) { + timeoutRef.unref(); + } + + this._pollingTimeout = timeoutRef; + + this.emit('_waitingForNextIteration'); + } + + _clearPollingTimeout() { + if (this._pollingTimeout) { + clearTimeout(this._pollingTimeout); + this._pollingTimeout = undefined; + } + } + + #addInternalListener(listener: InternalListener) { + this.#internalEventListeners.push(listener); + } + + #removeInternalListener(listener: InternalListener) { + this.#internalEventListeners.splice( + this.#internalEventListeners.indexOf(listener), + 1, + ); + } + + #rejectPendingLatestBlock(error: unknown) { + this.#pendingLatestBlock?.reject(error); + this.#pendingLatestBlock = undefined; } } /** - * Waits for the specified amount of time. + * Converts a number represented as a string in hexadecimal format into a native + * number. * - * @param duration - The amount of time in milliseconds. - * @param unref - Assuming this function is run in a Node context, governs - * whether Node should wait before the `setTimeout` has completed before ending - * the process (true for no, false for yes). Defaults to false. - * @returns A promise that can be used to wait. + * @param hexInt - The hex string. + * @returns The number. */ -function timeout(duration: number, unref: boolean) { - return new Promise((resolve) => { - const timeoutRef = setTimeout(resolve, duration); - // don't keep process open - if (timeoutRef.unref && unref) { - timeoutRef.unref(); - } - }); +function hexToInt(hexInt: string): number { + return Number.parseInt(hexInt, 16); } diff --git a/src/SubscribeBlockTracker.test.ts b/src/SubscribeBlockTracker.test.ts deleted file mode 100644 index 9da7711f..00000000 --- a/src/SubscribeBlockTracker.test.ts +++ /dev/null @@ -1,3297 +0,0 @@ -import EMPTY_FUNCTION from '../tests/emptyFunction'; -import recordCallsToSetTimeout from '../tests/recordCallsToSetTimeout'; -import { withSubscribeBlockTracker } from '../tests/withBlockTracker'; -import buildDeferred from '../tests/buildDeferred'; -import { SubscribeBlockTracker } from '.'; - -interface Sync { - oldBlock: string; - newBlock: string; -} - -const METHODS_TO_ADD_LISTENER = ['on', 'addListener'] as const; -const METHODS_TO_REMOVE_LISTENER = ['off', 'removeListener'] as const; -const METHODS_TO_GET_LATEST_BLOCK = [ - 'getLatestBlock', - 'checkForLatestBlock', -] as const; -const originalSetTimeout = setTimeout; - -describe('SubscribeBlockTracker', () => { - describe('constructor', () => { - it('should throw if given no options', () => { - expect(() => new SubscribeBlockTracker()).toThrow( - 'SubscribeBlockTracker - no provider specified.', - ); - }); - - it('should throw if given options but not given a provider', () => { - expect(() => new SubscribeBlockTracker({})).toThrow( - 'SubscribeBlockTracker - no provider specified.', - ); - }); - - it('should return a block tracker that is not running', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(({ blockTracker }) => { - expect(blockTracker.isRunning()).toBe(false); - }); - }); - }); - - describe('destroy', () => { - it('should stop the block tracker if any "latest" and "sync" events were added previously', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - blockTracker.on('latest', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('sync', resolve); - }); - expect(blockTracker.isRunning()).toBe(true); - - await blockTracker.destroy(); - - expect(blockTracker.isRunning()).toBe(false); - }); - }); - - it('should not start a timer to clear the current block number if called after removing all listeners but before enough time passes that the cache would have been cleared', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockResetDuration = 500; - - await withSubscribeBlockTracker( - { - blockTracker: { - blockResetDuration, - }, - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - blockTracker.on('latest', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('sync', resolve); - }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); - blockTracker.removeAllListeners(); - expect(setTimeoutRecorder.calls).not.toHaveLength(0); - - await blockTracker.destroy(); - - expect(setTimeoutRecorder.calls).toHaveLength(0); - await new Promise((resolve) => - originalSetTimeout(resolve, blockResetDuration), - ); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); - }, - ); - }); - - it('should only clear the current block number if enough time passes after all "latest" and "sync" events are removed', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - blockTracker.on('latest', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('sync', resolve); - }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); - blockTracker.removeAllListeners(); - await setTimeoutRecorder.next(); - - await blockTracker.destroy(); - - expect(blockTracker.getCurrentBlock()).toBeNull(); - }, - ); - }); - }); - - METHODS_TO_GET_LATEST_BLOCK.forEach((methodToGetLatestBlock) => { - describe(`${methodToGetLatestBlock}`, () => { - it('should start the block tracker immediately after being called', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - const promiseToGetLatestBlock = - blockTracker[methodToGetLatestBlock](); - expect(blockTracker.isRunning()).toBe(true); - // We have to wait for the promise to resolve after the assertion - // because by the time this promise resolves, the block tracker isn't - // running anymore - await promiseToGetLatestBlock; - }); - }); - - it('should stop the block tracker automatically after its promise is fulfilled', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - await blockTracker[methodToGetLatestBlock](); - expect(blockTracker.isRunning()).toBe(false); - }); - }); - - it('should fetch the latest block number', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const latestBlockNumber = await blockTracker[ - methodToGetLatestBlock - ](); - expect(latestBlockNumber).toStrictEqual('0x0'); - }, - ); - }); - - it('should not ask for a new block number while the current block number is cached', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(async ({ provider, blockTracker }) => { - const sendAsyncSpy = jest.spyOn(provider, 'sendAsync'); - await blockTracker[methodToGetLatestBlock](); - await blockTracker[methodToGetLatestBlock](); - const requestsForLatestBlock = sendAsyncSpy.mock.calls.filter( - (args) => { - return args[0].method === 'eth_blockNumber'; - }, - ); - expect(requestsForLatestBlock).toHaveLength(1); - }); - }); - - it('should ask for a new block number after the cached one is cleared', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockTrackerOptions = { - pollingInterval: 100, - blockResetDuration: 200, - }; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_unsubscribe', - response: { - result: true, - }, - }, - { - methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x1', - }, - }, - { - methodName: 'eth_unsubscribe', - response: { - result: true, - }, - }, - ], - }, - blockTracker: blockTrackerOptions, - }, - async ({ provider, blockTracker }) => { - const sendAsyncSpy = jest.spyOn(provider, 'sendAsync'); - await blockTracker[methodToGetLatestBlock](); - // For PollingBlockTracker, there are possibly multiple - // `setTimeout`s in play at this point. For SubscribeBlockTracker - // that is not the case, as it does not poll, but there is no harm - // in doing this. - await setTimeoutRecorder.nextMatchingDuration( - blockTrackerOptions.blockResetDuration, - ); - await blockTracker[methodToGetLatestBlock](); - const requestsForLatestBlock = sendAsyncSpy.mock.calls.filter( - (args) => { - return args[0].method === 'eth_blockNumber'; - }, - ); - expect(requestsForLatestBlock).toHaveLength(2); - }, - ); - }); - - METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { - it(`should not emit the "error" event (added via \`${methodToAddListener}\`) and should resolve with undefined if the request for the latest block number returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = - blockTracker[methodToGetLatestBlock](); - - await expect(promiseForCaughtError).toNeverResolve(); - const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toBeUndefined(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should never resolve if, while making the request for the latest block number, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownError = new Error('boom'); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw thrownError; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = - blockTracker[methodToGetLatestBlock](); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownError); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should never resolve if, while making the request for the latest block number, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownString = 'boom'; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw thrownString; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = - blockTracker[methodToGetLatestBlock](); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownString); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should never resolve if, while making the request for the latest block number, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = - blockTracker[methodToGetLatestBlock](); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should not emit the "error" event (added via \`${methodToAddListener}\`) and should still resolve with the latest block number if the request to subscribe returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = - blockTracker[methodToGetLatestBlock](); - - await expect(promiseForCaughtError).toNeverResolve(); - const latestBlockNumber = await promiseForLatestBlock; - expect(latestBlockNumber).toStrictEqual('0x0'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should never resolve if, while making the request to subscribe, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownError = new Error('boom'); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - implementation: () => { - throw thrownError; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = - blockTracker[methodToGetLatestBlock](); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownError); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should never resolve if, while making the request to subscribe, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownString = 'boom'; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - implementation: () => { - throw thrownString; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = - blockTracker[methodToGetLatestBlock](); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownString); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should never resolve if, while making the request to subscribe, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = - blockTracker[methodToGetLatestBlock](); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should not emit the "error" event (added via \`${methodToAddListener}\`) if the request to unsubscribe returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await blockTracker[methodToGetLatestBlock](); - - await expect(promiseForCaughtError).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownError = new Error('boom'); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - implementation: () => { - throw thrownError; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await blockTracker[methodToGetLatestBlock](); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownError); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownString = 'boom'; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - implementation: () => { - throw thrownString; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await blockTracker[methodToGetLatestBlock](); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownString); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await blockTracker[methodToGetLatestBlock](); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - }, - ); - }); - }); - - it('should update the current block number', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - await blockTracker[methodToGetLatestBlock](); - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); - }, - ); - }); - - it('should clear the current block number some time after being called', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockTrackerOptions = { - pollingInterval: 100, - blockResetDuration: 200, - }; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - blockTracker: blockTrackerOptions, - }, - async ({ blockTracker }) => { - await blockTracker[methodToGetLatestBlock](); - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); - - // For PollingBlockTracker, there are possibly multiple - // `setTimeout`s in play at this point. For SubscribeBlockTracker - // that is not the case, as it does not poll, but there is no harm - // in doing this. - await setTimeoutRecorder.nextMatchingDuration( - blockTrackerOptions.blockResetDuration, - ); - expect(blockTracker.getCurrentBlock()).toBeNull(); - }, - ); - }); - }); - }); - - METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { - describe(`${methodToAddListener}`, () => { - describe('"latest"', () => { - it('should start the block tracker', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(({ blockTracker }) => { - blockTracker[methodToAddListener]('latest', EMPTY_FUNCTION); - - expect(blockTracker.isRunning()).toBe(true); - }); - }); - - it('should emit "latest" soon after being listened to', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const latestBlockNumber = await new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - expect(latestBlockNumber).toStrictEqual('0x0'); - }, - ); - }); - - it('should emit "latest" as the subscription channel publishes new blocks', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x64', - }, - }, - ], - }, - }, - async ({ provider, blockTracker }) => { - const receivedBlockNumbers: string[] = []; - blockTracker.on('_started', () => { - provider.emit('data', null, { - method: 'eth_subscription', - params: { - subscription: '0x64', - result: { - number: '0x1', - }, - }, - }); - }); - - await new Promise((resolve) => { - blockTracker[methodToAddListener]( - 'latest', - (blockNumber: string) => { - receivedBlockNumbers.push(blockNumber); - if (receivedBlockNumbers.length === 2) { - resolve(); - } - }, - ); - }); - - expect(receivedBlockNumbers).toStrictEqual(['0x0', '0x1']); - }, - ); - }); - - it('should not emit "latest" if the subscription id of an incoming message does not match the created subscription id', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x64', - }, - }, - ], - }, - }, - async ({ provider, blockTracker }) => { - const receivedBlockNumbers: string[] = []; - - await new Promise((resolve) => { - blockTracker.on('_started', () => { - provider.emit('data', null, { - method: 'eth_subscription', - params: { - subscription: '0x1', - result: { - number: '0x1', - }, - }, - }); - resolve(); - }); - - blockTracker[methodToAddListener]( - 'latest', - (blockNumber: string) => { - receivedBlockNumbers.push(blockNumber); - }, - ); - }); - - expect(receivedBlockNumbers).toStrictEqual(['0x0']); - }, - ); - }); - - it('should not emit "latest" if the incoming message has no params', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x64', - }, - }, - ], - }, - }, - async ({ provider, blockTracker }) => { - const receivedBlockNumbers: string[] = []; - - await new Promise((resolve) => { - blockTracker.on('_started', () => { - provider.emit('data', null, { - method: 'eth_subscription', - }); - resolve(); - }); - - blockTracker[methodToAddListener]( - 'latest', - (blockNumber: string) => { - receivedBlockNumbers.push(blockNumber); - }, - ); - }); - - expect(receivedBlockNumbers).toStrictEqual(['0x0']); - }, - ); - }); - - it('should not emit "latest" if the newly fetched block number is less than the current block number', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x64', - }, - }, - ], - }, - }, - async ({ provider, blockTracker }) => { - const receivedBlockNumbers: string[] = []; - - await new Promise((resolve) => { - blockTracker.on('_started', () => { - provider.emit('data', null, { - method: 'eth_subscription', - params: { - subscription: '0x64', - result: { - number: '0x0', - }, - }, - }); - resolve(); - }); - - blockTracker[methodToAddListener]( - 'latest', - (blockNumber: string) => { - receivedBlockNumbers.push(blockNumber); - }, - ); - }); - - expect(receivedBlockNumbers).toStrictEqual(['0x1']); - }, - ); - }); - - it('should re-throw any error out of band that occurs in the listener', async () => { - await withSubscribeBlockTracker(async ({ blockTracker }) => { - const thrownError = new Error('boom'); - const promiseForCaughtError = new Promise((resolve) => { - recordCallsToSetTimeout({ - numAutomaticCalls: 1, - interceptCallback: (callback, stopPassingThroughCalls) => { - return async () => { - try { - await callback(); - } catch (error: unknown) { - resolve(error); - stopPassingThroughCalls(); - } - }; - }, - }); - }); - - blockTracker[methodToAddListener]('latest', () => { - throw thrownError; - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownError); - }); - }); - - it(`should not emit the "error" event and should emit "latest" with undefined if the request for the latest block number returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - const latestBlock = await promiseForLatestBlock; - expect(latestBlock).toBeUndefined(); - }, - ); - }); - - it(`should emit the "error" event and should not emit "latest" if, while making the request for the latest block number, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event and should not emit "latest" if, while making the request for the latest block number, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw 'boom'; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toStrictEqual('boom'); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event and should not emit "latest" if, while making the request for the latest block number, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - error: 'boom', - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x64', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should not emit the "error" event and should still emit "latest" with the latest block number if the request to subscribe returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_subscribe', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const latestBlockNumber = await new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - expect(latestBlockNumber).toStrictEqual('0x0'); - }, - ); - }); - - it(`should emit the "error" event and should not emit "latest" if, while making the request to subscribe, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - implementation: () => { - throw new Error('boom'); - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event and should not emit "latest" if, while making the request to subscribe, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - implementation: () => { - throw 'boom'; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toStrictEqual('boom'); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event and should not emit "latest" if, while making the request to subscribe, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it('should update the current block number', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - await new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); - }, - ); - }); - }); - - describe('"sync"', () => { - it('should start the block tracker', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(({ blockTracker }) => { - blockTracker[methodToAddListener]('sync', EMPTY_FUNCTION); - - expect(blockTracker.isRunning()).toBe(true); - }); - }); - - it('should emit "sync" soon after being listened to', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const sync = await new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); - }, - ); - }); - - it('should emit "sync" as the subscription channel publishes new blocks', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x64', - }, - }, - ], - }, - }, - async ({ provider, blockTracker }) => { - const syncs: Sync[] = []; - blockTracker.on('_started', () => { - provider.emit('data', null, { - method: 'eth_subscription', - params: { - subscription: '0x64', - result: { - number: '0x1', - }, - }, - }); - }); - - await new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', (sync: Sync) => { - syncs.push(sync); - if (syncs.length === 2) { - resolve(); - } - }); - }); - - expect(syncs).toStrictEqual([ - { oldBlock: null, newBlock: '0x0' }, - { oldBlock: '0x0', newBlock: '0x1' }, - ]); - }, - ); - }); - - it('should not emit "sync" if the subscription id of an incoming message does not match the created subscription id', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x64', - }, - }, - ], - }, - }, - async ({ provider, blockTracker }) => { - const syncs: Sync[] = []; - - await new Promise((resolve) => { - blockTracker.on('_started', () => { - provider.emit('data', null, { - method: 'eth_subscription', - params: { - subscription: '0x1', - result: { - number: '0x1', - }, - }, - }); - resolve(); - }); - - blockTracker[methodToAddListener]('sync', (sync: Sync) => { - syncs.push(sync); - }); - }); - - expect(syncs).toStrictEqual([ - { oldBlock: null, newBlock: '0x0' }, - ]); - }, - ); - }); - - it('should not emit "sync" if the incoming message has no params', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x64', - }, - }, - ], - }, - }, - async ({ provider, blockTracker }) => { - const syncs: Sync[] = []; - - await new Promise((resolve) => { - blockTracker.on('_started', () => { - provider.emit('data', null, { - method: 'eth_subscription', - }); - resolve(); - }); - - blockTracker[methodToAddListener]('sync', (sync: Sync) => { - syncs.push(sync); - }); - }); - - expect(syncs).toStrictEqual([ - { oldBlock: null, newBlock: '0x0' }, - ]); - }, - ); - }); - - it('should not emit "sync" if the newly fetched block number is less than the current block number', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x1', - }, - }, - { - methodName: 'eth_subscribe', - response: { - result: '0x64', - }, - }, - ], - }, - }, - async ({ provider, blockTracker }) => { - const syncs: Sync[] = []; - - await new Promise((resolve) => { - blockTracker.on('_started', () => { - provider.emit('data', null, { - method: 'eth_subscription', - params: { - subscription: '0x64', - result: { - number: '0x0', - }, - }, - }); - resolve(); - }); - - blockTracker[methodToAddListener]('sync', (sync: Sync) => { - syncs.push(sync); - }); - }); - - expect(syncs).toStrictEqual([ - { oldBlock: null, newBlock: '0x1' }, - ]); - }, - ); - }); - - it('should re-throw any error out of band that occurs in the listener', async () => { - await withSubscribeBlockTracker(async ({ blockTracker }) => { - const thrownError = new Error('boom'); - const promiseForCaughtError = new Promise((resolve) => { - recordCallsToSetTimeout({ - numAutomaticCalls: 1, - interceptCallback: (callback, stopPassingThroughCalls) => { - return async () => { - try { - await callback(); - } catch (error: unknown) { - resolve(error); - stopPassingThroughCalls(); - } - }; - }, - }); - }); - - blockTracker[methodToAddListener]('sync', () => { - throw thrownError; - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownError); - }); - }); - - it(`should not emit the "error" event and should emit "sync" with undefined in place of the latest block if the request for the latest block number returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - const sync = await promiseForSync; - expect(sync).toStrictEqual({ - oldBlock: null, - newBlock: undefined, - }); - }, - ); - }); - - it(`should emit the "error" event and should not emit "sync" if, while making a request for the latest block number, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw new Error('boom'); - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event and should not emit "sync" if, while making a request for the latest block number, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw 'boom'; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toStrictEqual('boom'); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event and should not emit "sync" if, while making the request for the latest block number, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should not emit the "error" event and should still emit "sync" with the latest block number if the request to subscribe returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - const sync = await promiseForSync; - expect(sync).toStrictEqual({ - oldBlock: null, - newBlock: '0x0', - }); - }, - ); - }); - - it(`should emit the "error" event and should not emit "sync" if, while making the request to subscribe, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - implementation: () => { - throw new Error('boom'); - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event and should not emit "latest" if, while making the request to subscribe, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - implementation: () => { - throw 'boom'; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toStrictEqual('boom'); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event and should not emit "sync" if, while making the request to subscribe, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it('should update the current block number', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - await new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); - }, - ); - }); - }); - - describe('some other event', () => { - it('should not start the block tracker', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(({ blockTracker }) => { - blockTracker[methodToAddListener]('somethingElse', EMPTY_FUNCTION); - - expect(blockTracker.isRunning()).toBe(false); - }); - }); - - it('should not update the current block number', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - blockTracker[methodToAddListener]( - 'somethingElse', - EMPTY_FUNCTION, - ); - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toBeNull(); - }, - ); - }); - }); - }); - }); - - METHODS_TO_REMOVE_LISTENER.forEach((methodToRemoveListener) => { - describe(`${methodToRemoveListener}`, () => { - describe('"latest"', () => { - it('should stop the block tracker if the last instance of this event is removed', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - const listener1 = EMPTY_FUNCTION; - const { promise: promiseForLatestBlock, resolve: listener2 } = - buildDeferred(); - - blockTracker.on('latest', listener1); - blockTracker.on('latest', listener2); - expect(blockTracker.isRunning()).toBe(true); - - await promiseForLatestBlock; - - blockTracker[methodToRemoveListener]('latest', listener1); - blockTracker[methodToRemoveListener]('latest', listener2); - expect(blockTracker.isRunning()).toBe(false); - }); - }); - - it('should clear the current block number some time after the last instance of this event is removed', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockTrackerOptions = { - pollingInterval: 100, - blockResetDuration: 200, - }; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - blockTracker: blockTrackerOptions, - }, - async ({ blockTracker }) => { - const listener1 = EMPTY_FUNCTION; - const { promise: promiseForLatestBlock, resolve: listener2 } = - buildDeferred(); - - blockTracker.on('latest', listener1); - blockTracker.on('latest', listener2); - await promiseForLatestBlock; - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); - - blockTracker[methodToRemoveListener]('latest', listener1); - blockTracker[methodToRemoveListener]('latest', listener2); - // For PollingBlockTracker, there are possibly multiple - // `setTimeout`s in play at this point. For SubscribeBlockTracker - // that is not the case, as it does not poll, but there is no harm - // in doing this. - await setTimeoutRecorder.nextMatchingDuration( - blockTrackerOptions.blockResetDuration, - ); - expect(blockTracker.getCurrentBlock()).toBeNull(); - }, - ); - }); - - METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { - it(`should not emit the "error" event (added via \`${methodToAddListener}\`) if the request to unsubscribe returns an error response`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const { promise: promiseForLatestBlock, resolve: listener } = - buildDeferred(); - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - blockTracker.on('latest', listener); - await promiseForLatestBlock; - blockTracker[methodToRemoveListener]('latest', listener); - await new Promise((resolve) => { - blockTracker.on('_ended', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider throws an Error`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - implementation: () => { - throw new Error('boom'); - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const { promise: promiseForLatestBlock, resolve: listener } = - buildDeferred(); - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - blockTracker.on('latest', listener); - await promiseForLatestBlock; - blockTracker[methodToRemoveListener]('latest', listener); - await new Promise((resolve) => { - blockTracker.on('_ended', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider throws a string`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - implementation: () => { - throw 'boom'; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const { promise: promiseForLatestBlock, resolve: listener } = - buildDeferred(); - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - blockTracker.on('latest', listener); - await promiseForLatestBlock; - blockTracker[methodToRemoveListener]('latest', listener); - await new Promise((resolve) => { - blockTracker.on('_ended', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toStrictEqual('boom'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider rejects with an error`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const { promise: promiseForLatestBlock, resolve: listener } = - buildDeferred(); - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - blockTracker.on('latest', listener); - await promiseForLatestBlock; - blockTracker[methodToRemoveListener]('latest', listener); - await new Promise((resolve) => { - blockTracker.on('_ended', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - }, - ); - }); - }); - }); - - describe('"sync"', () => { - it('should stop the block tracker if the last instance of this event is removed', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - const listener1 = EMPTY_FUNCTION; - const { promise: promiseForLatestBlock, resolve: listener2 } = - buildDeferred(); - - blockTracker.on('sync', listener1); - blockTracker.on('sync', listener2); - expect(blockTracker.isRunning()).toBe(true); - - await promiseForLatestBlock; - - blockTracker[methodToRemoveListener]('sync', listener1); - blockTracker[methodToRemoveListener]('sync', listener2); - expect(blockTracker.isRunning()).toBe(false); - }); - }); - - it('should clear the current block number some time after the last instance of this event is removed', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockTrackerOptions = { - pollingInterval: 100, - blockResetDuration: 200, - }; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - blockTracker: blockTrackerOptions, - }, - async ({ blockTracker }) => { - const listener1 = EMPTY_FUNCTION; - const { promise: promiseForLatestBlock, resolve: listener2 } = - buildDeferred(); - - blockTracker.on('sync', listener1); - blockTracker.on('sync', listener2); - await promiseForLatestBlock; - const currentBlockNumber = blockTracker.getCurrentBlock(); - expect(currentBlockNumber).toStrictEqual('0x0'); - - blockTracker[methodToRemoveListener]('sync', listener1); - blockTracker[methodToRemoveListener]('sync', listener2); - // For PollingBlockTracker, there are possibly multiple - // `setTimeout`s in play at this point. For SubscribeBlockTracker - // that is not the case, as it does not poll, but there is no harm - // in doing this. - await setTimeoutRecorder.nextMatchingDuration( - blockTrackerOptions.blockResetDuration, - ); - expect(blockTracker.getCurrentBlock()).toBeNull(); - }, - ); - }); - - METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { - it(`should not emit the "error" event (added via \`${methodToAddListener}\`) if the request to unsubscribe returns an error response`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const { promise: promiseForSync, resolve: listener } = - buildDeferred(); - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - blockTracker.on('sync', listener); - await promiseForSync; - blockTracker[methodToRemoveListener]('sync', listener); - await new Promise((resolve) => { - blockTracker.on('_ended', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider throws an Error`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - implementation: () => { - throw new Error('boom'); - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const { promise: promiseForSync, resolve: listener } = - buildDeferred(); - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - blockTracker.on('sync', listener); - await promiseForSync; - blockTracker[methodToRemoveListener]('sync', listener); - await new Promise((resolve) => { - blockTracker.on('_ended', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider throws a string`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - implementation: () => { - throw 'boom'; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const { promise: promiseForSync, resolve: listener } = - buildDeferred(); - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - blockTracker.on('sync', listener); - await promiseForSync; - blockTracker[methodToRemoveListener]('sync', listener); - await new Promise((resolve) => { - blockTracker.on('_ended', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toStrictEqual('boom'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider rejects with an error`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const { promise: promiseForSync, resolve: listener } = - buildDeferred(); - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - blockTracker.on('sync', listener); - await promiseForSync; - blockTracker[methodToRemoveListener]('sync', listener); - await new Promise((resolve) => { - blockTracker.on('_ended', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - }, - ); - }); - }); - }); - - describe('some other event', () => { - it('should not stop the block tracker', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - const { promise: promiseForLatestBlock, resolve: listener1 } = - buildDeferred(); - const listener2 = EMPTY_FUNCTION; - - blockTracker.on('latest', listener1); - blockTracker.on('somethingElse', listener2); - expect(blockTracker.isRunning()).toBe(true); - - await promiseForLatestBlock; - - blockTracker[methodToRemoveListener]('somethingElse', listener2); - expect(blockTracker.isRunning()).toBe(true); - }); - }); - }); - }); - }); - - describe('once', () => { - describe('"latest"', () => { - it('should start and then stop the block tracker automatically', async () => { - // We stub 2 calls because SubscribeBlockTracker#_synchronize will make a - // call (to proceed to the next iteration) and BaseBlockTracker will - // make a call (to reset the current block number when the tracker is - // not running) - recordCallsToSetTimeout({ numAutomaticCalls: 2 }); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - await new Promise((resolve) => { - blockTracker.on('_ended', resolve); - blockTracker.once('latest', EMPTY_FUNCTION); - }); - - expect(blockTracker.isRunning()).toBe(false); - }); - }); - - it('should set the current block number and then clear it some time afterward', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockTrackerOptions = { - pollingInterval: 100, - blockResetDuration: 200, - }; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - blockTracker: blockTrackerOptions, - }, - async ({ blockTracker }) => { - await new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); - - // For PollingBlockTracker, there are possibly multiple - // `setTimeout`s in play at this point. For SubscribeBlockTracker - // that is not the case, as it does not poll, but there is no harm - // in doing this. - await setTimeoutRecorder.nextMatchingDuration( - blockTrackerOptions.blockResetDuration, - ); - expect(blockTracker.getCurrentBlock()).toBeNull(); - }, - ); - }); - - METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { - it(`should not emit the "error" event (added via \`${methodToAddListener}\`) and should emit "latest" with undefined if the request for the latest block number returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - const latestBlockNumber = await promiseForLatestBlock; - expect(latestBlockNumber).toBeUndefined(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "latest" if, while making the request for the latest block number, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownError = new Error('boom'); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw thrownError; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownError); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "latest" if, while making the request for the latest block number, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownString = 'boom'; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw thrownString; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toMatch(thrownString); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "latest" if, while making the request for the latest block number, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should not emit the "error" event (added via \`${methodToAddListener}\`) and should still emit "latest" if the request to subscribe returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const latestBlockNumber = await new Promise((resolve) => { - blockTracker[methodToAddListener]('latest', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - expect(latestBlockNumber).toStrictEqual('0x0'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "latest" if, while making the request to subscribe, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownError = new Error('boom'); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - implementation: () => { - throw thrownError; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownError); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "latest" if, while making the request to subscribe, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownString = 'boom'; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - implementation: () => { - throw thrownString; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownString); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "latest" if, while making the request to subscribe, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForLatestBlock = new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForLatestBlock).toNeverResolve(); - }, - ); - }); - - it(`should not emit the "error" event (added via \`${methodToAddListener}\`) if the request to unsubscribe returns an error response`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider throws an Error`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - implementation: () => { - throw new Error('boom'); - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider throws a string`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - implementation: () => { - throw 'boom'; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toStrictEqual('boom'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider rejects with an error`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await new Promise((resolve) => { - blockTracker.once('latest', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - }, - ); - }); - }); - }); - - describe('"sync"', () => { - it('should start and then stop the block tracker automatically', async () => { - // We stub 2 calls because SubscribeBlockTracker#_synchronize will make a call - // (to proceed to the next iteration) and BaseBlockTracker will make a call - // (to reset the current block number when the tracker is not running) - recordCallsToSetTimeout({ numAutomaticCalls: 2 }); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - await new Promise((resolve) => { - blockTracker.on('_ended', resolve); - blockTracker.once('sync', EMPTY_FUNCTION); - }); - - expect(blockTracker.isRunning()).toBe(false); - }); - }); - - it('should set the current block number and then clear it some time afterward', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockTrackerOptions = { - pollingInterval: 100, - blockResetDuration: 200, - }; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - blockTracker: blockTrackerOptions, - }, - async ({ blockTracker }) => { - await new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); - - // For PollingBlockTracker, there are possibly multiple - // `setTimeout`s in play at this point. For SubscribeBlockTracker - // that is not the case, as it does not poll, but there is no harm - // in doing this. - await setTimeoutRecorder.nextMatchingDuration( - blockTrackerOptions.blockResetDuration, - ); - expect(blockTracker.getCurrentBlock()).toBeNull(); - }, - ); - }); - - METHODS_TO_ADD_LISTENER.forEach((methodToAddListener) => { - it(`should not emit the "error" event (added via \`${methodToAddListener}\`) and should emit "sync" with undefined in place of the latest block number if the request for the latest block number returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - const sync = await promiseForSync; - expect(sync).toStrictEqual({ - oldBlock: null, - newBlock: undefined, - }); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "sync" if, while making the request for the latest block number, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownError = new Error('boom'); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw thrownError; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownError); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "sync" if, while making the request for the latest block number, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownString = 'boom'; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - implementation: () => { - throw thrownString; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownString); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "sync" if, while making the request for the latest block number, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should not emit the "error" event (added via \`${methodToAddListener}\`) and should still emit "sync" if the request to subscribe returns an error response`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - response: { - error: 'boom', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const sync = await new Promise((resolve) => { - blockTracker[methodToAddListener]('sync', resolve); - }); - - await expect(promiseForCaughtError).toNeverResolve(); - expect(sync).toStrictEqual({ oldBlock: null, newBlock: '0x0' }); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "sync" if, while making the request to subscribe, the provider throws an Error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownError = new Error('boom'); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - implementation: () => { - throw thrownError; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownError); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should not emit "sync" if, while making the request to subscribe, the provider throws a string`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - const thrownString = 'boom'; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - implementation: () => { - throw thrownString; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toBe(thrownString); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) and should take a listener that is never called if, while making the request to subscribe, the provider rejects with an error`, async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_subscribe', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - const promiseForSync = new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - await expect(promiseForSync).toNeverResolve(); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider throws an Error`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - implementation: () => { - throw new Error('boom'); - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider throws a string`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - implementation: () => { - throw 'boom'; - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError).toStrictEqual('boom'); - }, - ); - }); - - it(`should emit the "error" event (added via \`${methodToAddListener}\`) if, while making the request to unsubscribe, the provider rejects with an error`, async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_unsubscribe', - error: 'boom', - }, - ], - }, - }, - async ({ blockTracker }) => { - const promiseForCaughtError = new Promise((resolve) => { - blockTracker[methodToAddListener]('error', resolve); - }); - - await new Promise((resolve) => { - blockTracker.once('sync', resolve); - }); - - const caughtError = await promiseForCaughtError; - expect(caughtError.message).toStrictEqual('boom'); - }, - ); - }); - }); - }); - - describe('some other event', () => { - it('should never start the block tracker', async () => { - // We stub 2 calls because SubscribeBlockTracker#_synchronize will make a call - // (to proceed to the next iteration) and BaseBlockTracker will make a call - // (to reset the current block number when the tracker is not running) - recordCallsToSetTimeout({ numAutomaticCalls: 2 }); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - const listener = jest.fn(); - blockTracker.on('_ended', listener); - blockTracker.once('somethingElse', EMPTY_FUNCTION); - - expect(listener).not.toHaveBeenCalled(); - }); - }); - - it('should never set the current block number', async () => { - recordCallsToSetTimeout({ numAutomaticCalls: 1 }); - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - }, - async ({ blockTracker }) => { - blockTracker.once('somethingElse', EMPTY_FUNCTION); - expect(blockTracker.getCurrentBlock()).toBeNull(); - }, - ); - }); - }); - }); - - describe('removeAllListeners', () => { - it('should stop the block tracker if any "latest" and "sync" events were added previously', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - blockTracker.on('latest', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('sync', resolve); - }); - expect(blockTracker.isRunning()).toBe(true); - - blockTracker.removeAllListeners(); - expect(blockTracker.isRunning()).toBe(false); - }); - }); - - it('should clear the current block number some time after all "latest" and "sync" events are removed', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockTrackerOptions = { - pollingInterval: 100, - blockResetDuration: 200, - }; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - blockTracker: blockTrackerOptions, - }, - async ({ blockTracker }) => { - blockTracker.on('latest', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('sync', resolve); - }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); - - blockTracker.removeAllListeners(); - // For PollingBlockTracker, there are possibly multiple `setTimeout`s - // in play at this point. For SubscribeBlockTracker that is not the - // case, as it does not poll, but there is no harm in doing this. - await setTimeoutRecorder.nextMatchingDuration( - blockTrackerOptions.blockResetDuration, - ); - expect(blockTracker.getCurrentBlock()).toBeNull(); - }, - ); - }); - - it('should stop the block tracker when all previously added "latest" and "sync" events are removed specifically', async () => { - recordCallsToSetTimeout(); - - await withSubscribeBlockTracker(async ({ blockTracker }) => { - await new Promise((resolve) => { - blockTracker.on('latest', EMPTY_FUNCTION); - blockTracker.on('sync', resolve); - }); - expect(blockTracker.isRunning()).toBe(true); - - blockTracker.removeAllListeners('latest'); - expect(blockTracker.isRunning()).toBe(true); - - blockTracker.removeAllListeners('sync'); - expect(blockTracker.isRunning()).toBe(false); - }); - }); - - it('should clear the current block number some time after all "latest" and "sync" events are removed specifically', async () => { - const setTimeoutRecorder = recordCallsToSetTimeout(); - const blockTrackerOptions = { - pollingInterval: 100, - blockResetDuration: 200, - }; - - await withSubscribeBlockTracker( - { - provider: { - stubs: [ - { - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }, - ], - }, - blockTracker: blockTrackerOptions, - }, - async ({ blockTracker }) => { - blockTracker.on('latest', EMPTY_FUNCTION); - await new Promise((resolve) => { - blockTracker.on('sync', resolve); - }); - expect(blockTracker.getCurrentBlock()).toStrictEqual('0x0'); - - blockTracker.removeAllListeners('latest'); - blockTracker.removeAllListeners('sync'); - // For PollingBlockTracker, there are possibly multiple `setTimeout`s - // in play at this point. For SubscribeBlockTracker that is not the - // case, as it does not poll, but there is no harm in doing this. - await setTimeoutRecorder.nextMatchingDuration( - blockTrackerOptions.blockResetDuration, - ); - expect(blockTracker.getCurrentBlock()).toBeNull(); - }, - ); - }); - }); -}); diff --git a/src/SubscribeBlockTracker.ts b/src/SubscribeBlockTracker.ts deleted file mode 100644 index 039f5dd6..00000000 --- a/src/SubscribeBlockTracker.ts +++ /dev/null @@ -1,97 +0,0 @@ -import getCreateRandomId from 'json-rpc-random-id'; -import { JsonRpcNotification, JsonRpcSuccess } from 'json-rpc-engine'; -import { BaseBlockTracker, Provider } from './BaseBlockTracker'; - -const createRandomId = getCreateRandomId(); - -export interface SubscribeBlockTrackerOptions { - provider?: Provider; - blockResetDuration?: number; -} - -interface SubscriptionNotificationParams { - subscription: string; - result: { number: string }; -} - -export class SubscribeBlockTracker extends BaseBlockTracker { - private _provider: Provider; - - private _subscriptionId: string | null; - - constructor(opts: SubscribeBlockTrackerOptions = {}) { - // parse + validate args - if (!opts.provider) { - throw new Error('SubscribeBlockTracker - no provider specified.'); - } - - // BaseBlockTracker constructor - super(opts); - // config - this._provider = opts.provider; - this._subscriptionId = null; - } - - async checkForLatestBlock(): Promise { - return await this.getLatestBlock(); - } - - protected async _start(): Promise { - if (this._subscriptionId === undefined || this._subscriptionId === null) { - try { - const blockNumber = (await this._call('eth_blockNumber')) as string; - this._subscriptionId = (await this._call( - 'eth_subscribe', - 'newHeads', - )) as string; - this._provider.on('data', this._handleSubData.bind(this)); - this._newPotentialLatest(blockNumber); - } catch (e) { - this.emit('error', e); - } - } - } - - protected async _end() { - if (this._subscriptionId !== null && this._subscriptionId !== undefined) { - try { - await this._call('eth_unsubscribe', this._subscriptionId); - this._subscriptionId = null; - } catch (e) { - this.emit('error', e); - } - } - } - - private _call(method: string, ...params: unknown[]): Promise { - return new Promise((resolve, reject) => { - this._provider.sendAsync( - { - id: createRandomId(), - method, - params, - jsonrpc: '2.0', - }, - (err, res) => { - if (err) { - reject(err); - } else { - resolve((res as JsonRpcSuccess).result); - } - }, - ); - }); - } - - private _handleSubData( - _: unknown, - response: JsonRpcNotification, - ): void { - if ( - response.method === 'eth_subscription' && - response.params?.subscription === this._subscriptionId - ) { - this._newPotentialLatest(response.params.result.number); - } - } -} diff --git a/src/index.ts b/src/index.ts index 11e7924f..20f0aa19 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,2 @@ export * from './PollingBlockTracker'; -export * from './SubscribeBlockTracker'; +export type * from './BlockTracker'; diff --git a/tests/buildDeferred.ts b/test/buildDeferred.ts similarity index 85% rename from tests/buildDeferred.ts rename to test/buildDeferred.ts index 5e332efe..0dfa1fc5 100644 --- a/tests/buildDeferred.ts +++ b/test/buildDeferred.ts @@ -9,7 +9,7 @@ export default function buildDeferred(): { resolve: (value: T) => void; } { let unwrappedResolve: (value: T) => void; - const promise = new Promise((r) => (unwrappedResolve = r)); + const promise = new Promise((resolve) => (unwrappedResolve = resolve)); const resolve = (value: T) => unwrappedResolve(value); return { promise, resolve }; } diff --git a/tests/emptyFunction.ts b/test/emptyFunction.ts similarity index 100% rename from tests/emptyFunction.ts rename to test/emptyFunction.ts diff --git a/tests/recordCallsToSetTimeout.ts b/test/recordCallsToSetTimeout.ts similarity index 81% rename from tests/recordCallsToSetTimeout.ts rename to test/recordCallsToSetTimeout.ts index 189d0e16..326bd769 100644 --- a/tests/recordCallsToSetTimeout.ts +++ b/test/recordCallsToSetTimeout.ts @@ -1,13 +1,14 @@ import EventEmitter from 'events'; + import EMPTY_FUNCTION from './emptyFunction'; type SetTimeoutCallback = () => any; -interface SetTimeoutCall { +type SetTimeoutCall = { callback: SetTimeoutCallback; duration: number; timeout: NodeJS.Timeout; -} +}; type InterceptingCallback = ( callback: SetTimeoutCallback, @@ -23,9 +24,9 @@ const originalSetTimeout = setTimeout; class SetTimeoutRecorder { public calls: SetTimeoutCall[]; - #interceptCallback: InterceptingCallback; + readonly #interceptCallback: InterceptingCallback; - #events: EventEmitter; + readonly #events: EventEmitter; #numAutomaticCallsRemaining: number; @@ -50,8 +51,12 @@ class SetTimeoutRecorder { * @returns A promise that resolves when the first `setTimeout` call is * called. */ - next(): Promise { - return new Promise((resolve) => { + async next(): Promise { + // Resolve pending Promises first. Pending Promises always get resolved before a `setTimeout` + // callback in practice, so this better reflects a real scenario. + jest.runOnlyPendingTimers(); + + await new Promise((resolve) => { if (this.calls.length > 0) { const call = this.calls.shift() as SetTimeoutCall; call.callback(); @@ -64,6 +69,9 @@ class SetTimeoutRecorder { }); } }); + // Resolve pending Promises before returning to better emulate a real scenario. + // This ensures tests can't accidentally insert synchronous code after a `setTimeout`. + jest.runOnlyPendingTimers(); } /** @@ -75,8 +83,12 @@ class SetTimeoutRecorder { * @returns A promise that resolves when a `setTimeout` call matching the * given duration is called. */ - nextMatchingDuration(duration: number): Promise { - return new Promise((resolve) => { + async nextMatchingDuration(duration: number): Promise { + // Resolve pending Promises first. Pending Promises always get resolved before a `setTimeout` + // callback in practice, so this better reflects a real scenario. + jest.runOnlyPendingTimers(); + + await new Promise((resolve) => { const index = this.calls.findIndex((call) => call.duration === duration); if (index === -1) { @@ -96,6 +108,13 @@ class SetTimeoutRecorder { resolve(); } }); + // Resolve pending Promises before returning to better emulate a real scenario. + // This ensures tests can't accidentally insert synchronous code after a `setTimeout`. + jest.runOnlyPendingTimers(); + } + + findCallsMatchingDuration(duration: number): SetTimeoutCall[] { + return this.calls.filter((call) => call.duration === duration); } /** @@ -160,8 +179,10 @@ class SetTimeoutRecorder { * * @param timeout - A Timeout object as returned by `setTimeout`. */ - _mockClearTimeoutImplementation = (timeout: NodeJS.Timeout): void => { - const index = this.calls.findIndex((c) => c.timeout === timeout); + _mockClearTimeoutImplementation = ( + timeout?: NodeJS.Timeout | string | number, + ): void => { + const index = this.calls.findIndex((call) => call.timeout === timeout); if (index !== -1) { this.calls.splice(index, 1); @@ -203,11 +224,11 @@ export default function recordCallsToSetTimeout({ }); jest - .spyOn(global, 'setTimeout') + .spyOn(globalThis, 'setTimeout') .mockImplementation(setTimeoutRecorder._mockSetTimeoutImplementation); jest - .spyOn(global, 'clearTimeout') + .spyOn(globalThis, 'clearTimeout') .mockImplementation(setTimeoutRecorder._mockClearTimeoutImplementation); return setTimeoutRecorder; diff --git a/tests/setupAfterEnv.ts b/test/setupAfterEnv.ts similarity index 92% rename from tests/setupAfterEnv.ts rename to test/setupAfterEnv.ts index 7b94024d..0fb7d837 100644 --- a/tests/setupAfterEnv.ts +++ b/test/setupAfterEnv.ts @@ -15,7 +15,7 @@ export {}; const UNRESOLVED = Symbol('timedOut'); // Store this in case it gets stubbed later -const originalSetTimeout = global.setTimeout; +const originalSetTimeout = globalThis.setTimeout; const TIME_TO_WAIT_UNTIL_UNRESOLVED = 100; /** @@ -28,7 +28,9 @@ const TIME_TO_WAIT_UNTIL_UNRESOLVED = 100; * this function. * @returns A promise that resolves to a symbol. */ -const treatUnresolvedAfter = (duration: number): Promise => { +const treatUnresolvedAfter = async ( + duration: number, +): Promise => { return new Promise((resolve) => { originalSetTimeout(resolve, duration, UNRESOLVED); }); @@ -61,8 +63,8 @@ expect.extend({ promise, treatUnresolvedAfter(TIME_TO_WAIT_UNTIL_UNRESOLVED), ]); - } catch (e) { - rejectionValue = e; + } catch (error) { + rejectionValue = error; } return resolutionValue === UNRESOLVED diff --git a/test/withBlockTracker.ts b/test/withBlockTracker.ts new file mode 100644 index 00000000..b9b7baa4 --- /dev/null +++ b/test/withBlockTracker.ts @@ -0,0 +1,182 @@ +import { providerFromEngine } from '@metamask/eth-json-rpc-provider'; +import type { + // Eip1193Request, + SafeEventEmitterProvider, +} from '@metamask/eth-json-rpc-provider'; +import { JsonRpcEngine } from '@metamask/json-rpc-engine'; +import type { Json } from '@metamask/utils'; +import util from 'util'; + +import type { PollingBlockTrackerOptions } from '../src'; +import { PollingBlockTracker } from '../src'; + +type WithPollingBlockTrackerOptions = { + provider?: FakeProviderOptions; + blockTracker?: PollingBlockTrackerOptions; +}; + +type WithPollingBlockTrackerCallback = (args: { + provider: SafeEventEmitterProvider; + blockTracker: PollingBlockTracker; +}) => void | Promise; + +/** + * An object that allows specifying the behavior of a specific invocation of + * `request`. The `methodName` always identifies the stub, but the behavior + * may be specified multiple ways: `request` can either return a result + * or reject with an error. + * + * methodName - The RPC method to which this stub will be matched. + * + * result - Instructs `request` to return a result. + * + * implementation - Allows overriding `request` entirely. Useful if + * you want it to throw an error. + * + * error - Instructs `request` to return a promise that rejects with + * this error. + */ +type FakeProviderStub = + | { + methodName: string; + result: any; + } + | { + methodName: string; + implementation: () => void; + } + | { + methodName: string; + error: unknown; + }; + +/** + * The set of options that a new instance of FakeProvider takes. + * + * stubs - A set of objects that allow specifying the behavior + * of specific invocations of `request` matching a `methodName`. + */ +type FakeProviderOptions = { + stubs?: FakeProviderStub[]; +}; + +/** + * Constructs a provider that returns fake responses for the various + * RPC methods that the provider supports can be supplied. + * + * @param options - The options. + * @param options.stubs - A set of objects that allow specifying the behavior + * of specific invocations of `request` matching a `methodName`. + * @returns The fake provider. + */ +function getFakeProvider({ + stubs: initialStubs = [], +}: { + stubs?: FakeProviderStub[]; +} = {}) { + const originalStubs = initialStubs.slice(); + + const stubs = initialStubs.slice(); + if (!stubs.some((stub) => stub.methodName === 'eth_blockNumber')) { + stubs.push({ + methodName: 'eth_blockNumber', + result: '0x0', + }); + } + + if (!stubs.some((stub) => stub.methodName === 'eth_subscribe')) { + stubs.push({ + methodName: 'eth_subscribe', + result: '0x0', + }); + } + + if (!stubs.some((stub) => stub.methodName === 'eth_unsubscribe')) { + stubs.push({ + methodName: 'eth_unsubscribe', + result: true, + }); + } + + const provider = providerFromEngine(new JsonRpcEngine()); + jest + .spyOn(provider, 'request') + .mockImplementation(async (eip1193Request): Promise => { + const index = stubs.findIndex( + (stub) => stub.methodName === eip1193Request.method, + ); + + if (index !== -1) { + const stub = stubs[index]; + stubs.splice(index, 1); + if ('implementation' in stub) { + stub.implementation(); + } else if ('result' in stub) { + return stub.result; + } else if ('error' in stub) { + throw stub.error; + } + return null; + } + + throw new Error( + `Could not find any stubs matching "${eip1193Request.method}". Perhaps they've already been called?\n\n` + + 'The original set of stubs were:\n\n' + + `${util.inspect(originalStubs, { depth: null })}\n\n` + + 'Current set of stubs:\n\n' + + `${util.inspect(stubs, { depth: null })}\n\n`, + ); + }); + return provider; +} + +/** + * Calls the given function with a built-in PollingBlockTracker, ensuring that + * all listeners that are on the block tracker are removed and any timers or + * loops that are running within the block tracker are properly stopped. + * + * @param options - Options that allow configuring the block tracker or + * provider. + * @param callback - A callback which will be called with the built block + * tracker. + * @returns The provider and block tracker. + */ +export async function withPollingBlockTracker( + options: WithPollingBlockTrackerOptions, + callback: WithPollingBlockTrackerCallback, +): Promise; +/** + * Calls the given function with a built-in PollingBlockTracker, ensuring that + * all listeners that are on the block tracker are removed and any timers or + * loops that are running within the block tracker are properly stopped. + * + * @param callback - A callback which will be called with the built block + * tracker. + * @returns The provider and block tracker. + */ +export async function withPollingBlockTracker( + callback: WithPollingBlockTrackerCallback, +): Promise; + +/* eslint-disable-next-line jsdoc/require-jsdoc */ +export async function withPollingBlockTracker( + ...args: + | [WithPollingBlockTrackerOptions, WithPollingBlockTrackerCallback] + | [WithPollingBlockTrackerCallback] +) { + const [options, callback] = args.length === 2 ? args : [{}, args[0]]; + const provider = + options.provider === undefined + ? getFakeProvider() + : getFakeProvider(options.provider); + const blockTrackerOptions = + options.blockTracker === undefined + ? { provider } + : { + provider, + ...options.blockTracker, + }; + const blockTracker = new PollingBlockTracker(blockTrackerOptions); + const callbackArgs = { provider, blockTracker }; + return await callback(callbackArgs); +} diff --git a/tests/withBlockTracker.ts b/tests/withBlockTracker.ts deleted file mode 100644 index 439c47ee..00000000 --- a/tests/withBlockTracker.ts +++ /dev/null @@ -1,282 +0,0 @@ -import util from 'util'; -import SafeEventEmitter from '@metamask/safe-event-emitter'; -import { JsonRpcRequest, JsonRpcResponse } from 'json-rpc-engine'; -import { Provider } from '../src/BaseBlockTracker'; -import { - SubscribeBlockTracker, - SubscribeBlockTrackerOptions, -} from '../src/SubscribeBlockTracker'; -import { - PollingBlockTracker, - PollingBlockTrackerOptions, -} from '../src/PollingBlockTracker'; - -interface WithPollingBlockTrackerOptions { - provider?: FakeProviderOptions; - blockTracker?: PollingBlockTrackerOptions; -} - -type WithPollingBlockTrackerCallback = (args: { - provider: FakeProvider; - blockTracker: PollingBlockTracker; -}) => void | Promise; - -interface WithSubscribeBlockTrackerOptions { - provider?: FakeProviderOptions; - blockTracker?: SubscribeBlockTrackerOptions; -} - -type WithSubscribeBlockTrackerCallback = (args: { - provider: FakeProvider; - blockTracker: SubscribeBlockTracker; -}) => void | Promise; - -/** - * An object that allows specifying the behavior of a specific invocation of - * `sendAsync`. The `methodName` always identifies the stub, but the behavior - * may be specified multiple ways: `sendAsync` can either return a promise or - * throw an error, and if it returns a promise, that promise can either be - * resolved with a response object or reject with an error. - * - * @property methodName - The RPC method to which this stub will be matched. - * @property response - Instructs `sendAsync` to return a promise that resolves - * with a response object. - * @property response.result - Specifies a successful response, with this as the - * `result`. - * @property response.error - Specifies an error response, with this as the - * `error`. - * @property implementation - Allows overriding `sendAsync` entirely. Useful if - * you want it to throw an error. - * @property error - Instructs `sendAsync` to return a promise that rejects with - * this error. - */ -type FakeProviderStub = - | { - methodName: string; - response: { result: any } | { error: string }; - } - | { - methodName: string; - implementation: () => void; - } - | { - methodName: string; - error: string; - }; - -/** - * The set of options that a new instance of FakeProvider takes. - * - * @property stubs - A set of objects that allow specifying the behavior - * of specific invocations of `sendAsync` matching a `methodName`. - */ -interface FakeProviderOptions { - stubs?: FakeProviderStub[]; -} - -/** - * FakeProvider is an implementation of the provider that a subclass of - * BaseBlockTracker is expected to take, supporting the same expected methods - * with the same expected interface, except that fake responses for the various - * RPC methods that the provider supports can be supplied. This ends up easier - * to define than using `jest.spyOn(...).mockImplementationOnce(...)` due to the - * types that `sendAsync` takes. - */ -class FakeProvider extends SafeEventEmitter implements Provider { - #stubs: FakeProviderStub[]; - - #originalStubs: FakeProviderStub[]; - - /** - * Makes a new instance of the fake provider. - * - * @param options - The options. - * @param options.stubs - A set of objects that allow specifying the behavior - * of specific invocations of `sendAsync` matching a `methodName`. - */ - constructor({ stubs = [] }: FakeProviderOptions = {}) { - super(); - this.#stubs = this.#buildStubsFrom(stubs); - this.#originalStubs = this.#stubs.slice(); - } - - sendAsync( - request: JsonRpcRequest, - callback: (err: Error, response: JsonRpcResponse) => void, - ) { - const index = this.#stubs.findIndex( - (stub) => stub.methodName === request.method, - ); - - if (index !== -1) { - const stub = this.#stubs[index]; - this.#stubs.splice(index, 1); - if ('implementation' in stub) { - stub.implementation(); - } else if ('response' in stub) { - if ('result' in stub.response) { - callback(null as unknown as Error, { - jsonrpc: '2.0', - id: 1, - result: stub.response.result, - }); - } else if ('error' in stub.response) { - callback(null as unknown as Error, { - jsonrpc: '2.0', - id: 1, - error: { - code: -999, - message: stub.response.error, - }, - }); - } - } else if ('error' in stub) { - callback(new Error(stub.error), null as unknown as JsonRpcResponse); - } - return; - } - - callback( - new Error( - `Could not find any stubs matching "${request.method}". Perhaps they've already been called?\n\n` + - 'The original set of stubs were:\n\n' + - `${util.inspect(this.#originalStubs, { depth: null })}\n\n` + - 'Current set of stubs:\n\n' + - `${util.inspect(this.#stubs, { depth: null })}\n\n`, - ), - null as unknown as JsonRpcResponse, - ); - } - - #buildStubsFrom(givenStubs: FakeProviderStub[]): FakeProviderStub[] { - const stubs = givenStubs.slice(); - - if (!stubs.some((stub) => stub.methodName === 'eth_blockNumber')) { - stubs.push({ - methodName: 'eth_blockNumber', - response: { - result: '0x0', - }, - }); - } - - if (!stubs.some((stub) => stub.methodName === 'eth_subscribe')) { - stubs.push({ - methodName: 'eth_subscribe', - response: { - result: '0x0', - }, - }); - } - - if (!stubs.some((stub) => stub.methodName === 'eth_unsubscribe')) { - stubs.push({ - methodName: 'eth_unsubscribe', - response: { - result: true, - }, - }); - } - - return stubs; - } -} - -/** - * Calls the given function with a built-in PollingBlockTracker, ensuring that - * all listeners that are on the block tracker are removed and any timers or - * loops that are running within the block tracker are properly stopped. - * - * @param options - Options that allow configuring the block tracker or - * provider. - * @param callback - A callback which will be called with the built block - * tracker. - */ -async function withPollingBlockTracker( - options: WithPollingBlockTrackerOptions, - callback: WithPollingBlockTrackerCallback, -): Promise; -/** - * Calls the given function with a built-in PollingBlockTracker, ensuring that - * all listeners that are on the block tracker are removed and any timers or - * loops that are running within the block tracker are properly stopped. - * - * @param callback - A callback which will be called with the built block - * tracker. - */ -async function withPollingBlockTracker( - callback: WithPollingBlockTrackerCallback, -): Promise; -/* eslint-disable-next-line jsdoc/require-jsdoc */ -async function withPollingBlockTracker( - ...args: - | [WithPollingBlockTrackerOptions, WithPollingBlockTrackerCallback] - | [WithPollingBlockTrackerCallback] -) { - const [options, callback] = args.length === 2 ? args : [{}, args[0]]; - const provider = - options.provider === undefined - ? new FakeProvider() - : new FakeProvider(options.provider); - const blockTrackerOptions = - options.blockTracker === undefined - ? { provider } - : { - provider, - ...options.blockTracker, - }; - const blockTracker = new PollingBlockTracker(blockTrackerOptions); - const callbackArgs = { provider, blockTracker }; - await callback(callbackArgs); -} - -/** - * Calls the given function with a built-in SubscribeBlockTracker, ensuring that - * all listeners that are on the block tracker are removed and any timers or - * loops that are running within the block tracker are properly stopped. - * - * @param options - Options that allow configuring the block tracker or - * provider. - * @param callback - A callback which will be called with the built block - * tracker. - */ -async function withSubscribeBlockTracker( - options: WithSubscribeBlockTrackerOptions, - callback: WithSubscribeBlockTrackerCallback, -): Promise; -/** - * Calls the given function with a built-in SubscribeBlockTracker, ensuring that - * all listeners that are on the block tracker are removed and any timers or - * loops that are running within the block tracker are properly stopped. - * - * @param callback - A callback which will be called with the built block - * tracker. - */ -async function withSubscribeBlockTracker( - callback: WithSubscribeBlockTrackerCallback, -): Promise; -/* eslint-disable-next-line jsdoc/require-jsdoc */ -async function withSubscribeBlockTracker( - ...args: - | [WithSubscribeBlockTrackerOptions, WithSubscribeBlockTrackerCallback] - | [WithSubscribeBlockTrackerCallback] -) { - const [options, callback] = args.length === 2 ? args : [{}, args[0]]; - const provider = - options.provider === undefined - ? new FakeProvider() - : new FakeProvider(options.provider); - - const blockTrackerOptions = - options.blockTracker === undefined - ? { provider } - : { - provider, - ...options.blockTracker, - }; - const blockTracker = new SubscribeBlockTracker(blockTrackerOptions); - const callbackArgs = { provider, blockTracker }; - await callback(callbackArgs); -} - -export { withPollingBlockTracker, withSubscribeBlockTracker }; diff --git a/tsconfig.build.json b/tsconfig.build.json index c6e00d65..0160af45 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -2,6 +2,8 @@ "extends": "./tsconfig.json", "compilerOptions": { "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, "inlineSources": true, "noEmit": false, "outDir": "dist", @@ -9,5 +11,14 @@ "sourceMap": true }, "include": ["./src/**/*.ts"], - "exclude": ["./src/**/*.test.ts"] + "exclude": [ + "./src/**/__fixtures__/**/*", + "./src/**/__mocks__/**/*", + "./src/**/__test__/**/*", + "./src/**/__tests__/**/*", + "./src/**/__snapshots__/**/*", + "./src/**/*.test.ts", + "./src/**/*.test-d.ts", + "./src/**/*.test.*.ts" + ] } diff --git a/tsconfig.json b/tsconfig.json index 66a51f75..df298a01 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,14 @@ { "compilerOptions": { "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, "lib": ["ES2020"], "module": "CommonJS", "moduleResolution": "node", "noEmit": true, + "noErrorTruncation": true, "strict": true, "target": "es2017" }, - "exclude": ["./dist/**/*"] + "exclude": ["./dist", "**/node_modules"] } diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 00000000..b527b625 --- /dev/null +++ b/typedoc.json @@ -0,0 +1,6 @@ +{ + "entryPoints": ["./src/index.ts"], + "excludePrivate": true, + "hideGenerator": true, + "out": "docs" +} diff --git a/yarn.config.cjs b/yarn.config.cjs new file mode 100644 index 00000000..d272409a --- /dev/null +++ b/yarn.config.cjs @@ -0,0 +1,286 @@ +/** @type {import('@yarnpkg/types')} */ +const { defineConfig } = require('@yarnpkg/types'); +const { readFile } = require('fs/promises'); +const { basename, resolve } = require('path'); + +/** + * Aliases for the Yarn type definitions, to make the code more readable. + * + * @typedef {import('@yarnpkg/types').Yarn.Constraints.Workspace} Workspace + * @typedef {import('@yarnpkg/types').Yarn.Constraints.Dependency} Dependency + */ + +/** + * The base URL for the GitHub repository. + * + * @type {string} + */ +const BASE_URL = 'https://github.com/MetaMask/'; + +/** + * Get the name of the workspace. The workspace name is expected to be in the + * form `@metamask/workspace-name`, and this function will extract + * `workspace-name`. + * + * @param {Workspace} workspace - The workspace. + * @returns {string} The name of the workspace. + */ +function getWorkspaceName(workspace) { + return basename(workspace.ident); +} + +/** + * Get the absolute path to a file within the workspace. + * + * @param {Workspace} workspace - The workspace. + * @param {string} path - The path to the file, relative to the workspace root. + * @returns {string} The absolute path to the file. + */ +function getWorkspacePath(workspace, path) { + return resolve(__dirname, workspace.cwd, path); +} + +/** + * Get the contents of a file within the workspace. The file is expected to be + * encoded as UTF-8. + * + * @param {Workspace} workspace - The workspace. + * @param {string} path - The path to the file, relative to the workspace root. + * @returns {Promise} The contents of the file. + */ +async function getWorkspaceFile(workspace, path) { + return await readFile(getWorkspacePath(workspace, path), 'utf8'); +} + +/** + * Expect that the workspace has the given field, and that it is a non-null + * value. If the field is not present, or is null, this will log an error, and + * cause the constraint to fail. + * + * If a value is provided, this will also verify that the field is equal to the + * given value. + * + * @param {Workspace} workspace - The workspace to check. + * @param {string} field - The field to check. + * @param {any} [value] - The value to check. + */ +function expectWorkspaceField(workspace, field, value) { + const fieldValue = workspace.manifest[field]; + if (fieldValue === null) { + workspace.error(`Missing required field "${field}".`); + return; + } + + if (value) { + workspace.set(field, value); + } +} + +/** + * Expect that the workspace has a description, and that it is a non-null + * string. If the description is not present, or is null, this will log an + * error, and cause the constraint to fail. + * + * This will also verify that the description does not end with a period. + * + * @param {Workspace} workspace - The workspace to check. + */ +function expectWorkspaceDescription(workspace) { + expectWorkspaceField(workspace, 'description'); + + const { description } = workspace.manifest; + if (typeof description !== 'string') { + workspace.error( + `Expected description to be a string, but got ${typeof description}.`, + ); + return; + } + + if (description.endsWith('.')) { + workspace.set('description', description.slice(0, -1)); + } +} + +/** + * Expect that if a dependency is listed under "dependencies", it is not also + * listed under "devDependencies". If it is, this will log an error, and cause + * the constraint to fail. + * + * @param {Workspace} workspace - The workspace to check. + */ +function expectWorkspaceDependencies(workspace) { + workspace.pkg.dependencies.forEach((dependency) => { + // `workspace.pkg` does not have a `devDependencies` field, so we need to + // check the `manifest` instead. + const isDependency = Boolean( + workspace.manifest.dependencies?.[dependency.ident], + ); + const isDevDependency = Boolean( + workspace.manifest.devDependencies?.[dependency.ident], + ); + + if (isDependency && isDevDependency) { + workspace.unset(`devDependencies.${dependency.ident}`); + } + }); +} + +/** + * Expect that the workspace has a README.md file, and that it is a non-empty + * string. The README.md is expected to: + * + * - Not contain template instructions (unless the workspace is the module + * template itself). + * - Match the version of Node.js specified in the `.nvmrc` file. + * + * @param {Workspace} workspace - The workspace to check. + * @param {string} workspaceName - The name of the workspace. + * @returns {Promise} + */ +async function expectReadme(workspace, workspaceName) { + const readme = await getWorkspaceFile(workspace, 'README.md'); + if ( + workspaceName !== 'metamask-module-template' && + readme.includes('## Template Instructions') + ) { + workspace.error( + 'The README.md contains template instructions. These instructions should be removed.', + ); + } + + if (!readme.includes(`yarn add @metamask/${workspaceName}`)) { + workspace.error( + `The README.md does not contain an example of how to install the package using Yarn (\`yarn add @metamask/${workspaceName}\`). Please add an example.`, + ); + } + + if (!readme.includes(`npm install @metamask/${workspaceName}`)) { + workspace.error( + `The README.md does not contain an example of how to install the package using npm (\`npm install @metamask/${workspaceName}\`). Please add an example.`, + ); + } +} + +/** + * Expect that the workspace has a pull_request_template.md file, and that it + * is a non-empty string. The pull_request_template.md is expected to: + * + * - Not contain an examples section (unless the workspace is the module + * template itself). + * + * @param {Workspace} workspace - The workspace to check. + * @param {string} workspaceName - The name of the workspace. + * @returns {Promise} + */ +async function expectPullRequestTemplate(workspace, workspaceName) { + if (workspaceName === 'metamask-module-template') { + return; + } + + const pullRequestTemplate = await getWorkspaceFile( + workspace, + '.github/pull_request_template.md', + ); + + if (!pullRequestTemplate) { + workspace.error( + 'The pull_request_template.md is missing. This should be added.', + ); + } + + if (pullRequestTemplate.includes('## Examples')) { + workspace.error( + 'The pull_request_template.md contains an examples section. This section should be removed.', + ); + } +} + +/** + * Expect that the workspace has a valid `exports` field. The `exports` field + * is expected to: + * + * - Export a `types` entrypoint as the first export, or not at all. + * + * This is required for proper TypeScript support when using `Node16` (or later) + * module resolution. + * + * @param {Workspace} workspace - The workspace to check. + * @returns {void} + */ +function expectExports(workspace) { + const { exports: manifestExports } = workspace.manifest; + Object.entries(manifestExports) + .filter(([, exportValue]) => typeof exportValue !== 'string') + .forEach(([exportName, exportObject]) => { + const keys = Object.keys(exportObject); + if (keys.includes('types') && keys[0] !== 'types') { + workspace.error( + `The "types" export must be the first export in the "exports" field for the export "${exportName}".`, + ); + } + }); +} + +module.exports = defineConfig({ + async constraints({ Yarn }) { + const workspace = Yarn.workspace(); + const workspaceName = getWorkspaceName(workspace); + const workspaceRepository = `${BASE_URL}${workspaceName}`; + + // The package must have a name, version, description, and license. + expectWorkspaceField(workspace, 'name', `@metamask/${workspaceName}`); + expectWorkspaceField(workspace, 'version'); + expectWorkspaceField(workspace, 'license'); + expectWorkspaceDescription(workspace); + + // The package must have a valid README.md file. + await expectReadme(workspace, workspaceName); + + // The package must have a valid pull request template. + await expectPullRequestTemplate(workspace, workspaceName); + + expectWorkspaceDependencies(workspace); + + // The homepage of the package must match its name. + workspace.set('homepage', `${workspaceRepository}#readme`); + + // The bugs URL of the package must point to the Issues page for the + // repository. + workspace.set('bugs.url', `${workspaceRepository}/issues`); + + // The package must specify Git as the repository type, and match the URL of + // a repository within the MetaMask organization. + workspace.set('repository.type', 'git'); + workspace.set('repository.url', `${workspaceRepository}.git`); + + // The package must specify the expected minimum Node versions + workspace.set('engines.node', '^18.16 || ^20 || >=22'); + + // The package must provide the location of the CommonJS-compatible + // entrypoint and its matching type declaration file. + workspace.set('main', './dist/index.cjs'); + workspace.set('exports["."].require.default', './dist/index.cjs'); + workspace.set('types', './dist/index.d.cts'); + workspace.set('exports["."].require.types', './dist/index.d.cts'); + + // The package must provide the location of the ESM-compatible JavaScript + // entrypoint and its matching type declaration file. + workspace.set('module', './dist/index.mjs'); + workspace.set('exports["."].import.default', './dist/index.mjs'); + workspace.set('exports["."].import.types', './dist/index.d.mts'); + + // The package must export a `package.json` file. + workspace.set('exports["./package.json"]', './package.json'); + + expectExports(workspace); + + // The list of files included in the package must only include files + // generated during the build process. + workspace.set('files', ['dist']); + + // The package is public, and should be published to the npm registry. + workspace.unset('private'); + workspace.set('publishConfig.access', 'public'); + workspace.set('publishConfig.registry', 'https://registry.npmjs.org/'); + }, +}); diff --git a/yarn.lock b/yarn.lock index 305daf8d..b73a8edc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,4517 +1,7221 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ampproject/remapping@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" - integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== - dependencies: - "@jridgewell/trace-mapping" "^0.3.0" - -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/code-frame@^7.0.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" - integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== - dependencies: - "@babel/highlight" "^7.0.0" - -"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== - dependencies: - "@babel/highlight" "^7.16.7" - -"@babel/compat-data@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" - integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== - -"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.8.0": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.9.tgz#6bae81a06d95f4d0dec5bb9d74bbc1f58babdcfe" - integrity sha512-5ug+SfZCpDAkVp9SFIZAzlW18rlzsOcJGaetCjkySnrXXDUw9AR8cDUm1iByTmdWM6yxX6/zycaV76w3YTF2gw== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.9" - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-module-transforms" "^7.17.7" - "@babel/helpers" "^7.17.9" - "@babel/parser" "^7.17.9" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.9" - "@babel/types" "^7.17.0" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" - -"@babel/generator@^7.17.9", "@babel/generator@^7.7.2": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.9.tgz#f4af9fd38fa8de143c29fce3f71852406fc1e2fc" - integrity sha512-rAdDousTwxbIxbz5I7GEQ3lUip+xVCXooZNbsydCWs3xA7ZsYOv+CFRdzGxRX78BmQHu9B1Eso59AOZQOJDEdQ== - dependencies: - "@babel/types" "^7.17.0" - jsesc "^2.5.1" - source-map "^0.5.0" - -"@babel/helper-compilation-targets@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz#a3c2924f5e5f0379b356d4cfb313d1414dc30e46" - integrity sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w== - dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-validator-option" "^7.16.7" - browserslist "^4.17.5" - semver "^6.3.0" - -"@babel/helper-environment-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" - integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-function-name@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" - integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== - dependencies: - "@babel/template" "^7.16.7" - "@babel/types" "^7.17.0" - -"@babel/helper-hoist-variables@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" - integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-module-imports@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-module-transforms@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz#3943c7f777139e7954a5355c815263741a9c1cbd" - integrity sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw== - dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.3" - "@babel/types" "^7.17.0" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" - integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== - -"@babel/helper-simple-access@^7.17.7": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz#aaa473de92b7987c6dfa7ce9a7d9674724823367" - integrity sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA== - dependencies: - "@babel/types" "^7.17.0" - -"@babel/helper-split-export-declaration@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" - integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== - -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== - -"@babel/helpers@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.9.tgz#b2af120821bfbe44f9907b1826e168e819375a1a" - integrity sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q== - dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.17.9" - "@babel/types" "^7.17.0" - -"@babel/highlight@^7.0.0", "@babel/highlight@^7.10.4", "@babel/highlight@^7.16.7": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3" - integrity sha512-J9PfEKCbFIv2X5bjTMiZu6Vf341N05QIY+d6FvVKynkG1S7G0j3I0QoRtWIrXhZ+/Nlb5Q0MzqL7TokEJ5BNHg== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef" - integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg== - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-import-meta@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.7.2": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" - integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - -"@babel/template@^7.16.7", "@babel/template@^7.3.3": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" - integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/parser" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/traverse@^7.17.3", "@babel/traverse@^7.17.9", "@babel/traverse@^7.7.2": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.9.tgz#1f9b207435d9ae4a8ed6998b2b82300d83c37a0d" - integrity sha512-PQO8sDIJ8SIwipTPiR71kJQCKQYB5NGImbOviK8K+kg5xkNSYXLBupuX9QhatFowrsvo9Hj8WgArg3W7ijNAQw== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.17.9" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.17.9" - "@babel/types" "^7.17.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" - integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" - to-fast-properties "^2.0.0" - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@cspotcode/source-map-consumer@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" - integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== - -"@cspotcode/source-map-support@0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" - integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== - dependencies: - "@cspotcode/source-map-consumer" "0.8.0" - -"@es-joy/jsdoccomment@0.10.8": - version "0.10.8" - resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.10.8.tgz#b3152887e25246410ed4ea569a55926ec13b2b05" - integrity sha512-3P1JiGL4xaR9PoTKUHa2N/LKwa2/eUdRqGwijMWWgBqbFEqJUVpmaOi2TcjcemrsRMgFLBzQCK4ToPhrSVDiFQ== - dependencies: - comment-parser "1.2.4" - esquery "^1.4.0" - jsdoc-type-pratt-parser "1.1.1" - -"@eslint/eslintrc@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== - dependencies: - ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - strip-json-comments "^3.1.1" - -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== - dependencies: - "@humanwhocodes/object-schema" "^1.2.0" - debug "^4.1.1" - minimatch "^3.0.4" - -"@humanwhocodes/object-schema@^1.2.0": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - 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" - -"@istanbuljs/schema@^0.1.2": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/console@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" - integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^27.5.1" - jest-util "^27.5.1" - slash "^3.0.0" - -"@jest/core@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" - integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== - dependencies: - "@jest/console" "^27.5.1" - "@jest/reporters" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.8.1" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^27.5.1" - jest-config "^27.5.1" - jest-haste-map "^27.5.1" - jest-message-util "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-resolve-dependencies "^27.5.1" - jest-runner "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - jest-watcher "^27.5.1" - micromatch "^4.0.4" - rimraf "^3.0.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/environment@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" - integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== - dependencies: - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - -"@jest/fake-timers@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" - integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== - dependencies: - "@jest/types" "^27.5.1" - "@sinonjs/fake-timers" "^8.0.1" - "@types/node" "*" - jest-message-util "^27.5.1" - jest-mock "^27.5.1" - jest-util "^27.5.1" - -"@jest/globals@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" - integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/types" "^27.5.1" - expect "^27.5.1" - -"@jest/reporters@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" - integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-haste-map "^27.5.1" - jest-resolve "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - slash "^3.0.0" - source-map "^0.6.0" - string-length "^4.0.1" - terminal-link "^2.0.0" - v8-to-istanbul "^8.1.0" - -"@jest/source-map@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" - integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.2.9" - source-map "^0.6.0" - -"@jest/test-result@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" - integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== - dependencies: - "@jest/console" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" - integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== - dependencies: - "@jest/test-result" "^27.5.1" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-runtime "^27.5.1" - -"@jest/transform@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" - integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^27.5.1" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-regex-util "^27.5.1" - jest-util "^27.5.1" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - -"@jest/types@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" - integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - -"@jridgewell/resolve-uri@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" - integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.11" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" - integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== - -"@jridgewell/trace-mapping@^0.3.0": - version "0.3.4" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" - integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@lavamoat/aa@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@lavamoat/aa/-/aa-2.0.1.tgz#fff7605101c9b7a5dd6495e999a492010fba702f" - integrity sha512-lS0DccPZaZyxEqs3+zj76cITrJdaazfIoTs8J3tjS9uA3yvFmZ/QFPsgE5AZxyoO8HPtaz5bGa8x605iNlBVXA== - dependencies: - resolve "^1.20.0" - -"@lavamoat/allow-scripts@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@lavamoat/allow-scripts/-/allow-scripts-2.0.2.tgz#57b4670e30ff720c306fff9adf775689bba0d999" - integrity sha512-bJUXKDau/NgAGngKKLDfbx72gBhgTOUSRgYA8RuHuEX1OgAIk8QMlcPDvwhBCb26mjEHDnxlp5F/Uov0uPEbQw== - dependencies: - "@lavamoat/aa" "^2.0.1" - "@npmcli/run-script" "^1.8.1" - yargs "^16.2.0" - -"@metamask/auto-changelog@^2.5.0": - version "2.6.1" - resolved "https://registry.yarnpkg.com/@metamask/auto-changelog/-/auto-changelog-2.6.1.tgz#5a6291df6c1592f010bd54f1a97814a4570b1eaf" - integrity sha512-7VI4lftbQQHbZcxl1W+qFTWHxoeDGybL22Q70SNyYUVIBLlK5PirJHPh1zVYL4jEFmW0rItLLAXd/OZDuVG1Jg== - dependencies: - diff "^5.0.0" - execa "^5.1.1" - semver "^7.3.5" - yargs "^17.0.1" - -"@metamask/eslint-config-jest@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@metamask/eslint-config-jest/-/eslint-config-jest-9.0.0.tgz#516fdf1f03f6f006b26ca790bf748e2189d19d17" - integrity sha512-tImEEWNRedcIMHZ3pmXDAQ+6xS61G3IEyqKf2+1xSMEMaa94KM+vo6v3GM7YB+M1DsErzgx3g70fEYtPItU4pw== - -"@metamask/eslint-config-nodejs@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@metamask/eslint-config-nodejs/-/eslint-config-nodejs-9.0.0.tgz#ec737a47c04febfb921ce844362d875ca2cae9e7" - integrity sha512-kPUrMPdpGeapbdG+LxysnDNzM9SlBNUvqVl1XoKnOGjo1pbZXB8hOI36PT3IlR1qa2FJumKYfgDSu7JLmOLxqQ== - -"@metamask/eslint-config-typescript@^9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@metamask/eslint-config-typescript/-/eslint-config-typescript-9.0.1.tgz#900d53579ce074734ac9bf4e3f66fc20b92bd6af" - integrity sha512-+W7MXCoq8Q29wvkAv0ycwKB82xMbl+LfkUoM8oWN4n7vyMDXgcgbNjY7ug+quJPZfDTJJ7fxgPmG8m4LrkEImw== - -"@metamask/eslint-config@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@metamask/eslint-config/-/eslint-config-9.0.0.tgz#22d4911b705f7e4e566efbdda0e37912da33e30f" - integrity sha512-mWlLGQKjXXFOj9EtDClKSoTLeQuPW2kM1w3EpUMf4goYAQ+kLXCCa8pEff6h8ApWAnjhYmXydA1znQ2J4XvD+A== - -"@metamask/safe-event-emitter@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" - integrity sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q== - -"@metamask/utils@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-3.0.1.tgz#53ed2b9cbbd12b18c1db6929728446633d6a74c4" - integrity sha512-FDWQ+MeeWQh0b/w2D50+oVPrRqUIvawDlPia+EH9NCOFN0Ty3KkzkQXfO6FgHKMyR4aWuS4SBOrhWFRW8km6lQ== - dependencies: - "@types/debug" "^4.1.7" - debug "^4.3.4" - fast-deep-equal "^3.1.3" - superstruct "^0.16.0" - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@npmcli/node-gyp@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz#a912e637418ffc5f2db375e93b85837691a43a33" - integrity sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA== - -"@npmcli/promise-spawn@^1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5" - integrity sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg== - dependencies: - infer-owner "^1.0.4" - -"@npmcli/run-script@^1.8.1": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-1.8.6.tgz#18314802a6660b0d4baa4c3afe7f1ad39d8c28b7" - integrity sha512-e42bVZnC6VluBZBAFEr3YrdqSspG3bgilyg4nSLBJ7TRGNCzxHa92XAHxQBLYg0BmgwO4b2mf3h/l5EkEWRn3g== - dependencies: - "@npmcli/node-gyp" "^1.0.2" - "@npmcli/promise-spawn" "^1.3.2" - node-gyp "^7.1.0" - read-package-json-fast "^2.0.1" - -"@sinonjs/commons@^1.7.0": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" - integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^8.0.1": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" - integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -"@tsconfig/node10@^1.0.7": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" - integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== - -"@tsconfig/node12@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" - integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== - -"@tsconfig/node14@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" - integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== - -"@tsconfig/node16@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" - integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== - -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.1.19" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" - integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" - integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" - integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" - integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== - dependencies: - "@babel/types" "^7.3.0" - -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== - -"@types/debug@^4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== - dependencies: - "@types/ms" "*" - -"@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/graceful-fs@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== - dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/jest@^27.4.1": - version "27.4.1" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d" - integrity sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw== - dependencies: - jest-matcher-utils "^27.0.0" - pretty-format "^27.0.0" - -"@types/json-rpc-random-id@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#d6b46e635f1bc6afc541e7daee6e53ef611947c9" - integrity sha512-pvZjgd9fif5/Ss+WqWoOSZIivLLvQqoluQZACPeLlIVh4T28TCS54P60KvO27NFuFxYjhJvz+SkuuwcXhiHhjA== - -"@types/json-schema@^7.0.7": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= - -"@types/minimatch@*": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - -"@types/ms@*": - version "0.7.31" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - -"@types/node@*", "@types/node@^17.0.23": - version "17.0.23" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da" - integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw== - -"@types/pify@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@types/pify/-/pify-5.0.1.tgz#10e398a89e3740dd5c316c502acad9ea5e444d3f" - integrity sha512-UYcJBAqWLyg+eITXGIu9DR7RXJFvSupz+Hf+RqJYHzDJedvDMTsB1JmDV6Qfna2g62VIxUKvoWqTxGHy6U/bLA== - -"@types/prettier@^2.1.5": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.6.0.tgz#efcbd41937f9ae7434c714ab698604822d890759" - integrity sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw== - -"@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== - -"@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== - -"@types/yargs@^16.0.0": - version "16.0.4" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" - integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== - dependencies: - "@types/yargs-parser" "*" - -"@typescript-eslint/eslint-plugin@^4.20.0": - version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" - integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg== - dependencies: - "@typescript-eslint/experimental-utils" "4.33.0" - "@typescript-eslint/scope-manager" "4.33.0" - debug "^4.3.1" - functional-red-black-tree "^1.0.1" - ignore "^5.1.8" - regexpp "^3.1.0" - semver "^7.3.5" - tsutils "^3.21.0" - -"@typescript-eslint/experimental-utils@4.33.0", "@typescript-eslint/experimental-utils@^4.0.1": - version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" - integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q== - dependencies: - "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.33.0" - "@typescript-eslint/types" "4.33.0" - "@typescript-eslint/typescript-estree" "4.33.0" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - -"@typescript-eslint/parser@^4.20.0": - version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" - integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA== - dependencies: - "@typescript-eslint/scope-manager" "4.33.0" - "@typescript-eslint/types" "4.33.0" - "@typescript-eslint/typescript-estree" "4.33.0" - debug "^4.3.1" - -"@typescript-eslint/scope-manager@4.33.0": - version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" - integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ== - dependencies: - "@typescript-eslint/types" "4.33.0" - "@typescript-eslint/visitor-keys" "4.33.0" - -"@typescript-eslint/types@4.33.0": - version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" - integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== - -"@typescript-eslint/typescript-estree@4.33.0": - version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" - integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA== - dependencies: - "@typescript-eslint/types" "4.33.0" - "@typescript-eslint/visitor-keys" "4.33.0" - debug "^4.3.1" - globby "^11.0.3" - is-glob "^4.0.1" - semver "^7.3.5" - tsutils "^3.21.0" - -"@typescript-eslint/visitor-keys@4.33.0": - version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" - integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg== - dependencies: - "@typescript-eslint/types" "4.33.0" - eslint-visitor-keys "^2.0.0" - -abab@^2.0.3, abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== - dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" - -acorn-jsx@^5.3.1: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^7.1.1, acorn@^7.4.0: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.2.4, acorn@^8.4.1: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -ajv@^6.10.0: - version "6.12.4" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234" - integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ== - 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" - -ajv@^6.12.3, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - 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" - -ajv@^8.0.1: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-colors@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^5.0.0, ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" - -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - -anymatch@^3.0.3: - version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" - integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@~1.1.2: - version "1.1.7" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" - integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -array-includes@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" - integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.flat@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13" - integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - -babel-jest@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" - integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== - dependencies: - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^27.5.1" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - -babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - 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" - -babel-plugin-jest-hoist@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" - integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.0.0" - "@types/babel__traverse" "^7.0.6" - -babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - 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" - -babel-preset-jest@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" - integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== - dependencies: - babel-plugin-jest-hoist "^27.5.1" - babel-preset-current-node-syntax "^1.0.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browserslist@^4.17.5: - version "4.20.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" - integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== - dependencies: - caniuse-lite "^1.0.30001317" - electron-to-chromium "^1.4.84" - escalade "^3.1.1" - node-releases "^2.0.2" - picocolors "^1.0.0" - -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001317: - version "1.0.30001327" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001327.tgz#c1546d7d7bb66506f0ccdad6a7d07fc6d668c858" - integrity sha512-1/Cg4jlD9qjZzhbzkzEaAC2JHsP0WrOc8Rd/3a3LuajGzGWR/hD7TVyvq99VqmTy99eVh8Zkmdq213OgvgXx7w== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - -ci-info@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" - integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== - -cjs-module-lexer@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" - integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -comment-parser@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.2.4.tgz#489f3ee55dfd184a6e4bffb31baba284453cb760" - integrity sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= - -convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -cssom@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== - -cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== - dependencies: - abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - -debug@4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -decimal.js@^10.2.1: - version "10.3.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" - integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== - -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= - -deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== - -define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -detect-indent@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" - integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== - -detect-newline@3.1.0, detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - -diff-sequences@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" - integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -diff@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -domexception@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" - integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== - dependencies: - webidl-conversions "^5.0.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -electron-to-chromium@^1.4.84: - version "1.4.106" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.106.tgz#e7a3bfa9d745dd9b9e597616cb17283cc349781a" - integrity sha512-ZYfpVLULm67K7CaaGP7DmjyeMY4naxsbTy+syVVxT6QHI1Ww8XbJjmr9fDckrhq44WzCrcC5kH3zGpdusxwwqg== - -emittery@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" - integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.0, es-abstract@^1.19.1: - version "1.19.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.2.tgz#8f7b696d8f15b167ae3640b4060670f3d054143f" - integrity sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.1" - is-string "^1.0.7" - is-weakref "^1.0.2" - object-inspect "^1.12.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -eslint-config-prettier@^8.1.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" - integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== - -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-import-resolver-typescript@^2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz#a90a4a1c80da8d632df25994c4c5fdcdd02b8751" - integrity sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ== - dependencies: - debug "^4.3.4" - glob "^7.2.0" - is-glob "^4.0.3" - resolve "^1.22.0" - tsconfig-paths "^3.14.1" - -eslint-module-utils@^2.7.3: - version "2.7.3" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz#ad7e3a10552fdd0642e1e55292781bd6e34876ee" - integrity sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ== - dependencies: - debug "^3.2.7" - find-up "^2.1.0" - -eslint-plugin-es@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" - integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - -eslint-plugin-import@^2.22.1: - version "2.26.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== - dependencies: - array-includes "^3.1.4" - array.prototype.flat "^1.2.5" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.3" - has "^1.0.3" - is-core-module "^2.8.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.values "^1.1.5" - resolve "^1.22.0" - tsconfig-paths "^3.14.1" - -eslint-plugin-jest@^24.1.3: - version "24.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz#206ac0833841e59e375170b15f8d0955219c4889" - integrity sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA== - dependencies: - "@typescript-eslint/experimental-utils" "^4.0.1" - -eslint-plugin-jsdoc@^36.1.0: - version "36.1.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-36.1.1.tgz#124cd0e53a5d07f01ebde916a96dd1a6009625d6" - integrity sha512-nuLDvH1EJaKx0PCa9oeQIxH6pACIhZd1gkalTUxZbaxxwokjs7TplqY0Q8Ew3CoZaf5aowm0g/Z3JGHCatt+gQ== - dependencies: - "@es-joy/jsdoccomment" "0.10.8" - comment-parser "1.2.4" - debug "^4.3.2" - esquery "^1.4.0" - jsdoc-type-pratt-parser "^1.1.1" - lodash "^4.17.21" - regextras "^0.8.0" - semver "^7.3.5" - spdx-expression-parse "^3.0.1" - -eslint-plugin-node@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" - integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== - dependencies: - eslint-plugin-es "^3.0.0" - eslint-utils "^2.0.0" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - -eslint-plugin-prettier@^3.3.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz#e9ddb200efb6f3d05ffe83b1665a716af4a387e5" - integrity sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g== - dependencies: - prettier-linter-helpers "^1.0.0" - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^2.0.0, eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint@^7.23.0: - version "7.32.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" - integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== - dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.3" - "@humanwhocodes/config-array" "^0.5.0" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^6.0.9" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== - dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" - -esprima@^4.0.0, esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -eth-rpc-errors@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-4.0.3.tgz#6ddb6190a4bf360afda82790bb7d9d5e724f423a" - integrity sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg== - dependencies: - fast-safe-stringify "^2.0.6" - -execa@^5.0.0, execa@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - 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" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= - -expect@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" - integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== - dependencies: - "@jest/types" "^27.5.1" - jest-get-type "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== - -fast-glob@^3.0.3, fast-glob@^3.2.9: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== - 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" - -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fast-safe-stringify@^2.0.6: - version "2.1.1" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" - integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== - dependencies: - bser "2.1.1" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.5" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" - integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -git-hooks-list@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/git-hooks-list/-/git-hooks-list-1.0.3.tgz#be5baaf78203ce342f2f844a9d2b03dba1b45156" - integrity sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ== - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.6.0, globals@^13.9.0: - version "13.13.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b" - integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A== - dependencies: - type-fest "^0.20.2" - -globby@10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.0.tgz#abfcd0630037ae174a88590132c2f6804e291072" - integrity sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw== - dependencies: - "@types/glob" "^7.1.1" - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.0.3" - glob "^7.1.3" - ignore "^5.1.1" - merge2 "^1.2.3" - slash "^3.0.0" - -globby@^11.0.3: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - 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" - -graceful-fs@^4.2.3, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -html-encoding-sniffer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" - integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== - dependencies: - whatwg-encoding "^1.0.5" - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.1, ignore@^5.1.8, ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - -is-core-module@^2.1.0, is-core-module@^2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" - integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typedarray@^1.0.0, is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== - -istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" - integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== - 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" - -istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.1.3: - version "3.1.4" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" - integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -jest-changed-files@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" - integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== - dependencies: - "@jest/types" "^27.5.1" - execa "^5.0.0" - throat "^6.0.1" - -jest-circus@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" - integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - expect "^27.5.1" - is-generator-fn "^2.0.0" - jest-each "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - slash "^3.0.0" - stack-utils "^2.0.3" - throat "^6.0.1" - -jest-cli@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" - integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== - dependencies: - "@jest/core" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - import-local "^3.0.2" - jest-config "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - prompts "^2.0.1" - yargs "^16.2.0" - -jest-config@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" - integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== - dependencies: - "@babel/core" "^7.8.0" - "@jest/test-sequencer" "^27.5.1" - "@jest/types" "^27.5.1" - babel-jest "^27.5.1" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.1" - graceful-fs "^4.2.9" - jest-circus "^27.5.1" - jest-environment-jsdom "^27.5.1" - jest-environment-node "^27.5.1" - jest-get-type "^27.5.1" - jest-jasmine2 "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-runner "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^27.5.1" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -jest-diff@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" - integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== - dependencies: - chalk "^4.0.0" - diff-sequences "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-docblock@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" - integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== - dependencies: - detect-newline "^3.0.0" - -jest-each@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" - integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== - dependencies: - "@jest/types" "^27.5.1" - chalk "^4.0.0" - jest-get-type "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - -jest-environment-jsdom@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" - integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - jest-util "^27.5.1" - jsdom "^16.6.0" - -jest-environment-node@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" - integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - jest-util "^27.5.1" - -jest-get-type@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" - integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== - -jest-haste-map@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" - integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== - dependencies: - "@jest/types" "^27.5.1" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^27.5.1" - jest-serializer "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - micromatch "^4.0.4" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.3.2" - -jest-jasmine2@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" - integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/source-map" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - expect "^27.5.1" - is-generator-fn "^2.0.0" - jest-each "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - throat "^6.0.1" - -jest-leak-detector@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" - integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== - dependencies: - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" - integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== - dependencies: - chalk "^4.0.0" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-message-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" - integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.5.1" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^27.5.1" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" - integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - -jest-pnp-resolver@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" - integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== - -jest-regex-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" - integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== - -jest-resolve-dependencies@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" - integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== - dependencies: - "@jest/types" "^27.5.1" - jest-regex-util "^27.5.1" - jest-snapshot "^27.5.1" - -jest-resolve@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" - integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== - dependencies: - "@jest/types" "^27.5.1" - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-pnp-resolver "^1.2.2" - jest-util "^27.5.1" - jest-validate "^27.5.1" - resolve "^1.20.0" - resolve.exports "^1.1.0" - slash "^3.0.0" - -jest-runner@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" - integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== - dependencies: - "@jest/console" "^27.5.1" - "@jest/environment" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.8.1" - graceful-fs "^4.2.9" - jest-docblock "^27.5.1" - jest-environment-jsdom "^27.5.1" - jest-environment-node "^27.5.1" - jest-haste-map "^27.5.1" - jest-leak-detector "^27.5.1" - jest-message-util "^27.5.1" - jest-resolve "^27.5.1" - jest-runtime "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - source-map-support "^0.5.6" - throat "^6.0.1" - -jest-runtime@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" - integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/globals" "^27.5.1" - "@jest/source-map" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - execa "^5.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-message-util "^27.5.1" - jest-mock "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-serializer@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" - integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== - dependencies: - "@types/node" "*" - graceful-fs "^4.2.9" - -jest-snapshot@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" - integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== - dependencies: - "@babel/core" "^7.7.2" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.0.0" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^27.5.1" - graceful-fs "^4.2.9" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - jest-haste-map "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-util "^27.5.1" - natural-compare "^1.4.0" - pretty-format "^27.5.1" - semver "^7.3.2" - -jest-util@^27.0.0, jest-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" - integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" - integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== - dependencies: - "@jest/types" "^27.5.1" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^27.5.1" - leven "^3.1.0" - pretty-format "^27.5.1" - -jest-watcher@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" - integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== - dependencies: - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - jest-util "^27.5.1" - string-length "^4.0.1" - -jest-worker@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" - integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== - dependencies: - "@jest/core" "^27.5.1" - import-local "^3.0.2" - jest-cli "^27.5.1" - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsdoc-type-pratt-parser@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.1.1.tgz#10fe5e409ba38de22a48b555598955a26ff0160f" - integrity sha512-uelRmpghNwPBuZScwgBG/OzodaFk5RbO5xaivBdsAY70icWfShwZ7PCMO0x1zSkOa8T1FzHThmrdoyg/0AwV5g== - -jsdoc-type-pratt-parser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-1.2.0.tgz#3482a3833b74a88c95a6ba7253f0c0de3b77b9f5" - integrity sha512-4STjeF14jp4bqha44nKMY1OUI6d2/g6uclHWUCZ7B4DoLzaB5bmpTkQrpqU+vSVzMD0LsKAOskcnI3I3VfIpmg== - -jsdom@^16.6.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" - integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== - dependencies: - abab "^2.0.5" - acorn "^8.2.4" - acorn-globals "^6.0.0" - cssom "^0.4.4" - cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" - escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.6" - xml-name-validator "^3.0.0" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-rpc-engine@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-6.1.0.tgz#bf5ff7d029e1c1bf20cb6c0e9f348dcd8be5a393" - integrity sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ== - dependencies: - "@metamask/safe-event-emitter" "^2.0.0" - eth-rpc-errors "^4.0.2" - -json-rpc-random-id@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz#ba49d96aded1444dbb8da3d203748acbbcdec8c8" - integrity sha1-uknZat7RRE27jaPSA3SKy7zeyMg= - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@2.x, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -lodash.memoize@4.x: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= - -lodash@^4.17.21, lodash@^4.7.0: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -lru-cache@^7.4.0: - version "7.8.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.8.1.tgz#68ee3f4807a57d2ba185b7fd90827d5c21ce82bb" - integrity sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg== - -make-dir@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-error@1.x, make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimatch@^3.0.4, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" - integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== - -minipass@^3.0.0: - version "3.1.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" - integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== - dependencies: - yallist "^4.0.0" - -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mkdirp@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -node-gyp@^7.1.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" - integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.3" - nopt "^5.0.0" - npmlog "^4.1.2" - request "^2.88.2" - rimraf "^3.0.2" - semver "^7.3.2" - tar "^6.0.2" - which "^2.0.2" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= - -node-releases@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" - integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== - -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - -normalize-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-normalize-package-bin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -npmlog@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -nwsapi@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" - integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-inspect@^1.12.0, object-inspect@^1.9.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" - integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== - -object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" - object-keys "^1.1.1" - -object.values@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - 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.3" - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - 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" - -parse5@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.6, path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pirates@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -prettier-plugin-packagejson@^2.2.11: - version "2.2.17" - resolved "https://registry.yarnpkg.com/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.2.17.tgz#fc5c93203f9091ad063d9ea5960d2e1a989b94ac" - integrity sha512-Z1l3stIdkEzuv5w2ZyLl7mvl1Q/7vr2wjLAaKCQtafPHB7h09dir0tgXK/W5iEc/jP+C4XtvJl/HhiZBvPh4rQ== - dependencies: - sort-package-json "1.55.0" - -prettier@^2.2.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" - integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== - -pretty-format@^27.0.0, pretty-format@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" - integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== - dependencies: - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^17.0.1" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -prompts@^2.0.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -psl@^1.1.28, psl@^1.1.33: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - -read-package-json-fast@^2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz#323ca529630da82cb34b36cc0b996693c98c2b83" - integrity sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ== - dependencies: - json-parse-even-better-errors "^2.3.0" - npm-normalize-package-bin "^1.0.1" - -readable-stream@^2.0.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -regexpp@^3.0.0, regexpp@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -regextras@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.8.0.tgz#ec0f99853d4912839321172f608b544814b02217" - integrity sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ== - -request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve.exports@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== - -resolve@^1.10.1: - version "1.19.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" - integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== - dependencies: - is-core-module "^2.1.0" - path-parse "^1.0.6" - -resolve@^1.20.0, resolve@^1.22.0: - version "1.22.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== - dependencies: - is-core-module "^2.8.1" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@^5.0.1, safe-buffer@^5.1.2: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -saxes@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" - integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== - dependencies: - xmlchars "^2.2.0" - -semver@7.x, semver@^7.2.1, semver@^7.3.2, semver@^7.3.5: - version "7.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.6.tgz#5d73886fb9c0c6602e79440b97165c29581cbb2b" - integrity sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w== - dependencies: - lru-cache "^7.4.0" - -semver@^6.0.0, semver@^6.1.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -sort-object-keys@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz#bff833fe85cab147b34742e45863453c1e190b45" - integrity sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg== - -sort-package-json@1.55.0: - version "1.55.0" - resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-1.55.0.tgz#150328328a9ac8b417b43d5a1fae74e5f27254e9" - integrity sha512-xhKvRD8WGbALjXQkVuk4/93Z/2NIO+5IzKamdMjN5kn3L+N+M9YWQssmM6GXlQr9v1F7PGWsOJEo1gvXOhM7Mg== - dependencies: - detect-indent "^6.0.0" - detect-newline "3.1.0" - git-hooks-list "1.0.3" - globby "10.0.0" - is-plain-obj "2.1.0" - sort-object-keys "^1.1.3" - -source-map-support@^0.5.6: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@^0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.11" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" - integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stack-utils@^2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" - integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== - dependencies: - escape-string-regexp "^2.0.0" - -string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - -strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -superstruct@^0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.16.0.tgz#9af5e059acd08e774789ad8880962427ef68dace" - integrity sha512-IDQtwnnlaan1NhuHqyD/U11lROYvCQ79JyfwlFU9xEVHzqV/Ys/RrwmHPCG0CVH/1g0BuodEjH1msxK2UHxehA== - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.0.0, supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-hyperlinks@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" - integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -table@^6.0.9: - version "6.8.0" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" - integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== - dependencies: - ajv "^8.0.1" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - -tar@^6.0.2: - version "6.1.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" - integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -throat@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" - integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== - -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -tough-cookie@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" - integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.1.2" - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tr46@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" - integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== - dependencies: - punycode "^2.1.1" - -ts-jest@^27.1.4: - version "27.1.4" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.4.tgz#84d42cf0f4e7157a52e7c64b1492c46330943e00" - integrity sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^27.0.0" - json5 "2.x" - lodash.memoize "4.x" - make-error "1.x" - semver "7.x" - yargs-parser "20.x" - -ts-node@^10.7.0: - version "10.7.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" - integrity sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A== - dependencies: - "@cspotcode/source-map-support" "0.7.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.0" - yn "3.1.1" - -tsconfig-paths@^3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typescript@~4.4.0: - version "4.4.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c" - integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA== - -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - -universalify@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8-compile-cache-lib@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8" - integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA== - -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -v8-to-istanbul@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" - integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - source-map "^0.7.3" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -w3c-xmlserializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" - integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== - dependencies: - xml-name-validator "^3.0.0" - -walker@^1.0.7: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - -webidl-conversions@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" - integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== - -webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - -whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - -whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - -whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" - integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== - dependencies: - lodash "^4.7.0" - tr46 "^2.1.0" - webidl-conversions "^6.1.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - 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" - -which@^2.0.1, which@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -ws@^7.4.6: - version "7.5.7" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" - integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== - -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - -xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@20.x, yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-parser@^21.0.0: - version "21.0.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" - integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== - -yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^17.0.1: - version "17.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.1.tgz#ebe23284207bb75cee7c408c33e722bfb27b5284" - integrity sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g== - dependencies: - cliui "^7.0.2" - 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.0.0" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10 + +"@aashutoshrathi/word-wrap@npm:^1.2.3": + version: 1.2.6 + resolution: "@aashutoshrathi/word-wrap@npm:1.2.6" + checksum: 10/6eebd12a5cd03cee38fcb915ef9f4ea557df6a06f642dfc7fe8eb4839eb5c9ca55a382f3604d52c14200b0c214c12af5e1f23d2a6d8e23ef2d016b105a9d6c0a + languageName: node + linkType: hard + +"@andrewbranch/untar.js@npm:^1.0.3": + version: 1.0.3 + resolution: "@andrewbranch/untar.js@npm:1.0.3" + checksum: 10/a32de53839fc61af90a394cf93d4368aacd167c9c80f0b3ba0c268460942a6ce2bfe257b6d3f03986b9dcb7368f10b9dc7f66c2f94254d2662da8278454e7d12 + languageName: node + linkType: hard + +"@arethetypeswrong/cli@npm:^0.15.3": + version: 0.15.4 + resolution: "@arethetypeswrong/cli@npm:0.15.4" + dependencies: + "@arethetypeswrong/core": "npm:0.15.1" + chalk: "npm:^4.1.2" + cli-table3: "npm:^0.6.3" + commander: "npm:^10.0.1" + marked: "npm:^9.1.2" + marked-terminal: "npm:^7.1.0" + semver: "npm:^7.5.4" + bin: + attw: dist/index.js + checksum: 10/3ae2a01e269300b3528a7963b36d53324f140e709c5e08da6e8c118b84607859dfef9236059ffb18b5eefe88c0df858989522f943c0a7bdcdb78f43513d57005 + languageName: node + linkType: hard + +"@arethetypeswrong/core@npm:0.15.1": + version: 0.15.1 + resolution: "@arethetypeswrong/core@npm:0.15.1" + dependencies: + "@andrewbranch/untar.js": "npm:^1.0.3" + fflate: "npm:^0.8.2" + semver: "npm:^7.5.4" + ts-expose-internals-conditionally: "npm:1.0.0-empty.0" + typescript: "npm:5.3.3" + validate-npm-package-name: "npm:^5.0.0" + checksum: 10/af07d7d0d93926b019d8dc412cee251db972e443be181ef4ef79d28d61f76542b2911a381397ab3ddc23d9a669d830994b4f3b0033f8244f3750027f319595af + languageName: node + linkType: hard + +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/code-frame@npm:7.27.1" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.27.1" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10/721b8a6e360a1fa0f1c9fe7351ae6c874828e119183688b533c477aa378f1010f37cc9afbfc4722c686d1f5cdd00da02eab4ba7278a0c504fa0d7a321dcd4fdf + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.27.2": + version: 7.28.4 + resolution: "@babel/compat-data@npm:7.28.4" + checksum: 10/95b7864e6b210c84c069743966da448c0cb50015a4de5e18dd755776a0b5e53c4653e74f26700aed8de922eaa3b8844fc5fc5b29bc64830249d2abe914aec832 + languageName: node + linkType: hard + +"@babel/core@npm:^7.1.0, @babel/core@npm:^7.12.3, @babel/core@npm:^7.7.2, @babel/core@npm:^7.8.0": + version: 7.28.4 + resolution: "@babel/core@npm:7.28.4" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.28.3" + "@babel/helper-compilation-targets": "npm:^7.27.2" + "@babel/helper-module-transforms": "npm:^7.28.3" + "@babel/helpers": "npm:^7.28.4" + "@babel/parser": "npm:^7.28.4" + "@babel/template": "npm:^7.27.2" + "@babel/traverse": "npm:^7.28.4" + "@babel/types": "npm:^7.28.4" + "@jridgewell/remapping": "npm:^2.3.5" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10/0593295241fac9be567145ef16f3858d34fc91390a9438c6d47476be9823af4cc0488c851c59702dd46b968e9fd46d17ddf0105ea30195ca85f5a66b4044c519 + languageName: node + linkType: hard + +"@babel/generator@npm:^7.28.3, @babel/generator@npm:^7.7.2": + version: 7.28.3 + resolution: "@babel/generator@npm:7.28.3" + dependencies: + "@babel/parser": "npm:^7.28.3" + "@babel/types": "npm:^7.28.2" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10/d00d1e6b51059e47594aab7920b88ec6fcef6489954a9172235ab57ad2e91b39c95376963a6e2e4cc7e8b88fa4f931018f71f9ab32bbc9c0bc0de35a0231f26c + languageName: node + linkType: hard + +"@babel/helper-compilation-targets@npm:^7.27.2": + version: 7.27.2 + resolution: "@babel/helper-compilation-targets@npm:7.27.2" + dependencies: + "@babel/compat-data": "npm:^7.27.2" + "@babel/helper-validator-option": "npm:^7.27.1" + browserslist: "npm:^4.24.0" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10/bd53c30a7477049db04b655d11f4c3500aea3bcbc2497cf02161de2ecf994fec7c098aabbcebe210ffabc2ecbdb1e3ffad23fb4d3f18723b814f423ea1749fe8 + languageName: node + linkType: hard + +"@babel/helper-globals@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/helper-globals@npm:7.28.0" + checksum: 10/91445f7edfde9b65dcac47f4f858f68dc1661bf73332060ab67ad7cc7b313421099a2bfc4bda30c3db3842cfa1e86fffbb0d7b2c5205a177d91b22c8d7d9cb47 + languageName: node + linkType: hard + +"@babel/helper-module-imports@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-module-imports@npm:7.27.1" + dependencies: + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10/58e792ea5d4ae71676e0d03d9fef33e886a09602addc3bd01388a98d87df9fcfd192968feb40ac4aedb7e287ec3d0c17b33e3ecefe002592041a91d8a1998a8d + languageName: node + linkType: hard + +"@babel/helper-module-transforms@npm:^7.28.3": + version: 7.28.3 + resolution: "@babel/helper-module-transforms@npm:7.28.3" + dependencies: + "@babel/helper-module-imports": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.3" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/598fdd8aa5b91f08542d0ba62a737847d0e752c8b95ae2566bc9d11d371856d6867d93e50db870fb836a6c44cfe481c189d8a2b35ca025a224f070624be9fa87 + languageName: node + linkType: hard + +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.8.0": + version: 7.22.5 + resolution: "@babel/helper-plugin-utils@npm:7.22.5" + checksum: 10/ab220db218089a2aadd0582f5833fd17fa300245999f5f8784b10f5a75267c4e808592284a29438a0da365e702f05acb369f99e1c915c02f9f9210ec60eab8ea + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-string-parser@npm:7.27.1" + checksum: 10/0ae29cc2005084abdae2966afdb86ed14d41c9c37db02c3693d5022fba9f5d59b011d039380b8e537c34daf117c549f52b452398f576e908fb9db3c7abbb3a00 + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-identifier@npm:7.27.1" + checksum: 10/75041904d21bdc0cd3b07a8ac90b11d64cd3c881e89cb936fa80edd734bf23c35e6bd1312611e8574c4eab1f3af0f63e8a5894f4699e9cfdf70c06fcf4252320 + languageName: node + linkType: hard + +"@babel/helper-validator-option@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-option@npm:7.27.1" + checksum: 10/db73e6a308092531c629ee5de7f0d04390835b21a263be2644276cb27da2384b64676cab9f22cd8d8dbd854c92b1d7d56fc8517cf0070c35d1c14a8c828b0903 + languageName: node + linkType: hard + +"@babel/helpers@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/helpers@npm:7.28.4" + dependencies: + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.28.4" + checksum: 10/5a70a82e196cf8808f8a449cc4780c34d02edda2bb136d39ce9d26e63b615f18e89a95472230c3ce7695db0d33e7026efeee56f6454ed43480f223007ed205eb + languageName: node + linkType: hard + +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.3, @babel/parser@npm:^7.28.4": + version: 7.28.4 + resolution: "@babel/parser@npm:7.28.4" + dependencies: + "@babel/types": "npm:^7.28.4" + bin: + parser: ./bin/babel-parser.js + checksum: 10/f54c46213ef180b149f6a17ea765bf40acc1aebe2009f594e2a283aec69a190c6dda1fdf24c61a258dbeb903abb8ffb7a28f1a378f8ab5d333846ce7b7e23bf1 + languageName: node + linkType: hard + +"@babel/plugin-syntax-async-generators@npm:^7.8.4": + version: 7.8.4 + resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/7ed1c1d9b9e5b64ef028ea5e755c0be2d4e5e4e3d6cf7df757b9a8c4cfa4193d268176d0f1f7fbecdda6fe722885c7fda681f480f3741d8a2d26854736f05367 + languageName: node + linkType: hard + +"@babel/plugin-syntax-bigint@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-bigint@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/3a10849d83e47aec50f367a9e56a6b22d662ddce643334b087f9828f4c3dd73bdc5909aaeabe123fed78515767f9ca43498a0e621c438d1cd2802d7fae3c9648 + languageName: node + linkType: hard + +"@babel/plugin-syntax-class-properties@npm:^7.8.3": + version: 7.12.13 + resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.12.13" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/24f34b196d6342f28d4bad303612d7ff566ab0a013ce89e775d98d6f832969462e7235f3e7eaf17678a533d4be0ba45d3ae34ab4e5a9dcbda5d98d49e5efa2fc + languageName: node + linkType: hard + +"@babel/plugin-syntax-import-meta@npm:^7.8.3": + version: 7.10.4 + resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/166ac1125d10b9c0c430e4156249a13858c0366d38844883d75d27389621ebe651115cb2ceb6dc011534d5055719fa1727b59f39e1ab3ca97820eef3dcab5b9b + languageName: node + linkType: hard + +"@babel/plugin-syntax-json-strings@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/bf5aea1f3188c9a507e16efe030efb996853ca3cadd6512c51db7233cc58f3ac89ff8c6bdfb01d30843b161cfe7d321e1bf28da82f7ab8d7e6bc5464666f354a + languageName: node + linkType: hard + +"@babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": + version: 7.10.4 + resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/aff33577037e34e515911255cdbb1fd39efee33658aa00b8a5fd3a4b903585112d037cce1cc9e4632f0487dc554486106b79ccd5ea63a2e00df4363f6d4ff886 + languageName: node + linkType: hard + +"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/87aca4918916020d1fedba54c0e232de408df2644a425d153be368313fdde40d96088feed6c4e5ab72aac89be5d07fef2ddf329a15109c5eb65df006bf2580d1 + languageName: node + linkType: hard + +"@babel/plugin-syntax-numeric-separator@npm:^7.8.3": + version: 7.10.4 + resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/01ec5547bd0497f76cc903ff4d6b02abc8c05f301c88d2622b6d834e33a5651aa7c7a3d80d8d57656a4588f7276eba357f6b7e006482f5b564b7a6488de493a1 + languageName: node + linkType: hard + +"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/fddcf581a57f77e80eb6b981b10658421bc321ba5f0a5b754118c6a92a5448f12a0c336f77b8abf734841e102e5126d69110a306eadb03ca3e1547cab31f5cbf + languageName: node + linkType: hard + +"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/910d90e72bc90ea1ce698e89c1027fed8845212d5ab588e35ef91f13b93143845f94e2539d831dc8d8ededc14ec02f04f7bd6a8179edd43a326c784e7ed7f0b9 + languageName: node + linkType: hard + +"@babel/plugin-syntax-optional-chaining@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/eef94d53a1453361553c1f98b68d17782861a04a392840341bc91780838dd4e695209c783631cf0de14c635758beafb6a3a65399846ffa4386bff90639347f30 + languageName: node + linkType: hard + +"@babel/plugin-syntax-top-level-await@npm:^7.8.3": + version: 7.14.5 + resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/bbd1a56b095be7820029b209677b194db9b1d26691fe999856462e66b25b281f031f3dfd91b1619e9dcf95bebe336211833b854d0fb8780d618e35667c2d0d7e + languageName: node + linkType: hard + +"@babel/plugin-syntax-typescript@npm:^7.7.2": + version: 7.22.5 + resolution: "@babel/plugin-syntax-typescript@npm:7.22.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/8ab7718fbb026d64da93681a57797d60326097fd7cb930380c8bffd9eb101689e90142c760a14b51e8e69c88a73ba3da956cb4520a3b0c65743aee5c71ef360a + languageName: node + linkType: hard + +"@babel/template@npm:^7.27.2, @babel/template@npm:^7.3.3": + version: 7.27.2 + resolution: "@babel/template@npm:7.27.2" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@babel/parser": "npm:^7.27.2" + "@babel/types": "npm:^7.27.1" + checksum: 10/fed15a84beb0b9340e5f81566600dbee5eccd92e4b9cc42a944359b1aa1082373391d9d5fc3656981dff27233ec935d0bc96453cf507f60a4b079463999244d8 + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.3, @babel/traverse@npm:^7.28.4, @babel/traverse@npm:^7.7.2": + version: 7.28.4 + resolution: "@babel/traverse@npm:7.28.4" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@babel/generator": "npm:^7.28.3" + "@babel/helper-globals": "npm:^7.28.0" + "@babel/parser": "npm:^7.28.4" + "@babel/template": "npm:^7.27.2" + "@babel/types": "npm:^7.28.4" + debug: "npm:^4.3.1" + checksum: 10/c3099364b7b1c36bcd111099195d4abeef16499e5defb1e56766b754e8b768c252e856ed9041665158aa1b31215fc6682632756803c8fa53405381ec08c4752b + languageName: node + linkType: hard + +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.4, @babel/types@npm:^7.3.3": + version: 7.28.4 + resolution: "@babel/types@npm:7.28.4" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.27.1" + checksum: 10/db50bf257aafa5d845ad16dae0587f57d596e4be4cbb233ea539976a4c461f9fbcc0bf3d37adae3f8ce5dcb4001462aa608f3558161258b585f6ce6ce21a2e45 + languageName: node + linkType: hard + +"@bcoe/v8-coverage@npm:^0.2.3": + version: 0.2.3 + resolution: "@bcoe/v8-coverage@npm:0.2.3" + checksum: 10/1a1f0e356a3bb30b5f1ced6f79c413e6ebacf130421f15fac5fcd8be5ddf98aedb4404d7f5624e3285b700e041f9ef938321f3ca4d359d5b716f96afa120d88d + languageName: node + linkType: hard + +"@colors/colors@npm:1.5.0": + version: 1.5.0 + resolution: "@colors/colors@npm:1.5.0" + checksum: 10/9d226461c1e91e95f067be2bdc5e6f99cfe55a721f45afb44122e23e4b8602eeac4ff7325af6b5a369f36396ee1514d3809af3f57769066d80d83790d8e53339 + languageName: node + linkType: hard + +"@cspotcode/source-map-support@npm:^0.8.0": + version: 0.8.1 + resolution: "@cspotcode/source-map-support@npm:0.8.1" + dependencies: + "@jridgewell/trace-mapping": "npm:0.3.9" + checksum: 10/b6e38a1712fab242c86a241c229cf562195aad985d0564bd352ac404be583029e89e93028ffd2c251d2c407ecac5fb0cbdca94a2d5c10f29ac806ede0508b3ff + languageName: node + linkType: hard + +"@emnapi/core@npm:^1.4.3": + version: 1.5.0 + resolution: "@emnapi/core@npm:1.5.0" + dependencies: + "@emnapi/wasi-threads": "npm:1.1.0" + tslib: "npm:^2.4.0" + checksum: 10/b500a69df001580731b0d355298b58832d44ab176937c0db7d10073a396f7a801ebcca10581f125a1cd88af4e6ecd6fbb04b78629cc703a424218b3a36d7bf50 + languageName: node + linkType: hard + +"@emnapi/runtime@npm:^1.4.3": + version: 1.5.0 + resolution: "@emnapi/runtime@npm:1.5.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/5311ce854306babc77f4bd94c2f973722714a0fab93c126239104ad52dea16a147bfed4c4cff3ca1eb32709607221c25d2f747ae8524cbeb9088058f02ff962b + languageName: node + linkType: hard + +"@emnapi/wasi-threads@npm:1.1.0": + version: 1.1.0 + resolution: "@emnapi/wasi-threads@npm:1.1.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/0d557e75262d2f4c95cb2a456ba0785ef61f919ce488c1d76e5e3acfd26e00c753ef928cd80068363e0c166ba8cc0141305daf0f81aad5afcd421f38f11e0f4e + languageName: node + linkType: hard + +"@es-joy/jsdoccomment@npm:~0.50.2": + version: 0.50.2 + resolution: "@es-joy/jsdoccomment@npm:0.50.2" + dependencies: + "@types/estree": "npm:^1.0.6" + "@typescript-eslint/types": "npm:^8.11.0" + comment-parser: "npm:1.4.1" + esquery: "npm:^1.6.0" + jsdoc-type-pratt-parser: "npm:~4.1.0" + checksum: 10/a309f01bd1691c6991e5efb78057ec9122ef33208fec2464d7b9e5838964b948fa46c9c944a09218a752b49267f05ac15b557018c8a1897fd8df47b944b4537f + languageName: node + linkType: hard + +"@eslint-community/eslint-utils@npm:^4.1.2, @eslint-community/eslint-utils@npm:^4.4.0, @eslint-community/eslint-utils@npm:^4.5.0, @eslint-community/eslint-utils@npm:^4.7.0, @eslint-community/eslint-utils@npm:^4.8.0": + version: 4.9.0 + resolution: "@eslint-community/eslint-utils@npm:4.9.0" + dependencies: + eslint-visitor-keys: "npm:^3.4.3" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 10/89b1eb3137e14c379865e60573f524fcc0ee5c4b0c7cd21090673e75e5a720f14b92f05ab2d02704c2314b67e67b6f96f3bb209ded6b890ced7b667aa4bf1fa2 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0, @eslint-community/regexpp@npm:^4.12.1": + version: 4.12.1 + resolution: "@eslint-community/regexpp@npm:4.12.1" + checksum: 10/c08f1dd7dd18fbb60bdd0d85820656d1374dd898af9be7f82cb00451313402a22d5e30569c150315b4385907cdbca78c22389b2a72ab78883b3173be317620cc + languageName: node + linkType: hard + +"@eslint/config-array@npm:^0.21.0": + version: 0.21.0 + resolution: "@eslint/config-array@npm:0.21.0" + dependencies: + "@eslint/object-schema": "npm:^2.1.6" + debug: "npm:^4.3.1" + minimatch: "npm:^3.1.2" + checksum: 10/f5a499e074ecf4b4a5efdca655418a12079d024b77d02fd35868eeb717c5bfdd8e32c6e8e1dd125330233a878026edda8062b13b4310169ba5bfee9623a67aa0 + languageName: node + linkType: hard + +"@eslint/config-helpers@npm:^0.4.0": + version: 0.4.0 + resolution: "@eslint/config-helpers@npm:0.4.0" + dependencies: + "@eslint/core": "npm:^0.16.0" + checksum: 10/d5fdbf927a77b98d2462f025f8b1a5b610609201f8d1dd47032a2937842f02bf3bdf9cb672025c83a00f3255dfd218172f989caa724853c4a8f434124a6d79ff + languageName: node + linkType: hard + +"@eslint/core@npm:^0.16.0": + version: 0.16.0 + resolution: "@eslint/core@npm:0.16.0" + dependencies: + "@types/json-schema": "npm:^7.0.15" + checksum: 10/3cea45971b2d0114267b6101b673270b5d8047448cc7a8cbfdca0b0245e9d5e081cb25f13551dc7d55a090f98c13b33f0c4999f8ee8ab058537e6037629a0f71 + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^3.3.1": + version: 3.3.1 + resolution: "@eslint/eslintrc@npm:3.3.1" + dependencies: + ajv: "npm:^6.12.4" + debug: "npm:^4.3.2" + espree: "npm:^10.0.1" + globals: "npm:^14.0.0" + ignore: "npm:^5.2.0" + import-fresh: "npm:^3.2.1" + js-yaml: "npm:^4.1.0" + minimatch: "npm:^3.1.2" + strip-json-comments: "npm:^3.1.1" + checksum: 10/cc240addbab3c5fceaa65b2c8d5d4fd77ddbbf472c2f74f0270b9d33263dc9116840b6099c46b64c9680301146250439b044ed79278a1bcc557da412a4e3c1bb + languageName: node + linkType: hard + +"@eslint/js@npm:9.37.0, @eslint/js@npm:^9.11.0": + version: 9.37.0 + resolution: "@eslint/js@npm:9.37.0" + checksum: 10/2ead426ed47af0b914c7d7064eb59fede858483cf9511f78ded840708aca578138f2a6c375916d520f4f2ecf25945f4bd47b8a84e42106b4eb46f7708a36db1d + languageName: node + linkType: hard + +"@eslint/object-schema@npm:^2.1.6": + version: 2.1.6 + resolution: "@eslint/object-schema@npm:2.1.6" + checksum: 10/266085c8d3fa6cd99457fb6350dffb8ee39db9c6baf28dc2b86576657373c92a568aec4bae7d142978e798b74c271696672e103202d47a0c148da39154351ed6 + languageName: node + linkType: hard + +"@eslint/plugin-kit@npm:^0.4.0": + version: 0.4.0 + resolution: "@eslint/plugin-kit@npm:0.4.0" + dependencies: + "@eslint/core": "npm:^0.16.0" + levn: "npm:^0.4.1" + checksum: 10/2c37ca00e352447215aeadcaff5765faead39695f1cb91cd3079a43261b234887caf38edc462811bb3401acf8c156c04882f87740df936838290c705351483be + languageName: node + linkType: hard + +"@ethereumjs/common@npm:^3.2.0": + version: 3.2.0 + resolution: "@ethereumjs/common@npm:3.2.0" + dependencies: + "@ethereumjs/util": "npm:^8.1.0" + crc-32: "npm:^1.2.0" + checksum: 10/b3f612406b6bcefaf9117ceb42eff58d311e2b50205e3d55b4c793d803de517efbc84075e058dc0e2ec27a2bff11dfc279dda1fa2b249ed6ab3973be045898f4 + languageName: node + linkType: hard + +"@ethereumjs/rlp@npm:^4.0.1": + version: 4.0.1 + resolution: "@ethereumjs/rlp@npm:4.0.1" + bin: + rlp: bin/rlp + checksum: 10/bfdffd634ce72f3b17e3d085d071f2fe7ce9680aebdf10713d74b30afd80ef882d17f19ff7175fcb049431a56e800bd3558d3b028bd0d82341927edb303ab450 + languageName: node + linkType: hard + +"@ethereumjs/tx@npm:^4.2.0": + version: 4.2.0 + resolution: "@ethereumjs/tx@npm:4.2.0" + dependencies: + "@ethereumjs/common": "npm:^3.2.0" + "@ethereumjs/rlp": "npm:^4.0.1" + "@ethereumjs/util": "npm:^8.1.0" + ethereum-cryptography: "npm:^2.0.0" + checksum: 10/cbd2ffc3ef76ca5416d58f2f694858d9fcac946e6a107fef44cf3f308a7c9fcc996a6847868609354d72d5b356faee68408e9d5601c4c4f7dad8e18cb2c24a95 + languageName: node + linkType: hard + +"@ethereumjs/util@npm:^8.1.0": + version: 8.1.0 + resolution: "@ethereumjs/util@npm:8.1.0" + dependencies: + "@ethereumjs/rlp": "npm:^4.0.1" + ethereum-cryptography: "npm:^2.0.0" + micro-ftch: "npm:^0.3.1" + checksum: 10/cc35338932e49b15e54ca6e548b32a1f48eed7d7e1d34ee743e4d3600dd616668bd50f70139e86c5c35f55aac35fba3b6cc4e6f679cf650aeba66bf93016200c + languageName: node + linkType: hard + +"@humanfs/core@npm:^0.19.1": + version: 0.19.1 + resolution: "@humanfs/core@npm:0.19.1" + checksum: 10/270d936be483ab5921702623bc74ce394bf12abbf57d9145a69e8a0d1c87eb1c768bd2d93af16c5705041e257e6d9cc7529311f63a1349f3678abc776fc28523 + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.7 + resolution: "@humanfs/node@npm:0.16.7" + dependencies: + "@humanfs/core": "npm:^0.19.1" + "@humanwhocodes/retry": "npm:^0.4.0" + checksum: 10/b3633d3dce898592cac515ba5e6693c78e6be92863541d3eaf2c009b10f52b2fa62ff6e6e06f240f2447ddbe7b5f1890bc34e9308470675c876eee207553a08d + languageName: node + linkType: hard + +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: 10/e993950e346331e5a32eefb27948ecdee2a2c4ab3f072b8f566cd213ef485dd50a3ca497050608db91006f5479e43f91a439aef68d2a313bd3ded06909c7c5b3 + languageName: node + linkType: hard + +"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2": + version: 0.4.3 + resolution: "@humanwhocodes/retry@npm:0.4.3" + checksum: 10/0b32cfd362bea7a30fbf80bb38dcaf77fee9c2cae477ee80b460871d03590110ac9c77d654f04ec5beaf71b6f6a89851bdf6c1e34ccdf2f686bd86fcd97d9e61 + languageName: node + linkType: hard + +"@isaacs/balanced-match@npm:^4.0.1": + version: 4.0.1 + resolution: "@isaacs/balanced-match@npm:4.0.1" + checksum: 10/102fbc6d2c0d5edf8f6dbf2b3feb21695a21bc850f11bc47c4f06aa83bd8884fde3fe9d6d797d619901d96865fdcb4569ac2a54c937992c48885c5e3d9967fe8 + languageName: node + linkType: hard + +"@isaacs/brace-expansion@npm:^5.0.0": + version: 5.0.0 + resolution: "@isaacs/brace-expansion@npm:5.0.0" + dependencies: + "@isaacs/balanced-match": "npm:^4.0.1" + checksum: 10/cf3b7f206aff12128214a1df764ac8cdbc517c110db85249b945282407e3dfc5c6e66286383a7c9391a059fc8e6e6a8ca82262fc9d2590bd615376141fbebd2d + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 10/e9ed5fd27c3aec1095e3a16e0c0cf148d1fee55a38665c35f7b3f86a9b5d00d042ddaabc98e8a1cb7463b9378c15f22a94eb35e99469c201453eb8375191f243 + languageName: node + linkType: hard + +"@istanbuljs/load-nyc-config@npm:^1.0.0": + version: 1.1.0 + resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" + dependencies: + camelcase: "npm:^5.3.1" + find-up: "npm:^4.1.0" + get-package-type: "npm:^0.1.0" + js-yaml: "npm:^3.13.1" + resolve-from: "npm:^5.0.0" + checksum: 10/b000a5acd8d4fe6e34e25c399c8bdbb5d3a202b4e10416e17bfc25e12bab90bb56d33db6089ae30569b52686f4b35ff28ef26e88e21e69821d2b85884bd055b8 + languageName: node + linkType: hard + +"@istanbuljs/schema@npm:^0.1.2": + version: 0.1.3 + resolution: "@istanbuljs/schema@npm:0.1.3" + checksum: 10/a9b1e49acdf5efc2f5b2359f2df7f90c5c725f2656f16099e8b2cd3a000619ecca9fc48cf693ba789cf0fd989f6e0df6a22bc05574be4223ecdbb7997d04384b + languageName: node + linkType: hard + +"@jest/console@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/console@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + jest-message-util: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + slash: "npm:^3.0.0" + checksum: 10/f724ff9693b09711fded8b87145c3446091bde87f572e210667c2b8290b5364c776f3a99c7d1fd6d5642f7f9424d5acc312c12e9cc4da2ef0260d34547869fdd + languageName: node + linkType: hard + +"@jest/core@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/core@npm:27.5.1" + dependencies: + "@jest/console": "npm:^27.5.1" + "@jest/reporters": "npm:^27.5.1" + "@jest/test-result": "npm:^27.5.1" + "@jest/transform": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + ansi-escapes: "npm:^4.2.1" + chalk: "npm:^4.0.0" + emittery: "npm:^0.8.1" + exit: "npm:^0.1.2" + graceful-fs: "npm:^4.2.9" + jest-changed-files: "npm:^27.5.1" + jest-config: "npm:^27.5.1" + jest-haste-map: "npm:^27.5.1" + jest-message-util: "npm:^27.5.1" + jest-regex-util: "npm:^27.5.1" + jest-resolve: "npm:^27.5.1" + jest-resolve-dependencies: "npm:^27.5.1" + jest-runner: "npm:^27.5.1" + jest-runtime: "npm:^27.5.1" + jest-snapshot: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + jest-validate: "npm:^27.5.1" + jest-watcher: "npm:^27.5.1" + micromatch: "npm:^4.0.4" + rimraf: "npm:^3.0.0" + slash: "npm:^3.0.0" + strip-ansi: "npm:^6.0.0" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: 10/79eb63c3197336c39de6a3341d3f5e7dbca7e20796bd4ee3d725e4ef2832f4d07242898a8af6c9de19ebd700983385a3df16c024b4497f8beb666c8ffe96ccb4 + languageName: node + linkType: hard + +"@jest/environment@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/environment@npm:27.5.1" + dependencies: + "@jest/fake-timers": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + jest-mock: "npm:^27.5.1" + checksum: 10/74a2a4427f82b096c4f7223c56a27f64487ee4639b017129f31e99ebb2e9a614eb365ec77c3701d6eedc1c8d711ad2dd4b31d6dfad72cbb6d73a4f1fdc4a86cb + languageName: node + linkType: hard + +"@jest/fake-timers@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/fake-timers@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + "@sinonjs/fake-timers": "npm:^8.0.1" + "@types/node": "npm:*" + jest-message-util: "npm:^27.5.1" + jest-mock: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + checksum: 10/dd8b736edbc8da77af3ca14ffaa2f331168618db7b879a3a07a4667af11ae4ff840f64a61e3828e217ee94f06d5a9ba30bf19e5103bb74e193b8216ce4c0708d + languageName: node + linkType: hard + +"@jest/globals@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/globals@npm:27.5.1" + dependencies: + "@jest/environment": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + expect: "npm:^27.5.1" + checksum: 10/f3b06e9b81686d7a5dd7bafb229cba73bdc90d3e16815deebf302d3a402ac29a1e9bafa274d908caefe7083938402619974c89420d247ab8739acd652c11b16d + languageName: node + linkType: hard + +"@jest/reporters@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/reporters@npm:27.5.1" + dependencies: + "@bcoe/v8-coverage": "npm:^0.2.3" + "@jest/console": "npm:^27.5.1" + "@jest/test-result": "npm:^27.5.1" + "@jest/transform": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + collect-v8-coverage: "npm:^1.0.0" + exit: "npm:^0.1.2" + glob: "npm:^7.1.2" + graceful-fs: "npm:^4.2.9" + istanbul-lib-coverage: "npm:^3.0.0" + istanbul-lib-instrument: "npm:^5.1.0" + istanbul-lib-report: "npm:^3.0.0" + istanbul-lib-source-maps: "npm:^4.0.0" + istanbul-reports: "npm:^3.1.3" + jest-haste-map: "npm:^27.5.1" + jest-resolve: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + jest-worker: "npm:^27.5.1" + slash: "npm:^3.0.0" + source-map: "npm:^0.6.0" + string-length: "npm:^4.0.1" + terminal-link: "npm:^2.0.0" + v8-to-istanbul: "npm:^8.1.0" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: 10/d49aea4e5b09f9a316f0ff303d11f2db057cadaf370e3e706c024e4ea7f270899cccf7488711def4a930bc23e4f4676f406d1c646f8c6656de4c43dd40652877 + languageName: node + linkType: hard + +"@jest/source-map@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/source-map@npm:27.5.1" + dependencies: + callsites: "npm:^3.0.0" + graceful-fs: "npm:^4.2.9" + source-map: "npm:^0.6.0" + checksum: 10/90b1f4212b7191d594275c9b9aae18319b944e4ed018af74a1661fd9b783983074d00369a111274697b87193aa2b084f0f022a265d070f4a66d39d06d14a0336 + languageName: node + linkType: hard + +"@jest/test-result@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/test-result@npm:27.5.1" + dependencies: + "@jest/console": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/istanbul-lib-coverage": "npm:^2.0.0" + collect-v8-coverage: "npm:^1.0.0" + checksum: 10/43cdc31b39857d4d6487345f1bfb9c97157ddfb7ff3e3b843f3999d4a3be5b1e7c1079302459ea627976fa9da7462426dfb26cf231ef2b6eb79bc80b67361c23 + languageName: node + linkType: hard + +"@jest/test-sequencer@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/test-sequencer@npm:27.5.1" + dependencies: + "@jest/test-result": "npm:^27.5.1" + graceful-fs: "npm:^4.2.9" + jest-haste-map: "npm:^27.5.1" + jest-runtime: "npm:^27.5.1" + checksum: 10/74c9c773eb0d8de581e17a7ea1d9173b835c0c91b40665caa42fd68931a2ee7429f9ed59c97a15855d3ad46024a17e7387ad4b900d4540890a7681d4a8a42bdd + languageName: node + linkType: hard + +"@jest/transform@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/transform@npm:27.5.1" + dependencies: + "@babel/core": "npm:^7.1.0" + "@jest/types": "npm:^27.5.1" + babel-plugin-istanbul: "npm:^6.1.1" + chalk: "npm:^4.0.0" + convert-source-map: "npm:^1.4.0" + fast-json-stable-stringify: "npm:^2.0.0" + graceful-fs: "npm:^4.2.9" + jest-haste-map: "npm:^27.5.1" + jest-regex-util: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + micromatch: "npm:^4.0.4" + pirates: "npm:^4.0.4" + slash: "npm:^3.0.0" + source-map: "npm:^0.6.1" + write-file-atomic: "npm:^3.0.0" + checksum: 10/9e0bec99971d28fc205e5e282be384a0269760b8452aa94e3d400465819b6c790c862ec5597d8c9439f2da97e68c0c4cec071340ff3e4c4414a34e5b2a19074a + languageName: node + linkType: hard + +"@jest/types@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/types@npm:27.5.1" + dependencies: + "@types/istanbul-lib-coverage": "npm:^2.0.0" + "@types/istanbul-reports": "npm:^3.0.0" + "@types/node": "npm:*" + "@types/yargs": "npm:^16.0.0" + chalk: "npm:^4.0.0" + checksum: 10/d3ca1655673539c54665f3e9135dc70887feb6b667b956e712c38f42e513ae007d3593b8075aecea8f2db7119f911773010f17f93be070b1725fbc6225539b6e + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.13 + resolution: "@jridgewell/gen-mapping@npm:0.3.13" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10/902f8261dcf450b4af7b93f9656918e02eec80a2169e155000cb2059f90113dd98f3ccf6efc6072cee1dd84cac48cade51da236972d942babc40e4c23da4d62a + languageName: node + linkType: hard + +"@jridgewell/remapping@npm:^2.3.5": + version: 2.3.5 + resolution: "@jridgewell/remapping@npm:2.3.5" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10/c2bb01856e65b506d439455f28aceacf130d6c023d1d4e3b48705e88def3571753e1a887daa04b078b562316c92d26ce36408a60534bceca3f830aec88a339ad + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 10/97106439d750a409c22c8bff822d648f6a71f3aa9bc8e5129efdc36343cd3096ddc4eeb1c62d2fe48e9bdd4db37b05d4646a17114ecebd3bbcacfa2de51c3c1d + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10/5d9d207b462c11e322d71911e55e21a4e2772f71ffe8d6f1221b8eb5ae6774458c1d242f897fb0814e8714ca9a6b498abfa74dfe4f434493342902b1a48b33a5 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:0.3.9": + version: 0.3.9 + resolution: "@jridgewell/trace-mapping@npm:0.3.9" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.0.3" + "@jridgewell/sourcemap-codec": "npm:^1.4.10" + checksum: 10/83deafb8e7a5ca98993c2c6eeaa93c270f6f647a4c0dc00deb38c9cf9b2d3b7bf15e8839540155247ef034a052c0ec4466f980bf0c9e2ab63b97d16c0cedd3ff + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.28": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10/da0283270e691bdb5543806077548532791608e52386cfbbf3b9e8fb00457859d1bd01d512851161c886eb3a2f3ce6fd9bcf25db8edf3bddedd275bd4a88d606 + languageName: node + linkType: hard + +"@lavamoat/aa@npm:^4.3.4": + version: 4.3.4 + resolution: "@lavamoat/aa@npm:4.3.4" + dependencies: + resolve: "npm:1.22.10" + bin: + lavamoat-ls: src/cli.js + checksum: 10/062e85d6e13f4f59be6bc632d19166e5fdc0c2402aa4d7c2ce39308542d6b4daf8721f498360520abb6707e5590b6755f767c32c075291effeb24c48ed3a18b4 + languageName: node + linkType: hard + +"@lavamoat/allow-scripts@npm:^3.0.4": + version: 3.4.0 + resolution: "@lavamoat/allow-scripts@npm:3.4.0" + dependencies: + "@lavamoat/aa": "npm:^4.3.4" + "@npmcli/run-script": "npm:8.1.0" + bin-links: "npm:4.0.4" + npm-normalize-package-bin: "npm:3.0.1" + type-fest: "npm:4.41.0" + yargs: "npm:17.7.2" + bin: + allow-scripts: src/cli.js + checksum: 10/e845200f5ef9136d26ba370b49aecc23b1677d0fc5d9613c689ae3e8d09e9a7f0dacdef2a72f2a832c66eda4945b2faa9b72428bee216f98a2846c32cf5350d9 + languageName: node + linkType: hard + +"@metamask/auto-changelog@npm:^3.4.4": + version: 3.4.4 + resolution: "@metamask/auto-changelog@npm:3.4.4" + dependencies: + diff: "npm:^5.0.0" + execa: "npm:^5.1.1" + prettier: "npm:^2.8.8" + semver: "npm:^7.3.5" + yargs: "npm:^17.0.1" + bin: + auto-changelog: dist/cli.js + checksum: 10/70e98529a153ebeab10410dbc3f567014999f77ed82f2b52f1b36501b28a4e3614c809a90c89600a739d7710595bfecc30e2260410e6afac7539f8db65a48f2c + languageName: node + linkType: hard + +"@metamask/eslint-config-jest@npm:^14.0.0": + version: 14.0.0 + resolution: "@metamask/eslint-config-jest@npm:14.0.0" + dependencies: + "@eslint/js": "npm:^9.11.0" + globals: "npm:^15.9.0" + peerDependencies: + "@metamask/eslint-config": ^14.0.0 + eslint: ^9.11.0 + eslint-plugin-jest: ^28.8.3 + checksum: 10/e7c4f14ff8eae8c1311cd1a941217c39bacf249650b1953138a958472af609a8396722e7b1a0c86386d07f92d7570c3e29754335fe4ef8608a9abf03c7aff6fb + languageName: node + linkType: hard + +"@metamask/eslint-config-nodejs@npm:^14.0.0": + version: 14.0.0 + resolution: "@metamask/eslint-config-nodejs@npm:14.0.0" + dependencies: + "@eslint/js": "npm:^9.11.0" + globals: "npm:^15.9.0" + peerDependencies: + "@metamask/eslint-config": ^14.0.0 + eslint: ^9.11.0 + eslint-plugin-n: ^17.10.3 + checksum: 10/62a69e0a258b6b0ef8cbb844a3420115ff213648f55e1b3863dd29fa5892de8013f8157317e8279f68b7e82c69c97edc15c0040ad49469756393a711d91b0fff + languageName: node + linkType: hard + +"@metamask/eslint-config-typescript@npm:^14.0.0": + version: 14.0.0 + resolution: "@metamask/eslint-config-typescript@npm:14.0.0" + dependencies: + "@eslint/js": "npm:^9.11.0" + peerDependencies: + "@metamask/eslint-config": ^14.0.0 + eslint: ^9.11.0 + eslint-import-resolver-typescript: ^3.6.3 + eslint-plugin-import-x: ^4.3.0 + eslint-plugin-jsdoc: ^50.2.4 + typescript: ">=4.8.4 <5.6" + typescript-eslint: ^8.6.0 + checksum: 10/cbf0a9e8523292d41140f90630863d034301422f16e6a42e5881c3593e83c07d0394787563d3e88fee02aa22042a9ca974363d3f192374e31bb0729c6ca8734e + languageName: node + linkType: hard + +"@metamask/eslint-config@npm:^14.0.0": + version: 14.0.0 + resolution: "@metamask/eslint-config@npm:14.0.0" + dependencies: + "@eslint/js": "npm:^9.11.0" + globals: "npm:^15.9.0" + peerDependencies: + eslint: ^9.11.0 + eslint-config-prettier: ^9.1.0 + eslint-plugin-import-x: ^4.3.0 + eslint-plugin-jsdoc: ^50.2.4 + eslint-plugin-prettier: ^5.2.1 + eslint-plugin-promise: ^7.1.0 + prettier: ^3.3.3 + checksum: 10/b7ae38bf777e9341b8dfac75e98159fb5d5da7d913af2312b586c82370c84acff68ee78e3b104a3577a971d593c6039bd909c8d7ca41cb7a69ed069871080c8a + languageName: node + linkType: hard + +"@metamask/eth-block-tracker@workspace:.": + version: 0.0.0-use.local + resolution: "@metamask/eth-block-tracker@workspace:." + dependencies: + "@arethetypeswrong/cli": "npm:^0.15.3" + "@jest/types": "npm:^27.5.1" + "@lavamoat/allow-scripts": "npm:^3.0.4" + "@metamask/auto-changelog": "npm:^3.4.4" + "@metamask/eslint-config": "npm:^14.0.0" + "@metamask/eslint-config-jest": "npm:^14.0.0" + "@metamask/eslint-config-nodejs": "npm:^14.0.0" + "@metamask/eslint-config-typescript": "npm:^14.0.0" + "@metamask/eth-json-rpc-provider": "npm:^5.0.0" + "@metamask/json-rpc-engine": "npm:^10.0.0" + "@metamask/safe-event-emitter": "npm:^3.1.1" + "@metamask/utils": "npm:^11.0.1" + "@ts-bridge/cli": "npm:^0.6.3" + "@types/jest": "npm:^27.4.1" + "@types/json-rpc-random-id": "npm:^1.0.1" + "@types/node": "npm:^18.18" + "@yarnpkg/types": "npm:^4.0.1" + depcheck: "npm:^1.4.3" + eslint: "npm:^9.11.0" + eslint-config-prettier: "npm:^9.1.0" + eslint-import-resolver-typescript: "npm:^3.6.3" + eslint-plugin-import-x: "npm:^4.3.0" + eslint-plugin-jest: "npm:^28.8.3" + eslint-plugin-jsdoc: "npm:^50.2.4" + eslint-plugin-n: "npm:^17.10.3" + eslint-plugin-prettier: "npm:^5.2.1" + eslint-plugin-promise: "npm:^7.1.0" + jest: "npm:^27.5.1" + json-rpc-random-id: "npm:^1.0.1" + prettier: "npm:^3.3.3" + prettier-plugin-packagejson: "npm:^2.5.8" + rimraf: "npm:^3.0.2" + ts-jest: "npm:^27.1.4" + ts-node: "npm:^10.9.1" + typedoc: "npm:^0.24.8" + typescript: "npm:~5.2.2" + typescript-eslint: "npm:^8.7.0" + languageName: unknown + linkType: soft + +"@metamask/eth-json-rpc-provider@npm:^5.0.0": + version: 5.0.0 + resolution: "@metamask/eth-json-rpc-provider@npm:5.0.0" + dependencies: + "@metamask/json-rpc-engine": "npm:^10.1.0" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/safe-event-emitter": "npm:^3.0.0" + "@metamask/utils": "npm:^11.8.0" + uuid: "npm:^8.3.2" + checksum: 10/b09a4c06bf570c09b045583733ba2cf5047937e84d42b4c13f8b6a1e39acae083f032aed16c17b37dd4b86cab16f6e52b0ba788d4f3a63c4301a614d69cad937 + languageName: node + linkType: hard + +"@metamask/json-rpc-engine@npm:^10.0.0, @metamask/json-rpc-engine@npm:^10.1.0": + version: 10.1.0 + resolution: "@metamask/json-rpc-engine@npm:10.1.0" + dependencies: + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/safe-event-emitter": "npm:^3.0.0" + "@metamask/utils": "npm:^11.8.0" + checksum: 10/af41cd52074286e1d82917cc41b65954f79d96158c70c7426f89c572f9178b31c674658b6079f13df22a47d9d7743ddcfa8180df6e6cbabc30d848a172186d32 + languageName: node + linkType: hard + +"@metamask/rpc-errors@npm:^7.0.2": + version: 7.0.2 + resolution: "@metamask/rpc-errors@npm:7.0.2" + dependencies: + "@metamask/utils": "npm:^11.0.1" + fast-safe-stringify: "npm:^2.0.6" + checksum: 10/daf77a48b3f970585ef1f2efe3383d620fd4bffb550e8c6378b04a052f6948724a0b7e8a3e45b8b73298c70c4b9594b71fe0272664ea99620fe36e23443f8545 + languageName: node + linkType: hard + +"@metamask/safe-event-emitter@npm:^3.0.0, @metamask/safe-event-emitter@npm:^3.1.1": + version: 3.1.2 + resolution: "@metamask/safe-event-emitter@npm:3.1.2" + checksum: 10/8ef7579f9317eb5c94ecf3e6abb8d13b119af274b678805eac76abe4c0667bfdf539f385e552bb973e96333b71b77aa7c787cb3fce9cd5fb4b00f1dbbabf880d + languageName: node + linkType: hard + +"@metamask/superstruct@npm:^3.1.0": + version: 3.1.0 + resolution: "@metamask/superstruct@npm:3.1.0" + checksum: 10/5066fe228d5f11da387606d7f9545de2b473ab5a9e0f1bb8aea2f52d3e2c9d25e427151acde61f4a2de80a07a9871fe9505ad06abca6a61b7c3b54ed5c403b01 + languageName: node + linkType: hard + +"@metamask/utils@npm:^11.0.1, @metamask/utils@npm:^11.8.0": + version: 11.8.0 + resolution: "@metamask/utils@npm:11.8.0" + dependencies: + "@ethereumjs/tx": "npm:^4.2.0" + "@metamask/superstruct": "npm:^3.1.0" + "@noble/hashes": "npm:^1.3.1" + "@scure/base": "npm:^1.1.3" + "@types/debug": "npm:^4.1.7" + "@types/lodash": "npm:^4.17.20" + debug: "npm:^4.3.4" + lodash: "npm:^4.17.21" + pony-cause: "npm:^2.1.10" + semver: "npm:^7.5.4" + uuid: "npm:^9.0.1" + checksum: 10/d5a9d8c04223fc62b0d4a078b505e062f5d1d47e752df36802189bec19a9e68aee7a9b0df9b15e7e6fa15fd9d65f61c7e4909604209dddc21f0943cd9a2fd5d1 + languageName: node + linkType: hard + +"@napi-rs/wasm-runtime@npm:^0.2.11": + version: 0.2.12 + resolution: "@napi-rs/wasm-runtime@npm:0.2.12" + dependencies: + "@emnapi/core": "npm:^1.4.3" + "@emnapi/runtime": "npm:^1.4.3" + "@tybys/wasm-util": "npm:^0.10.0" + checksum: 10/5fd518182427980c28bc724adf06c5f32f9a8915763ef560b5f7d73607d30cd15ac86d0cbd2eb80d4cfab23fc80d0876d89ca36a9daadcb864bc00917c94187c + languageName: node + linkType: hard + +"@noble/curves@npm:1.0.0, @noble/curves@npm:~1.0.0": + version: 1.0.0 + resolution: "@noble/curves@npm:1.0.0" + dependencies: + "@noble/hashes": "npm:1.3.0" + checksum: 10/6db884e03b3f6c773317bcf4611bf1d9adb8084eab0bf6158407cc998c9c5dcb0560741bdd0aaca9c4393c9e8a3dcd7592b4148a6cfd561d0a00addb77a6129f + languageName: node + linkType: hard + +"@noble/hashes@npm:1.3.0": + version: 1.3.0 + resolution: "@noble/hashes@npm:1.3.0" + checksum: 10/4680a71941c06ac897cc9eab9d229717d5af1147cea5e8cd4942190c817426ad3173ded750d897f58d764b869f9347d4fc3f6b3c16574541ac81906efa9ddc36 + languageName: node + linkType: hard + +"@noble/hashes@npm:^1.3.1, @noble/hashes@npm:~1.3.0": + version: 1.3.2 + resolution: "@noble/hashes@npm:1.3.2" + checksum: 10/685f59d2d44d88e738114b71011d343a9f7dce9dfb0a121f1489132f9247baa60bc985e5ec6f3213d114fbd1e1168e7294644e46cbd0ce2eba37994f28eeb51b + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 10/6ab2a9b8a1d67b067922c36f259e3b3dfd6b97b219c540877a4944549a4d49ea5ceba5663905ab5289682f1f3c15ff441d02f0447f620a42e1cb5e1937174d4b + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 10/012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 10/40033e33e96e97d77fba5a238e4bba4487b8284678906a9f616b5579ddaf868a18874c0054a75402c9fbaaa033a25ceae093af58c9c30278e35c23c9479e79b0 + languageName: node + linkType: hard + +"@nolyfill/is-core-module@npm:1.0.39": + version: 1.0.39 + resolution: "@nolyfill/is-core-module@npm:1.0.39" + checksum: 10/0d6e098b871eca71d875651288e1f0fa770a63478b0b50479c99dc760c64175a56b5b04f58d5581bbcc6b552b8191ab415eada093d8df9597ab3423c8cac1815 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^2.0.0": + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.3" + checksum: 10/96fc0036b101bae5032dc2a4cd832efb815ce9b33f9ee2f29909ee49d96a0026b3565f73c507a69eb8603f5cb32e0ae45a70cab1e2655990a4e06ae99f7f572a + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.1 + resolution: "@npmcli/fs@npm:3.1.1" + dependencies: + semver: "npm:^7.3.5" + checksum: 10/1e0e04087049b24b38bc0b30d87a9388ee3ca1d3fdfc347c2f77d84fcfe6a51f250bc57ba2c1f614d7e4285c6c62bf8c769bc19aa0949ea39e5b043ee023b0bd + languageName: node + linkType: hard + +"@npmcli/git@npm:^5.0.0": + version: 5.0.8 + resolution: "@npmcli/git@npm:5.0.8" + dependencies: + "@npmcli/promise-spawn": "npm:^7.0.0" + ini: "npm:^4.1.3" + lru-cache: "npm:^10.0.1" + npm-pick-manifest: "npm:^9.0.0" + proc-log: "npm:^4.0.0" + promise-inflight: "npm:^1.0.1" + promise-retry: "npm:^2.0.1" + semver: "npm:^7.3.5" + which: "npm:^4.0.0" + checksum: 10/e6f94175fb9dde13d84849b29b32ffb4c4df968822cc85df2aebfca13bf8ca76f33b1d281911f5bcddc95bccba2f9e795669c736a38de4d9c76efb5047ffb4fb + languageName: node + linkType: hard + +"@npmcli/node-gyp@npm:^3.0.0": + version: 3.0.0 + resolution: "@npmcli/node-gyp@npm:3.0.0" + checksum: 10/dd9fed3e80df8fbb20443f28651a8ed7235f2c15286ecc010e2d3cd392c85912e59ef29218c0b02f098defb4cbc8cdf045aab1d32d5cef6ace289913196ed5df + languageName: node + linkType: hard + +"@npmcli/package-json@npm:^5.0.0": + version: 5.2.1 + resolution: "@npmcli/package-json@npm:5.2.1" + dependencies: + "@npmcli/git": "npm:^5.0.0" + glob: "npm:^10.2.2" + hosted-git-info: "npm:^7.0.0" + json-parse-even-better-errors: "npm:^3.0.0" + normalize-package-data: "npm:^6.0.0" + proc-log: "npm:^4.0.0" + semver: "npm:^7.5.3" + checksum: 10/304a819b93f79a6e0e56cb371961a66d2db72142e310d545ecbbbe4d917025a30601aa8e63a5f0cc28f0fe281c116bdaf79b334619b105a1d027a2b769ecd137 + languageName: node + linkType: hard + +"@npmcli/promise-spawn@npm:^7.0.0": + version: 7.0.2 + resolution: "@npmcli/promise-spawn@npm:7.0.2" + dependencies: + which: "npm:^4.0.0" + checksum: 10/94cbbbeeb20342026c3b68fc8eb09e1600b7645d4e509f2588ef5ea7cff977eb01e628cc8e014595d04a6af4b4bc5c467c950a8135920f39f7c7b57fba43f4e9 + languageName: node + linkType: hard + +"@npmcli/run-script@npm:8.1.0": + version: 8.1.0 + resolution: "@npmcli/run-script@npm:8.1.0" + dependencies: + "@npmcli/node-gyp": "npm:^3.0.0" + "@npmcli/package-json": "npm:^5.0.0" + "@npmcli/promise-spawn": "npm:^7.0.0" + node-gyp: "npm:^10.0.0" + proc-log: "npm:^4.0.0" + which: "npm:^4.0.0" + checksum: 10/256bd580f82b98db93e54065bf9bcc94946be4f2d668a062cf756cb8ea091f58ef7154b3d2450d79738081a150f25cc48f6075351911e672f24ffd34350f02f2 + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 10/115e8ceeec6bc69dff2048b35c0ab4f8bbee12d8bb6c1f4af758604586d802b6e669dcb02dda61d078de42c2b4ddce41b3d9e726d7daa6b4b850f4adbf7333ff + languageName: node + linkType: hard + +"@pkgr/core@npm:^0.2.9": + version: 0.2.9 + resolution: "@pkgr/core@npm:0.2.9" + checksum: 10/bb2fb86977d63f836f8f5b09015d74e6af6488f7a411dcd2bfdca79d76b5a681a9112f41c45bdf88a9069f049718efc6f3900d7f1de66a2ec966068308ae517f + languageName: node + linkType: hard + +"@scure/base@npm:^1.1.3, @scure/base@npm:~1.1.0": + version: 1.1.3 + resolution: "@scure/base@npm:1.1.3" + checksum: 10/cb715fa8cdb043c4d96b6ba0666791d4eb4d033f7b5285a853aba25e0ba94914f05ff5d956029ad060005f9bdd02dab0caef9a0a63f07ed096a2c2a0c0cf9c36 + languageName: node + linkType: hard + +"@scure/bip32@npm:1.3.0": + version: 1.3.0 + resolution: "@scure/bip32@npm:1.3.0" + dependencies: + "@noble/curves": "npm:~1.0.0" + "@noble/hashes": "npm:~1.3.0" + "@scure/base": "npm:~1.1.0" + checksum: 10/1fabcc7f2215910b35980bfc455c03fc4ae7f848efed066fe3867960a8dfceb6141c932496434fc2cfbf385d270ff9efdfce2571992e4584103f82e45ac2103f + languageName: node + linkType: hard + +"@scure/bip39@npm:1.2.0": + version: 1.2.0 + resolution: "@scure/bip39@npm:1.2.0" + dependencies: + "@noble/hashes": "npm:~1.3.0" + "@scure/base": "npm:~1.1.0" + checksum: 10/2a260eefea0b2658c5d3b2cb982479ef650552c3007e57f667b445943c79717eb923c1a104a664b4873bc210aeb59859bf890c3e7b47fb51ed5b94dc96f75105 + languageName: node + linkType: hard + +"@sindresorhus/is@npm:^4.6.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: 10/e7f36ed72abfcd5e0355f7423a72918b9748bb1ef370a59f3e5ad8d40b728b85d63b272f65f63eec1faf417cda89dcb0aeebe94015647b6054659c1442fe5ce0 + languageName: node + linkType: hard + +"@sinonjs/commons@npm:^1.7.0": + version: 1.8.6 + resolution: "@sinonjs/commons@npm:1.8.6" + dependencies: + type-detect: "npm:4.0.8" + checksum: 10/51987338fd8b4d1e135822ad593dd23a3288764aa41d83c695124d512bc38b87eece859078008651ecc7f1df89a7e558a515dc6f02d21a93be4ba50b39a28914 + languageName: node + linkType: hard + +"@sinonjs/fake-timers@npm:^8.0.1": + version: 8.1.0 + resolution: "@sinonjs/fake-timers@npm:8.1.0" + dependencies: + "@sinonjs/commons": "npm:^1.7.0" + checksum: 10/da50ddd68411617fcf72d9fb70b621aa2a6d17faa93a2769c7af390c88b40e045f84544db022dd1ac30a6db115d2a0f96473854d4a106b0174351f22d42910ce + languageName: node + linkType: hard + +"@tootallnate/once@npm:1": + version: 1.1.2 + resolution: "@tootallnate/once@npm:1.1.2" + checksum: 10/e1fb1bbbc12089a0cb9433dc290f97bddd062deadb6178ce9bcb93bb7c1aecde5e60184bc7065aec42fe1663622a213493c48bbd4972d931aae48315f18e1be9 + languageName: node + linkType: hard + +"@ts-bridge/cli@npm:^0.6.3": + version: 0.6.3 + resolution: "@ts-bridge/cli@npm:0.6.3" + dependencies: + "@ts-bridge/resolver": "npm:^0.2.0" + chalk: "npm:^5.3.0" + cjs-module-lexer: "npm:^1.3.1" + yargs: "npm:^17.7.2" + peerDependencies: + typescript: ">=4.8.0" + bin: + ts-bridge: ./dist/index.js + tsbridge: ./dist/index.js + checksum: 10/01cba56ff0f097ca0ef15b79cff80a6be07b7f237e7153f63f7a9acf911583d0a410385fa1711d7b14e3a5e95fed63310b6a743700e7ecc0dd3a2d97a0df75b3 + languageName: node + linkType: hard + +"@ts-bridge/resolver@npm:^0.2.0": + version: 0.2.0 + resolution: "@ts-bridge/resolver@npm:0.2.0" + checksum: 10/d4cfd1f47e9648a5f9c893b1b076adabde3a57cbe81ef823bcbbcc77a122fb6f06d99f40ff48198f8dc766bfc4b3b351d4e87cfcf2db64f7e6db924eb82a5db1 + languageName: node + linkType: hard + +"@tsconfig/node10@npm:^1.0.7": + version: 1.0.8 + resolution: "@tsconfig/node10@npm:1.0.8" + checksum: 10/b8d5fffbc6b17ef64ef74f7fdbccee02a809a063ade785c3648dae59406bc207f70ea2c4296f92749b33019fa36a5ae716e42e49cc7f1bbf0fd147be0d6b970a + languageName: node + linkType: hard + +"@tsconfig/node12@npm:^1.0.7": + version: 1.0.9 + resolution: "@tsconfig/node12@npm:1.0.9" + checksum: 10/a01b2400ab3582b86b589c6d31dcd0c0656f333adecde85d6d7d4086adb059808b82692380bb169546d189bf771ae21d02544a75b57bd6da4a5dd95f8567bec9 + languageName: node + linkType: hard + +"@tsconfig/node14@npm:^1.0.0": + version: 1.0.1 + resolution: "@tsconfig/node14@npm:1.0.1" + checksum: 10/976345e896c0f059867f94f8d0f6ddb8b1844fb62bf36b727de8a9a68f024857e5db97ed51d3325e23e0616a5e48c034ff51a8d595b3fe7e955f3587540489be + languageName: node + linkType: hard + +"@tsconfig/node16@npm:^1.0.2": + version: 1.0.2 + resolution: "@tsconfig/node16@npm:1.0.2" + checksum: 10/ca94d3639714672bbfd55f03521d3f56bb6a25479bd425da81faf21f13e1e9d15f40f97377dedbbf477a5841c5b0c8f4cd1b391f33553d750b9202c54c2c07aa + languageName: node + linkType: hard + +"@tybys/wasm-util@npm:^0.10.0": + version: 0.10.1 + resolution: "@tybys/wasm-util@npm:0.10.1" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/7fe0d239397aebb002ac4855d30c197c06a05ea8df8511350a3a5b1abeefe26167c60eda8a5508337571161e4c4b53d7c1342296123f9607af8705369de9fa7f + languageName: node + linkType: hard + +"@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.14": + version: 7.20.5 + resolution: "@types/babel__core@npm:7.20.5" + dependencies: + "@babel/parser": "npm:^7.20.7" + "@babel/types": "npm:^7.20.7" + "@types/babel__generator": "npm:*" + "@types/babel__template": "npm:*" + "@types/babel__traverse": "npm:*" + checksum: 10/c32838d280b5ab59d62557f9e331d3831f8e547ee10b4f85cb78753d97d521270cebfc73ce501e9fb27fe71884d1ba75e18658692c2f4117543f0fc4e3e118b3 + languageName: node + linkType: hard + +"@types/babel__generator@npm:*": + version: 7.6.4 + resolution: "@types/babel__generator@npm:7.6.4" + dependencies: + "@babel/types": "npm:^7.0.0" + checksum: 10/34f361a0d54a0d85ea4c4b5122c4025a5738fe6795361c85f07a4f8f9add383de640e8611edeeb8339db8203c2d64bff30be266bdcfe3cf777c19e8d34f9cebc + languageName: node + linkType: hard + +"@types/babel__template@npm:*": + version: 7.4.1 + resolution: "@types/babel__template@npm:7.4.1" + dependencies: + "@babel/parser": "npm:^7.1.0" + "@babel/types": "npm:^7.0.0" + checksum: 10/649fe8b42c2876be1fd28c6ed9b276f78152d5904ec290b6c861d9ef324206e0a5c242e8305c421ac52ecf6358fa7e32ab7a692f55370484825c1df29b1596ee + languageName: node + linkType: hard + +"@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.4, @types/babel__traverse@npm:^7.0.6": + version: 7.28.0 + resolution: "@types/babel__traverse@npm:7.28.0" + dependencies: + "@babel/types": "npm:^7.28.2" + checksum: 10/371c5e1b40399ef17570e630b2943617b84fafde2860a56f0ebc113d8edb1d0534ade0175af89eda1ae35160903c33057ed42457e165d4aa287fedab2c82abcf + languageName: node + linkType: hard + +"@types/debug@npm:^4.1.7": + version: 4.1.7 + resolution: "@types/debug@npm:4.1.7" + dependencies: + "@types/ms": "npm:*" + checksum: 10/0a7b89d8ed72526858f0b61c6fd81f477853e8c4415bb97f48b1b5545248d2ae389931680b94b393b993a7cfe893537a200647d93defe6d87159b96812305adc + languageName: node + linkType: hard + +"@types/estree@npm:^1.0.6": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: 10/25a4c16a6752538ffde2826c2cc0c6491d90e69cd6187bef4a006dd2c3c45469f049e643d7e516c515f21484dc3d48fd5c870be158a5beb72f5baf3dc43e4099 + languageName: node + linkType: hard + +"@types/graceful-fs@npm:^4.1.2": + version: 4.1.9 + resolution: "@types/graceful-fs@npm:4.1.9" + dependencies: + "@types/node": "npm:*" + checksum: 10/79d746a8f053954bba36bd3d94a90c78de995d126289d656fb3271dd9f1229d33f678da04d10bce6be440494a5a73438e2e363e92802d16b8315b051036c5256 + languageName: node + linkType: hard + +"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1": + version: 2.0.4 + resolution: "@types/istanbul-lib-coverage@npm:2.0.4" + checksum: 10/a25d7589ee65c94d31464c16b72a9dc81dfa0bea9d3e105ae03882d616e2a0712a9c101a599ec482d297c3591e16336962878cb3eb1a0a62d5b76d277a890ce7 + languageName: node + linkType: hard + +"@types/istanbul-lib-report@npm:*": + version: 3.0.0 + resolution: "@types/istanbul-lib-report@npm:3.0.0" + dependencies: + "@types/istanbul-lib-coverage": "npm:*" + checksum: 10/f121dcac8a6b8184f3cab97286d8d519f1937fa8620ada5dbc43b699d602b8be289e4a4bccbd6ee1aade6869d3c9fb68bf04c6fdca8c5b0c4e7e314c31c7900a + languageName: node + linkType: hard + +"@types/istanbul-reports@npm:^3.0.0": + version: 3.0.1 + resolution: "@types/istanbul-reports@npm:3.0.1" + dependencies: + "@types/istanbul-lib-report": "npm:*" + checksum: 10/f1ad54bc68f37f60b30c7915886b92f86b847033e597f9b34f2415acdbe5ed742fa559a0a40050d74cdba3b6a63c342cac1f3a64dba5b68b66a6941f4abd7903 + languageName: node + linkType: hard + +"@types/jest@npm:^27.4.1": + version: 27.5.2 + resolution: "@types/jest@npm:27.5.2" + dependencies: + jest-matcher-utils: "npm:^27.0.0" + pretty-format: "npm:^27.0.0" + checksum: 10/8608696fbdea81bc9a600d1c5aeb290063357eaa55c0174e7db15087c4f483113b35f8b4c4ae364d2632cfed15a4dd674786254826b946c896de5612c8cb1a26 + languageName: node + linkType: hard + +"@types/json-rpc-random-id@npm:^1.0.1": + version: 1.0.1 + resolution: "@types/json-rpc-random-id@npm:1.0.1" + checksum: 10/622a1e1bd6aa8b6260806258bbe66dd7bb0069b7e68d8252a49a11c2d1ac6dca2b3f2eb17a84d49dcad59f23ceeb9de0482e5016b27f26fcde763383e9345e26 + languageName: node + linkType: hard + +"@types/json-schema@npm:^7.0.15": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 10/1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 + languageName: node + linkType: hard + +"@types/lodash@npm:^4.17.20": + version: 4.17.20 + resolution: "@types/lodash@npm:4.17.20" + checksum: 10/8cd8ad3bd78d2e06a93ae8d6c9907981d5673655fec7cb274a4d9a59549aab5bb5b3017361280773b8990ddfccf363e14d1b37c97af8a9fe363de677f9a61524 + languageName: node + linkType: hard + +"@types/minimatch@npm:^3.0.3": + version: 3.0.5 + resolution: "@types/minimatch@npm:3.0.5" + checksum: 10/c41d136f67231c3131cf1d4ca0b06687f4a322918a3a5adddc87ce90ed9dbd175a3610adee36b106ae68c0b92c637c35e02b58c8a56c424f71d30993ea220b92 + languageName: node + linkType: hard + +"@types/ms@npm:*": + version: 0.7.31 + resolution: "@types/ms@npm:0.7.31" + checksum: 10/6647b295fb2a5b8347c35efabaaed1777221f094be9941d387b4bf11df0eeacb3f8a4e495b8b66ce0e4c00593bc53ab5fc25f01ebb274cd989a834ae578099de + languageName: node + linkType: hard + +"@types/node@npm:*, @types/node@npm:^18.18": + version: 18.19.130 + resolution: "@types/node@npm:18.19.130" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 10/ebb85c6edcec78df926de27d828ecbeb1b3d77c165ceef95bfc26e171edbc1924245db4eb2d7d6230206fe6b1a1f7665714fe1c70739e9f5980d8ce31af6ef82 + languageName: node + linkType: hard + +"@types/parse-json@npm:^4.0.0": + version: 4.0.2 + resolution: "@types/parse-json@npm:4.0.2" + checksum: 10/5bf62eec37c332ad10059252fc0dab7e7da730764869c980b0714777ad3d065e490627be9f40fc52f238ffa3ac4199b19de4127196910576c2fe34dd47c7a470 + languageName: node + linkType: hard + +"@types/prettier@npm:^2.1.5": + version: 2.6.0 + resolution: "@types/prettier@npm:2.6.0" + checksum: 10/289e6c50358b7dd0df0e62c3c943ef3232e9a8a11ad545e958cd4ea34a5bc595971adad9f46ebbb185e23154bd01020e9bd23040cd0d3858f320acf7a1817322 + languageName: node + linkType: hard + +"@types/stack-utils@npm:^2.0.0": + version: 2.0.1 + resolution: "@types/stack-utils@npm:2.0.1" + checksum: 10/205fdbe3326b7046d7eaf5e494d8084f2659086a266f3f9cf00bccc549c8e36e407f88168ad4383c8b07099957ad669f75f2532ed4bc70be2b037330f7bae019 + languageName: node + linkType: hard + +"@types/yargs-parser@npm:*": + version: 21.0.0 + resolution: "@types/yargs-parser@npm:21.0.0" + checksum: 10/c4caec730c1ee09466588389ba4ac83d85a01423c539b9565bb5b5a084bff3f4e47bfb7c06e963c0ef8d4929cf6fca0bc2923a33ef16727cdba60e95c8cdd0d0 + languageName: node + linkType: hard + +"@types/yargs@npm:^16.0.0": + version: 16.0.9 + resolution: "@types/yargs@npm:16.0.9" + dependencies: + "@types/yargs-parser": "npm:*" + checksum: 10/8f31cbfcd5c3ac67c27e26026d8b9af0c37770fb2421b661939ba06d136f5a4fa61528a5d0f495d5802fbf1d9244b499e664d8d884e3eb3c36d556fb7c278f18 + languageName: node + linkType: hard + +"@typescript-eslint/eslint-plugin@npm:8.46.1": + version: 8.46.1 + resolution: "@typescript-eslint/eslint-plugin@npm:8.46.1" + dependencies: + "@eslint-community/regexpp": "npm:^4.10.0" + "@typescript-eslint/scope-manager": "npm:8.46.1" + "@typescript-eslint/type-utils": "npm:8.46.1" + "@typescript-eslint/utils": "npm:8.46.1" + "@typescript-eslint/visitor-keys": "npm:8.46.1" + graphemer: "npm:^1.4.0" + ignore: "npm:^7.0.0" + natural-compare: "npm:^1.4.0" + ts-api-utils: "npm:^2.1.0" + peerDependencies: + "@typescript-eslint/parser": ^8.46.1 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10/9fd8c279584e11c7dcfcac6dddc4dde8719f8fe79349f5a2d0473ffcee198dd543a5311b24c601228ae03cc1a47b29118261bcf45f7f697c8ba1e4289fda4096 + languageName: node + linkType: hard + +"@typescript-eslint/parser@npm:8.46.1": + version: 8.46.1 + resolution: "@typescript-eslint/parser@npm:8.46.1" + dependencies: + "@typescript-eslint/scope-manager": "npm:8.46.1" + "@typescript-eslint/types": "npm:8.46.1" + "@typescript-eslint/typescript-estree": "npm:8.46.1" + "@typescript-eslint/visitor-keys": "npm:8.46.1" + debug: "npm:^4.3.4" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10/4edcb49bb001e9a0e72155c4181f941be00c603bf277c283d4185dca528e9642da927032e8d2671c444ca1904c7f51743029b4b48c12e94d39df2dac49d7d3ff + languageName: node + linkType: hard + +"@typescript-eslint/project-service@npm:8.46.1": + version: 8.46.1 + resolution: "@typescript-eslint/project-service@npm:8.46.1" + dependencies: + "@typescript-eslint/tsconfig-utils": "npm:^8.46.1" + "@typescript-eslint/types": "npm:^8.46.1" + debug: "npm:^4.3.4" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10/d63cbb88524be85ba626c4969bdec1cd5c1ab64b6ebdd565a45698e700efb764f192db1cdc3322f4d63d3acd8d0a36e2685b89bdfa2edf50fda3c2d0cb6efdd7 + languageName: node + linkType: hard + +"@typescript-eslint/scope-manager@npm:8.46.1": + version: 8.46.1 + resolution: "@typescript-eslint/scope-manager@npm:8.46.1" + dependencies: + "@typescript-eslint/types": "npm:8.46.1" + "@typescript-eslint/visitor-keys": "npm:8.46.1" + checksum: 10/3d73812087a17be84184cc68143d4dca7602b8cd4bf5ad334e541d4b3acf5c65c58935369dcf66ab81b38014fe0c6bc57ac2f655fdd69b3e24161a827b86bd34 + languageName: node + linkType: hard + +"@typescript-eslint/tsconfig-utils@npm:8.46.1, @typescript-eslint/tsconfig-utils@npm:^8.46.1": + version: 8.46.1 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.46.1" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10/f033d68a53f62c7cc4c09e5697dd9b7fa34a3c3e79133e0b14ca582821869b77e81d3942b91535f6ef789ffaaad31eef1e1ace20518e7de0935a55a16120fae7 + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:8.46.1": + version: 8.46.1 + resolution: "@typescript-eslint/type-utils@npm:8.46.1" + dependencies: + "@typescript-eslint/types": "npm:8.46.1" + "@typescript-eslint/typescript-estree": "npm:8.46.1" + "@typescript-eslint/utils": "npm:8.46.1" + debug: "npm:^4.3.4" + ts-api-utils: "npm:^2.1.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10/db989c1f55624b34da24eaf0dc230ee696a1f2a614ea95a8dd3b8635ad47d748140be2345ed7afcee844dfabd41129f5a8ca583b1a4d6ecc7d581f89c5e508e2 + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:8.46.1, @typescript-eslint/types@npm:^8.11.0, @typescript-eslint/types@npm:^8.35.0, @typescript-eslint/types@npm:^8.46.1": + version: 8.46.1 + resolution: "@typescript-eslint/types@npm:8.46.1" + checksum: 10/d162ddf6d77d8c9bdfca942da5de5fb4ba80efa740b14077482b5a71282f1d05e1b1dd393ae810eb2923ca9c845bd26b4a9d2dbf25d43dd5d9cb6e20c2a1db46 + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:8.46.1": + version: 8.46.1 + resolution: "@typescript-eslint/typescript-estree@npm:8.46.1" + dependencies: + "@typescript-eslint/project-service": "npm:8.46.1" + "@typescript-eslint/tsconfig-utils": "npm:8.46.1" + "@typescript-eslint/types": "npm:8.46.1" + "@typescript-eslint/visitor-keys": "npm:8.46.1" + debug: "npm:^4.3.4" + fast-glob: "npm:^3.3.2" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^2.1.0" + peerDependencies: + typescript: ">=4.8.4 <6.0.0" + checksum: 10/af068a14d6d0b4849e9f0e52b7ddcd24c266f099528c7b62ff2bebebc0fb82d07439bf6dc565b27cf2fed0af0aaae618aae220676d0fb041c93ec2a8163f0da1 + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:8.46.1, @typescript-eslint/utils@npm:^6.0.0 || ^7.0.0 || ^8.0.0": + version: 8.46.1 + resolution: "@typescript-eslint/utils@npm:8.46.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.7.0" + "@typescript-eslint/scope-manager": "npm:8.46.1" + "@typescript-eslint/types": "npm:8.46.1" + "@typescript-eslint/typescript-estree": "npm:8.46.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10/a8fed8aebd34a559c5abd780649edd6be632531e4930b19642f0fdc862b77bff463ef200e8ced48ba489c3fceee7443b6735c87b918b97b98e95e842cd8a38b5 + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:8.46.1": + version: 8.46.1 + resolution: "@typescript-eslint/visitor-keys@npm:8.46.1" + dependencies: + "@typescript-eslint/types": "npm:8.46.1" + eslint-visitor-keys: "npm:^4.2.1" + checksum: 10/eed1c5ce08d2743bd2ec95a33f2118a67596b1b9fa5bf6a3d84ed09ca66e09af3cc91ef3e302c2222e5882e13576340532b586030b3652ce046eb218cd4508b7 + languageName: node + linkType: hard + +"@unrs/resolver-binding-android-arm-eabi@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-android-arm-eabi@npm:1.11.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-android-arm64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-android-arm64@npm:1.11.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-darwin-arm64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.11.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-darwin-x64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-darwin-x64@npm:1.11.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-freebsd-x64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.11.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-x64-musl@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.11.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-wasm32-wasi@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.11.1" + dependencies: + "@napi-rs/wasm-runtime": "npm:^0.2.11" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@vue/compiler-core@npm:3.5.22": + version: 3.5.22 + resolution: "@vue/compiler-core@npm:3.5.22" + dependencies: + "@babel/parser": "npm:^7.28.4" + "@vue/shared": "npm:3.5.22" + entities: "npm:^4.5.0" + estree-walker: "npm:^2.0.2" + source-map-js: "npm:^1.2.1" + checksum: 10/ed0ca730dbefebb311f8a65eec66185df5019dd5bfc389f962972eb46dfa93d135fbe0819bf6c1feac107d116594b1fc951c93323fe06f9b2530ec24a795bba6 + languageName: node + linkType: hard + +"@vue/compiler-dom@npm:3.5.22": + version: 3.5.22 + resolution: "@vue/compiler-dom@npm:3.5.22" + dependencies: + "@vue/compiler-core": "npm:3.5.22" + "@vue/shared": "npm:3.5.22" + checksum: 10/32c22faa8d0167541b6590c0610adde2f733debe9f58271b39695ec2dc3ab149b34a2066b72c8ddb53f3722b731ef02556af40a998b4059048b4879e64710b77 + languageName: node + linkType: hard + +"@vue/compiler-sfc@npm:^3.3.4": + version: 3.5.22 + resolution: "@vue/compiler-sfc@npm:3.5.22" + dependencies: + "@babel/parser": "npm:^7.28.4" + "@vue/compiler-core": "npm:3.5.22" + "@vue/compiler-dom": "npm:3.5.22" + "@vue/compiler-ssr": "npm:3.5.22" + "@vue/shared": "npm:3.5.22" + estree-walker: "npm:^2.0.2" + magic-string: "npm:^0.30.19" + postcss: "npm:^8.5.6" + source-map-js: "npm:^1.2.1" + checksum: 10/490cc5b604c3de9de46784c9b49b35bc49e5d7884b24d180d7b3719fec903d5348d6a6b73087c77c786b648d706d16ae9a16cf937d2a98d821bd3c1c2000afc3 + languageName: node + linkType: hard + +"@vue/compiler-ssr@npm:3.5.22": + version: 3.5.22 + resolution: "@vue/compiler-ssr@npm:3.5.22" + dependencies: + "@vue/compiler-dom": "npm:3.5.22" + "@vue/shared": "npm:3.5.22" + checksum: 10/78a0b687736861e5e97623a91a329252613ce9b69097371650efe5cfbee5ab22e34b165b68affa6e717b1f7d43c8990df93e1d1136c482fdd85a739137db81e4 + languageName: node + linkType: hard + +"@vue/shared@npm:3.5.22": + version: 3.5.22 + resolution: "@vue/shared@npm:3.5.22" + checksum: 10/8dac35e4ed992da493db8a7430e7c1a09aae1029771e3e7fd3cf2ec64a039f989baef52a47c2864041b01f3de822518c55954bc1c1f2de69690d28761197467d + languageName: node + linkType: hard + +"@yarnpkg/types@npm:^4.0.1": + version: 4.0.1 + resolution: "@yarnpkg/types@npm:4.0.1" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10/f391763cd955356e9aad551b29e8de7bbf68a6c8992af7cdc950ccf53f8aff6695ad81aa4c8a8e7c582786a840a4f30617732e2cb49f4109b971a9242c31c9fc + languageName: node + linkType: hard + +"abab@npm:^2.0.3, abab@npm:^2.0.5": + version: 2.0.6 + resolution: "abab@npm:2.0.6" + checksum: 10/ebe95d7278999e605823fc515a3b05d689bc72e7f825536e73c95ebf621636874c6de1b749b3c4bf866b96ccd4b3a2802efa313d0e45ad51a413c8c73247db20 + languageName: node + linkType: hard + +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: 10/ca0a54e35bea4ece0ecb68a47b312e1a9a6f772408d5bcb9051230aaa94b0460671c5b5c9cb3240eb5b7bc94c52476550eb221f65a0bbd0145bdc9f3113a6707 + languageName: node + linkType: hard + +"acorn-globals@npm:^6.0.0": + version: 6.0.0 + resolution: "acorn-globals@npm:6.0.0" + dependencies: + acorn: "npm:^7.1.1" + acorn-walk: "npm:^7.1.1" + checksum: 10/72d95e5b5e585f9acd019b993ab8bbba68bb3cbc9d9b5c1ebb3c2f1fe5981f11deababfb4949f48e6262f9c57878837f5958c0cca396f81023814680ca878042 + languageName: node + linkType: hard + +"acorn-jsx@npm:^5.3.2": + version: 5.3.2 + resolution: "acorn-jsx@npm:5.3.2" + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: 10/d4371eaef7995530b5b5ca4183ff6f062ca17901a6d3f673c9ac011b01ede37e7a1f7f61f8f5cfe709e88054757bb8f3277dc4061087cdf4f2a1f90ccbcdb977 + languageName: node + linkType: hard + +"acorn-walk@npm:^7.1.1": + version: 7.2.0 + resolution: "acorn-walk@npm:7.2.0" + checksum: 10/4d3e186f729474aed3bc3d0df44692f2010c726582655b20a23347bef650867655521c48ada444cb4fda241ee713dcb792da363ec74c6282fa884fb7144171bb + languageName: node + linkType: hard + +"acorn-walk@npm:^8.1.1": + version: 8.2.0 + resolution: "acorn-walk@npm:8.2.0" + checksum: 10/e69f7234f2adfeb16db3671429a7c80894105bd7534cb2032acf01bb26e6a847952d11a062d071420b43f8d82e33d2e57f26fe87d9cce0853e8143d8910ff1de + languageName: node + linkType: hard + +"acorn@npm:^7.1.1": + version: 7.4.1 + resolution: "acorn@npm:7.4.1" + bin: + acorn: bin/acorn + checksum: 10/8be2a40714756d713dfb62544128adce3b7102c6eb94bc312af196c2cc4af76e5b93079bd66b05e9ca31b35a9b0ce12171d16bc55f366cafdb794fdab9d753ec + languageName: node + linkType: hard + +"acorn@npm:^8.15.0, acorn@npm:^8.2.4, acorn@npm:^8.4.1": + version: 8.15.0 + resolution: "acorn@npm:8.15.0" + bin: + acorn: bin/acorn + checksum: 10/77f2de5051a631cf1729c090e5759148459cdb76b5f5c70f890503d629cf5052357b0ce783c0f976dd8a93c5150f59f6d18df1def3f502396a20f81282482fa4 + languageName: node + linkType: hard + +"agent-base@npm:6": + version: 6.0.2 + resolution: "agent-base@npm:6.0.2" + dependencies: + debug: "npm:4" + checksum: 10/21fb903e0917e5cb16591b4d0ef6a028a54b83ac30cd1fca58dece3d4e0990512a8723f9f83130d88a41e2af8b1f7be1386fda3ea2d181bb1a62155e75e95e23 + languageName: node + linkType: hard + +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" + dependencies: + debug: "npm:^4.3.4" + checksum: 10/c478fec8f79953f118704d007a38f2a185458853f5c45579b9669372bd0e12602e88dc2ad0233077831504f7cd6fcc8251c383375bba5eaaf563b102938bda26 + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 10/1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + languageName: node + linkType: hard + +"ajv@npm:^6.12.4": + version: 6.12.6 + resolution: "ajv@npm:6.12.6" + dependencies: + fast-deep-equal: "npm:^3.1.1" + fast-json-stable-stringify: "npm:^2.0.0" + json-schema-traverse: "npm:^0.4.1" + uri-js: "npm:^4.2.2" + checksum: 10/48d6ad21138d12eb4d16d878d630079a2bda25a04e745c07846a4ad768319533031e28872a9b3c5790fa1ec41aabdf2abed30a56e5a03ebc2cf92184b8ee306c + languageName: node + linkType: hard + +"ansi-escapes@npm:^4.2.1": + version: 4.3.2 + resolution: "ansi-escapes@npm:4.3.2" + dependencies: + type-fest: "npm:^0.21.3" + checksum: 10/8661034456193ffeda0c15c8c564a9636b0c04094b7f78bd01517929c17c504090a60f7a75f949f5af91289c264d3e1001d91492c1bd58efc8e100500ce04de2 + languageName: node + linkType: hard + +"ansi-escapes@npm:^7.0.0": + version: 7.1.1 + resolution: "ansi-escapes@npm:7.1.1" + dependencies: + environment: "npm:^1.0.0" + checksum: 10/a67a9fd832e5e4e9c854bb1aab233416b1fcac373377fd6cc703926eb7da990b5fd12f5e37fab00f3d88dc1ebc8bd1ecffb76750e92c8cbdaa3d82038d3907d8 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 10/2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1, ansi-regex@npm:^6.1.0": + version: 6.2.2 + resolution: "ansi-regex@npm:6.2.2" + checksum: 10/9b17ce2c6daecc75bcd5966b9ad672c23b184dc3ed9bf3c98a0702f0d2f736c15c10d461913568f2cf527a5e64291c7473358885dd493305c84a1cfed66ba94f + languageName: node + linkType: hard + +"ansi-sequence-parser@npm:^1.1.0": + version: 1.1.3 + resolution: "ansi-sequence-parser@npm:1.1.3" + checksum: 10/0f298aad5c9429dc71fc85668b4b502a5c0670c6dc1253b6e9ed5fc7d457a05ede5b10fd0d69a33a1435e41c0a841360bec9131053bdce04a2367c475acb97d6 + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 10/b4494dfbfc7e4591b4711a396bd27e540f8153914123dccb4cdbbcb514015ada63a3809f362b9d8d4f6b17a706f1d7bea3c6f974b15fa5ae76b5b502070889ff + languageName: node + linkType: hard + +"ansi-styles@npm:^5.0.0": + version: 5.2.0 + resolution: "ansi-styles@npm:5.2.0" + checksum: 10/d7f4e97ce0623aea6bc0d90dcd28881ee04cba06c570b97fd3391bd7a268eedfd9d5e2dd4fdcbdd82b8105df5faf6f24aaedc08eaf3da898e702db5948f63469 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: 10/70fdf883b704d17a5dfc9cde206e698c16bcd74e7f196ab821511651aee4f9f76c9514bdfa6ca3a27b5e49138b89cb222a28caf3afe4567570139577f991df32 + languageName: node + linkType: hard + +"any-promise@npm:^1.0.0": + version: 1.3.0 + resolution: "any-promise@npm:1.3.0" + checksum: 10/6737469ba353b5becf29e4dc3680736b9caa06d300bda6548812a8fee63ae7d336d756f88572fa6b5219aed36698d808fa55f62af3e7e6845c7a1dc77d240edb + languageName: node + linkType: hard + +"anymatch@npm:^3.0.3": + version: 3.1.2 + resolution: "anymatch@npm:3.1.2" + dependencies: + normalize-path: "npm:^3.0.0" + picomatch: "npm:^2.0.4" + checksum: 10/985163db2292fac9e5a1e072bf99f1b5baccf196e4de25a0b0b81865ebddeb3b3eb4480734ef0a2ac8c002845396b91aa89121f5b84f93981a4658164a9ec6e9 + languageName: node + linkType: hard + +"are-docs-informative@npm:^0.0.2": + version: 0.0.2 + resolution: "are-docs-informative@npm:0.0.2" + checksum: 10/12cdae51a4bb369832ef1a35840604247d4ed0cbc8392f2519988d170f92c3f8c60e465844f41acba1ec3062d0edb2e9133fca38cb9c1214309153d50a25fa29 + languageName: node + linkType: hard + +"arg@npm:^4.1.0": + version: 4.1.3 + resolution: "arg@npm:4.1.3" + checksum: 10/969b491082f20cad166649fa4d2073ea9e974a4e5ac36247ca23d2e5a8b3cb12d60e9ff70a8acfe26d76566c71fd351ee5e6a9a6595157eb36f92b1fd64e1599 + languageName: node + linkType: hard + +"argparse@npm:^1.0.7": + version: 1.0.10 + resolution: "argparse@npm:1.0.10" + dependencies: + sprintf-js: "npm:~1.0.2" + checksum: 10/c6a621343a553ff3779390bb5ee9c2263d6643ebcd7843227bdde6cc7adbed796eb5540ca98db19e3fd7b4714e1faa51551f8849b268bb62df27ddb15cbcd91e + languageName: node + linkType: hard + +"argparse@npm:^2.0.1": + version: 2.0.1 + resolution: "argparse@npm:2.0.1" + checksum: 10/18640244e641a417ec75a9bd38b0b2b6b95af5199aa241b131d4b2fb206f334d7ecc600bd194861610a5579084978bfcbb02baa399dbe442d56d0ae5e60dbaef + languageName: node + linkType: hard + +"array-differ@npm:^3.0.0": + version: 3.0.0 + resolution: "array-differ@npm:3.0.0" + checksum: 10/117edd9df5c1530bd116c6e8eea891d4bd02850fd89b1b36e532b6540e47ca620a373b81feca1c62d1395d9ae601516ba538abe5e8172d41091da2c546b05fb7 + languageName: node + linkType: hard + +"array-union@npm:^2.1.0": + version: 2.1.0 + resolution: "array-union@npm:2.1.0" + checksum: 10/5bee12395cba82da674931df6d0fea23c4aa4660cb3b338ced9f828782a65caa232573e6bf3968f23e0c5eb301764a382cef2f128b170a9dc59de0e36c39f98d + languageName: node + linkType: hard + +"arrify@npm:^2.0.1": + version: 2.0.1 + resolution: "arrify@npm:2.0.1" + checksum: 10/067c4c1afd182806a82e4c1cb8acee16ab8b5284fbca1ce29408e6e91281c36bb5b612f6ddfbd40a0f7a7e0c75bf2696eb94c027f6e328d6e9c52465c98e4209 + languageName: node + linkType: hard + +"async-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-function@npm:1.0.0" + checksum: 10/1a09379937d846f0ce7614e75071c12826945d4e417db634156bf0e4673c495989302f52186dfa9767a1d9181794554717badd193ca2bbab046ef1da741d8efd + languageName: node + linkType: hard + +"async-generator-function@npm:^1.0.0": + version: 1.0.0 + resolution: "async-generator-function@npm:1.0.0" + checksum: 10/3d49e7acbeee9e84537f4cb0e0f91893df8eba976759875ae8ee9e3d3c82f6ecdebdb347c2fad9926b92596d93cdfc78ecc988bcdf407e40433e8e8e6fe5d78e + languageName: node + linkType: hard + +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 10/3ce727cbc78f69d6a4722517a58ee926c8c21083633b1d3fdf66fd688f6c127a53a592141bd4866f9b63240a86e9d8e974b13919450bd17fa33c2d22c4558ad8 + languageName: node + linkType: hard + +"babel-jest@npm:^27.5.1": + version: 27.5.1 + resolution: "babel-jest@npm:27.5.1" + dependencies: + "@jest/transform": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/babel__core": "npm:^7.1.14" + babel-plugin-istanbul: "npm:^6.1.1" + babel-preset-jest: "npm:^27.5.1" + chalk: "npm:^4.0.0" + graceful-fs: "npm:^4.2.9" + slash: "npm:^3.0.0" + peerDependencies: + "@babel/core": ^7.8.0 + checksum: 10/d032823796072b3c269edaa623dd7fe6ecf2f72aff5b003066e7b16ad0ec4068ed04f3f569237183161d28b638936121975014bcb26ae539e669f2bdad5babe6 + languageName: node + linkType: hard + +"babel-plugin-istanbul@npm:^6.1.1": + version: 6.1.1 + resolution: "babel-plugin-istanbul@npm:6.1.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.0.0" + "@istanbuljs/load-nyc-config": "npm:^1.0.0" + "@istanbuljs/schema": "npm:^0.1.2" + istanbul-lib-instrument: "npm:^5.0.4" + test-exclude: "npm:^6.0.0" + checksum: 10/ffd436bb2a77bbe1942a33245d770506ab2262d9c1b3c1f1da7f0592f78ee7445a95bc2efafe619dd9c1b6ee52c10033d6c7d29ddefe6f5383568e60f31dfe8d + languageName: node + linkType: hard + +"babel-plugin-jest-hoist@npm:^27.5.1": + version: 27.5.1 + resolution: "babel-plugin-jest-hoist@npm:27.5.1" + dependencies: + "@babel/template": "npm:^7.3.3" + "@babel/types": "npm:^7.3.3" + "@types/babel__core": "npm:^7.0.0" + "@types/babel__traverse": "npm:^7.0.6" + checksum: 10/9e334903433fd92ef9a65ea5c61f7d786238704b1327d9ca227ef40ef7142fba2bb8219bcb9b2d56eaf36ecfbcc50aa1e177db64508438569e98cfd67cce5043 + languageName: node + linkType: hard + +"babel-preset-current-node-syntax@npm:^1.0.0": + version: 1.0.1 + resolution: "babel-preset-current-node-syntax@npm:1.0.1" + dependencies: + "@babel/plugin-syntax-async-generators": "npm:^7.8.4" + "@babel/plugin-syntax-bigint": "npm:^7.8.3" + "@babel/plugin-syntax-class-properties": "npm:^7.8.3" + "@babel/plugin-syntax-import-meta": "npm:^7.8.3" + "@babel/plugin-syntax-json-strings": "npm:^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" + "@babel/plugin-syntax-numeric-separator": "npm:^7.8.3" + "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" + "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" + "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" + "@babel/plugin-syntax-top-level-await": "npm:^7.8.3" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/94561959cb12bfa80867c9eeeace7c3d48d61707d33e55b4c3fdbe82fc745913eb2dbfafca62aef297421b38aadcb58550e5943f50fbcebbeefd70ce2bed4b74 + languageName: node + linkType: hard + +"babel-preset-jest@npm:^27.5.1": + version: 27.5.1 + resolution: "babel-preset-jest@npm:27.5.1" + dependencies: + babel-plugin-jest-hoist: "npm:^27.5.1" + babel-preset-current-node-syntax: "npm:^1.0.0" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/251bcea11c18fd9672fec104eadb45b43f117ceeb326fa7345ced778d4c1feab29343cd7a87a1dcfae4997d6c851a8b386d7f7213792da6e23b74f4443a8976d + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 10/9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"baseline-browser-mapping@npm:^2.8.9": + version: 2.8.16 + resolution: "baseline-browser-mapping@npm:2.8.16" + bin: + baseline-browser-mapping: dist/cli.js + checksum: 10/52a5807591daeffc810b783b1afa20c4017dd94e5bb74934bcde4dd408758e492610e330cfe6e609a0f0bde5ce210dd934271540fb931389d6838db17ec8cfef + languageName: node + linkType: hard + +"bin-links@npm:4.0.4": + version: 4.0.4 + resolution: "bin-links@npm:4.0.4" + dependencies: + cmd-shim: "npm:^6.0.0" + npm-normalize-package-bin: "npm:^3.0.0" + read-cmd-shim: "npm:^4.0.0" + write-file-atomic: "npm:^5.0.0" + checksum: 10/58d62143aacdbb783b076e9bdd970d8470f2750e1076d6fd1ae559fa532c4647478dd2550a911ba22d4c9e6339881451046e2fbc4b8958f4bf3bf8e5144d1e4d + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" + dependencies: + balanced-match: "npm:^1.0.0" + concat-map: "npm:0.0.1" + checksum: 10/faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: 10/a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + languageName: node + linkType: hard + +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: "npm:^7.1.1" + checksum: 10/fad11a0d4697a27162840b02b1fad249c1683cbc510cd5bf1a471f2f8085c046d41094308c577a50a03a579dd99d5a6b3724c4b5e8b14df2c4443844cfcda2c6 + languageName: node + linkType: hard + +"browser-process-hrtime@npm:^1.0.0": + version: 1.0.0 + resolution: "browser-process-hrtime@npm:1.0.0" + checksum: 10/e30f868cdb770b1201afb714ad1575dd86366b6e861900884665fb627109b3cc757c40067d3bfee1ff2a29c835257ea30725a8018a9afd02ac1c24b408b1e45f + languageName: node + linkType: hard + +"browserslist@npm:^4.24.0": + version: 4.26.3 + resolution: "browserslist@npm:4.26.3" + dependencies: + baseline-browser-mapping: "npm:^2.8.9" + caniuse-lite: "npm:^1.0.30001746" + electron-to-chromium: "npm:^1.5.227" + node-releases: "npm:^2.0.21" + update-browserslist-db: "npm:^1.1.3" + bin: + browserslist: cli.js + checksum: 10/49add06fd753a2514d84c75a7de8d9fb3d70be675e53b72981d87f0c0ff40d8a8cd0bd92f77400381704be0bf1c9c5c65aef95d03843d69475ff55188aa12124 + languageName: node + linkType: hard + +"bs-logger@npm:0.x": + version: 0.2.6 + resolution: "bs-logger@npm:0.2.6" + dependencies: + fast-json-stable-stringify: "npm:2.x" + checksum: 10/e6d3ff82698bb3f20ce64fb85355c5716a3cf267f3977abe93bf9c32a2e46186b253f48a028ae5b96ab42bacd2c826766d9ae8cf6892f9b944656be9113cf212 + languageName: node + linkType: hard + +"bser@npm:2.1.1": + version: 2.1.1 + resolution: "bser@npm:2.1.1" + dependencies: + node-int64: "npm:^0.4.0" + checksum: 10/edba1b65bae682450be4117b695997972bd9a3c4dfee029cab5bcb72ae5393a79a8f909b8bc77957eb0deec1c7168670f18f4d5c556f46cdd3bca5f3b3a8d020 + languageName: node + linkType: hard + +"buffer-from@npm:^1.0.0": + version: 1.1.2 + resolution: "buffer-from@npm:1.1.2" + checksum: 10/0448524a562b37d4d7ed9efd91685a5b77a50672c556ea254ac9a6d30e3403a517d8981f10e565db24e8339413b43c97ca2951f10e399c6125a0d8911f5679bb + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.4 + resolution: "cacache@npm:18.0.4" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: 10/ca2f7b2d3003f84d362da9580b5561058ccaecd46cba661cbcff0375c90734b610520d46b472a339fd032d91597ad6ed12dde8af81571197f3c9772b5d35b104 + languageName: node + linkType: hard + +"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + checksum: 10/00482c1f6aa7cfb30fb1dbeb13873edf81cfac7c29ed67a5957d60635a56b2a4a480f1016ddbdb3395cc37900d46037fb965043a51c5c789ffeab4fc535d18b5 + languageName: node + linkType: hard + +"callsite@npm:^1.0.0": + version: 1.0.0 + resolution: "callsite@npm:1.0.0" + checksum: 10/39fc89ef9dbee7d5491bc69034fc16fbb8876a73456f831cc27060b5828e94357bb6705e0127a6d0182d79b03dbdb0ef88223d0b599c26667c871c89b30eb681 + languageName: node + linkType: hard + +"callsites@npm:^3.0.0": + version: 3.1.0 + resolution: "callsites@npm:3.1.0" + checksum: 10/072d17b6abb459c2ba96598918b55868af677154bec7e73d222ef95a8fdb9bbf7dae96a8421085cdad8cd190d86653b5b6dc55a4484f2e5b2e27d5e0c3fc15b3 + languageName: node + linkType: hard + +"camelcase@npm:^5.3.1": + version: 5.3.1 + resolution: "camelcase@npm:5.3.1" + checksum: 10/e6effce26b9404e3c0f301498184f243811c30dfe6d0b9051863bd8e4034d09c8c2923794f280d6827e5aa055f6c434115ff97864a16a963366fb35fd673024b + languageName: node + linkType: hard + +"camelcase@npm:^6.2.0, camelcase@npm:^6.3.0": + version: 6.3.0 + resolution: "camelcase@npm:6.3.0" + checksum: 10/8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001746": + version: 1.0.30001750 + resolution: "caniuse-lite@npm:1.0.30001750" + checksum: 10/2b912758d817cd2c2c179246e282f8b598695ec733bc446183e1d381eada60889c4770a1dfd86075e046a43d55f9922e2eaed1501347fcb12a38716cc14be297 + languageName: node + linkType: hard + +"chalk@npm:^4.0.0, chalk@npm:^4.1.2": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: "npm:^4.1.0" + supports-color: "npm:^7.1.0" + checksum: 10/cb3f3e594913d63b1814d7ca7c9bafbf895f75fbf93b92991980610dfd7b48500af4e3a5d4e3a8f337990a96b168d7eb84ee55efdce965e2ee8efc20f8c8f139 + languageName: node + linkType: hard + +"chalk@npm:^5.3.0, chalk@npm:^5.4.1": + version: 5.6.2 + resolution: "chalk@npm:5.6.2" + checksum: 10/1b2f48f6fba1370670d5610f9cd54c391d6ede28f4b7062dd38244ea5768777af72e5be6b74fb6c6d54cb84c4a2dff3f3afa9b7cb5948f7f022cfd3d087989e0 + languageName: node + linkType: hard + +"char-regex@npm:^1.0.2": + version: 1.0.2 + resolution: "char-regex@npm:1.0.2" + checksum: 10/1ec5c2906adb9f84e7f6732a40baef05d7c85401b82ffcbc44b85fbd0f7a2b0c2a96f2eb9cf55cae3235dc12d4023003b88f09bcae8be9ae894f52ed746f4d48 + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: 10/c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f + languageName: node + linkType: hard + +"ci-info@npm:^3.2.0": + version: 3.3.0 + resolution: "ci-info@npm:3.3.0" + checksum: 10/8adea555a4f92e4f80f5e58e63277b349efa439dabfc6e2ca3773126f3fea7699f3546ff931f996a08f9905b2f6a7fc4d671a0c549cfedab7369e35aa0723b00 + languageName: node + linkType: hard + +"cjs-module-lexer@npm:^1.0.0, cjs-module-lexer@npm:^1.3.1": + version: 1.4.3 + resolution: "cjs-module-lexer@npm:1.4.3" + checksum: 10/d2b92f919a2dedbfd61d016964fce8da0035f827182ed6839c97cac56e8a8077cfa6a59388adfe2bc588a19cef9bbe830d683a76a6e93c51f65852062cfe2591 + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 10/2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + languageName: node + linkType: hard + +"cli-highlight@npm:^2.1.11": + version: 2.1.11 + resolution: "cli-highlight@npm:2.1.11" + dependencies: + chalk: "npm:^4.0.0" + highlight.js: "npm:^10.7.1" + mz: "npm:^2.4.0" + parse5: "npm:^5.1.1" + parse5-htmlparser2-tree-adapter: "npm:^6.0.0" + yargs: "npm:^16.0.0" + bin: + highlight: bin/highlight + checksum: 10/05d2b5beb8a4d3259f693517d013bf53d04ad20f470b77c3d02e051963092fae388388e3127f67d3679884a0c32cb855bf590292017c5e68c0f8d86f4b8e146e + languageName: node + linkType: hard + +"cli-table3@npm:^0.6.3, cli-table3@npm:^0.6.5": + version: 0.6.5 + resolution: "cli-table3@npm:0.6.5" + dependencies: + "@colors/colors": "npm:1.5.0" + string-width: "npm:^4.2.0" + dependenciesMeta: + "@colors/colors": + optional: true + checksum: 10/8dca71256f6f1367bab84c33add3f957367c7c43750a9828a4212ebd31b8df76bd7419d386e3391ac7419698a8540c25f1a474584028f35b170841cde2e055c5 + languageName: node + linkType: hard + +"cliui@npm:^7.0.2": + version: 7.0.4 + resolution: "cliui@npm:7.0.4" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.0" + wrap-ansi: "npm:^7.0.0" + checksum: 10/db858c49af9d59a32d603987e6fddaca2ce716cd4602ba5a2bb3a5af1351eebe82aba8dff3ef3e1b331f7fa9d40ca66e67bdf8e7c327ce0ea959747ead65c0ef + languageName: node + linkType: hard + +"cliui@npm:^8.0.1": + version: 8.0.1 + resolution: "cliui@npm:8.0.1" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^7.0.0" + checksum: 10/eaa5561aeb3135c2cddf7a3b3f562fc4238ff3b3fc666869ef2adf264be0f372136702f16add9299087fb1907c2e4ec5dbfe83bd24bce815c70a80c6c1a2e950 + languageName: node + linkType: hard + +"cmd-shim@npm:^6.0.0": + version: 6.0.1 + resolution: "cmd-shim@npm:6.0.1" + checksum: 10/d0718e4a49265a9195ced19f662a77569ce5939145451125bdc8bb302781f15564ade92f6c49e231f9d0bb6f3d71db1a2d0a50af940490eb324e152325039541 + languageName: node + linkType: hard + +"co@npm:^4.6.0": + version: 4.6.0 + resolution: "co@npm:4.6.0" + checksum: 10/a5d9f37091c70398a269e625cedff5622f200ed0aa0cff22ee7b55ed74a123834b58711776eb0f1dc58eb6ebbc1185aa7567b57bd5979a948c6e4f85073e2c05 + languageName: node + linkType: hard + +"collect-v8-coverage@npm:^1.0.0": + version: 1.0.1 + resolution: "collect-v8-coverage@npm:1.0.1" + checksum: 10/85b26945ab9b8e15077f877a4a5bc91d836480c600bac4cd0a0e8be8515583fdfc393ccff049ff3e9f46cac39e5295af049209f3c484f30a028056cc5dd1fe8a + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 10/fa00c91b4332b294de06b443923246bccebe9fab1b253f7fe1772d37b06a2269b4039a85e309abe1fe11b267b11c08d1d0473fda3badd6167f57313af2887a64 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: 10/b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: "npm:~1.0.0" + checksum: 10/2e969e637d05d09fa50b02d74c83a1186f6914aae89e6653b62595cc75a221464f884f55f231b8f4df7a49537fba60bdc0427acd2bf324c09a1dbb84837e36e4 + languageName: node + linkType: hard + +"commander@npm:^10.0.1": + version: 10.0.1 + resolution: "commander@npm:10.0.1" + checksum: 10/8799faa84a30da985802e661cc9856adfaee324d4b138413013ef7f087e8d7924b144c30a1f1405475f0909f467665cd9e1ce13270a2f41b141dab0b7a58f3fb + languageName: node + linkType: hard + +"comment-parser@npm:1.4.1, comment-parser@npm:^1.4.1": + version: 1.4.1 + resolution: "comment-parser@npm:1.4.1" + checksum: 10/16a3260b5e77819ebd9c99b0b65c7d6723b1ff73487bac9ce2d8f016a2847dd689e8663b88e1fad1444bbea89847c42f785708ac86a2c55f614f7095249bbf6b + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 10/9680699c8e2b3af0ae22592cb764acaf973f292a7b71b8a06720233011853a58e256c89216a10cbe889727532fd77f8bcd49a760cedfde271b8e006c20e079f2 + languageName: node + linkType: hard + +"convert-source-map@npm:^1.4.0, convert-source-map@npm:^1.6.0": + version: 1.9.0 + resolution: "convert-source-map@npm:1.9.0" + checksum: 10/dc55a1f28ddd0e9485ef13565f8f756b342f9a46c4ae18b843fe3c30c675d058d6a4823eff86d472f187b176f0adf51ea7b69ea38be34be4a63cbbf91b0593c8 + languageName: node + linkType: hard + +"convert-source-map@npm:^2.0.0": + version: 2.0.0 + resolution: "convert-source-map@npm:2.0.0" + checksum: 10/c987be3ec061348cdb3c2bfb924bec86dea1eacad10550a85ca23edb0fe3556c3a61c7399114f3331ccb3499d7fd0285ab24566e5745929412983494c3926e15 + languageName: node + linkType: hard + +"cosmiconfig@npm:^7.1.0": + version: 7.1.0 + resolution: "cosmiconfig@npm:7.1.0" + dependencies: + "@types/parse-json": "npm:^4.0.0" + import-fresh: "npm:^3.2.1" + parse-json: "npm:^5.0.0" + path-type: "npm:^4.0.0" + yaml: "npm:^1.10.0" + checksum: 10/03600bb3870c80ed151b7b706b99a1f6d78df8f4bdad9c95485072ea13358ef294b13dd99f9e7bf4cc0b43bcd3599d40df7e648750d21c2f6817ca2cd687e071 + languageName: node + linkType: hard + +"crc-32@npm:^1.2.0": + version: 1.2.2 + resolution: "crc-32@npm:1.2.2" + bin: + crc32: bin/crc32.njs + checksum: 10/824f696a5baaf617809aa9cd033313c8f94f12d15ebffa69f10202480396be44aef9831d900ab291638a8022ed91c360696dd5b1ba691eb3f34e60be8835b7c3 + languageName: node + linkType: hard + +"create-require@npm:^1.1.0": + version: 1.1.1 + resolution: "create-require@npm:1.1.1" + checksum: 10/a9a1503d4390d8b59ad86f4607de7870b39cad43d929813599a23714831e81c520bddf61bcdd1f8e30f05fd3a2b71ae8538e946eb2786dc65c2bbc520f692eff + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 10/0d52657d7ae36eb130999dffff1168ec348687b48dd38e2ff59992ed916c88d328cf1d07ff4a4a10bc78de5e1c23f04b306d569e42f7a2293915c081e4dfee86 + languageName: node + linkType: hard + +"cssom@npm:^0.4.4": + version: 0.4.4 + resolution: "cssom@npm:0.4.4" + checksum: 10/6302c5f9b33a15f5430349f91553dd370f60707b1f2bb2c21954abe307b701d6095da134679fd0891a7814bc98061e1639bd0562d8f70c2dc529918111be8d2b + languageName: node + linkType: hard + +"cssom@npm:~0.3.6": + version: 0.3.8 + resolution: "cssom@npm:0.3.8" + checksum: 10/49eacc88077555e419646c0ea84ddc73c97e3a346ad7cb95e22f9413a9722d8964b91d781ce21d378bd5ae058af9a745402383fa4e35e9cdfd19654b63f892a9 + languageName: node + linkType: hard + +"cssstyle@npm:^2.3.0": + version: 2.3.0 + resolution: "cssstyle@npm:2.3.0" + dependencies: + cssom: "npm:~0.3.6" + checksum: 10/46f7f05a153446c4018b0454ee1464b50f606cb1803c90d203524834b7438eb52f3b173ba0891c618f380ced34ee12020675dc0052a7f1be755fe4ebc27ee977 + languageName: node + linkType: hard + +"data-urls@npm:^2.0.0": + version: 2.0.0 + resolution: "data-urls@npm:2.0.0" + dependencies: + abab: "npm:^2.0.3" + whatwg-mimetype: "npm:^2.3.0" + whatwg-url: "npm:^8.0.0" + checksum: 10/97caf828aac25e25e04ba6869db0f99c75e6859bb5b424ada28d3e7841941ebf08ddff3c1b1bb4585986bd507a5d54c2a716853ea6cb98af877400e637393e71 + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0, debug@npm:^4.4.1": + version: 4.4.3 + resolution: "debug@npm:4.4.3" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10/9ada3434ea2993800bd9a1e320bd4aa7af69659fb51cca685d390949434bc0a8873c21ed7c9b852af6f2455a55c6d050aa3937d52b3c69f796dab666f762acad + languageName: node + linkType: hard + +"decimal.js@npm:^10.2.1": + version: 10.6.0 + resolution: "decimal.js@npm:10.6.0" + checksum: 10/c0d45842d47c311d11b38ce7ccc911121953d4df3ebb1465d92b31970eb4f6738a065426a06094af59bee4b0d64e42e7c8984abd57b6767c64ea90cf90bb4a69 + languageName: node + linkType: hard + +"dedent@npm:^0.7.0": + version: 0.7.0 + resolution: "dedent@npm:0.7.0" + checksum: 10/87de191050d9a40dd70cad01159a0bcf05ecb59750951242070b6abf9569088684880d00ba92a955b4058804f16eeaf91d604f283929b4f614d181cd7ae633d2 + languageName: node + linkType: hard + +"deep-is@npm:^0.1.3": + version: 0.1.4 + resolution: "deep-is@npm:0.1.4" + checksum: 10/ec12d074aef5ae5e81fa470b9317c313142c9e8e2afe3f8efa124db309720db96d1d222b82b84c834e5f87e7a614b44a4684b6683583118b87c833b3be40d4d8 + languageName: node + linkType: hard + +"deepmerge@npm:^4.2.2": + version: 4.2.2 + resolution: "deepmerge@npm:4.2.2" + checksum: 10/0e58ed14f530d08f9b996cfc3a41b0801691620235bc5e1883260e3ed1c1b4a1dfb59f865770e45d5dfb1d7ee108c4fc10c2f85e822989d4123490ea90be2545 + languageName: node + linkType: hard + +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 10/46fe6e83e2cb1d85ba50bd52803c68be9bd953282fa7096f51fc29edd5d67ff84ff753c51966061e5ba7cb5e47ef6d36a91924eddb7f3f3483b1c560f77a0020 + languageName: node + linkType: hard + +"depcheck@npm:^1.4.3": + version: 1.4.7 + resolution: "depcheck@npm:1.4.7" + dependencies: + "@babel/parser": "npm:^7.23.0" + "@babel/traverse": "npm:^7.23.2" + "@vue/compiler-sfc": "npm:^3.3.4" + callsite: "npm:^1.0.0" + camelcase: "npm:^6.3.0" + cosmiconfig: "npm:^7.1.0" + debug: "npm:^4.3.4" + deps-regex: "npm:^0.2.0" + findup-sync: "npm:^5.0.0" + ignore: "npm:^5.2.4" + is-core-module: "npm:^2.12.0" + js-yaml: "npm:^3.14.1" + json5: "npm:^2.2.3" + lodash: "npm:^4.17.21" + minimatch: "npm:^7.4.6" + multimatch: "npm:^5.0.0" + please-upgrade-node: "npm:^3.2.0" + readdirp: "npm:^3.6.0" + require-package-name: "npm:^2.0.1" + resolve: "npm:^1.22.3" + resolve-from: "npm:^5.0.0" + semver: "npm:^7.5.4" + yargs: "npm:^16.2.0" + bin: + depcheck: bin/depcheck.js + checksum: 10/e35e87517348a3fd678f9ed7324cb96aff350c65cd0ede7da5be303f03144ad66a18d03ff2b52531cd7900b2ca83f8c2a4fac3295e00db8f701f92fb33744b78 + languageName: node + linkType: hard + +"deps-regex@npm:^0.2.0": + version: 0.2.0 + resolution: "deps-regex@npm:0.2.0" + checksum: 10/d8eeb89727037f2ae680a619f8eefbc8475d21c3d5273e2bbcb9838aabd1c93fd9e011f51bcda5bd65f042921c1bc156119d9a8a2f3539aa4009950b8f9c79b3 + languageName: node + linkType: hard + +"detect-file@npm:^1.0.0": + version: 1.0.0 + resolution: "detect-file@npm:1.0.0" + checksum: 10/1861e4146128622e847abe0e1ed80fef01e78532665858a792267adf89032b7a9c698436137707fcc6f02956c2a6a0052d6a0cef5be3d4b76b1ff0da88e2158a + languageName: node + linkType: hard + +"detect-indent@npm:^7.0.1": + version: 7.0.2 + resolution: "detect-indent@npm:7.0.2" + checksum: 10/ef215d1b55a14f677ce03e840973b25362b6f8cd3f566bc82831fa1abb2be6a95423729bc573dc2334b1371ad7be18d9ec67e1a9611b71a04cb6d63f0d8e54cc + languageName: node + linkType: hard + +"detect-newline@npm:^3.0.0": + version: 3.1.0 + resolution: "detect-newline@npm:3.1.0" + checksum: 10/ae6cd429c41ad01b164c59ea36f264a2c479598e61cba7c99da24175a7ab80ddf066420f2bec9a1c57a6bead411b4655ff15ad7d281c000a89791f48cbe939e7 + languageName: node + linkType: hard + +"detect-newline@npm:^4.0.1": + version: 4.0.1 + resolution: "detect-newline@npm:4.0.1" + checksum: 10/0409ecdfb93419591ccff24fccfe2ddddad29b66637d1ed898872125b25af05014fdeedc9306339577060f69f59fe6e9830cdd80948597f136dfbffefa60599c + languageName: node + linkType: hard + +"diff-sequences@npm:^27.5.1": + version: 27.5.1 + resolution: "diff-sequences@npm:27.5.1" + checksum: 10/34d852a13eb82735c39944a050613f952038614ce324256e1c3544948fa090f1ca7f329a4f1f57c31fe7ac982c17068d8915b633e300f040b97708c81ceb26cd + languageName: node + linkType: hard + +"diff@npm:^4.0.1": + version: 4.0.2 + resolution: "diff@npm:4.0.2" + checksum: 10/ec09ec2101934ca5966355a229d77afcad5911c92e2a77413efda5455636c4cf2ce84057e2d7715227a2eeeda04255b849bd3ae3a4dd22eb22e86e76456df069 + languageName: node + linkType: hard + +"diff@npm:^5.0.0": + version: 5.0.0 + resolution: "diff@npm:5.0.0" + checksum: 10/4a179a75b17cbb420eb9145be913f9ddb34b47cb2ba4301e80ae745122826a468f02ca8f5e56945958de26ace594899c8381acb6659c88e7803ef078b53d690c + languageName: node + linkType: hard + +"domexception@npm:^2.0.1": + version: 2.0.1 + resolution: "domexception@npm:2.0.1" + dependencies: + webidl-conversions: "npm:^5.0.0" + checksum: 10/d638e9cb05c52999f1b2eb87c374b03311ea5b1d69c2f875bc92da73e17db60c12142b45c950228642ff7f845c536b65305483350d080df59003a653da80b691 + languageName: node + linkType: hard + +"dunder-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "dunder-proto@npm:1.0.1" + dependencies: + call-bind-apply-helpers: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.2.0" + checksum: 10/5add88a3d68d42d6e6130a0cac450b7c2edbe73364bbd2fc334564418569bea97c6943a8fcd70e27130bf32afc236f30982fc4905039b703f23e9e0433c29934 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 10/9b1d3e1baefeaf7d70799db8774149cef33b97183a6addceeba0cf6b85ba23ee2686f302f14482006df32df75d32b17c509c143a3689627929e4a8efaf483952 + languageName: node + linkType: hard + +"electron-to-chromium@npm:^1.5.227": + version: 1.5.237 + resolution: "electron-to-chromium@npm:1.5.237" + checksum: 10/d21837cfc70038f547d8bf2328e5139f5e4143e365d64633fca568772dd68ceac2cf0d802f0d16921e6df925efb3527f2ba664dbcfa7ddd75e21465d2b0d4a6c + languageName: node + linkType: hard + +"emittery@npm:^0.8.1": + version: 0.8.1 + resolution: "emittery@npm:0.8.1" + checksum: 10/3b882c0bdc3121b4e92b85315f87da0db8e965766d6c7ff70a8f45e0c38ed49d561936650afa32759d8fb320a458bc9e12631799a0a276e9e8a960ae16c1f6f1 + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: 10/c72d67a6821be15ec11997877c437491c313d924306b8da5d87d2a2bcc2cec9903cb5b04ee1a088460501d8e5b44f10df82fdc93c444101a7610b80c8b6938e1 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 10/915acf859cea7131dac1b2b5c9c8e35c4849e325a1d114c30adb8cd615970f6dca0e27f64f3a4949d7d6ed86ecd79a1c5c63f02e697513cddd7b5835c90948b8 + languageName: node + linkType: hard + +"emojilib@npm:^2.4.0": + version: 2.4.0 + resolution: "emojilib@npm:2.4.0" + checksum: 10/bef767eca49acaa881388d91bee6936ea57ae367d603d5227ff0a9da3e2d1e774a61c447e5f2f4901797d023c4b5239bc208285b6172a880d3655024a0f44980 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: 10/bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + languageName: node + linkType: hard + +"enhanced-resolve@npm:^5.17.1": + version: 5.18.3 + resolution: "enhanced-resolve@npm:5.18.3" + dependencies: + graceful-fs: "npm:^4.2.4" + tapable: "npm:^2.2.0" + checksum: 10/a4d0a1eacba3079f617b68c8f7e17583c3cbc572055c2edca41c0fa0230a49f6e9b2c6ffd4128cc5f84e15ea6cc313ae2b01e1057fcd252fabef70220a5d9f6a + languageName: node + linkType: hard + +"entities@npm:^4.5.0": + version: 4.5.0 + resolution: "entities@npm:4.5.0" + checksum: 10/ede2a35c9bce1aeccd055a1b445d41c75a14a2bb1cd22e242f20cf04d236cdcd7f9c859eb83f76885327bfae0c25bf03303665ee1ce3d47c5927b98b0e3e3d48 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 10/65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"environment@npm:^1.0.0": + version: 1.1.0 + resolution: "environment@npm:1.1.0" + checksum: 10/dd3c1b9825e7f71f1e72b03c2344799ac73f2e9ef81b78ea8b373e55db021786c6b9f3858ea43a436a2c4611052670ec0afe85bc029c384cc71165feee2f4ba6 + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 10/1d20d825cdcce8d811bfbe86340f4755c02655a7feb2f13f8c880566d9d72a3f6c92c192a6867632e490d6da67b678271f46e01044996a6443e870331100dfdd + languageName: node + linkType: hard + +"error-ex@npm:^1.3.1": + version: 1.3.2 + resolution: "error-ex@npm:1.3.2" + dependencies: + is-arrayish: "npm:^0.2.1" + checksum: 10/d547740aa29c34e753fb6fed2c5de81802438529c12b3673bd37b6bb1fe49b9b7abdc3c11e6062fe625d8a296b3cf769a80f878865e25e685f787763eede3ffb + languageName: node + linkType: hard + +"es-define-property@npm:^1.0.1": + version: 1.0.1 + resolution: "es-define-property@npm:1.0.1" + checksum: 10/f8dc9e660d90919f11084db0a893128f3592b781ce967e4fccfb8f3106cb83e400a4032c559184ec52ee1dbd4b01e7776c7cd0b3327b1961b1a4a7008920fe78 + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10/96e65d640156f91b707517e8cdc454dd7d47c32833aa3e85d79f24f9eb7ea85f39b63e36216ef0114996581969b59fe609a94e30316b08f5f4df1d44134cf8d5 + languageName: node + linkType: hard + +"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": + version: 1.1.1 + resolution: "es-object-atoms@npm:1.1.1" + dependencies: + es-errors: "npm:^1.3.0" + checksum: 10/54fe77de288451dae51c37bfbfe3ec86732dc3778f98f3eb3bdb4bf48063b2c0b8f9c93542656986149d08aa5be3204286e2276053d19582b76753f1a2728867 + languageName: node + linkType: hard + +"es-set-tostringtag@npm:^2.1.0": + version: 2.1.0 + resolution: "es-set-tostringtag@npm:2.1.0" + dependencies: + es-errors: "npm:^1.3.0" + get-intrinsic: "npm:^1.2.6" + has-tostringtag: "npm:^1.0.2" + hasown: "npm:^2.0.2" + checksum: 10/86814bf8afbcd8966653f731415888019d4bc4aca6b6c354132a7a75bb87566751e320369654a101d23a91c87a85c79b178bcf40332839bd347aff437c4fb65f + languageName: node + linkType: hard + +"escalade@npm:^3.1.1, escalade@npm:^3.2.0": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 10/9d7169e3965b2f9ae46971afa392f6e5a25545ea30f2e2dd99c9b0a95a3f52b5653681a84f5b2911a413ddad2d7a93d3514165072f349b5ffc59c75a899970d6 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^2.0.0": + version: 2.0.0 + resolution: "escape-string-regexp@npm:2.0.0" + checksum: 10/9f8a2d5743677c16e85c810e3024d54f0c8dea6424fad3c79ef6666e81dd0846f7437f5e729dfcdac8981bc9e5294c39b4580814d114076b8d36318f46ae4395 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 10/98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 + languageName: node + linkType: hard + +"escodegen@npm:^2.0.0": + version: 2.1.0 + resolution: "escodegen@npm:2.1.0" + dependencies: + esprima: "npm:^4.0.1" + estraverse: "npm:^5.2.0" + esutils: "npm:^2.0.2" + source-map: "npm:~0.6.1" + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: bin/escodegen.js + esgenerate: bin/esgenerate.js + checksum: 10/47719a65b2888b4586e3fa93769068b275961c13089e90d5d01a96a6e8e95871b1c3893576814c8fbf08a4a31a496f37e7b2c937cf231270f4d81de012832c7c + languageName: node + linkType: hard + +"eslint-compat-utils@npm:^0.5.1": + version: 0.5.1 + resolution: "eslint-compat-utils@npm:0.5.1" + dependencies: + semver: "npm:^7.5.4" + peerDependencies: + eslint: ">=6.0.0" + checksum: 10/ac65ac1c6107cf19f63f5fc17cea361c9cb1336be7356f23dbb0fac10979974b4622e13e950be43cbf431801f2c07f7dab448573181ccf6edc0b86d5b5304511 + languageName: node + linkType: hard + +"eslint-config-prettier@npm:^9.1.0": + version: 9.1.2 + resolution: "eslint-config-prettier@npm:9.1.2" + peerDependencies: + eslint: ">=7.0.0" + bin: + eslint-config-prettier: bin/cli.js + checksum: 10/e4bba2d76df9dc6e2adca2866e544bfd1ff32232fc483743c04cedd93918a90a327b56d4a7e3f9d3fa32d90bd50b034d09df987860260064b18c026b8bbd15aa + languageName: node + linkType: hard + +"eslint-import-context@npm:^0.1.9": + version: 0.1.9 + resolution: "eslint-import-context@npm:0.1.9" + dependencies: + get-tsconfig: "npm:^4.10.1" + stable-hash-x: "npm:^0.2.0" + peerDependencies: + unrs-resolver: ^1.0.0 + peerDependenciesMeta: + unrs-resolver: + optional: true + checksum: 10/f0778126bb3aae57c8c68946c71c4418927e9d39f72099b799d9c47a3b5712d6c9166b63ee8be58a020961dcc9216df09c856b825336af375ccbbdeedfc82a99 + languageName: node + linkType: hard + +"eslint-import-resolver-typescript@npm:^3.6.3": + version: 3.10.1 + resolution: "eslint-import-resolver-typescript@npm:3.10.1" + dependencies: + "@nolyfill/is-core-module": "npm:1.0.39" + debug: "npm:^4.4.0" + get-tsconfig: "npm:^4.10.0" + is-bun-module: "npm:^2.0.0" + stable-hash: "npm:^0.0.5" + tinyglobby: "npm:^0.2.13" + unrs-resolver: "npm:^1.6.2" + peerDependencies: + eslint: "*" + eslint-plugin-import: "*" + eslint-plugin-import-x: "*" + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + checksum: 10/b8d6a9b2045c70f043f722f78c9e65bc0283126f0ad92c8f07473f7647d77f7b1562f765a472f17e06b81897b407091c0ec9f2e4592b158c9fd92d0b0c33de89 + languageName: node + linkType: hard + +"eslint-plugin-es-x@npm:^7.8.0": + version: 7.8.0 + resolution: "eslint-plugin-es-x@npm:7.8.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.1.2" + "@eslint-community/regexpp": "npm:^4.11.0" + eslint-compat-utils: "npm:^0.5.1" + peerDependencies: + eslint: ">=8" + checksum: 10/1df8d52c4fadc06854ce801af05b05f2642aa2deb918fb7d37738596eabd70b7f21a22b150b78ec9104bac6a1b6b4fb796adea2364ede91b01d20964849ce5f7 + languageName: node + linkType: hard + +"eslint-plugin-import-x@npm:^4.3.0": + version: 4.16.1 + resolution: "eslint-plugin-import-x@npm:4.16.1" + dependencies: + "@typescript-eslint/types": "npm:^8.35.0" + comment-parser: "npm:^1.4.1" + debug: "npm:^4.4.1" + eslint-import-context: "npm:^0.1.9" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.3 || ^10.0.1" + semver: "npm:^7.7.2" + stable-hash-x: "npm:^0.2.0" + unrs-resolver: "npm:^1.9.2" + peerDependencies: + "@typescript-eslint/utils": ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + eslint-import-resolver-node: "*" + peerDependenciesMeta: + "@typescript-eslint/utils": + optional: true + eslint-import-resolver-node: + optional: true + checksum: 10/d1390d49499b613c1334e48fe8b104221584a1473fbec8974584002561aacef5347c4450c559df6fe24c3abe3b0d167eefdc5510e794e96a4ea4f9cb1d501515 + languageName: node + linkType: hard + +"eslint-plugin-jest@npm:^28.8.3": + version: 28.14.0 + resolution: "eslint-plugin-jest@npm:28.14.0" + dependencies: + "@typescript-eslint/utils": "npm:^6.0.0 || ^7.0.0 || ^8.0.0" + peerDependencies: + "@typescript-eslint/eslint-plugin": ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + jest: "*" + peerDependenciesMeta: + "@typescript-eslint/eslint-plugin": + optional: true + jest: + optional: true + checksum: 10/6032497bd97d6dd010450d5fdf535b8613a2789f4f83764ae04361c48d06d92f3d9b2e4350914b8fd857b6e611ba2b5282a1133ab8ec51b3e7053f9d336058e6 + languageName: node + linkType: hard + +"eslint-plugin-jsdoc@npm:^50.2.4": + version: 50.8.0 + resolution: "eslint-plugin-jsdoc@npm:50.8.0" + dependencies: + "@es-joy/jsdoccomment": "npm:~0.50.2" + are-docs-informative: "npm:^0.0.2" + comment-parser: "npm:1.4.1" + debug: "npm:^4.4.1" + escape-string-regexp: "npm:^4.0.0" + espree: "npm:^10.3.0" + esquery: "npm:^1.6.0" + parse-imports-exports: "npm:^0.2.4" + semver: "npm:^7.7.2" + spdx-expression-parse: "npm:^4.0.0" + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + checksum: 10/8857bb6583e04af0a1949e602e2b5b2abc5a951583bdc5a3baa0cc24f7c16db367cbc44e008c45b06dc2029685f0eb1ff6a0bb91e90fd82710ce30952d878d5d + languageName: node + linkType: hard + +"eslint-plugin-n@npm:^17.10.3": + version: 17.23.1 + resolution: "eslint-plugin-n@npm:17.23.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.5.0" + enhanced-resolve: "npm:^5.17.1" + eslint-plugin-es-x: "npm:^7.8.0" + get-tsconfig: "npm:^4.8.1" + globals: "npm:^15.11.0" + globrex: "npm:^0.1.2" + ignore: "npm:^5.3.2" + semver: "npm:^7.6.3" + ts-declaration-location: "npm:^1.0.6" + peerDependencies: + eslint: ">=8.23.0" + checksum: 10/0bac0127e9fe8fb7b81d9b07cadf626bc8e384884e84c51ae5ca510980d37a3bf5980e5edfaf49bc8e9fce95cc624b8217f6fa38763e8340d14524fd06ab16c5 + languageName: node + linkType: hard + +"eslint-plugin-prettier@npm:^5.2.1": + version: 5.5.4 + resolution: "eslint-plugin-prettier@npm:5.5.4" + dependencies: + prettier-linter-helpers: "npm:^1.0.0" + synckit: "npm:^0.11.7" + peerDependencies: + "@types/eslint": ">=8.0.0" + eslint: ">=8.0.0" + eslint-config-prettier: ">= 7.0.0 <10.0.0 || >=10.1.0" + prettier: ">=3.0.0" + peerDependenciesMeta: + "@types/eslint": + optional: true + eslint-config-prettier: + optional: true + checksum: 10/5e39e3b7046d4ba0e1111cc2048630ee9d0aa5d5bb00d6230bef56893fdae37cbe2261babfb26db350cc2ad517c81d283b3f8b04cfee4e5aef7cd4bee72f90de + languageName: node + linkType: hard + +"eslint-plugin-promise@npm:^7.1.0": + version: 7.2.1 + resolution: "eslint-plugin-promise@npm:7.2.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.4.0" + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + checksum: 10/e7447159d52dbc0fdaacfad18571906bb783f9f41f497e73f9b0351e9cc79497f9a9053fbef8141d0c027c16c768a1ef7f8cd4709a4a5cbb14636e862a1ccb34 + languageName: node + linkType: hard + +"eslint-scope@npm:^8.4.0": + version: 8.4.0 + resolution: "eslint-scope@npm:8.4.0" + dependencies: + esrecurse: "npm:^4.3.0" + estraverse: "npm:^5.2.0" + checksum: 10/e8e611701f65375e034c62123946e628894f0b54aa8cb11abe224816389abe5cd74cf16b62b72baa36504f22d1a958b9b8b0169b82397fe2e7997674c0d09b06 + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^3.4.3": + version: 3.4.3 + resolution: "eslint-visitor-keys@npm:3.4.3" + checksum: 10/3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^4.2.1": + version: 4.2.1 + resolution: "eslint-visitor-keys@npm:4.2.1" + checksum: 10/3ee00fc6a7002d4b0ffd9dc99e13a6a7882c557329e6c25ab254220d71e5c9c4f89dca4695352949ea678eb1f3ba912a18ef8aac0a7fe094196fd92f441bfce2 + languageName: node + linkType: hard + +"eslint@npm:^9.11.0": + version: 9.37.0 + resolution: "eslint@npm:9.37.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.8.0" + "@eslint-community/regexpp": "npm:^4.12.1" + "@eslint/config-array": "npm:^0.21.0" + "@eslint/config-helpers": "npm:^0.4.0" + "@eslint/core": "npm:^0.16.0" + "@eslint/eslintrc": "npm:^3.3.1" + "@eslint/js": "npm:9.37.0" + "@eslint/plugin-kit": "npm:^0.4.0" + "@humanfs/node": "npm:^0.16.6" + "@humanwhocodes/module-importer": "npm:^1.0.1" + "@humanwhocodes/retry": "npm:^0.4.2" + "@types/estree": "npm:^1.0.6" + "@types/json-schema": "npm:^7.0.15" + ajv: "npm:^6.12.4" + chalk: "npm:^4.0.0" + cross-spawn: "npm:^7.0.6" + debug: "npm:^4.3.2" + escape-string-regexp: "npm:^4.0.0" + eslint-scope: "npm:^8.4.0" + eslint-visitor-keys: "npm:^4.2.1" + espree: "npm:^10.4.0" + esquery: "npm:^1.5.0" + esutils: "npm:^2.0.2" + fast-deep-equal: "npm:^3.1.3" + file-entry-cache: "npm:^8.0.0" + find-up: "npm:^5.0.0" + glob-parent: "npm:^6.0.2" + ignore: "npm:^5.2.0" + imurmurhash: "npm:^0.1.4" + is-glob: "npm:^4.0.0" + json-stable-stringify-without-jsonify: "npm:^1.0.1" + lodash.merge: "npm:^4.6.2" + minimatch: "npm:^3.1.2" + natural-compare: "npm:^1.4.0" + optionator: "npm:^0.9.3" + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true + bin: + eslint: bin/eslint.js + checksum: 10/c7530470c9cafe9a7f768477f7894d9b9d28e92995186223e99fbd9edeb391119e2a70678a2e98e213ae37cbb41de89403b510f5f33df2340aa65dd6f2a3c0bb + languageName: node + linkType: hard + +"espree@npm:^10.0.1, espree@npm:^10.3.0, espree@npm:^10.4.0": + version: 10.4.0 + resolution: "espree@npm:10.4.0" + dependencies: + acorn: "npm:^8.15.0" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^4.2.1" + checksum: 10/9b355b32dbd1cc9f57121d5ee3be258fab87ebeb7c83fc6c02e5af1a74fc8c5ba79fe8c663e69ea112c3e84a1b95e6a2067ac4443ee7813bb85ac7581acb8bf9 + languageName: node + linkType: hard + +"esprima@npm:^4.0.0, esprima@npm:^4.0.1": + version: 4.0.1 + resolution: "esprima@npm:4.0.1" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: 10/f1d3c622ad992421362294f7acf866aa9409fbad4eb2e8fa230bd33944ce371d32279667b242d8b8907ec2b6ad7353a717f3c0e60e748873a34a7905174bc0eb + languageName: node + linkType: hard + +"esquery@npm:^1.5.0, esquery@npm:^1.6.0": + version: 1.6.0 + resolution: "esquery@npm:1.6.0" + dependencies: + estraverse: "npm:^5.1.0" + checksum: 10/c587fb8ec9ed83f2b1bc97cf2f6854cc30bf784a79d62ba08c6e358bf22280d69aee12827521cf38e69ae9761d23fb7fde593ce315610f85655c139d99b05e5a + languageName: node + linkType: hard + +"esrecurse@npm:^4.3.0": + version: 4.3.0 + resolution: "esrecurse@npm:4.3.0" + dependencies: + estraverse: "npm:^5.2.0" + checksum: 10/44ffcd89e714ea6b30143e7f119b104fc4d75e77ee913f34d59076b40ef2d21967f84e019f84e1fd0465b42cdbf725db449f232b5e47f29df29ed76194db8e16 + languageName: node + linkType: hard + +"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": + version: 5.3.0 + resolution: "estraverse@npm:5.3.0" + checksum: 10/37cbe6e9a68014d34dbdc039f90d0baf72436809d02edffcc06ba3c2a12eb298048f877511353b130153e532aac8d68ba78430c0dd2f44806ebc7c014b01585e + languageName: node + linkType: hard + +"estree-walker@npm:^2.0.2": + version: 2.0.2 + resolution: "estree-walker@npm:2.0.2" + checksum: 10/b02109c5d46bc2ed47de4990eef770f7457b1159a229f0999a09224d2b85ffeed2d7679cffcff90aeb4448e94b0168feb5265b209cdec29aad50a3d6e93d21e2 + languageName: node + linkType: hard + +"esutils@npm:^2.0.2": + version: 2.0.3 + resolution: "esutils@npm:2.0.3" + checksum: 10/b23acd24791db11d8f65be5ea58fd9a6ce2df5120ae2da65c16cfc5331ff59d5ac4ef50af66cd4bde238881503ec839928a0135b99a036a9cdfa22d17fd56cdb + languageName: node + linkType: hard + +"ethereum-cryptography@npm:^2.0.0": + version: 2.0.0 + resolution: "ethereum-cryptography@npm:2.0.0" + dependencies: + "@noble/curves": "npm:1.0.0" + "@noble/hashes": "npm:1.3.0" + "@scure/bip32": "npm:1.3.0" + "@scure/bip39": "npm:1.2.0" + checksum: 10/1f87b4d322fce0801d38741955df1dec20861939ea0c0a89dddf182906f21453f7134662e09fe268e35be9a3848f61667349836b5eb5f4efd6b9a02c1e3bcc85 + languageName: node + linkType: hard + +"execa@npm:^5.0.0, execa@npm:^5.1.1": + version: 5.1.1 + resolution: "execa@npm:5.1.1" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^6.0.0" + human-signals: "npm:^2.1.0" + is-stream: "npm:^2.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^4.0.1" + onetime: "npm:^5.1.2" + signal-exit: "npm:^3.0.3" + strip-final-newline: "npm:^2.0.0" + checksum: 10/8ada91f2d70f7dff702c861c2c64f21dfdc1525628f3c0454fd6f02fce65f7b958616cbd2b99ca7fa4d474e461a3d363824e91b3eb881705231abbf387470597 + languageName: node + linkType: hard + +"exit@npm:^0.1.2": + version: 0.1.2 + resolution: "exit@npm:0.1.2" + checksum: 10/387555050c5b3c10e7a9e8df5f43194e95d7737c74532c409910e585d5554eaff34960c166643f5e23d042196529daad059c292dcf1fb61b8ca878d3677f4b87 + languageName: node + linkType: hard + +"expand-tilde@npm:^2.0.0, expand-tilde@npm:^2.0.2": + version: 2.0.2 + resolution: "expand-tilde@npm:2.0.2" + dependencies: + homedir-polyfill: "npm:^1.0.1" + checksum: 10/2efe6ed407d229981b1b6ceb552438fbc9e5c7d6a6751ad6ced3e0aa5cf12f0b299da695e90d6c2ac79191b5c53c613e508f7149e4573abfbb540698ddb7301a + languageName: node + linkType: hard + +"expect@npm:^27.5.1": + version: 27.5.1 + resolution: "expect@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + jest-get-type: "npm:^27.5.1" + jest-matcher-utils: "npm:^27.5.1" + jest-message-util: "npm:^27.5.1" + checksum: 10/65152be11e791361bb8f74b2516b6ba83021ac4a280b16575340a7dbb72be7fb51b021119a3f40f309a36b375cfb05d4854d5d7af3c53a293a342afc7f86bdaa + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 10/2d9bbb6473de7051f96790d5f9a678f32e60ed0aa70741dc7fdc96fec8d631124ec3374ac144387604f05afff9500f31a1d45bd9eee4cdc2e4f9ad2d9b9d5dbd + languageName: node + linkType: hard + +"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": + version: 3.1.3 + resolution: "fast-deep-equal@npm:3.1.3" + checksum: 10/e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d + languageName: node + linkType: hard + +"fast-diff@npm:^1.1.2": + version: 1.2.0 + resolution: "fast-diff@npm:1.2.0" + checksum: 10/f62419b3d770f201d51c3ee8c4443b752b3ba2d548a6639026b7e09a08203ed2699a8d1fe21efcb8c5186135002d5d2916c12a687cac63785626456a92915adc + languageName: node + linkType: hard + +"fast-glob@npm:^3.3.2": + version: 3.3.3 + resolution: "fast-glob@npm:3.3.3" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.8" + checksum: 10/dcc6432b269762dd47381d8b8358bf964d8f4f60286ac6aa41c01ade70bda459ff2001b516690b96d5365f68a49242966112b5d5cc9cd82395fa8f9d017c90ad + languageName: node + linkType: hard + +"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0": + version: 2.1.0 + resolution: "fast-json-stable-stringify@npm:2.1.0" + checksum: 10/2c20055c1fa43c922428f16ca8bb29f2807de63e5c851f665f7ac9790176c01c3b40335257736b299764a8d383388dabc73c8083b8e1bc3d99f0a941444ec60e + languageName: node + linkType: hard + +"fast-levenshtein@npm:^2.0.6": + version: 2.0.6 + resolution: "fast-levenshtein@npm:2.0.6" + checksum: 10/eb7e220ecf2bab5159d157350b81d01f75726a4382f5a9266f42b9150c4523b9795f7f5d9fbbbeaeac09a441b2369f05ee02db48ea938584205530fe5693cfe1 + languageName: node + linkType: hard + +"fast-safe-stringify@npm:^2.0.6": + version: 2.1.1 + resolution: "fast-safe-stringify@npm:2.1.1" + checksum: 10/dc1f063c2c6ac9533aee14d406441f86783a8984b2ca09b19c2fe281f9ff59d315298bc7bc22fd1f83d26fe19ef2f20e2ddb68e96b15040292e555c5ced0c1e4 + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.13.0 + resolution: "fastq@npm:1.13.0" + dependencies: + reusify: "npm:^1.0.4" + checksum: 10/0902cb9b81accf34e5542612c8a1df6c6ea47674f85bcc9cdc38795a28b53e4a096f751cfcf4fb25d2ea42fee5447499ba6cf5af5d0209297e1d1fd4dd551bb6 + languageName: node + linkType: hard + +"fb-watchman@npm:^2.0.0": + version: 2.0.1 + resolution: "fb-watchman@npm:2.0.1" + dependencies: + bser: "npm:2.1.1" + checksum: 10/9a03efc7d41ce3ca3d799d63505a1f7312caddf4e7737d39f2165bfe4872cbd4b87eccc9e6c57229ea08f14b4d7187896da31a7270b8da7a4aaa8fba2d3d1c42 + languageName: node + linkType: hard + +"fdir@npm:^6.5.0": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10/14ca1c9f0a0e8f4f2e9bf4e8551065a164a09545dae548c12a18d238b72e51e5a7b39bd8e5494b56463a0877672d0a6c1ef62c6fa0677db1b0c847773be939b1 + languageName: node + linkType: hard + +"fflate@npm:^0.8.2": + version: 0.8.2 + resolution: "fflate@npm:0.8.2" + checksum: 10/2bd26ba6d235d428de793c6a0cd1aaa96a06269ebd4e21b46c8fd1bd136abc631acf27e188d47c3936db090bf3e1ede11d15ce9eae9bffdc4bfe1b9dc66ca9cb + languageName: node + linkType: hard + +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" + dependencies: + flat-cache: "npm:^4.0.0" + checksum: 10/afe55c4de4e0d226a23c1eae62a7219aafb390859122608a89fa4df6addf55c7fd3f1a2da6f5b41e7cdff496e4cf28bbd215d53eab5c817afa96d2b40c81bfb0 + languageName: node + linkType: hard + +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: 10/a7095cb39e5bc32fada2aa7c7249d3f6b01bd1ce461a61b0adabacccabd9198500c6fb1f68a7c851a657e273fce2233ba869638897f3d7ed2e87a2d89b4436ea + languageName: node + linkType: hard + +"find-up@npm:^4.0.0, find-up@npm:^4.1.0": + version: 4.1.0 + resolution: "find-up@npm:4.1.0" + dependencies: + locate-path: "npm:^5.0.0" + path-exists: "npm:^4.0.0" + checksum: 10/4c172680e8f8c1f78839486e14a43ef82e9decd0e74145f40707cc42e7420506d5ec92d9a11c22bd2c48fb0c384ea05dd30e10dd152fefeec6f2f75282a8b844 + languageName: node + linkType: hard + +"find-up@npm:^5.0.0": + version: 5.0.0 + resolution: "find-up@npm:5.0.0" + dependencies: + locate-path: "npm:^6.0.0" + path-exists: "npm:^4.0.0" + checksum: 10/07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 + languageName: node + linkType: hard + +"findup-sync@npm:^5.0.0": + version: 5.0.0 + resolution: "findup-sync@npm:5.0.0" + dependencies: + detect-file: "npm:^1.0.0" + is-glob: "npm:^4.0.3" + micromatch: "npm:^4.0.4" + resolve-dir: "npm:^1.0.1" + checksum: 10/576716c77a0e8330b17ae9cba27d1fda8907c8cda7bf33a47f1999e16e089bfc6df4dd62933e0760f430736183c054348c34aa45dd882d49c8c098f55b89ee1d + languageName: node + linkType: hard + +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" + dependencies: + flatted: "npm:^3.2.9" + keyv: "npm:^4.5.4" + checksum: 10/58ce851d9045fffc7871ce2bd718bc485ad7e777bf748c054904b87c351ff1080c2c11da00788d78738bfb51b71e4d5ea12d13b98eb36e3358851ffe495b62dc + languageName: node + linkType: hard + +"flatted@npm:^3.2.9": + version: 3.3.3 + resolution: "flatted@npm:3.3.3" + checksum: 10/8c96c02fbeadcf4e8ffd0fa24983241e27698b0781295622591fc13585e2f226609d95e422bcf2ef044146ffacb6b68b1f20871454eddf75ab3caa6ee5f4a1fe + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.3.0 + resolution: "foreground-child@npm:3.3.0" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 10/e3a60480f3a09b12273ce2c5fcb9514d98dd0e528f58656a1b04680225f918d60a2f81f6a368f2f3b937fcee9cfc0cbf16f1ad9a0bc6a3a6e103a84c9a90087e + languageName: node + linkType: hard + +"form-data@npm:^3.0.0": + version: 3.0.4 + resolution: "form-data@npm:3.0.4" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + es-set-tostringtag: "npm:^2.1.0" + hasown: "npm:^2.0.2" + mime-types: "npm:^2.1.35" + checksum: 10/68e4598e55cb193ef80304bff4d7513bf81ed4116d57b29c6c9a4c28c6f7ce57d46ddd60ba1a80aadf26703a722551e660bca2acaf9212d8b6e1f2e180d9e668 + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/03191781e94bc9a54bd376d3146f90fe8e082627c502185dbf7b9b3032f66b0b142c1115f3b2cc5936575fc1b44845ce903dd4c21bec2a8d69f3bd56f9cee9ec + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10/af143246cf6884fe26fa281621d45cfe111d34b30535a475bfa38dafe343dadb466c047a924ffc7d6b7b18265df4110224ce3803806dbb07173bf2087b648d7f + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 10/e703107c28e362d8d7b910bbcbfd371e640a3bb45ae157a362b5952c0030c0b6d4981140ec319b347bce7adc025dd7813da1ff908a945ac214d64f5402a51b96 + languageName: node + linkType: hard + +"fsevents@npm:^2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" + dependencies: + node-gyp: "npm:latest" + checksum: 10/6b5b6f5692372446ff81cf9501c76e3e0459a4852b3b5f1fc72c103198c125a6b8c72f5f166bdd76ffb2fca261e7f6ee5565daf80dca6e571e55bcc589cc1256 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin": + version: 2.3.2 + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 10/185e20d20f10c8d661d59aac0f3b63b31132d492e1b11fcc2a93cb2c47257ebaee7407c38513efd2b35cafdf972d9beb2ea4593c1e0f3bf8f2744836928d7454 + languageName: node + linkType: hard + +"generator-function@npm:^2.0.0": + version: 2.0.1 + resolution: "generator-function@npm:2.0.1" + checksum: 10/eb7e7eb896c5433f3d40982b2ccacdb3dd990dd3499f14040e002b5d54572476513be8a2e6f9609f6e41ab29f2c4469307611ddbfc37ff4e46b765c326663805 + languageName: node + linkType: hard + +"gensync@npm:^1.0.0-beta.2": + version: 1.0.0-beta.2 + resolution: "gensync@npm:1.0.0-beta.2" + checksum: 10/17d8333460204fbf1f9160d067e1e77f908a5447febb49424b8ab043026049835c9ef3974445c57dbd39161f4d2b04356d7de12b2eecaa27a7a7ea7d871cbedd + languageName: node + linkType: hard + +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: 10/b9769a836d2a98c3ee734a88ba712e62703f1df31b94b784762c433c27a386dd6029ff55c2a920c392e33657d80191edbf18c61487e198844844516f843496b9 + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.2.6": + version: 1.3.1 + resolution: "get-intrinsic@npm:1.3.1" + dependencies: + async-function: "npm:^1.0.0" + async-generator-function: "npm:^1.0.0" + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + function-bind: "npm:^1.1.2" + generator-function: "npm:^2.0.0" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + math-intrinsics: "npm:^1.1.0" + checksum: 10/bb579dda84caa4a3a41611bdd483dade7f00f246f2a7992eb143c5861155290df3fdb48a8406efa3dfb0b434e2c8fafa4eebd469e409d0439247f85fc3fa2cc1 + languageName: node + linkType: hard + +"get-package-type@npm:^0.1.0": + version: 0.1.0 + resolution: "get-package-type@npm:0.1.0" + checksum: 10/bba0811116d11e56d702682ddef7c73ba3481f114590e705fc549f4d868972263896af313c57a25c076e3c0d567e11d919a64ba1b30c879be985fc9d44f96148 + languageName: node + linkType: hard + +"get-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "get-proto@npm:1.0.1" + dependencies: + dunder-proto: "npm:^1.0.1" + es-object-atoms: "npm:^1.0.0" + checksum: 10/4fc96afdb58ced9a67558698b91433e6b037aaa6f1493af77498d7c85b141382cf223c0e5946f334fb328ee85dfe6edd06d218eaf09556f4bc4ec6005d7f5f7b + languageName: node + linkType: hard + +"get-stream@npm:^6.0.0": + version: 6.0.1 + resolution: "get-stream@npm:6.0.1" + checksum: 10/781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 + languageName: node + linkType: hard + +"get-tsconfig@npm:^4.10.0, get-tsconfig@npm:^4.10.1, get-tsconfig@npm:^4.8.1": + version: 4.12.0 + resolution: "get-tsconfig@npm:4.12.0" + dependencies: + resolve-pkg-maps: "npm:^1.0.0" + checksum: 10/1bce6263de6da11c747e804aad1d2d2c1cd893ea4b34a135c3bc1da94f7a8a29d4b23c47e73fd0b1b812650ad48956db5415430f56d7c73670a337a5c4fe4559 + languageName: node + linkType: hard + +"git-hooks-list@npm:^4.0.0": + version: 4.1.1 + resolution: "git-hooks-list@npm:4.1.1" + checksum: 10/a56c8cc3dab505bde2c6de032164a9113968ab7f249dfe2c9f2f23be872165f88c91e097994e009d31e56dd1e81c1f714d0972133314d8d3c6bd92a847ba562f + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 10/32cd106ce8c0d83731966d31517adb766d02c3812de49c30cfe0675c7c0ae6630c11214c54a5ae67aca882cf738d27fd7768f21aa19118b9245950554be07247 + languageName: node + linkType: hard + +"glob-parent@npm:^6.0.2": + version: 6.0.2 + resolution: "glob-parent@npm:6.0.2" + dependencies: + is-glob: "npm:^4.0.3" + checksum: 10/c13ee97978bef4f55106b71e66428eb1512e71a7466ba49025fc2aec59a5bfb0954d5abd58fc5ee6c9b076eef4e1f6d3375c2e964b88466ca390da4419a786a8 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.4.5 + resolution: "glob@npm:10.4.5" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^1.11.1" + bin: + glob: dist/esm/bin.mjs + checksum: 10/698dfe11828b7efd0514cd11e573eaed26b2dff611f0400907281ce3eab0c1e56143ef9b35adc7c77ecc71fba74717b510c7c223d34ca8a98ec81777b293d4ac + languageName: node + linkType: hard + +"glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 10/59452a9202c81d4508a43b8af7082ca5c76452b9fcc4a9ab17655822e6ce9b21d4f8fbadabe4fe3faef448294cec249af305e2cd824b7e9aaf689240e5e96a7b + languageName: node + linkType: hard + +"global-modules@npm:^1.0.0": + version: 1.0.0 + resolution: "global-modules@npm:1.0.0" + dependencies: + global-prefix: "npm:^1.0.1" + is-windows: "npm:^1.0.1" + resolve-dir: "npm:^1.0.0" + checksum: 10/e4031a01c0c7401349bb69e1499c7268d636552b16374c0002d677c7a6185da6782a2927a7a3a7c046eb7be97cd26b3c7b1b736f9818ecc7ac09e9d61449065e + languageName: node + linkType: hard + +"global-prefix@npm:^1.0.1": + version: 1.0.2 + resolution: "global-prefix@npm:1.0.2" + dependencies: + expand-tilde: "npm:^2.0.2" + homedir-polyfill: "npm:^1.0.1" + ini: "npm:^1.3.4" + is-windows: "npm:^1.0.1" + which: "npm:^1.2.14" + checksum: 10/68cf78f81cd85310095ca1f0ec22dd5f43a1059646b2c7b3fc4a7c9ce744356e66ca833adda4e5753e38021847aaec393a159a029ba2d257c08ccb3f00ca2899 + languageName: node + linkType: hard + +"globals@npm:^14.0.0": + version: 14.0.0 + resolution: "globals@npm:14.0.0" + checksum: 10/03939c8af95c6df5014b137cac83aa909090c3a3985caef06ee9a5a669790877af8698ab38007e4c0186873adc14c0b13764acc754b16a754c216cc56aa5f021 + languageName: node + linkType: hard + +"globals@npm:^15.11.0, globals@npm:^15.9.0": + version: 15.15.0 + resolution: "globals@npm:15.15.0" + checksum: 10/7f561c87b2fd381b27fc2db7df8a4ea7a9bb378667b8a7193e61fd2ca3a876479174e2a303a74345fbea6e1242e16db48915c1fd3bf35adcf4060a795b425e18 + languageName: node + linkType: hard + +"globrex@npm:^0.1.2": + version: 0.1.2 + resolution: "globrex@npm:0.1.2" + checksum: 10/81ce62ee6f800d823d6b7da7687f841676d60ee8f51f934ddd862e4057316d26665c4edc0358d4340a923ac00a514f8b67c787e28fe693aae16350f4e60d55e9 + languageName: node + linkType: hard + +"gopd@npm:^1.2.0": + version: 1.2.0 + resolution: "gopd@npm:1.2.0" + checksum: 10/94e296d69f92dc1c0768fcfeecfb3855582ab59a7c75e969d5f96ce50c3d201fd86d5a2857c22565764d5bb8a816c7b1e58f133ec318cd56274da36c5e3fb1a1 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: 10/bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 + languageName: node + linkType: hard + +"graphemer@npm:^1.4.0": + version: 1.4.0 + resolution: "graphemer@npm:1.4.0" + checksum: 10/6dd60dba97007b21e3a829fab3f771803cc1292977fe610e240ea72afd67e5690ac9eeaafc4a99710e78962e5936ab5a460787c2a1180f1cb0ccfac37d29f897 + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 10/261a1357037ead75e338156b1f9452c016a37dcd3283a972a30d9e4a87441ba372c8b81f818cd0fbcd9c0354b4ae7e18b9e1afa1971164aef6d18c2b6095a8ad + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": + version: 1.1.0 + resolution: "has-symbols@npm:1.1.0" + checksum: 10/959385c98696ebbca51e7534e0dc723ada325efa3475350951363cce216d27373e0259b63edb599f72eb94d6cde8577b4b2375f080b303947e560f85692834fa + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.2": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" + dependencies: + has-symbols: "npm:^1.0.3" + checksum: 10/c74c5f5ceee3c8a5b8bc37719840dc3749f5b0306d818974141dda2471a1a2ca6c8e46b9d6ac222c5345df7a901c9b6f350b1e6d62763fec877e26609a401bfe + languageName: node + linkType: hard + +"hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 10/7898a9c1788b2862cf0f9c345a6bec77ba4a0c0983c7f19d610c382343d4f98fa260686b225dfb1f88393a66679d2ec58ee310c1d6868c081eda7918f32cc70a + languageName: node + linkType: hard + +"highlight.js@npm:^10.7.1": + version: 10.7.3 + resolution: "highlight.js@npm:10.7.3" + checksum: 10/db8d10a541936b058e221dbde77869664b2b45bca75d660aa98065be2cd29f3924755fbc7348213f17fd931aefb6e6597448ba6fe82afba6d8313747a91983ee + languageName: node + linkType: hard + +"homedir-polyfill@npm:^1.0.1": + version: 1.0.3 + resolution: "homedir-polyfill@npm:1.0.3" + dependencies: + parse-passwd: "npm:^1.0.0" + checksum: 10/18dd4db87052c6a2179d1813adea0c4bfcfa4f9996f0e226fefb29eb3d548e564350fa28ec46b0bf1fbc0a1d2d6922ceceb80093115ea45ff8842a4990139250 + languageName: node + linkType: hard + +"hosted-git-info@npm:^7.0.0": + version: 7.0.2 + resolution: "hosted-git-info@npm:7.0.2" + dependencies: + lru-cache: "npm:^10.0.1" + checksum: 10/8f085df8a4a637d995f357f48b1e3f6fc1f9f92e82b33fb406415b5741834ed431a510a09141071001e8deea2eee43ce72786463e2aa5e5a70db8648c0eedeab + languageName: node + linkType: hard + +"html-encoding-sniffer@npm:^2.0.1": + version: 2.0.1 + resolution: "html-encoding-sniffer@npm:2.0.1" + dependencies: + whatwg-encoding: "npm:^1.0.5" + checksum: 10/70365109cad69ee60376715fe0a56dd9ebb081327bf155cda93b2c276976c79cbedee2b988de6b0aefd0671a5d70597a35796e6e7d91feeb2c0aba46df059630 + languageName: node + linkType: hard + +"html-escaper@npm:^2.0.0": + version: 2.0.2 + resolution: "html-escaper@npm:2.0.2" + checksum: 10/034d74029dcca544a34fb6135e98d427acd73019796ffc17383eaa3ec2fe1c0471dcbbc8f8ed39e46e86d43ccd753a160631615e4048285e313569609b66d5b7 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 10/362d5ed66b12ceb9c0a328fb31200b590ab1b02f4a254a697dc796850cc4385603e75f53ec59f768b2dad3bfa1464bd229f7de278d2899a0e3beffc634b6683f + languageName: node + linkType: hard + +"http-proxy-agent@npm:^4.0.1": + version: 4.0.1 + resolution: "http-proxy-agent@npm:4.0.1" + dependencies: + "@tootallnate/once": "npm:1" + agent-base: "npm:6" + debug: "npm:4" + checksum: 10/2e17f5519f2f2740b236d1d14911ea4be170c67419dc15b05ea9a860a22c5d9c6ff4da270972117067cc2cefeba9df5f7cd5e7818fdc6ae52b6acf2a533e5fdd + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: 10/d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^5.0.0": + version: 5.0.0 + resolution: "https-proxy-agent@npm:5.0.0" + dependencies: + agent-base: "npm:6" + debug: "npm:4" + checksum: 10/517037badcbbe30757a9a88aaf5e8c198d31aa0b1e9c0a49a0053ab8e812809242218cc9ea1929171f74d95ae1ec89782ba471ffc3709b8910e91d1761f5f1a6 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.5 + resolution: "https-proxy-agent@npm:7.0.5" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 10/6679d46159ab3f9a5509ee80c3a3fc83fba3a920a5e18d32176c3327852c3c00ad640c0c4210a8fd70ea3c4a6d3a1b375bf01942516e7df80e2646bdc77658ab + languageName: node + linkType: hard + +"human-signals@npm:^2.1.0": + version: 2.1.0 + resolution: "human-signals@npm:2.1.0" + checksum: 10/df59be9e0af479036798a881d1f136c4a29e0b518d4abb863afbd11bf30efa3eeb1d0425fc65942dcc05ab3bf40205ea436b0ff389f2cd20b75b8643d539bf86 + languageName: node + linkType: hard + +"iconv-lite@npm:0.4.24": + version: 0.4.24 + resolution: "iconv-lite@npm:0.4.24" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3" + checksum: 10/6d3a2dac6e5d1fb126d25645c25c3a1209f70cceecc68b8ef51ae0da3cdc078c151fade7524a30b12a3094926336831fca09c666ef55b37e2c69638b5d6bd2e3 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10/24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"ignore@npm:^5.2.0, ignore@npm:^5.2.4, ignore@npm:^5.3.2": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10/cceb6a457000f8f6a50e1196429750d782afce5680dd878aa4221bd79972d68b3a55b4b1458fc682be978f4d3c6a249046aa0880637367216444ab7b014cfc98 + languageName: node + linkType: hard + +"ignore@npm:^7.0.0": + version: 7.0.5 + resolution: "ignore@npm:7.0.5" + checksum: 10/f134b96a4de0af419196f52c529d5c6120c4456ff8a6b5a14ceaaa399f883e15d58d2ce651c9b69b9388491d4669dda47285d307e827de9304a53a1824801bc6 + languageName: node + linkType: hard + +"import-fresh@npm:^3.2.1": + version: 3.3.0 + resolution: "import-fresh@npm:3.3.0" + dependencies: + parent-module: "npm:^1.0.0" + resolve-from: "npm:^4.0.0" + checksum: 10/2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa + languageName: node + linkType: hard + +"import-local@npm:^3.0.2": + version: 3.1.0 + resolution: "import-local@npm:3.1.0" + dependencies: + pkg-dir: "npm:^4.2.0" + resolve-cwd: "npm:^3.0.0" + bin: + import-local-fixture: fixtures/cli.js + checksum: 10/bfcdb63b5e3c0e245e347f3107564035b128a414c4da1172a20dc67db2504e05ede4ac2eee1252359f78b0bfd7b19ef180aec427c2fce6493ae782d73a04cddd + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 10/2d30b157a91fe1c1d7c6f653cbf263f039be6c5bfa959245a16d4ee191fc0f2af86c08545b6e6beeb041c56b574d2d5b9f95343d378ab49c0f37394d541e7fc8 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: 10/cd3f5cbc9ca2d624c6a1f53f12e6b341659aba0e2d3254ae2b4464aaea8b4294cdb09616abbc59458f980531f2429784ed6a420d48d245bcad0811980c9efae9 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: 10/d2ebd65441a38c8336c223d1b80b921b9fa737e37ea466fd7e253cb000c64ae1f17fa59e68130ef5bda92cfd8d36b83d37dab0eb0a4558bcfec8e8cdfd2dcb67 + languageName: node + linkType: hard + +"inherits@npm:2": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 + languageName: node + linkType: hard + +"ini@npm:^1.3.4": + version: 1.3.8 + resolution: "ini@npm:1.3.8" + checksum: 10/314ae176e8d4deb3def56106da8002b462221c174ddb7ce0c49ee72c8cd1f9044f7b10cc555a7d8850982c3b9ca96fc212122749f5234bc2b6fb05fb942ed566 + languageName: node + linkType: hard + +"ini@npm:^4.1.3": + version: 4.1.3 + resolution: "ini@npm:4.1.3" + checksum: 10/f536b414d1442e5b233429e2b56efcdb354109b2d65ddd489e5939d8f0f5ad23c88aa2b19c92987249d0dd63ba8192e9aeb1a02b0459549c5a9ff31acd729a5d + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 10/1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c + languageName: node + linkType: hard + +"is-arrayish@npm:^0.2.1": + version: 0.2.1 + resolution: "is-arrayish@npm:0.2.1" + checksum: 10/73ced84fa35e59e2c57da2d01e12cd01479f381d7f122ce41dcbb713f09dbfc651315832cd2bf8accba7681a69e4d6f1e03941d94dd10040d415086360e7005e + languageName: node + linkType: hard + +"is-bun-module@npm:^2.0.0": + version: 2.0.0 + resolution: "is-bun-module@npm:2.0.0" + dependencies: + semver: "npm:^7.7.1" + checksum: 10/cded5a1a58368b847872d08617975d620ad94426d76a932f3e08d55b4574d199e0a62a4fb024fa2dc444200b71719eb0bffc5d3d1e1cc82e29b293bb8d66a990 + languageName: node + linkType: hard + +"is-core-module@npm:^2.12.0, is-core-module@npm:^2.16.0": + version: 2.16.1 + resolution: "is-core-module@npm:2.16.1" + dependencies: + hasown: "npm:^2.0.2" + checksum: 10/452b2c2fb7f889cbbf7e54609ef92cf6c24637c568acc7e63d166812a0fb365ae8a504c333a29add8bdb1686704068caa7f4e4b639b650dde4f00a038b8941fb + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: 10/df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 10/44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-generator-fn@npm:^2.0.0": + version: 2.1.0 + resolution: "is-generator-fn@npm:2.1.0" + checksum: 10/a6ad5492cf9d1746f73b6744e0c43c0020510b59d56ddcb78a91cbc173f09b5e6beff53d75c9c5a29feb618bfef2bf458e025ecf3a57ad2268e2fb2569f56215 + languageName: node + linkType: hard + +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 10/3ed74f2b0cdf4f401f38edb0442ddfde3092d79d7d35c9919c86641efdbcbb32e45aa3c0f70ce5eecc946896cd5a0f26e4188b9f2b881876f7cb6c505b82da11 + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 10/93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 10/6a6c3383f68afa1e05b286af866017c78f1226d43ac8cb064e115ff9ed85eb33f5c4f7216c96a71e4dfea289ef52c5da3aef5bbfade8ffe47a0465d70c0c8e86 + languageName: node + linkType: hard + +"is-plain-obj@npm:^4.1.0": + version: 4.1.0 + resolution: "is-plain-obj@npm:4.1.0" + checksum: 10/6dc45da70d04a81f35c9310971e78a6a3c7a63547ef782e3a07ee3674695081b6ca4e977fbb8efc48dae3375e0b34558d2bcd722aec9bddfa2d7db5b041be8ce + languageName: node + linkType: hard + +"is-potential-custom-element-name@npm:^1.0.1": + version: 1.0.1 + resolution: "is-potential-custom-element-name@npm:1.0.1" + checksum: 10/ced7bbbb6433a5b684af581872afe0e1767e2d1146b2207ca0068a648fb5cab9d898495d1ac0583524faaf24ca98176a7d9876363097c2d14fee6dd324f3a1ab + languageName: node + linkType: hard + +"is-stream@npm:^2.0.0": + version: 2.0.1 + resolution: "is-stream@npm:2.0.1" + checksum: 10/b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 + languageName: node + linkType: hard + +"is-typedarray@npm:^1.0.0": + version: 1.0.0 + resolution: "is-typedarray@npm:1.0.0" + checksum: 10/4b433bfb0f9026f079f4eb3fbaa4ed2de17c9995c3a0b5c800bec40799b4b2a8b4e051b1ada77749deb9ded4ae52fe2096973f3a93ff83df1a5a7184a669478c + languageName: node + linkType: hard + +"is-windows@npm:^1.0.1": + version: 1.0.2 + resolution: "is-windows@npm:1.0.2" + checksum: 10/438b7e52656fe3b9b293b180defb4e448088e7023a523ec21a91a80b9ff8cdb3377ddb5b6e60f7c7de4fa8b63ab56e121b6705fe081b3cf1b828b0a380009ad7 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 10/7c9f715c03aff08f35e98b1fadae1b9267b38f0615d501824f9743f3aab99ef10e303ce7db3f186763a0b70a19de5791ebfc854ff884d5a8c4d92211f642ec92 + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 10/7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": + version: 3.2.0 + resolution: "istanbul-lib-coverage@npm:3.2.0" + checksum: 10/31621b84ad29339242b63d454243f558a7958ee0b5177749bacf1f74be7d95d3fd93853738ef7eebcddfaf3eab014716e51392a8dbd5aa1bdc1b15c2ebc53c24 + languageName: node + linkType: hard + +"istanbul-lib-instrument@npm:^5.0.4, istanbul-lib-instrument@npm:^5.1.0": + version: 5.2.1 + resolution: "istanbul-lib-instrument@npm:5.2.1" + dependencies: + "@babel/core": "npm:^7.12.3" + "@babel/parser": "npm:^7.14.7" + "@istanbuljs/schema": "npm:^0.1.2" + istanbul-lib-coverage: "npm:^3.2.0" + semver: "npm:^6.3.0" + checksum: 10/bbc4496c2f304d799f8ec22202ab38c010ac265c441947f075c0f7d46bd440b45c00e46017cf9053453d42182d768b1d6ed0e70a142c95ab00df9843aa5ab80e + languageName: node + linkType: hard + +"istanbul-lib-report@npm:^3.0.0": + version: 3.0.0 + resolution: "istanbul-lib-report@npm:3.0.0" + dependencies: + istanbul-lib-coverage: "npm:^3.0.0" + make-dir: "npm:^3.0.0" + supports-color: "npm:^7.1.0" + checksum: 10/06b37952e9cb0fe419a37c7f3d74612a098167a9eb0e5264228036e78b42ca5226501e8130738b5306d94bae2ea068ca674080d4af959992523d84aacff67728 + languageName: node + linkType: hard + +"istanbul-lib-source-maps@npm:^4.0.0": + version: 4.0.1 + resolution: "istanbul-lib-source-maps@npm:4.0.1" + dependencies: + debug: "npm:^4.1.1" + istanbul-lib-coverage: "npm:^3.0.0" + source-map: "npm:^0.6.1" + checksum: 10/5526983462799aced011d776af166e350191b816821ea7bcf71cab3e5272657b062c47dc30697a22a43656e3ced78893a42de677f9ccf276a28c913190953b82 + languageName: node + linkType: hard + +"istanbul-reports@npm:^3.1.3": + version: 3.1.4 + resolution: "istanbul-reports@npm:3.1.4" + dependencies: + html-escaper: "npm:^2.0.0" + istanbul-lib-report: "npm:^3.0.0" + checksum: 10/b720f7ff87a37e1500e001913e781395b96cc6ca4d475e01da2ec78d1571435ded4b1b31fb53ef8d760bc5fa691b2b6b647bcb4c1238f6aaf58b261d47510c93 + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 10/96f8786eaab98e4bf5b2a5d6d9588ea46c4d06bbc4f2eb861fdd7b6b182b16f71d8a70e79820f335d52653b16d4843b29dd9cdcf38ae80406756db9199497cf3 + languageName: node + linkType: hard + +"jest-changed-files@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-changed-files@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + execa: "npm:^5.0.0" + throat: "npm:^6.0.1" + checksum: 10/fad21687f899e527bc23b3cabda1b1fa74acb8e17e81bca4d6ca10ab83ebf1d7555f38ba66dda148f97c45b816f941aa4694a09ed0d16a4d7fe3216abf1a222f + languageName: node + linkType: hard + +"jest-circus@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-circus@npm:27.5.1" + dependencies: + "@jest/environment": "npm:^27.5.1" + "@jest/test-result": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + co: "npm:^4.6.0" + dedent: "npm:^0.7.0" + expect: "npm:^27.5.1" + is-generator-fn: "npm:^2.0.0" + jest-each: "npm:^27.5.1" + jest-matcher-utils: "npm:^27.5.1" + jest-message-util: "npm:^27.5.1" + jest-runtime: "npm:^27.5.1" + jest-snapshot: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + pretty-format: "npm:^27.5.1" + slash: "npm:^3.0.0" + stack-utils: "npm:^2.0.3" + throat: "npm:^6.0.1" + checksum: 10/cf8502d2c7669a89d6d9c309842a6bae1b336335f9a108b0ba3d555dcc635c6cc119d28627a5df455215a8bb04bdcdf18b1fee3441aca39c78c8b10053cd33f7 + languageName: node + linkType: hard + +"jest-cli@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-cli@npm:27.5.1" + dependencies: + "@jest/core": "npm:^27.5.1" + "@jest/test-result": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + chalk: "npm:^4.0.0" + exit: "npm:^0.1.2" + graceful-fs: "npm:^4.2.9" + import-local: "npm:^3.0.2" + jest-config: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + jest-validate: "npm:^27.5.1" + prompts: "npm:^2.0.1" + yargs: "npm:^16.2.0" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + bin: + jest: bin/jest.js + checksum: 10/527be160786a14f541b3f75e6241da1bd9ba51894fc9f2ba6466dba7f6ffd3a03de02b40d172ad1d29edc725847f7dd4f6dbf71d304d2364b075ec81c9a53224 + languageName: node + linkType: hard + +"jest-config@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-config@npm:27.5.1" + dependencies: + "@babel/core": "npm:^7.8.0" + "@jest/test-sequencer": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + babel-jest: "npm:^27.5.1" + chalk: "npm:^4.0.0" + ci-info: "npm:^3.2.0" + deepmerge: "npm:^4.2.2" + glob: "npm:^7.1.1" + graceful-fs: "npm:^4.2.9" + jest-circus: "npm:^27.5.1" + jest-environment-jsdom: "npm:^27.5.1" + jest-environment-node: "npm:^27.5.1" + jest-get-type: "npm:^27.5.1" + jest-jasmine2: "npm:^27.5.1" + jest-regex-util: "npm:^27.5.1" + jest-resolve: "npm:^27.5.1" + jest-runner: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + jest-validate: "npm:^27.5.1" + micromatch: "npm:^4.0.4" + parse-json: "npm:^5.2.0" + pretty-format: "npm:^27.5.1" + slash: "npm:^3.0.0" + strip-json-comments: "npm:^3.1.1" + peerDependencies: + ts-node: ">=9.0.0" + peerDependenciesMeta: + ts-node: + optional: true + checksum: 10/63bc2dce50289ff921debedab766daa5122129671c77a9f4137d153a27b29ef77725db15d4809553b687c83495cd7ffefc8eadfd8dfa940d7ea878de57f428c2 + languageName: node + linkType: hard + +"jest-diff@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-diff@npm:27.5.1" + dependencies: + chalk: "npm:^4.0.0" + diff-sequences: "npm:^27.5.1" + jest-get-type: "npm:^27.5.1" + pretty-format: "npm:^27.5.1" + checksum: 10/af454f30f33af625832bdb02614e188a41e33ce79086b43f95dbcc515274dd36bf8443b8d0299e22c2416e7591da4321e6bc7f2b0aef56471d1133c6b6833221 + languageName: node + linkType: hard + +"jest-docblock@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-docblock@npm:27.5.1" + dependencies: + detect-newline: "npm:^3.0.0" + checksum: 10/65c765c5418986313685b7c49dcd844cd3bc281807a35f778d6ba479246b6ea070cdd98384582a9aed1a0d3ebf94b7fb14a33df5975aaae2eb20dc00281731f4 + languageName: node + linkType: hard + +"jest-each@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-each@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + chalk: "npm:^4.0.0" + jest-get-type: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + pretty-format: "npm:^27.5.1" + checksum: 10/d73e3c7bbcd3a073e9fa29bd1f200bb9757cbcc568460c1d0971fc21924800f2d3e421219a85e20c54ea2a0129d2da9e2dfc266b6014244c5901f3ca2de7a99e + languageName: node + linkType: hard + +"jest-environment-jsdom@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-environment-jsdom@npm:27.5.1" + dependencies: + "@jest/environment": "npm:^27.5.1" + "@jest/fake-timers": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + jest-mock: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + jsdom: "npm:^16.6.0" + checksum: 10/bc104aef7d7530d0740402aa84ac812138b6d1e51fe58adecce679f82b99340ddab73e5ec68fa079f33f50c9ddec9728fc9f0ddcca2ad6f0b351eed2762cc555 + languageName: node + linkType: hard + +"jest-environment-node@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-environment-node@npm:27.5.1" + dependencies: + "@jest/environment": "npm:^27.5.1" + "@jest/fake-timers": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + jest-mock: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + checksum: 10/0f988330c4f3eec092e3fb37ea753b0c6f702e83cd8f4d770af9c2bf964a70bc45fbd34ec6fdb6d71ce98a778d9f54afd673e63f222e4667fff289e8069dba39 + languageName: node + linkType: hard + +"jest-get-type@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-get-type@npm:27.5.1" + checksum: 10/63064ab70195c21007d897c1157bf88ff94a790824a10f8c890392e7d17eda9c3900513cb291ca1c8d5722cad79169764e9a1279f7c8a9c4cd6e9109ff04bbc0 + languageName: node + linkType: hard + +"jest-haste-map@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-haste-map@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + "@types/graceful-fs": "npm:^4.1.2" + "@types/node": "npm:*" + anymatch: "npm:^3.0.3" + fb-watchman: "npm:^2.0.0" + fsevents: "npm:^2.3.2" + graceful-fs: "npm:^4.2.9" + jest-regex-util: "npm:^27.5.1" + jest-serializer: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + jest-worker: "npm:^27.5.1" + micromatch: "npm:^4.0.4" + walker: "npm:^1.0.7" + dependenciesMeta: + fsevents: + optional: true + checksum: 10/cbf42e4a3d2b6fc8ad64d732c1bb8a230fe25ad3df7f9f93e8af2950691ef9a5241a9d48c5c88e365744a7467b8cb00ab21c01baee4ee0c2b62acc657782545f + languageName: node + linkType: hard + +"jest-jasmine2@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-jasmine2@npm:27.5.1" + dependencies: + "@jest/environment": "npm:^27.5.1" + "@jest/source-map": "npm:^27.5.1" + "@jest/test-result": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + co: "npm:^4.6.0" + expect: "npm:^27.5.1" + is-generator-fn: "npm:^2.0.0" + jest-each: "npm:^27.5.1" + jest-matcher-utils: "npm:^27.5.1" + jest-message-util: "npm:^27.5.1" + jest-runtime: "npm:^27.5.1" + jest-snapshot: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + pretty-format: "npm:^27.5.1" + throat: "npm:^6.0.1" + checksum: 10/052d3c99c36295564a6688ae7e66cfd59997ca9589ccaaa2551d344d84699816a6b8c7bebf3a5f7bcdf691a07f7065c61f4a0770b810e5d887acd21f80a06304 + languageName: node + linkType: hard + +"jest-leak-detector@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-leak-detector@npm:27.5.1" + dependencies: + jest-get-type: "npm:^27.5.1" + pretty-format: "npm:^27.5.1" + checksum: 10/5c9689060960567ddaf16c570d87afa760a461885765d2c71ef4f4857bbc3af1482c34e3cce88e50beefde1bf35e33530b020480752057a7e3dbb1ca0bae359f + languageName: node + linkType: hard + +"jest-matcher-utils@npm:^27.0.0, jest-matcher-utils@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-matcher-utils@npm:27.5.1" + dependencies: + chalk: "npm:^4.0.0" + jest-diff: "npm:^27.5.1" + jest-get-type: "npm:^27.5.1" + pretty-format: "npm:^27.5.1" + checksum: 10/037f99878a0515581d7728ed3aed03707810f4da5a1c7ffb9d68a2c6c3180851a6ec40b559af37fbe891dde3ba12552b19e47b8188a27b6c5a53376be6907f32 + languageName: node + linkType: hard + +"jest-message-util@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-message-util@npm:27.5.1" + dependencies: + "@babel/code-frame": "npm:^7.12.13" + "@jest/types": "npm:^27.5.1" + "@types/stack-utils": "npm:^2.0.0" + chalk: "npm:^4.0.0" + graceful-fs: "npm:^4.2.9" + micromatch: "npm:^4.0.4" + pretty-format: "npm:^27.5.1" + slash: "npm:^3.0.0" + stack-utils: "npm:^2.0.3" + checksum: 10/8fbf39dc25a7ef328dab22efcb3b198cbc788e309bc93e39fdb42b5541dba201c76acf47df476a4ee3d3fc6a6898e77bfc02677c198a98af91db1af0a435ade6 + languageName: node + linkType: hard + +"jest-mock@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-mock@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + checksum: 10/be9a8777801659227d3bb85317a3aca617542779a290a6a45c9addec8bda29f494a524cb4af96c82b825ecb02171e320dfbfde3e3d9218672f9e38c9fac118f4 + languageName: node + linkType: hard + +"jest-pnp-resolver@npm:^1.2.2": + version: 1.2.3 + resolution: "jest-pnp-resolver@npm:1.2.3" + peerDependencies: + jest-resolve: "*" + peerDependenciesMeta: + jest-resolve: + optional: true + checksum: 10/db1a8ab2cb97ca19c01b1cfa9a9c8c69a143fde833c14df1fab0766f411b1148ff0df878adea09007ac6a2085ec116ba9a996a6ad104b1e58c20adbf88eed9b2 + languageName: node + linkType: hard + +"jest-regex-util@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-regex-util@npm:27.5.1" + checksum: 10/d45ca7a9543616a34f7f3079337439cf07566e677a096472baa2810e274b9808b76767c97b0a4029b8a5b82b9d256dee28ef9ad4138b2b9e5933f6fac106c418 + languageName: node + linkType: hard + +"jest-resolve-dependencies@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-resolve-dependencies@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + jest-regex-util: "npm:^27.5.1" + jest-snapshot: "npm:^27.5.1" + checksum: 10/c67af97afad1da88f5530317c732bbd1262d1225f6cd7f4e4740a5db48f90ab0bd8564738ac70d1a43934894f9aef62205c1b8f8ee89e5c7a737e6a121ee4c25 + languageName: node + linkType: hard + +"jest-resolve@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-resolve@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + chalk: "npm:^4.0.0" + graceful-fs: "npm:^4.2.9" + jest-haste-map: "npm:^27.5.1" + jest-pnp-resolver: "npm:^1.2.2" + jest-util: "npm:^27.5.1" + jest-validate: "npm:^27.5.1" + resolve: "npm:^1.20.0" + resolve.exports: "npm:^1.1.0" + slash: "npm:^3.0.0" + checksum: 10/93659a9d5ec365a9f2fd3fcaa8f799e3bd090318c48890951ca4325e863f4eb778bb7f7e8d1d8495eda4c157ee771d93fb31f37364ce1a36a09f77f1089e52a1 + languageName: node + linkType: hard + +"jest-runner@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-runner@npm:27.5.1" + dependencies: + "@jest/console": "npm:^27.5.1" + "@jest/environment": "npm:^27.5.1" + "@jest/test-result": "npm:^27.5.1" + "@jest/transform": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + emittery: "npm:^0.8.1" + graceful-fs: "npm:^4.2.9" + jest-docblock: "npm:^27.5.1" + jest-environment-jsdom: "npm:^27.5.1" + jest-environment-node: "npm:^27.5.1" + jest-haste-map: "npm:^27.5.1" + jest-leak-detector: "npm:^27.5.1" + jest-message-util: "npm:^27.5.1" + jest-resolve: "npm:^27.5.1" + jest-runtime: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + jest-worker: "npm:^27.5.1" + source-map-support: "npm:^0.5.6" + throat: "npm:^6.0.1" + checksum: 10/97bd741f442ebbcebfdb5e8389c0df645448d0b4b634e4128b3387d6fe432cf0f93feb0ecfc3842fed20a35c43c24460ed5dd89d7501ca9e2fdba65e5a4edf37 + languageName: node + linkType: hard + +"jest-runtime@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-runtime@npm:27.5.1" + dependencies: + "@jest/environment": "npm:^27.5.1" + "@jest/fake-timers": "npm:^27.5.1" + "@jest/globals": "npm:^27.5.1" + "@jest/source-map": "npm:^27.5.1" + "@jest/test-result": "npm:^27.5.1" + "@jest/transform": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + chalk: "npm:^4.0.0" + cjs-module-lexer: "npm:^1.0.0" + collect-v8-coverage: "npm:^1.0.0" + execa: "npm:^5.0.0" + glob: "npm:^7.1.3" + graceful-fs: "npm:^4.2.9" + jest-haste-map: "npm:^27.5.1" + jest-message-util: "npm:^27.5.1" + jest-mock: "npm:^27.5.1" + jest-regex-util: "npm:^27.5.1" + jest-resolve: "npm:^27.5.1" + jest-snapshot: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + slash: "npm:^3.0.0" + strip-bom: "npm:^4.0.0" + checksum: 10/cc6cdce5bee4bc02935a4671394e19962f3469eeb6e823442ca99e5670fd87f60ed64b7c7156ac13d2799fc44fe9bb806454a3f17c8342bd35e564b1a40e3920 + languageName: node + linkType: hard + +"jest-serializer@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-serializer@npm:27.5.1" + dependencies: + "@types/node": "npm:*" + graceful-fs: "npm:^4.2.9" + checksum: 10/803e03a552278610edc6753c0dd9fa5bb5cd3ca47414a7b2918106efb62b79fd5e9ae785d0a21f12a299fa599fea8acc1fa6dd41283328cee43962cf7df9bb44 + languageName: node + linkType: hard + +"jest-snapshot@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-snapshot@npm:27.5.1" + dependencies: + "@babel/core": "npm:^7.7.2" + "@babel/generator": "npm:^7.7.2" + "@babel/plugin-syntax-typescript": "npm:^7.7.2" + "@babel/traverse": "npm:^7.7.2" + "@babel/types": "npm:^7.0.0" + "@jest/transform": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/babel__traverse": "npm:^7.0.4" + "@types/prettier": "npm:^2.1.5" + babel-preset-current-node-syntax: "npm:^1.0.0" + chalk: "npm:^4.0.0" + expect: "npm:^27.5.1" + graceful-fs: "npm:^4.2.9" + jest-diff: "npm:^27.5.1" + jest-get-type: "npm:^27.5.1" + jest-haste-map: "npm:^27.5.1" + jest-matcher-utils: "npm:^27.5.1" + jest-message-util: "npm:^27.5.1" + jest-util: "npm:^27.5.1" + natural-compare: "npm:^1.4.0" + pretty-format: "npm:^27.5.1" + semver: "npm:^7.3.2" + checksum: 10/01b2c70c56980f21fc299fa68a1d1e3a9612f06d2fcdd1cf60f636c3dd427b814efc5f15aacc567e0c3b28fd32129be4a10fca34555f358534fc88e5cee4ffbb + languageName: node + linkType: hard + +"jest-util@npm:^27.0.0, jest-util@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-util@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + ci-info: "npm:^3.2.0" + graceful-fs: "npm:^4.2.9" + picomatch: "npm:^2.2.3" + checksum: 10/ecc7da41769558e57dbde544141ffceb536ee53b663de1e002d4b86784cea500a10f9a7f02e8b804e517aa0e34d3145118734c7e8b5071f9f18a153ede5b062d + languageName: node + linkType: hard + +"jest-validate@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-validate@npm:27.5.1" + dependencies: + "@jest/types": "npm:^27.5.1" + camelcase: "npm:^6.2.0" + chalk: "npm:^4.0.0" + jest-get-type: "npm:^27.5.1" + leven: "npm:^3.1.0" + pretty-format: "npm:^27.5.1" + checksum: 10/1fc4d46ecead311a0362bb8ea7767718b682e3d73b65c2bf55cb33722c13bb340e52d20f35d7af38918f8655a78ebbedf3d8a9eaba4ac067883cef006fcf9197 + languageName: node + linkType: hard + +"jest-watcher@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-watcher@npm:27.5.1" + dependencies: + "@jest/test-result": "npm:^27.5.1" + "@jest/types": "npm:^27.5.1" + "@types/node": "npm:*" + ansi-escapes: "npm:^4.2.1" + chalk: "npm:^4.0.0" + jest-util: "npm:^27.5.1" + string-length: "npm:^4.0.1" + checksum: 10/2c2f6cb4256d5cf90c4ae2d8400d5a40399aea9152c85b8b04c3fe4cbecb65e188462de1267d134a42c69d2ddb13a6e50a8ea1aef809b1e4c8fff7a0019ca2c4 + languageName: node + linkType: hard + +"jest-worker@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-worker@npm:27.5.1" + dependencies: + "@types/node": "npm:*" + merge-stream: "npm:^2.0.0" + supports-color: "npm:^8.0.0" + checksum: 10/06c6e2a84591d9ede704d5022fc13791e8876e83397c89d481b0063332abbb64c0f01ef4ca7de520b35c7a1058556078d6bdc3631376f4e9ffb42316c1a8488e + languageName: node + linkType: hard + +"jest@npm:^27.5.1": + version: 27.5.1 + resolution: "jest@npm:27.5.1" + dependencies: + "@jest/core": "npm:^27.5.1" + import-local: "npm:^3.0.2" + jest-cli: "npm:^27.5.1" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + bin: + jest: bin/jest.js + checksum: 10/a1435098e1885e48d2a46c660176cd34d69bc80fa72966a1ea8781ab6d5355ee514d45cf871d2da2b5a54509979e53d39fbb9b149c94e430127f44ed0d70639c + languageName: node + linkType: hard + +"js-tokens@npm:^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 10/af37d0d913fb56aec6dc0074c163cc71cd23c0b8aad5c2350747b6721d37ba118af35abdd8b33c47ec2800de07dedb16a527ca9c530ee004093e04958bd0cbf2 + languageName: node + linkType: hard + +"js-yaml@npm:^3.13.1, js-yaml@npm:^3.14.1": + version: 3.14.1 + resolution: "js-yaml@npm:3.14.1" + dependencies: + argparse: "npm:^1.0.7" + esprima: "npm:^4.0.0" + bin: + js-yaml: bin/js-yaml.js + checksum: 10/9e22d80b4d0105b9899135365f746d47466ed53ef4223c529b3c0f7a39907743fdbd3c4379f94f1106f02755b5e90b2faaf84801a891135544e1ea475d1a1379 + languageName: node + linkType: hard + +"js-yaml@npm:^4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" + dependencies: + argparse: "npm:^2.0.1" + bin: + js-yaml: bin/js-yaml.js + checksum: 10/c138a34a3fd0d08ebaf71273ad4465569a483b8a639e0b118ff65698d257c2791d3199e3f303631f2cb98213fa7b5f5d6a4621fd0fff819421b990d30d967140 + languageName: node + linkType: hard + +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: 10/bebe7ae829bbd586ce8cbe83501dd8cb8c282c8902a8aeeed0a073a89dc37e8103b1244f3c6acd60278bcbfe12d93a3f83c9ac396868a3b3bbc3c5e5e3b648ef + languageName: node + linkType: hard + +"jsdoc-type-pratt-parser@npm:~4.1.0": + version: 4.1.0 + resolution: "jsdoc-type-pratt-parser@npm:4.1.0" + checksum: 10/30d88f95f6cbb4a1aa6d4b0d0ae46eb1096e606235ecaf9bab7a3ed5da860516b5d1cd967182765002f292c627526db918f3e56d34637bcf810e6ef84d403f3f + languageName: node + linkType: hard + +"jsdom@npm:^16.6.0": + version: 16.7.0 + resolution: "jsdom@npm:16.7.0" + dependencies: + abab: "npm:^2.0.5" + acorn: "npm:^8.2.4" + acorn-globals: "npm:^6.0.0" + cssom: "npm:^0.4.4" + cssstyle: "npm:^2.3.0" + data-urls: "npm:^2.0.0" + decimal.js: "npm:^10.2.1" + domexception: "npm:^2.0.1" + escodegen: "npm:^2.0.0" + form-data: "npm:^3.0.0" + html-encoding-sniffer: "npm:^2.0.1" + http-proxy-agent: "npm:^4.0.1" + https-proxy-agent: "npm:^5.0.0" + is-potential-custom-element-name: "npm:^1.0.1" + nwsapi: "npm:^2.2.0" + parse5: "npm:6.0.1" + saxes: "npm:^5.0.1" + symbol-tree: "npm:^3.2.4" + tough-cookie: "npm:^4.0.0" + w3c-hr-time: "npm:^1.0.2" + w3c-xmlserializer: "npm:^2.0.0" + webidl-conversions: "npm:^6.1.0" + whatwg-encoding: "npm:^1.0.5" + whatwg-mimetype: "npm:^2.3.0" + whatwg-url: "npm:^8.5.0" + ws: "npm:^7.4.6" + xml-name-validator: "npm:^3.0.0" + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + checksum: 10/c530c04b0e3718769a66e19b0b5c762126658bce384d6743b807a28a9d89beba4ad932e474f570323efe6ce832b3d9a8f94816fd6c4d386416d5ea0b64e07ebc + languageName: node + linkType: hard + +"jsesc@npm:^3.0.2": + version: 3.1.0 + resolution: "jsesc@npm:3.1.0" + bin: + jsesc: bin/jsesc + checksum: 10/20bd37a142eca5d1794f354db8f1c9aeb54d85e1f5c247b371de05d23a9751ecd7bd3a9c4fc5298ea6fa09a100dafb4190fa5c98c6610b75952c3487f3ce7967 + languageName: node + linkType: hard + +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 10/82876154521b7b68ba71c4f969b91572d1beabadd87bd3a6b236f85fbc7dc4695089191ed60bb59f9340993c51b33d479f45b6ba9f3548beb519705281c32c3c + languageName: node + linkType: hard + +"json-parse-even-better-errors@npm:^2.3.0": + version: 2.3.1 + resolution: "json-parse-even-better-errors@npm:2.3.1" + checksum: 10/5f3a99009ed5f2a5a67d06e2f298cc97bc86d462034173308156f15b43a6e850be8511dc204b9b94566305da2947f7d90289657237d210351a39059ff9d666cf + languageName: node + linkType: hard + +"json-parse-even-better-errors@npm:^3.0.0": + version: 3.0.0 + resolution: "json-parse-even-better-errors@npm:3.0.0" + checksum: 10/f1970b5220c7fa23d888565510752c3d5e863f93668a202fcaa719739fa41485dfc6a1db212f702ebd3c873851cc067aebc2917e3f79763cae2fdb95046f38f3 + languageName: node + linkType: hard + +"json-rpc-random-id@npm:^1.0.1": + version: 1.0.1 + resolution: "json-rpc-random-id@npm:1.0.1" + checksum: 10/fcd2e884193a129ace4002bd65a86e9cdb206733b4693baea77bd8b372cf8de3043fbea27716a2c9a716581a908ca8d978d9dfec4847eb2cf77edb4cf4b2252c + languageName: node + linkType: hard + +"json-schema-traverse@npm:^0.4.1": + version: 0.4.1 + resolution: "json-schema-traverse@npm:0.4.1" + checksum: 10/7486074d3ba247769fda17d5181b345c9fb7d12e0da98b22d1d71a5db9698d8b4bd900a3ec1a4ffdd60846fc2556274a5c894d0c48795f14cb03aeae7b55260b + languageName: node + linkType: hard + +"json-stable-stringify-without-jsonify@npm:^1.0.1": + version: 1.0.1 + resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" + checksum: 10/12786c2e2f22c27439e6db0532ba321f1d0617c27ad8cb1c352a0e9249a50182fd1ba8b52a18899291604b0c32eafa8afd09e51203f19109a0537f68db2b652d + languageName: node + linkType: hard + +"json5@npm:2.x, json5@npm:^2.2.3": + version: 2.2.3 + resolution: "json5@npm:2.2.3" + bin: + json5: lib/cli.js + checksum: 10/1db67b853ff0de3534085d630691d3247de53a2ed1390ba0ddff681ea43e9b3e30ecbdb65c5e9aab49435e44059c23dbd6fee8ee619419ba37465bb0dd7135da + languageName: node + linkType: hard + +"jsonc-parser@npm:^3.2.0": + version: 3.3.1 + resolution: "jsonc-parser@npm:3.3.1" + checksum: 10/9b0dc391f20b47378f843ef1e877e73ec652a5bdc3c5fa1f36af0f119a55091d147a86c1ee86a232296f55c929bba174538c2bf0312610e0817a22de131cc3f4 + languageName: node + linkType: hard + +"keyv@npm:^4.5.4": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: "npm:3.0.1" + checksum: 10/167eb6ef64cc84b6fa0780ee50c9de456b422a1e18802209234f7c2cf7eae648c7741f32e50d7e24ccb22b24c13154070b01563d642755b156c357431a191e75 + languageName: node + linkType: hard + +"kleur@npm:^3.0.3": + version: 3.0.3 + resolution: "kleur@npm:3.0.3" + checksum: 10/0c0ecaf00a5c6173d25059c7db2113850b5457016dfa1d0e3ef26da4704fbb186b4938d7611246d86f0ddf1bccf26828daa5877b1f232a65e7373d0122a83e7f + languageName: node + linkType: hard + +"leven@npm:^3.1.0": + version: 3.1.0 + resolution: "leven@npm:3.1.0" + checksum: 10/638401d534585261b6003db9d99afd244dfe82d75ddb6db5c0df412842d5ab30b2ef18de471aaec70fe69a46f17b4ae3c7f01d8a4e6580ef7adb9f4273ad1e55 + languageName: node + linkType: hard + +"levn@npm:^0.4.1": + version: 0.4.1 + resolution: "levn@npm:0.4.1" + dependencies: + prelude-ls: "npm:^1.2.1" + type-check: "npm:~0.4.0" + checksum: 10/2e4720ff79f21ae08d42374b0a5c2f664c5be8b6c8f565bb4e1315c96ed3a8acaa9de788ffed82d7f2378cf36958573de07ef92336cb5255ed74d08b8318c9ee + languageName: node + linkType: hard + +"lines-and-columns@npm:^1.1.6": + version: 1.2.4 + resolution: "lines-and-columns@npm:1.2.4" + checksum: 10/0c37f9f7fa212b38912b7145e1cd16a5f3cd34d782441c3e6ca653485d326f58b3caccda66efce1c5812bde4961bbde3374fae4b0d11bf1226152337f3894aa5 + languageName: node + linkType: hard + +"locate-path@npm:^5.0.0": + version: 5.0.0 + resolution: "locate-path@npm:5.0.0" + dependencies: + p-locate: "npm:^4.1.0" + checksum: 10/83e51725e67517287d73e1ded92b28602e3ae5580b301fe54bfb76c0c723e3f285b19252e375712316774cf52006cb236aed5704692c32db0d5d089b69696e30 + languageName: node + linkType: hard + +"locate-path@npm:^6.0.0": + version: 6.0.0 + resolution: "locate-path@npm:6.0.0" + dependencies: + p-locate: "npm:^5.0.0" + checksum: 10/72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a + languageName: node + linkType: hard + +"lodash.memoize@npm:4.x": + version: 4.1.2 + resolution: "lodash.memoize@npm:4.1.2" + checksum: 10/192b2168f310c86f303580b53acf81ab029761b9bd9caa9506a019ffea5f3363ea98d7e39e7e11e6b9917066c9d36a09a11f6fe16f812326390d8f3a54a1a6da + languageName: node + linkType: hard + +"lodash.merge@npm:^4.6.2": + version: 4.6.2 + resolution: "lodash.merge@npm:4.6.2" + checksum: 10/d0ea2dd0097e6201be083865d50c3fb54fbfbdb247d9cc5950e086c991f448b7ab0cdab0d57eacccb43473d3f2acd21e134db39f22dac2d6c9ba6bf26978e3d6 + languageName: node + linkType: hard + +"lodash@npm:^4.17.21, lodash@npm:^4.7.0": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: 10/c08619c038846ea6ac754abd6dd29d2568aa705feb69339e836dfa8d8b09abbb2f859371e86863eda41848221f9af43714491467b5b0299122431e202bb0c532 + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 10/e6e90267360476720fa8e83cc168aa2bf0311f3f2eea20a6ba78b90a885ae72071d9db132f40fda4129c803e7dcec3a6b6a6fbb44ca90b081630b810b5d6a41a + languageName: node + linkType: hard + +"lru-cache@npm:^5.1.1": + version: 5.1.1 + resolution: "lru-cache@npm:5.1.1" + dependencies: + yallist: "npm:^3.0.2" + checksum: 10/951d2673dcc64a7fb888bf3d13bc2fdf923faca97d89cdb405ba3dfff77e2b26e5798d405e78fcd7094c9e7b8b4dab2ddc5a4f8a11928af24a207b7c738ca3f8 + languageName: node + linkType: hard + +"lunr@npm:^2.3.9": + version: 2.3.9 + resolution: "lunr@npm:2.3.9" + checksum: 10/f2f6db34c046f5a767782fe2454e6dd69c75ba3c5cf5c1cb9cacca2313a99c2ba78ff8fa67dac866fb7c4ffd5f22e06684793f5f15ba14bddb598b94513d54bf + languageName: node + linkType: hard + +"magic-string@npm:^0.30.19": + version: 0.30.19 + resolution: "magic-string@npm:0.30.19" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.5" + checksum: 10/5045467fad59ddfba6ccfb00fde6edbc0f841089f0da07d844cf513c73de289bbbf933bde16168cba2c9ef38d75ac68e1617a5ce74aae16d6f39285bda1d51c4 + languageName: node + linkType: hard + +"make-dir@npm:^3.0.0": + version: 3.1.0 + resolution: "make-dir@npm:3.1.0" + dependencies: + semver: "npm:^6.0.0" + checksum: 10/484200020ab5a1fdf12f393fe5f385fc8e4378824c940fba1729dcd198ae4ff24867bc7a5646331e50cead8abff5d9270c456314386e629acec6dff4b8016b78 + languageName: node + linkType: hard + +"make-error@npm:1.x, make-error@npm:^1.1.1": + version: 1.3.6 + resolution: "make-error@npm:1.3.6" + checksum: 10/b86e5e0e25f7f777b77fabd8e2cbf15737972869d852a22b7e73c17623928fccb826d8e46b9951501d3f20e51ad74ba8c59ed584f610526a48f8ccf88aaec402 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^13.0.0": + version: 13.0.1 + resolution: "make-fetch-happen@npm:13.0.1" + dependencies: + "@npmcli/agent": "npm:^2.0.0" + cacache: "npm:^18.0.0" + http-cache-semantics: "npm:^4.1.1" + is-lambda: "npm:^1.0.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + proc-log: "npm:^4.2.0" + promise-retry: "npm:^2.0.1" + ssri: "npm:^10.0.0" + checksum: 10/11bae5ad6ac59b654dbd854f30782f9de052186c429dfce308eda42374528185a100ee40ac9ffdc36a2b6c821ecaba43913e4730a12f06f15e895ea9cb23fa59 + languageName: node + linkType: hard + +"makeerror@npm:1.0.12": + version: 1.0.12 + resolution: "makeerror@npm:1.0.12" + dependencies: + tmpl: "npm:1.0.5" + checksum: 10/4c66ddfc654537333da952c084f507fa4c30c707b1635344eb35be894d797ba44c901a9cebe914aa29a7f61357543ba09b09dddbd7f65b4aee756b450f169f40 + languageName: node + linkType: hard + +"marked-terminal@npm:^7.1.0": + version: 7.3.0 + resolution: "marked-terminal@npm:7.3.0" + dependencies: + ansi-escapes: "npm:^7.0.0" + ansi-regex: "npm:^6.1.0" + chalk: "npm:^5.4.1" + cli-highlight: "npm:^2.1.11" + cli-table3: "npm:^0.6.5" + node-emoji: "npm:^2.2.0" + supports-hyperlinks: "npm:^3.1.0" + peerDependencies: + marked: ">=1 <16" + checksum: 10/1dfdfe752a4ebe6aec8de4a51180612a5f29982026b104a86215efb46b82b2a1942531a6bb840163c8d827e3eadc5cf93272e6eb29ec549f72b73b8b2eb97cfe + languageName: node + linkType: hard + +"marked@npm:^4.3.0": + version: 4.3.0 + resolution: "marked@npm:4.3.0" + bin: + marked: bin/marked.js + checksum: 10/c830bb4cb3705b754ca342b656e8a582d7428706b2678c898b856f6030c134ce2d1e19136efa3e6a1841f7330efbd24963d6bdeddc57d2938e906250f99895d0 + languageName: node + linkType: hard + +"marked@npm:^9.1.2": + version: 9.1.6 + resolution: "marked@npm:9.1.6" + bin: + marked: bin/marked.js + checksum: 10/29d073500c70b6b53cd35a8d19f5e43df6e2819ddeca8848a31901b87b82ca0ea46a8a831920c656c69c33ad5dce4b75654c4c4ced34a67f4e4e4a31c7620cfe + languageName: node + linkType: hard + +"math-intrinsics@npm:^1.1.0": + version: 1.1.0 + resolution: "math-intrinsics@npm:1.1.0" + checksum: 10/11df2eda46d092a6035479632e1ec865b8134bdfc4bd9e571a656f4191525404f13a283a515938c3a8de934dbfd9c09674d9da9fa831e6eb7e22b50b197d2edd + languageName: node + linkType: hard + +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 10/6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 + languageName: node + linkType: hard + +"merge2@npm:^1.3.0": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 10/7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 + languageName: node + linkType: hard + +"micro-ftch@npm:^0.3.1": + version: 0.3.1 + resolution: "micro-ftch@npm:0.3.1" + checksum: 10/a7ab07d25e28ec4ae492ce4542ea9b06eee85538742b3b1263b247366ee8872f2c5ce9c8651138b2f1d22c8212f691a7b8b5384fe86ead5aff1852e211f1c035 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.4, micromatch@npm:^4.0.8": + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" + dependencies: + braces: "npm:^3.0.3" + picomatch: "npm:^2.3.1" + checksum: 10/6bf2a01672e7965eb9941d1f02044fad2bd12486b5553dc1116ff24c09a8723157601dc992e74c911d896175918448762df3b3fd0a6b61037dd1a9766ddfbf58 + languageName: node + linkType: hard + +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 10/54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 + languageName: node + linkType: hard + +"mime-types@npm:^2.1.35": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 10/89aa9651b67644035de2784a6e665fc685d79aba61857e02b9c8758da874a754aed4a9aced9265f5ed1171fd934331e5516b84a7f0218031b6fa0270eca1e51a + languageName: node + linkType: hard + +"mimic-fn@npm:^2.1.0": + version: 2.1.0 + resolution: "mimic-fn@npm:2.1.0" + checksum: 10/d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a + languageName: node + linkType: hard + +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10/e0b25b04cd4ec6732830344e5739b13f8690f8a012d73445a4a19fbc623f5dd481ef7a5827fde25954cd6026fede7574cc54dc4643c99d6c6b653d6203f94634 + languageName: node + linkType: hard + +"minimatch@npm:^7.4.6": + version: 7.4.6 + resolution: "minimatch@npm:7.4.6" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10/0046ba1161ac6414bde1b07c440792ebcdb2ed93e6714c85c73974332b709b7e692801550bc9da22028a8613407b3f13861e17dd0dd44f4babdeacd44950430b + languageName: node + linkType: hard + +"minimatch@npm:^9.0.0, minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10/dd6a8927b063aca6d910b119e1f2df6d2ce7d36eab91de83167dd136bb85e1ebff97b0d3de1cb08bd1f7e018ca170b4962479fefab5b2a69e2ae12cb2edc8348 + languageName: node + linkType: hard + +"minimatch@npm:^9.0.3 || ^10.0.1": + version: 10.0.3 + resolution: "minimatch@npm:10.0.3" + dependencies: + "@isaacs/brace-expansion": "npm:^5.0.0" + checksum: 10/d5b8b2538b367f2cfd4aeef27539fddeee58d1efb692102b848e4a968a09780a302c530eb5aacfa8c57f7299155fb4b4e85219ad82664dcef5c66f657111d9b8 + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10/b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.5 + resolution: "minipass-fetch@npm:3.0.5" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: 10/c669948bec1373313aaa8f104b962a3ced9f45c49b26366a4b0ae27ccdfa9c5740d72c8a84d3f8623d7a61c5fc7afdfda44789008c078f61a62441142efc4a97 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10/40982d8d836a52b0f37049a0a7e5d0f089637298e6d9b45df9c115d4f0520682a78258905e5c8b180fb41b593b0a82cc1361d2c74b45f7ada66334f84d1ecfdd + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10/a5c6ef069f70d9a524d3428af39f2b117ff8cd84172e19b754e7264a33df460873e6eb3d6e55758531580970de50ae950c496256bb4ad3691a2974cddff189f0 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 10/61682162d29f45d3152b78b08bab7fb32ca10899bc5991ffe98afc18c9e9543bd1e3be94f8b8373ba6262497db63607079dc242ea62e43e7b2270837b7347c93 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 10/c25f0ee8196d8e6036661104bacd743785b2599a21de5c516b32b3fa2b83113ac89a2358465bc04956baab37ffb956ae43be679b2262bf7be15fce467ccd7950 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: 10/ae0f45436fb51344dcb87938446a32fbebb540d0e191d63b35e1c773d47512e17307bf54aa88326cc6d176594d00e4423563a091f7266c2f9a6872cdc1e234d1 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: 10/d71b8dcd4b5af2fe13ecf3bd24070263489404fe216488c5ba7e38ece1f54daf219e72a833a3a2dc404331e870e9f44963a33399589490956bff003a3404d3b2 + languageName: node + linkType: hard + +"ms@npm:^2.1.3": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: 10/aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d + languageName: node + linkType: hard + +"multimatch@npm:^5.0.0": + version: 5.0.0 + resolution: "multimatch@npm:5.0.0" + dependencies: + "@types/minimatch": "npm:^3.0.3" + array-differ: "npm:^3.0.0" + array-union: "npm:^2.1.0" + arrify: "npm:^2.0.1" + minimatch: "npm:^3.0.4" + checksum: 10/82c8030a53af965cab48da22f1b0f894ef99e16ee680dabdfbd38d2dfacc3c8208c475203d747afd9e26db44118ed0221d5a0d65268c864f06d6efc7ac6df812 + languageName: node + linkType: hard + +"mz@npm:^2.4.0": + version: 2.7.0 + resolution: "mz@npm:2.7.0" + dependencies: + any-promise: "npm:^1.0.0" + object-assign: "npm:^4.0.1" + thenify-all: "npm:^1.0.0" + checksum: 10/8427de0ece99a07e9faed3c0c6778820d7543e3776f9a84d22cf0ec0a8eb65f6e9aee9c9d353ff9a105ff62d33a9463c6ca638974cc652ee8140cd1e35951c87 + languageName: node + linkType: hard + +"nanoid@npm:^3.3.11": + version: 3.3.11 + resolution: "nanoid@npm:3.3.11" + bin: + nanoid: bin/nanoid.cjs + checksum: 10/73b5afe5975a307aaa3c95dfe3334c52cdf9ae71518176895229b8d65ab0d1c0417dd081426134eb7571c055720428ea5d57c645138161e7d10df80815527c48 + languageName: node + linkType: hard + +"napi-postinstall@npm:^0.3.0": + version: 0.3.4 + resolution: "napi-postinstall@npm:0.3.4" + bin: + napi-postinstall: lib/cli.js + checksum: 10/5541381508f9e1051ff3518701c7130ebac779abb3a1ffe9391fcc3cab4cc0569b0ba0952357db3f6b12909c3bb508359a7a60261ffd795feebbdab967175832 + languageName: node + linkType: hard + +"natural-compare@npm:^1.4.0": + version: 1.4.0 + resolution: "natural-compare@npm:1.4.0" + checksum: 10/23ad088b08f898fc9b53011d7bb78ec48e79de7627e01ab5518e806033861bef68d5b0cd0e2205c2f36690ac9571ff6bcb05eb777ced2eeda8d4ac5b44592c3d + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 10/2723fb822a17ad55c93a588a4bc44d53b22855bf4be5499916ca0cab1e7165409d0b288ba2577d7b029f10ce18cf2ed8e703e5af31c984e1e2304277ef979837 + languageName: node + linkType: hard + +"node-emoji@npm:^2.2.0": + version: 2.2.0 + resolution: "node-emoji@npm:2.2.0" + dependencies: + "@sindresorhus/is": "npm:^4.6.0" + char-regex: "npm:^1.0.2" + emojilib: "npm:^2.4.0" + skin-tone: "npm:^2.0.0" + checksum: 10/2548668f5cc9f781c94dc39971a630b2887111e0970c29fc523e924819d1b39b53a2694a4d1046861adf538c4462d06ee0269c48717ccad30336a918d9a911d5 + languageName: node + linkType: hard + +"node-gyp@npm:^10.0.0, node-gyp@npm:latest": + version: 10.3.1 + resolution: "node-gyp@npm:10.3.1" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^4.1.0" + semver: "npm:^7.3.5" + tar: "npm:^6.2.1" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 10/d3004f648559e42d7ec8791ea75747fe8a163a6061c202e311e5d7a5f6266baa9a5f5c6fde7be563974c88b030c5d0855fd945364f52fcd230d2a2ceee7be80d + languageName: node + linkType: hard + +"node-int64@npm:^0.4.0": + version: 0.4.0 + resolution: "node-int64@npm:0.4.0" + checksum: 10/b7afc2b65e56f7035b1a2eec57ae0fbdee7d742b1cdcd0f4387562b6527a011ab1cbe9f64cc8b3cca61e3297c9637c8bf61cec2e6b8d3a711d4b5267dfafbe02 + languageName: node + linkType: hard + +"node-releases@npm:^2.0.21": + version: 2.0.23 + resolution: "node-releases@npm:2.0.23" + checksum: 10/f937b23e279b791bc7842d71536e8520ea12efa2c307e5803227ecbba1c807a932bbe3c26d6a8c0e12e21cb3f9c6a6d4ed14beee489ff9e9be49f6d4cf0c7aa4 + languageName: node + linkType: hard + +"nopt@npm:^7.0.0": + version: 7.2.1 + resolution: "nopt@npm:7.2.1" + dependencies: + abbrev: "npm:^2.0.0" + bin: + nopt: bin/nopt.js + checksum: 10/95a1f6dec8a81cd18cdc2fed93e6f0b4e02cf6bdb4501c848752c6e34f9883d9942f036a5e3b21a699047d8a448562d891e67492df68ec9c373e6198133337ae + languageName: node + linkType: hard + +"normalize-package-data@npm:^6.0.0": + version: 6.0.2 + resolution: "normalize-package-data@npm:6.0.2" + dependencies: + hosted-git-info: "npm:^7.0.0" + semver: "npm:^7.3.5" + validate-npm-package-license: "npm:^3.0.4" + checksum: 10/7c4216a2426aa76c0197f8372f06b23a0484d62b3518fb5c0f6ebccb16376bdfab29ceba96f95c75f60506473198f1337fe337b945c8df0541fe32b8049ab4c9 + languageName: node + linkType: hard + +"normalize-path@npm:^3.0.0": + version: 3.0.0 + resolution: "normalize-path@npm:3.0.0" + checksum: 10/88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20 + languageName: node + linkType: hard + +"npm-install-checks@npm:^6.0.0": + version: 6.3.0 + resolution: "npm-install-checks@npm:6.3.0" + dependencies: + semver: "npm:^7.1.1" + checksum: 10/6c20dadb878a0d2f1f777405217b6b63af1299d0b43e556af9363ee6eefaa98a17dfb7b612a473a473e96faf7e789c58b221e0d8ffdc1d34903c4f71618df3b4 + languageName: node + linkType: hard + +"npm-normalize-package-bin@npm:3.0.1, npm-normalize-package-bin@npm:^3.0.0": + version: 3.0.1 + resolution: "npm-normalize-package-bin@npm:3.0.1" + checksum: 10/de416d720ab22137a36292ff8a333af499ea0933ef2320a8c6f56a73b0f0448227fec4db5c890d702e26d21d04f271415eab6580b5546456861cc0c19498a4bf + languageName: node + linkType: hard + +"npm-package-arg@npm:^11.0.0": + version: 11.0.3 + resolution: "npm-package-arg@npm:11.0.3" + dependencies: + hosted-git-info: "npm:^7.0.0" + proc-log: "npm:^4.0.0" + semver: "npm:^7.3.5" + validate-npm-package-name: "npm:^5.0.0" + checksum: 10/bacc863907edf98940286edc2fd80327901c1e8b34426d538cdc708ed66bc6567f06d742d838eaf35db6804347bb4ba56ca9cef032c4b52743b33e7a22a2678e + languageName: node + linkType: hard + +"npm-pick-manifest@npm:^9.0.0": + version: 9.1.0 + resolution: "npm-pick-manifest@npm:9.1.0" + dependencies: + npm-install-checks: "npm:^6.0.0" + npm-normalize-package-bin: "npm:^3.0.0" + npm-package-arg: "npm:^11.0.0" + semver: "npm:^7.3.5" + checksum: 10/e759e4fe4076da9169cf522964a80bbc096d50cd24c8c44b50b44706c4479bd9d9d018fbdb76c6ea0c6037e012e07c6c917a1ecaa7ae1a1169cddfae1c0f24b6 + languageName: node + linkType: hard + +"npm-run-path@npm:^4.0.1": + version: 4.0.1 + resolution: "npm-run-path@npm:4.0.1" + dependencies: + path-key: "npm:^3.0.0" + checksum: 10/5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23 + languageName: node + linkType: hard + +"nwsapi@npm:^2.2.0": + version: 2.2.22 + resolution: "nwsapi@npm:2.2.22" + checksum: 10/6bdeeb61345873808b914c002d351049a2678bcae0dd957ad20949da25eca583b19a9c750f510b776b6554a2e0ee8df4e6fb13fd7a46c6025ead0b19e70378b3 + languageName: node + linkType: hard + +"object-assign@npm:^4.0.1": + version: 4.1.1 + resolution: "object-assign@npm:4.1.1" + checksum: 10/fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f + languageName: node + linkType: hard + +"once@npm:^1.3.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10/cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + languageName: node + linkType: hard + +"onetime@npm:^5.1.2": + version: 5.1.2 + resolution: "onetime@npm:5.1.2" + dependencies: + mimic-fn: "npm:^2.1.0" + checksum: 10/e9fd0695a01cf226652f0385bf16b7a24153dbbb2039f764c8ba6d2306a8506b0e4ce570de6ad99c7a6eb49520743afdb66edd95ee979c1a342554ed49a9aadd + languageName: node + linkType: hard + +"optionator@npm:^0.9.3": + version: 0.9.3 + resolution: "optionator@npm:0.9.3" + dependencies: + "@aashutoshrathi/word-wrap": "npm:^1.2.3" + deep-is: "npm:^0.1.3" + fast-levenshtein: "npm:^2.0.6" + levn: "npm:^0.4.1" + prelude-ls: "npm:^1.2.1" + type-check: "npm:^0.4.0" + checksum: 10/fa28d3016395974f7fc087d6bbf0ac7f58ac3489f4f202a377e9c194969f329a7b88c75f8152b33fb08794a30dcd5c079db6bb465c28151357f113d80bbf67da + languageName: node + linkType: hard + +"p-limit@npm:^2.2.0": + version: 2.3.0 + resolution: "p-limit@npm:2.3.0" + dependencies: + p-try: "npm:^2.0.0" + checksum: 10/84ff17f1a38126c3314e91ecfe56aecbf36430940e2873dadaa773ffe072dc23b7af8e46d4b6485d302a11673fe94c6b67ca2cfbb60c989848b02100d0594ac1 + languageName: node + linkType: hard + +"p-limit@npm:^3.0.2": + version: 3.1.0 + resolution: "p-limit@npm:3.1.0" + dependencies: + yocto-queue: "npm:^0.1.0" + checksum: 10/7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 + languageName: node + linkType: hard + +"p-locate@npm:^4.1.0": + version: 4.1.0 + resolution: "p-locate@npm:4.1.0" + dependencies: + p-limit: "npm:^2.2.0" + checksum: 10/513bd14a455f5da4ebfcb819ef706c54adb09097703de6aeaa5d26fe5ea16df92b48d1ac45e01e3944ce1e6aa2a66f7f8894742b8c9d6e276e16cd2049a2b870 + languageName: node + linkType: hard + +"p-locate@npm:^5.0.0": + version: 5.0.0 + resolution: "p-locate@npm:5.0.0" + dependencies: + p-limit: "npm:^3.0.2" + checksum: 10/1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 10/7ba4a2b1e24c05e1fc14bbaea0fc6d85cf005ae7e9c9425d4575550f37e2e584b1af97bcde78eacd7559208f20995988d52881334db16cf77bc1bcf68e48ed7c + languageName: node + linkType: hard + +"p-try@npm:^2.0.0": + version: 2.2.0 + resolution: "p-try@npm:2.2.0" + checksum: 10/f8a8e9a7693659383f06aec604ad5ead237c7a261c18048a6e1b5b85a5f8a067e469aa24f5bc009b991ea3b058a87f5065ef4176793a200d4917349881216cae + languageName: node + linkType: hard + +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 10/58ee9538f2f762988433da00e26acc788036914d57c71c246bf0be1b60cdbd77dd60b6a3e1a30465f0b248aeb80079e0b34cb6050b1dfa18c06953bb1cbc7602 + languageName: node + linkType: hard + +"parent-module@npm:^1.0.0": + version: 1.0.1 + resolution: "parent-module@npm:1.0.1" + dependencies: + callsites: "npm:^3.0.0" + checksum: 10/6ba8b255145cae9470cf5551eb74be2d22281587af787a2626683a6c20fbb464978784661478dd2a3f1dad74d1e802d403e1b03c1a31fab310259eec8ac560ff + languageName: node + linkType: hard + +"parse-imports-exports@npm:^0.2.4": + version: 0.2.4 + resolution: "parse-imports-exports@npm:0.2.4" + dependencies: + parse-statements: "npm:1.0.11" + checksum: 10/144d459771d1aeaa80eebffe43a2074c34e5b79a86d326c907efea90b62ff41af9555600b8e117e6cab717654d8e20b440e9ab09cdbbc9092f352cb0a9e1f3a3 + languageName: node + linkType: hard + +"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": + version: 5.2.0 + resolution: "parse-json@npm:5.2.0" + dependencies: + "@babel/code-frame": "npm:^7.0.0" + error-ex: "npm:^1.3.1" + json-parse-even-better-errors: "npm:^2.3.0" + lines-and-columns: "npm:^1.1.6" + checksum: 10/62085b17d64da57f40f6afc2ac1f4d95def18c4323577e1eced571db75d9ab59b297d1d10582920f84b15985cbfc6b6d450ccbf317644cfa176f3ed982ad87e2 + languageName: node + linkType: hard + +"parse-passwd@npm:^1.0.0": + version: 1.0.0 + resolution: "parse-passwd@npm:1.0.0" + checksum: 10/4e55e0231d58f828a41d0f1da2bf2ff7bcef8f4cb6146e69d16ce499190de58b06199e6bd9b17fbf0d4d8aef9052099cdf8c4f13a6294b1a522e8e958073066e + languageName: node + linkType: hard + +"parse-statements@npm:1.0.11": + version: 1.0.11 + resolution: "parse-statements@npm:1.0.11" + checksum: 10/287c2739f4cbffa08e28a95ea2d3ff4a8a51ddb367df6212ae2cd80580a1189e09c6edcb8277fc05d0fdbcb93c86ad16b591f317e2fe12ac4189de738863e514 + languageName: node + linkType: hard + +"parse5-htmlparser2-tree-adapter@npm:^6.0.0": + version: 6.0.1 + resolution: "parse5-htmlparser2-tree-adapter@npm:6.0.1" + dependencies: + parse5: "npm:^6.0.1" + checksum: 10/3400a2cd1ad450b2fe148544154f86ea53d3ed6b6eab56c78bb43b9629d3dfe9f580dffd75bbf32be134ffef645b68081fc764bf75c210f236ab9c5c8c38c252 + languageName: node + linkType: hard + +"parse5@npm:6.0.1, parse5@npm:^6.0.1": + version: 6.0.1 + resolution: "parse5@npm:6.0.1" + checksum: 10/dfb110581f62bd1425725a7c784ae022a24669bd0efc24b58c71fc731c4d868193e2ebd85b74cde2dbb965e4dcf07059b1e651adbec1b3b5267531bd132fdb75 + languageName: node + linkType: hard + +"parse5@npm:^5.1.1": + version: 5.1.1 + resolution: "parse5@npm:5.1.1" + checksum: 10/5b509744cfe81488a33be05578df490c460690e64519fa67f0a0acb9c1bca05914e8acad17a977e2cf5964a000e43959b40024f0c243dd6595dd0cca8a32f71b + languageName: node + linkType: hard + +"path-exists@npm:^4.0.0": + version: 4.0.0 + resolution: "path-exists@npm:4.0.0" + checksum: 10/505807199dfb7c50737b057dd8d351b82c033029ab94cb10a657609e00c1bc53b951cfdbccab8de04c5584d5eff31128ce6afd3db79281874a5ef2adbba55ed1 + languageName: node + linkType: hard + +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 10/060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8 + languageName: node + linkType: hard + +"path-key@npm:^3.0.0, path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 10/55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-parse@npm:^1.0.7": + version: 1.0.7 + resolution: "path-parse@npm:1.0.7" + checksum: 10/49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a + languageName: node + linkType: hard + +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 10/5e8845c159261adda6f09814d7725683257fcc85a18f329880ab4d7cc1d12830967eae5d5894e453f341710d5484b8fdbbd4d75181b4d6e1eb2f4dc7aeadc434 + languageName: node + linkType: hard + +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 10/5b1e2daa247062061325b8fdbfd1fb56dde0a448fb1455453276ea18c60685bdad23a445dc148cf87bc216be1573357509b7d4060494a6fd768c7efad833ee45 + languageName: node + linkType: hard + +"picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10/e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 + languageName: node + linkType: hard + +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 10/60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc + languageName: node + linkType: hard + +"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3": + version: 4.0.3 + resolution: "picomatch@npm:4.0.3" + checksum: 10/57b99055f40b16798f2802916d9c17e9744e620a0db136554af01d19598b96e45e2f00014c91d1b8b13874b80caa8c295b3d589a3f72373ec4aaf54baa5962d5 + languageName: node + linkType: hard + +"pirates@npm:^4.0.4": + version: 4.0.5 + resolution: "pirates@npm:4.0.5" + checksum: 10/3728bae0cf6c18c3d25f5449ee8c5bc1a6a83bca688abe0e1654ce8c069bfd408170397cef133ed9ec8b0faeb4093c5c728d0e72ab7b3385256cd87008c40364 + languageName: node + linkType: hard + +"pkg-dir@npm:^4.2.0": + version: 4.2.0 + resolution: "pkg-dir@npm:4.2.0" + dependencies: + find-up: "npm:^4.0.0" + checksum: 10/9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6 + languageName: node + linkType: hard + +"please-upgrade-node@npm:^3.2.0": + version: 3.2.0 + resolution: "please-upgrade-node@npm:3.2.0" + dependencies: + semver-compare: "npm:^1.0.0" + checksum: 10/d87c41581a2a022fbe25965a97006238cd9b8cbbf49b39f78d262548149a9d30bd2bdf35fec3d810e0001e630cd46ef13c7e19c389dea8de7e64db271a2381bb + languageName: node + linkType: hard + +"pony-cause@npm:^2.1.10": + version: 2.1.10 + resolution: "pony-cause@npm:2.1.10" + checksum: 10/906563565030996d0c40ba79a584e2f298391931acc59c98510f9fd583d72cd9e9c58b0fb5a25bbae19daf16840f94cb9c1ee72c7ed5ef249ecba147cee40495 + languageName: node + linkType: hard + +"postcss@npm:^8.5.6": + version: 8.5.6 + resolution: "postcss@npm:8.5.6" + dependencies: + nanoid: "npm:^3.3.11" + picocolors: "npm:^1.1.1" + source-map-js: "npm:^1.2.1" + checksum: 10/9e4fbe97574091e9736d0e82a591e29aa100a0bf60276a926308f8c57249698935f35c5d2f4e80de778d0cbb8dcffab4f383d85fd50c5649aca421c3df729b86 + languageName: node + linkType: hard + +"prelude-ls@npm:^1.2.1": + version: 1.2.1 + resolution: "prelude-ls@npm:1.2.1" + checksum: 10/0b9d2c76801ca652a7f64892dd37b7e3fab149a37d2424920099bf894acccc62abb4424af2155ab36dea8744843060a2d8ddc983518d0b1e22265a22324b72ed + languageName: node + linkType: hard + +"prettier-linter-helpers@npm:^1.0.0": + version: 1.0.0 + resolution: "prettier-linter-helpers@npm:1.0.0" + dependencies: + fast-diff: "npm:^1.1.2" + checksum: 10/00ce8011cf6430158d27f9c92cfea0a7699405633f7f1d4a45f07e21bf78e99895911cbcdc3853db3a824201a7c745bd49bfea8abd5fb9883e765a90f74f8392 + languageName: node + linkType: hard + +"prettier-plugin-packagejson@npm:^2.5.8": + version: 2.5.19 + resolution: "prettier-plugin-packagejson@npm:2.5.19" + dependencies: + sort-package-json: "npm:3.4.0" + synckit: "npm:0.11.11" + peerDependencies: + prettier: ">= 1.16.0" + peerDependenciesMeta: + prettier: + optional: true + checksum: 10/a3caba8b62f92b53a8414cf1061a87bb5931e790c77022c64f3fa12122cf78b392912525deb9671bcdb196106a3078d4dcc6ae076fe2e14e26931b9d9b0195f1 + languageName: node + linkType: hard + +"prettier@npm:^2.8.8": + version: 2.8.8 + resolution: "prettier@npm:2.8.8" + bin: + prettier: bin-prettier.js + checksum: 10/00cdb6ab0281f98306cd1847425c24cbaaa48a5ff03633945ab4c701901b8e96ad558eb0777364ffc312f437af9b5a07d0f45346266e8245beaf6247b9c62b24 + languageName: node + linkType: hard + +"prettier@npm:^3.3.3": + version: 3.6.2 + resolution: "prettier@npm:3.6.2" + bin: + prettier: bin/prettier.cjs + checksum: 10/1213691706bcef1371d16ef72773c8111106c3533b660b1cc8ec158bd109cdf1462804125f87f981f23c4a3dba053b6efafda30ab0114cc5b4a725606bb9ff26 + languageName: node + linkType: hard + +"pretty-format@npm:^27.0.0, pretty-format@npm:^27.5.1": + version: 27.5.1 + resolution: "pretty-format@npm:27.5.1" + dependencies: + ansi-regex: "npm:^5.0.1" + ansi-styles: "npm:^5.0.0" + react-is: "npm:^17.0.1" + checksum: 10/248990cbef9e96fb36a3e1ae6b903c551ca4ddd733f8d0912b9cc5141d3d0b3f9f8dfb4d799fb1c6723382c9c2083ffbfa4ad43ff9a0e7535d32d41fd5f01da6 + languageName: node + linkType: hard + +"proc-log@npm:^4.0.0, proc-log@npm:^4.1.0, proc-log@npm:^4.2.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 10/4e1394491b717f6c1ade15c570ecd4c2b681698474d3ae2d303c1e4b6ab9455bd5a81566211e82890d5a5ae9859718cc6954d5150bb18b09b72ecb297beae90a + languageName: node + linkType: hard + +"promise-inflight@npm:^1.0.1": + version: 1.0.1 + resolution: "promise-inflight@npm:1.0.1" + checksum: 10/1560d413ea20c5a74f3631d39ba8cbd1972b9228072a755d01e1f5ca5110382d9af76a1582d889445adc6e75bb5ac4886b56dc4b6eae51b30145d7bb1ac7505b + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 10/96e1a82453c6c96eef53a37a1d6134c9f2482f94068f98a59145d0986ca4e497bf110a410adf73857e588165eab3899f0ebcf7b3890c1b3ce802abc0d65967d4 + languageName: node + linkType: hard + +"prompts@npm:^2.0.1": + version: 2.4.2 + resolution: "prompts@npm:2.4.2" + dependencies: + kleur: "npm:^3.0.3" + sisteransi: "npm:^1.0.5" + checksum: 10/c52536521a4d21eff4f2f2aa4572446cad227464066365a7167e52ccf8d9839c099f9afec1aba0eed3d5a2514b3e79e0b3e7a1dc326b9acde6b75d27ed74b1a9 + languageName: node + linkType: hard + +"psl@npm:^1.1.33": + version: 1.15.0 + resolution: "psl@npm:1.15.0" + dependencies: + punycode: "npm:^2.3.1" + checksum: 10/5e7467eb5196eb7900d156783d12907d445c0122f76c73203ce96b148a6ccf8c5450cc805887ffada38ff92d634afcf33720c24053cb01d5b6598d1c913c5caf + languageName: node + linkType: hard + +"punycode@npm:^2.1.0, punycode@npm:^2.1.1, punycode@npm:^2.3.1": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: 10/febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 + languageName: node + linkType: hard + +"querystringify@npm:^2.1.1": + version: 2.2.0 + resolution: "querystringify@npm:2.2.0" + checksum: 10/46ab16f252fd892fc29d6af60966d338cdfeea68a231e9457631ffd22d67cec1e00141e0a5236a2eb16c0d7d74175d9ec1d6f963660c6f2b1c2fc85b194c5680 + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 10/72900df0616e473e824202113c3df6abae59150dfb73ed13273503127235320e9c8ca4aaaaccfd58cf417c6ca92a6e68ee9a5c3182886ae949a768639b388a7b + languageName: node + linkType: hard + +"react-is@npm:^17.0.1": + version: 17.0.2 + resolution: "react-is@npm:17.0.2" + checksum: 10/73b36281e58eeb27c9cc6031301b6ae19ecdc9f18ae2d518bdb39b0ac564e65c5779405d623f1df9abf378a13858b79442480244bd579968afc1faf9a2ce5e05 + languageName: node + linkType: hard + +"read-cmd-shim@npm:^4.0.0": + version: 4.0.0 + resolution: "read-cmd-shim@npm:4.0.0" + checksum: 10/69a83acf0a3e2357762d5944a6f4a3f3c5527d0f9fe8a5c9362225aaf702ccfa580ff3bc0b84809c99e88861a5e5be147629717f02ff9befdac68fca1ccc7664 + languageName: node + linkType: hard + +"readdirp@npm:^3.6.0": + version: 3.6.0 + resolution: "readdirp@npm:3.6.0" + dependencies: + picomatch: "npm:^2.2.1" + checksum: 10/196b30ef6ccf9b6e18c4e1724b7334f72a093d011a99f3b5920470f0b3406a51770867b3e1ae9711f227ef7a7065982f6ee2ce316746b2cb42c88efe44297fe7 + languageName: node + linkType: hard + +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: 10/a72468e2589270d91f06c7d36ec97a88db53ae5d6fe3787fadc943f0b0276b10347f89b363b2a82285f650bdcc135ad4a257c61bdd4d00d6df1fa24875b0ddaf + languageName: node + linkType: hard + +"require-package-name@npm:^2.0.1": + version: 2.0.1 + resolution: "require-package-name@npm:2.0.1" + checksum: 10/3332d4eec10a730627ca20f37a8a7d57badd9e8953f238472aa457b0084907f86ca5b2af94694a0c8bb2e1101bdb3ed6ddc964d2044b040fe076a9bf5b19755f + languageName: node + linkType: hard + +"requires-port@npm:^1.0.0": + version: 1.0.0 + resolution: "requires-port@npm:1.0.0" + checksum: 10/878880ee78ccdce372784f62f52a272048e2d0827c29ae31e7f99da18b62a2b9463ea03a75f277352f4697c100183debb0532371ad515a2d49d4bfe596dd4c20 + languageName: node + linkType: hard + +"resolve-cwd@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-cwd@npm:3.0.0" + dependencies: + resolve-from: "npm:^5.0.0" + checksum: 10/546e0816012d65778e580ad62b29e975a642989108d9a3c5beabfb2304192fa3c9f9146fbdfe213563c6ff51975ae41bac1d3c6e047dd9572c94863a057b4d81 + languageName: node + linkType: hard + +"resolve-dir@npm:^1.0.0, resolve-dir@npm:^1.0.1": + version: 1.0.1 + resolution: "resolve-dir@npm:1.0.1" + dependencies: + expand-tilde: "npm:^2.0.0" + global-modules: "npm:^1.0.0" + checksum: 10/ef736b8ed60d6645c3b573da17d329bfb50ec4e1d6c5ffd6df49e3497acef9226f9810ea6823b8ece1560e01dcb13f77a9f6180d4f242d00cc9a8f4de909c65c + languageName: node + linkType: hard + +"resolve-from@npm:^4.0.0": + version: 4.0.0 + resolution: "resolve-from@npm:4.0.0" + checksum: 10/91eb76ce83621eea7bbdd9b55121a5c1c4a39e54a9ce04a9ad4517f102f8b5131c2cf07622c738a6683991bf54f2ce178f5a42803ecbd527ddc5105f362cc9e3 + languageName: node + linkType: hard + +"resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 10/be18a5e4d76dd711778664829841cde690971d02b6cbae277735a09c1c28f407b99ef6ef3cd585a1e6546d4097b28df40ed32c4a287b9699dcf6d7f208495e23 + languageName: node + linkType: hard + +"resolve-pkg-maps@npm:^1.0.0": + version: 1.0.0 + resolution: "resolve-pkg-maps@npm:1.0.0" + checksum: 10/0763150adf303040c304009231314d1e84c6e5ebfa2d82b7d94e96a6e82bacd1dcc0b58ae257315f3c8adb89a91d8d0f12928241cba2df1680fbe6f60bf99b0e + languageName: node + linkType: hard + +"resolve.exports@npm:^1.1.0": + version: 1.1.1 + resolution: "resolve.exports@npm:1.1.1" + checksum: 10/de58c30aca30883f0e29910e4ad1b7b9986ec5f69434ef2e957ddbe52d3250e138ddd2688e8cd67909b4ee9bf3437424c718a5962d59edd610f035b861ef8441 + languageName: node + linkType: hard + +"resolve@npm:1.22.10, resolve@npm:^1.20.0, resolve@npm:^1.22.3": + version: 1.22.10 + resolution: "resolve@npm:1.22.10" + dependencies: + is-core-module: "npm:^2.16.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10/0a398b44da5c05e6e421d70108822c327675febb880eebe905587628de401854c61d5df02866ff34fc4cb1173a51c9f0e84a94702738df3611a62e2acdc68181 + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A1.22.10#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.3#optional!builtin": + version: 1.22.10 + resolution: "resolve@patch:resolve@npm%3A1.22.10#optional!builtin::version=1.22.10&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.16.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10/d4d878bfe3702d215ea23e75e0e9caf99468e3db76f5ca100d27ebdc527366fee3877e54bce7d47cc72ca8952fc2782a070d238bfa79a550eeb0082384c3b81a + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 10/1f914879f97e7ee931ad05fe3afa629bd55270fc6cf1c1e589b6a99fab96d15daad0fa1a52a00c729ec0078045fe3e399bd4fd0c93bcc906957bdc17f89cb8e6 + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: 10/14222c9e1d3f9ae01480c50d96057228a8524706db79cdeb5a2ce5bb7070dd9f409a6f84a02cbef8cdc80d39aef86f2dd03d155188a1300c599b05437dcd2ffb + languageName: node + linkType: hard + +"rimraf@npm:^3.0.0, rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: bin.js + checksum: 10/063ffaccaaaca2cfd0ef3beafb12d6a03dd7ff1260d752d62a6077b5dfff6ae81bea571f655bb6b589d366930ec1bdd285d40d560c0dae9b12f125e54eb743d5 + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: 10/cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 10/7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 + languageName: node + linkType: hard + +"saxes@npm:^5.0.1": + version: 5.0.1 + resolution: "saxes@npm:5.0.1" + dependencies: + xmlchars: "npm:^2.2.0" + checksum: 10/148b5f98fdd45df25fa1abef35d72cdf6457ac5aef3b7d59d60f770af09d8cf6e7e3a074197071222441d68670fd3198590aba9985e37c4738af2df2f44d0686 + languageName: node + linkType: hard + +"semver-compare@npm:^1.0.0": + version: 1.0.0 + resolution: "semver-compare@npm:1.0.0" + checksum: 10/75f9c7a7786d1756f64b1429017746721e07bd7691bdad6368f7643885d3a98a27586777e9699456564f4844b407e9f186cc1d588a3f9c0be71310e517e942c3 + languageName: node + linkType: hard + +"semver@npm:7.x, semver@npm:^7.1.1, semver@npm:^7.3.2, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.1, semver@npm:^7.7.2": + version: 7.7.3 + resolution: "semver@npm:7.7.3" + bin: + semver: bin/semver.js + checksum: 10/8dbc3168e057a38fc322af909c7f5617483c50caddba135439ff09a754b20bdd6482a5123ff543dad4affa488ecf46ec5fb56d61312ad20bb140199b88dfaea9 + languageName: node + linkType: hard + +"semver@npm:^6.0.0, semver@npm:^6.3.0, semver@npm:^6.3.1": + version: 6.3.1 + resolution: "semver@npm:6.3.1" + bin: + semver: bin/semver.js + checksum: 10/1ef3a85bd02a760c6ef76a45b8c1ce18226de40831e02a00bad78485390b98b6ccaa31046245fc63bba4a47a6a592b6c7eedc65cc47126e60489f9cc1ce3ed7e + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 10/6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 10/1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"shiki@npm:^0.14.1": + version: 0.14.7 + resolution: "shiki@npm:0.14.7" + dependencies: + ansi-sequence-parser: "npm:^1.1.0" + jsonc-parser: "npm:^3.2.0" + vscode-oniguruma: "npm:^1.7.0" + vscode-textmate: "npm:^8.0.0" + checksum: 10/be3f2444c65bd0c57802026f171cb42ad571d361ee885be0c292b60785f68c70f19b69310f5ffe7f7a93db4c5ef50211e0a0248794bc6bb48d242bc43fe72a62 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: 10/a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.0.1 + resolution: "signal-exit@npm:4.0.1" + checksum: 10/3d345d3a6c3ed533aa8107f8fab73257cf8ddacd0a297c00d0fd3c960a9802900e3cbc518076254ee4ab99ef253b059929d6bf907c5fbc805fdc8a186d900bc0 + languageName: node + linkType: hard + +"sisteransi@npm:^1.0.5": + version: 1.0.5 + resolution: "sisteransi@npm:1.0.5" + checksum: 10/aba6438f46d2bfcef94cf112c835ab395172c75f67453fe05c340c770d3c402363018ae1ab4172a1026a90c47eaccf3af7b6ff6fa749a680c2929bd7fa2b37a4 + languageName: node + linkType: hard + +"skin-tone@npm:^2.0.0": + version: 2.0.0 + resolution: "skin-tone@npm:2.0.0" + dependencies: + unicode-emoji-modifier-base: "npm:^1.0.0" + checksum: 10/19de157586b8019cacc55eb25d9d640f00fc02415761f3e41a4527142970fd4e7f6af0333bc90e879858766c20a976107bb386ffd4c812289c01d51f2c8d182c + languageName: node + linkType: hard + +"slash@npm:^3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 10/94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 10/927484aa0b1640fd9473cee3e0a0bcad6fce93fd7bbc18bac9ad0c33686f5d2e2c422fba24b5899c184524af01e11dd2bd051c2bf2b07e47aff8ca72cbfc60d2 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.4 + resolution: "socks-proxy-agent@npm:8.0.4" + dependencies: + agent-base: "npm:^7.1.1" + debug: "npm:^4.3.4" + socks: "npm:^2.8.3" + checksum: 10/c8e7c2b398338b49a0a0f4d2bae5c0602aeeca6b478b99415927b6c5db349ca258448f2c87c6958ebf83eea17d42cbc5d1af0bfecb276cac10b9658b0f07f7d7 + languageName: node + linkType: hard + +"socks@npm:^2.8.3": + version: 2.8.3 + resolution: "socks@npm:2.8.3" + dependencies: + ip-address: "npm:^9.0.5" + smart-buffer: "npm:^4.2.0" + checksum: 10/ffcb622c22481dfcd7589aae71fbfd71ca34334064d181df64bf8b7feaeee19706aba4cffd1de35cc7bbaeeaa0af96be2d7f40fcbc7bc0ab69533a7ae9ffc4fb + languageName: node + linkType: hard + +"sort-object-keys@npm:^1.1.3": + version: 1.1.3 + resolution: "sort-object-keys@npm:1.1.3" + checksum: 10/abea944d6722a1710a1aa6e4f9509da085d93d5fc0db23947cb411eedc7731f80022ce8fa68ed83a53dd2ac7441fcf72a3f38c09b3d9bbc4ff80546aa2e151ad + languageName: node + linkType: hard + +"sort-package-json@npm:3.4.0": + version: 3.4.0 + resolution: "sort-package-json@npm:3.4.0" + dependencies: + detect-indent: "npm:^7.0.1" + detect-newline: "npm:^4.0.1" + git-hooks-list: "npm:^4.0.0" + is-plain-obj: "npm:^4.1.0" + semver: "npm:^7.7.1" + sort-object-keys: "npm:^1.1.3" + tinyglobby: "npm:^0.2.12" + bin: + sort-package-json: cli.js + checksum: 10/f8009b037d0e1ba48819ddf498a34500f778058833b962b5f0d481943def68e2633259e679f29dbb6356fbab2bbc9ffa18524bc6decdcfd4341ab1a6aadee571 + languageName: node + linkType: hard + +"source-map-js@npm:^1.2.1": + version: 1.2.1 + resolution: "source-map-js@npm:1.2.1" + checksum: 10/ff9d8c8bf096d534a5b7707e0382ef827b4dd360a577d3f34d2b9f48e12c9d230b5747974ee7c607f0df65113732711bb701fe9ece3c7edbd43cb2294d707df3 + languageName: node + linkType: hard + +"source-map-support@npm:^0.5.6": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: 10/8317e12d84019b31e34b86d483dd41d6f832f389f7417faf8fc5c75a66a12d9686e47f589a0554a868b8482f037e23df9d040d29387eb16fa14cb85f091ba207 + languageName: node + linkType: hard + +"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 10/59ef7462f1c29d502b3057e822cdbdae0b0e565302c4dd1a95e11e793d8d9d62006cdc10e0fd99163ca33ff2071360cf50ee13f90440806e7ed57d81cba2f7ff + languageName: node + linkType: hard + +"source-map@npm:^0.7.3": + version: 0.7.6 + resolution: "source-map@npm:0.7.6" + checksum: 10/c8d2da7c57c14f3fd7568f764b39ad49bbf9dd7632b86df3542b31fed117d4af2fb74a4f886fc06baf7a510fee68e37998efc3080aacdac951c36211dc29a7a3 + languageName: node + linkType: hard + +"spdx-correct@npm:^3.0.0": + version: 3.2.0 + resolution: "spdx-correct@npm:3.2.0" + dependencies: + spdx-expression-parse: "npm:^3.0.0" + spdx-license-ids: "npm:^3.0.0" + checksum: 10/cc2e4dbef822f6d12142116557d63f5facf3300e92a6bd24e907e4865e17b7e1abd0ee6b67f305cae6790fc2194175a24dc394bfcc01eea84e2bdad728e9ae9a + languageName: node + linkType: hard + +"spdx-exceptions@npm:^2.1.0": + version: 2.3.0 + resolution: "spdx-exceptions@npm:2.3.0" + checksum: 10/cb69a26fa3b46305637123cd37c85f75610e8c477b6476fa7354eb67c08128d159f1d36715f19be6f9daf4b680337deb8c65acdcae7f2608ba51931540687ac0 + languageName: node + linkType: hard + +"spdx-expression-parse@npm:^3.0.0": + version: 3.0.1 + resolution: "spdx-expression-parse@npm:3.0.1" + dependencies: + spdx-exceptions: "npm:^2.1.0" + spdx-license-ids: "npm:^3.0.0" + checksum: 10/a1c6e104a2cbada7a593eaa9f430bd5e148ef5290d4c0409899855ce8b1c39652bcc88a725259491a82601159d6dc790bedefc9016c7472f7de8de7361f8ccde + languageName: node + linkType: hard + +"spdx-expression-parse@npm:^4.0.0": + version: 4.0.0 + resolution: "spdx-expression-parse@npm:4.0.0" + dependencies: + spdx-exceptions: "npm:^2.1.0" + spdx-license-ids: "npm:^3.0.0" + checksum: 10/936be681fbf5edeec3a79c023136479f70d6edb3fd3875089ac86cd324c6c8c81add47399edead296d1d0af17ae5ce88c7f88885eb150b62c2ff6e535841ca6a + languageName: node + linkType: hard + +"spdx-license-ids@npm:^3.0.0": + version: 3.0.11 + resolution: "spdx-license-ids@npm:3.0.11" + checksum: 10/aed256585883aef483590e15d8352b6b787f01cc7e3e120e10457383d574b2cd314d8325854f5f831733ee2e257a6010a57adc93fc166648cc3bc9ab7cd1ea6b + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: 10/e7587128c423f7e43cc625fe2f87e6affdf5ca51c1cc468e910d8aaca46bb44a7fbcfa552f787b1d3987f7043aeb4527d1b99559e6621e01b42b3f45e5a24cbb + languageName: node + linkType: hard + +"sprintf-js@npm:~1.0.2": + version: 1.0.3 + resolution: "sprintf-js@npm:1.0.3" + checksum: 10/c34828732ab8509c2741e5fd1af6b767c3daf2c642f267788f933a65b1614943c282e74c4284f4fa749c264b18ee016a0d37a3e5b73aee446da46277d3a85daa + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.6 + resolution: "ssri@npm:10.0.6" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10/f92c1b3cc9bfd0a925417412d07d999935917bc87049f43ebec41074661d64cf720315661844106a77da9f8204b6d55ae29f9514e673083cae39464343af2a8b + languageName: node + linkType: hard + +"stable-hash-x@npm:^0.2.0": + version: 0.2.0 + resolution: "stable-hash-x@npm:0.2.0" + checksum: 10/136f05d0e4d441876012b423541476ff5b695c93b56d1959560be858b9e324ea6de6c16ecbd735a040ee8396427dd867bed0bf90b2cdb1fc422566747b91a0e5 + languageName: node + linkType: hard + +"stable-hash@npm:^0.0.5": + version: 0.0.5 + resolution: "stable-hash@npm:0.0.5" + checksum: 10/9222ea2c558e37c4a576cb4e406966b9e6aa05b93f5c4f09ef4aaabe3577439b9b8fbff407b16840b63e2ae83de74290c7b1c2da7360d571e480e46a4aec0a56 + languageName: node + linkType: hard + +"stack-utils@npm:^2.0.3": + version: 2.0.5 + resolution: "stack-utils@npm:2.0.5" + dependencies: + escape-string-regexp: "npm:^2.0.0" + checksum: 10/a6d64e5dd24d321289ebefdff2e210ece75fdf20dbcdb702b86da1f7b730743fae3e9337adae4a5cc00d4970d748ff758387df3ea7c71c45b466c43c7359bc00 + languageName: node + linkType: hard + +"string-length@npm:^4.0.1": + version: 4.0.2 + resolution: "string-length@npm:4.0.2" + dependencies: + char-regex: "npm:^1.0.2" + strip-ansi: "npm:^6.0.0" + checksum: 10/ce85533ef5113fcb7e522bcf9e62cb33871aa99b3729cec5595f4447f660b0cefd542ca6df4150c97a677d58b0cb727a3fe09ac1de94071d05526c73579bf505 + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: 10/e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 10/7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: 10/ae3b5436d34fadeb6096367626ce987057713c566e1e7768818797e00ac5d62023d0f198c4e681eae9e20701721980b26a64a8f5b91238869592a9c6800719a2 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 10/475f53e9c44375d6e72807284024ac5d668ee1d06010740dec0b9744f2ddf47de8d7151f80e5f6190fc8f384e802fdf9504b76a7e9020c9faee7103623338be2 + languageName: node + linkType: hard + +"strip-bom@npm:^4.0.0": + version: 4.0.0 + resolution: "strip-bom@npm:4.0.0" + checksum: 10/9dbcfbaf503c57c06af15fe2c8176fb1bf3af5ff65003851a102749f875a6dbe0ab3b30115eccf6e805e9d756830d3e40ec508b62b3f1ddf3761a20ebe29d3f3 + languageName: node + linkType: hard + +"strip-final-newline@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-final-newline@npm:2.0.0" + checksum: 10/69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 + languageName: node + linkType: hard + +"strip-json-comments@npm:^3.1.1": + version: 3.1.1 + resolution: "strip-json-comments@npm:3.1.1" + checksum: 10/492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 + languageName: node + linkType: hard + +"supports-color@npm:^7.0.0, supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10/c8bb7afd564e3b26b50ca6ee47572c217526a1389fe018d00345856d4a9b08ffbd61fadaf283a87368d94c3dcdb8f5ffe2650a5a65863e21ad2730ca0f05210a + languageName: node + linkType: hard + +"supports-color@npm:^8.0.0": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10/157b534df88e39c5518c5e78c35580c1eca848d7dbaf31bbe06cdfc048e22c7ff1a9d046ae17b25691128f631a51d9ec373c1b740c12ae4f0de6e292037e4282 + languageName: node + linkType: hard + +"supports-hyperlinks@npm:^2.0.0": + version: 2.3.0 + resolution: "supports-hyperlinks@npm:2.3.0" + dependencies: + has-flag: "npm:^4.0.0" + supports-color: "npm:^7.0.0" + checksum: 10/3e7df6e9eaa177d7bfbbe065c91325e9b482f48de0f7c9133603e3ffa8af31cbceac104a0941cd0266a57f8e691de6eb58b79fec237852dc84ed7ad152b116b0 + languageName: node + linkType: hard + +"supports-hyperlinks@npm:^3.1.0": + version: 3.2.0 + resolution: "supports-hyperlinks@npm:3.2.0" + dependencies: + has-flag: "npm:^4.0.0" + supports-color: "npm:^7.0.0" + checksum: 10/f7924de6049fc30bc808f98d3561318c1a4e3d55d786f9fede5e23dc5a7b0f625485bd1143135b496d521ccd0110463f2c077eb71a4ce0cf783b8b31f7909242 + languageName: node + linkType: hard + +"supports-preserve-symlinks-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "supports-preserve-symlinks-flag@npm:1.0.0" + checksum: 10/a9dc19ae2220c952bd2231d08ddeecb1b0328b61e72071ff4000c8384e145cc07c1c0bdb3b5a1cb06e186a7b2790f1dee793418b332f6ddf320de25d9125be7e + languageName: node + linkType: hard + +"symbol-tree@npm:^3.2.4": + version: 3.2.4 + resolution: "symbol-tree@npm:3.2.4" + checksum: 10/c09a00aadf279d47d0c5c46ca3b6b2fbaeb45f0a184976d599637d412d3a70bbdc043ff33effe1206dea0e36e0ad226cb957112e7ce9a4bf2daedf7fa4f85c53 + languageName: node + linkType: hard + +"synckit@npm:0.11.11, synckit@npm:^0.11.7": + version: 0.11.11 + resolution: "synckit@npm:0.11.11" + dependencies: + "@pkgr/core": "npm:^0.2.9" + checksum: 10/6ecd88212b5be80004376b6ea74babcba284566ff59a50d8803afcaa78c165b5d268635c1dd84532ee3f690a979409e1eda225a8a35bed2d135ffdcea06ce7b0 + languageName: node + linkType: hard + +"tapable@npm:^2.2.0": + version: 2.3.0 + resolution: "tapable@npm:2.3.0" + checksum: 10/496a841039960533bb6e44816a01fffc2a1eb428bb2051ecab9e87adf07f19e1f937566cbbbb09dceff31163c0ffd81baafcad84db900b601f0155dd0b37e9f2 + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.2.1": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: 10/bfbfbb2861888077fc1130b84029cdc2721efb93d1d1fb80f22a7ac3a98ec6f8972f29e564103bbebf5e97be67ebc356d37fa48dbc4960600a1eb7230fbd1ea0 + languageName: node + linkType: hard + +"terminal-link@npm:^2.0.0": + version: 2.1.1 + resolution: "terminal-link@npm:2.1.1" + dependencies: + ansi-escapes: "npm:^4.2.1" + supports-hyperlinks: "npm:^2.0.0" + checksum: 10/ce3d2cd3a438c4a9453947aa664581519173ea40e77e2534d08c088ee6dda449eabdbe0a76d2a516b8b73c33262fedd10d5270ccf7576ae316e3db170ce6562f + languageName: node + linkType: hard + +"test-exclude@npm:^6.0.0": + version: 6.0.0 + resolution: "test-exclude@npm:6.0.0" + dependencies: + "@istanbuljs/schema": "npm:^0.1.2" + glob: "npm:^7.1.4" + minimatch: "npm:^3.0.4" + checksum: 10/8fccb2cb6c8fcb6bb4115394feb833f8b6cf4b9503ec2485c2c90febf435cac62abe882a0c5c51a37b9bbe70640cdd05acf5f45e486ac4583389f4b0855f69e5 + languageName: node + linkType: hard + +"thenify-all@npm:^1.0.0": + version: 1.6.0 + resolution: "thenify-all@npm:1.6.0" + dependencies: + thenify: "npm:>= 3.1.0 < 4" + checksum: 10/dba7cc8a23a154cdcb6acb7f51d61511c37a6b077ec5ab5da6e8b874272015937788402fd271fdfc5f187f8cb0948e38d0a42dcc89d554d731652ab458f5343e + languageName: node + linkType: hard + +"thenify@npm:>= 3.1.0 < 4": + version: 3.3.1 + resolution: "thenify@npm:3.3.1" + dependencies: + any-promise: "npm:^1.0.0" + checksum: 10/486e1283a867440a904e36741ff1a177faa827cf94d69506f7e3ae4187b9afdf9ec368b3d8da225c192bfe2eb943f3f0080594156bf39f21b57cd1411e2e7f6d + languageName: node + linkType: hard + +"throat@npm:^6.0.1": + version: 6.0.2 + resolution: "throat@npm:6.0.2" + checksum: 10/acd99f4b7362bcf6dcc517b01517165a00f7270d0c4fe2ca06c73b6217f022f76fb20e8ca98283b25ccb85d97a5f96dbcac5577d60bb0bda1eff92fa8e79fbd7 + languageName: node + linkType: hard + +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.13": + version: 0.2.15 + resolution: "tinyglobby@npm:0.2.15" + dependencies: + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.3" + checksum: 10/d72bd826a8b0fa5fa3929e7fe5ba48fceb2ae495df3a231b6c5408cd7d8c00b58ab5a9c2a76ba56a62ee9b5e083626f1f33599734bed1ffc4b792406408f0ca2 + languageName: node + linkType: hard + +"tmpl@npm:1.0.5": + version: 1.0.5 + resolution: "tmpl@npm:1.0.5" + checksum: 10/cd922d9b853c00fe414c5a774817be65b058d54a2d01ebb415840960406c669a0fc632f66df885e24cb022ec812739199ccbdb8d1164c3e513f85bfca5ab2873 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10/10dda13571e1f5ad37546827e9b6d4252d2e0bc176c24a101252153ef435d83696e2557fe128c4678e4e78f5f01e83711c703eef9814eb12dab028580d45980a + languageName: node + linkType: hard + +"tough-cookie@npm:^4.0.0": + version: 4.1.4 + resolution: "tough-cookie@npm:4.1.4" + dependencies: + psl: "npm:^1.1.33" + punycode: "npm:^2.1.1" + universalify: "npm:^0.2.0" + url-parse: "npm:^1.5.3" + checksum: 10/75663f4e2cd085f16af0b217e4218772adf0617fb3227171102618a54ce0187a164e505d61f773ed7d65988f8ff8a8f935d381f87da981752c1171b076b4afac + languageName: node + linkType: hard + +"tr46@npm:^2.1.0": + version: 2.1.0 + resolution: "tr46@npm:2.1.0" + dependencies: + punycode: "npm:^2.1.1" + checksum: 10/302b13f458da713b2a6ff779a0c1d27361d369fdca6c19330536d31db61789b06b246968fc879fdac818a92d02643dca1a0f4da5618df86aea4a79fb3243d3f3 + languageName: node + linkType: hard + +"ts-api-utils@npm:^2.1.0": + version: 2.1.0 + resolution: "ts-api-utils@npm:2.1.0" + peerDependencies: + typescript: ">=4.8.4" + checksum: 10/02e55b49d9617c6eebf8aadfa08d3ca03ca0cd2f0586ad34117fdfc7aa3cd25d95051843fde9df86665ad907f99baed179e7a117b11021417f379e4d2614eacd + languageName: node + linkType: hard + +"ts-declaration-location@npm:^1.0.6": + version: 1.0.7 + resolution: "ts-declaration-location@npm:1.0.7" + dependencies: + picomatch: "npm:^4.0.2" + peerDependencies: + typescript: ">=4.0.0" + checksum: 10/a7932fc75d41f10c16089f8f5a5c1ea49d6afca30f09c91c1df14d0a8510f72bcb9f8a395c04f060b66b855b6bd7ea4df81b335fb9d21bef402969a672a4afa7 + languageName: node + linkType: hard + +"ts-expose-internals-conditionally@npm:1.0.0-empty.0": + version: 1.0.0-empty.0 + resolution: "ts-expose-internals-conditionally@npm:1.0.0-empty.0" + checksum: 10/6b4f546fc59f04f68d579f1bc0704541ec17521f84d32a15b45bef5dbc7a787143a065e19541cc5b64ff494f16f223bce59f3f5bf10ec538e5739e23c0efb878 + languageName: node + linkType: hard + +"ts-jest@npm:^27.1.4": + version: 27.1.5 + resolution: "ts-jest@npm:27.1.5" + dependencies: + bs-logger: "npm:0.x" + fast-json-stable-stringify: "npm:2.x" + jest-util: "npm:^27.0.0" + json5: "npm:2.x" + lodash.memoize: "npm:4.x" + make-error: "npm:1.x" + semver: "npm:7.x" + yargs-parser: "npm:20.x" + peerDependencies: + "@babel/core": ">=7.0.0-beta.0 <8" + "@types/jest": ^27.0.0 + babel-jest: ">=27.0.0 <28" + jest: ^27.0.0 + typescript: ">=3.8 <5.0" + peerDependenciesMeta: + "@babel/core": + optional: true + "@types/jest": + optional: true + babel-jest: + optional: true + esbuild: + optional: true + bin: + ts-jest: cli.js + checksum: 10/7675946cefc8c652ec35f2fd600ffb99c8e5db5ac355ceb8317707862c586ee46f7ddd589bd206fa8be2598bc4a87c5a53eb4198af78723f5661c90e32200ba3 + languageName: node + linkType: hard + +"ts-node@npm:^10.9.1": + version: 10.9.2 + resolution: "ts-node@npm:10.9.2" + dependencies: + "@cspotcode/source-map-support": "npm:^0.8.0" + "@tsconfig/node10": "npm:^1.0.7" + "@tsconfig/node12": "npm:^1.0.7" + "@tsconfig/node14": "npm:^1.0.0" + "@tsconfig/node16": "npm:^1.0.2" + acorn: "npm:^8.4.1" + acorn-walk: "npm:^8.1.1" + arg: "npm:^4.1.0" + create-require: "npm:^1.1.0" + diff: "npm:^4.0.1" + make-error: "npm:^1.1.1" + v8-compile-cache-lib: "npm:^3.0.1" + yn: "npm:3.1.1" + 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 + 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 + checksum: 10/a91a15b3c9f76ac462f006fa88b6bfa528130dcfb849dd7ef7f9d640832ab681e235b8a2bc58ecde42f72851cc1d5d4e22c901b0c11aa51001ea1d395074b794 + languageName: node + linkType: hard + +"tslib@npm:^2.4.0": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: 10/3e2e043d5c2316461cb54e5c7fe02c30ef6dccb3384717ca22ae5c6b5bc95232a6241df19c622d9c73b809bea33b187f6dbc73030963e29950c2141bc32a79f7 + languageName: node + linkType: hard + +"type-check@npm:^0.4.0, type-check@npm:~0.4.0": + version: 0.4.0 + resolution: "type-check@npm:0.4.0" + dependencies: + prelude-ls: "npm:^1.2.1" + checksum: 10/14687776479d048e3c1dbfe58a2409e00367810d6960c0f619b33793271ff2a27f81b52461f14a162f1f89a9b1d8da1b237fc7c99b0e1fdcec28ec63a86b1fec + languageName: node + linkType: hard + +"type-detect@npm:4.0.8": + version: 4.0.8 + resolution: "type-detect@npm:4.0.8" + checksum: 10/5179e3b8ebc51fce1b13efb75fdea4595484433f9683bbc2dca6d99789dba4e602ab7922d2656f2ce8383987467f7770131d4a7f06a26287db0615d2f4c4ce7d + languageName: node + linkType: hard + +"type-fest@npm:4.41.0": + version: 4.41.0 + resolution: "type-fest@npm:4.41.0" + checksum: 10/617ace794ac0893c2986912d28b3065ad1afb484cad59297835a0807dc63286c39e8675d65f7de08fafa339afcb8fe06a36e9a188b9857756ae1e92ee8bda212 + languageName: node + linkType: hard + +"type-fest@npm:^0.21.3": + version: 0.21.3 + resolution: "type-fest@npm:0.21.3" + checksum: 10/f4254070d9c3d83a6e573bcb95173008d73474ceadbbf620dd32d273940ca18734dff39c2b2480282df9afe5d1675ebed5499a00d791758748ea81f61a38961f + languageName: node + linkType: hard + +"typedarray-to-buffer@npm:^3.1.5": + version: 3.1.5 + resolution: "typedarray-to-buffer@npm:3.1.5" + dependencies: + is-typedarray: "npm:^1.0.0" + checksum: 10/7c850c3433fbdf4d04f04edfc751743b8f577828b8e1eb93b95a3bce782d156e267d83e20fb32b3b47813e69a69ab5e9b5342653332f7d21c7d1210661a7a72c + languageName: node + linkType: hard + +"typedoc@npm:^0.24.8": + version: 0.24.8 + resolution: "typedoc@npm:0.24.8" + dependencies: + lunr: "npm:^2.3.9" + marked: "npm:^4.3.0" + minimatch: "npm:^9.0.0" + shiki: "npm:^0.14.1" + peerDependencies: + typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x + bin: + typedoc: bin/typedoc + checksum: 10/4f2f92ddde3f70a1a9666507f6bdf6620023599bd2c2a3ed3f8f909f9c28d92594c30ee6ee68f5a248ff70e09623acf1323bad633cb713b9f2e36bbd4fccf683 + languageName: node + linkType: hard + +"typescript-eslint@npm:^8.7.0": + version: 8.46.1 + resolution: "typescript-eslint@npm:8.46.1" + dependencies: + "@typescript-eslint/eslint-plugin": "npm:8.46.1" + "@typescript-eslint/parser": "npm:8.46.1" + "@typescript-eslint/typescript-estree": "npm:8.46.1" + "@typescript-eslint/utils": "npm:8.46.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <6.0.0" + checksum: 10/ba6914cc4006390908de9e3de295c2f7110461175a818608d198e2d1529e726c32d778fe9e224ea30464ba2c4a43c05f534d2dbc5aabf297354a2aa49a2e1cd6 + languageName: node + linkType: hard + +"typescript@npm:5.3.3": + version: 5.3.3 + resolution: "typescript@npm:5.3.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/6e4e6a14a50c222b3d14d4ea2f729e79f972fa536ac1522b91202a9a65af3605c2928c4a790a4a50aa13694d461c479ba92cedaeb1e7b190aadaa4e4b96b8e18 + languageName: node + linkType: hard + +"typescript@npm:~5.2.2": + version: 5.2.2 + resolution: "typescript@npm:5.2.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/d65e50eb849bd21ff8677e5b9447f9c6e74777e346afd67754934264dcbf4bd59e7d2473f6062d9a015d66bd573311166357e3eb07fea0b52859cf9bb2b58555 + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A5.3.3#optional!builtin": + version: 5.3.3 + resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin::version=5.3.3&hash=e012d7" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/c93786fcc9a70718ba1e3819bab56064ead5817004d1b8186f8ca66165f3a2d0100fee91fa64c840dcd45f994ca5d615d8e1f566d39a7470fc1e014dbb4cf15d + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A~5.2.2#optional!builtin": + version: 5.2.2 + resolution: "typescript@patch:typescript@npm%3A5.2.2#optional!builtin::version=5.2.2&hash=f3b441" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10/f79cc2ba802c94c2b78dbb00d767a10adb67368ae764709737dc277273ec148aa4558033a03ce901406b35fddf4eac46dabc94a1e1d12d2587e2b9cfe5707b4a + languageName: node + linkType: hard + +"undici-types@npm:~5.26.4": + version: 5.26.5 + resolution: "undici-types@npm:5.26.5" + checksum: 10/0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd + languageName: node + linkType: hard + +"unicode-emoji-modifier-base@npm:^1.0.0": + version: 1.0.0 + resolution: "unicode-emoji-modifier-base@npm:1.0.0" + checksum: 10/6e1521d35fa69493207eb8b41f8edb95985d8b3faf07c01d820a1830b5e8403e20002563e2f84683e8e962a49beccae789f0879356bf92a4ec7a4dd8e2d16fdb + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 10/8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 10/40912a8963fc02fb8b600cf50197df4a275c602c60de4cac4f75879d3c48558cfac48de08a25cc10df8112161f7180b3bbb4d662aadb711568602f9eddee54f0 + languageName: node + linkType: hard + +"universalify@npm:^0.2.0": + version: 0.2.0 + resolution: "universalify@npm:0.2.0" + checksum: 10/e86134cb12919d177c2353196a4cc09981524ee87abf621f7bc8d249dbbbebaec5e7d1314b96061497981350df786e4c5128dbf442eba104d6e765bc260678b5 + languageName: node + linkType: hard + +"unrs-resolver@npm:^1.6.2, unrs-resolver@npm:^1.9.2": + version: 1.11.1 + resolution: "unrs-resolver@npm:1.11.1" + dependencies: + "@unrs/resolver-binding-android-arm-eabi": "npm:1.11.1" + "@unrs/resolver-binding-android-arm64": "npm:1.11.1" + "@unrs/resolver-binding-darwin-arm64": "npm:1.11.1" + "@unrs/resolver-binding-darwin-x64": "npm:1.11.1" + "@unrs/resolver-binding-freebsd-x64": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm64-musl": "npm:1.11.1" + "@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-riscv64-musl": "npm:1.11.1" + "@unrs/resolver-binding-linux-s390x-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-x64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-x64-musl": "npm:1.11.1" + "@unrs/resolver-binding-wasm32-wasi": "npm:1.11.1" + "@unrs/resolver-binding-win32-arm64-msvc": "npm:1.11.1" + "@unrs/resolver-binding-win32-ia32-msvc": "npm:1.11.1" + "@unrs/resolver-binding-win32-x64-msvc": "npm:1.11.1" + napi-postinstall: "npm:^0.3.0" + dependenciesMeta: + "@unrs/resolver-binding-android-arm-eabi": + optional: true + "@unrs/resolver-binding-android-arm64": + optional: true + "@unrs/resolver-binding-darwin-arm64": + optional: true + "@unrs/resolver-binding-darwin-x64": + optional: true + "@unrs/resolver-binding-freebsd-x64": + optional: true + "@unrs/resolver-binding-linux-arm-gnueabihf": + optional: true + "@unrs/resolver-binding-linux-arm-musleabihf": + optional: true + "@unrs/resolver-binding-linux-arm64-gnu": + optional: true + "@unrs/resolver-binding-linux-arm64-musl": + optional: true + "@unrs/resolver-binding-linux-ppc64-gnu": + optional: true + "@unrs/resolver-binding-linux-riscv64-gnu": + optional: true + "@unrs/resolver-binding-linux-riscv64-musl": + optional: true + "@unrs/resolver-binding-linux-s390x-gnu": + optional: true + "@unrs/resolver-binding-linux-x64-gnu": + optional: true + "@unrs/resolver-binding-linux-x64-musl": + optional: true + "@unrs/resolver-binding-wasm32-wasi": + optional: true + "@unrs/resolver-binding-win32-arm64-msvc": + optional: true + "@unrs/resolver-binding-win32-ia32-msvc": + optional: true + "@unrs/resolver-binding-win32-x64-msvc": + optional: true + checksum: 10/4de653508cbaae47883a896bd5cdfef0e5e87b428d62620d16fd35cd534beaebf08ebf0cf2f8b4922aa947b2fe745180facf6cc3f39ba364f7ce0f974cb06a70 + languageName: node + linkType: hard + +"update-browserslist-db@npm:^1.1.3": + version: 1.1.3 + resolution: "update-browserslist-db@npm:1.1.3" + dependencies: + escalade: "npm:^3.2.0" + picocolors: "npm:^1.1.1" + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 10/87af2776054ffb9194cf95e0201547d041f72ee44ce54b144da110e65ea7ca01379367407ba21de5c9edd52c74d95395366790de67f3eb4cc4afa0fe4424e76f + languageName: node + linkType: hard + +"uri-js@npm:^4.2.2": + version: 4.4.1 + resolution: "uri-js@npm:4.4.1" + dependencies: + punycode: "npm:^2.1.0" + checksum: 10/b271ca7e3d46b7160222e3afa3e531505161c9a4e097febae9664e4b59912f4cbe94861361a4175edac3a03fee99d91e44b6a58c17a634bc5a664b19fc76fbcb + languageName: node + linkType: hard + +"url-parse@npm:^1.5.3": + version: 1.5.10 + resolution: "url-parse@npm:1.5.10" + dependencies: + querystringify: "npm:^2.1.1" + requires-port: "npm:^1.0.0" + checksum: 10/c9e96bc8c5b34e9f05ddfeffc12f6aadecbb0d971b3cc26015b58d5b44676a99f50d5aeb1e5c9e61fa4d49961ae3ab1ae997369ed44da51b2f5ac010d188e6ad + languageName: node + linkType: hard + +"uuid@npm:^8.3.2": + version: 8.3.2 + resolution: "uuid@npm:8.3.2" + bin: + uuid: dist/bin/uuid + checksum: 10/9a5f7aa1d6f56dd1e8d5f2478f855f25c645e64e26e347a98e98d95781d5ed20062d6cca2eecb58ba7c84bc3910be95c0451ef4161906abaab44f9cb68ffbdd1 + languageName: node + linkType: hard + +"uuid@npm:^9.0.1": + version: 9.0.1 + resolution: "uuid@npm:9.0.1" + bin: + uuid: dist/bin/uuid + checksum: 10/9d0b6adb72b736e36f2b1b53da0d559125ba3e39d913b6072f6f033e0c87835b414f0836b45bcfaf2bdf698f92297fea1c3cc19b0b258bc182c9c43cc0fab9f2 + languageName: node + linkType: hard + +"v8-compile-cache-lib@npm:^3.0.1": + version: 3.0.1 + resolution: "v8-compile-cache-lib@npm:3.0.1" + checksum: 10/88d3423a52b6aaf1836be779cab12f7016d47ad8430dffba6edf766695e6d90ad4adaa3d8eeb512cc05924f3e246c4a4ca51e089dccf4402caa536b5e5be8961 + languageName: node + linkType: hard + +"v8-to-istanbul@npm:^8.1.0": + version: 8.1.1 + resolution: "v8-to-istanbul@npm:8.1.1" + dependencies: + "@types/istanbul-lib-coverage": "npm:^2.0.1" + convert-source-map: "npm:^1.6.0" + source-map: "npm:^0.7.3" + checksum: 10/db5469f133a7cfb7680a28ddfb31aad2cc64f282fa7cf0c8e91f91bfd542bf61597260282be28c9648f0f2114963a24b273ed92af9a5cad6cb629c708ca72f8e + languageName: node + linkType: hard + +"validate-npm-package-license@npm:^3.0.4": + version: 3.0.4 + resolution: "validate-npm-package-license@npm:3.0.4" + dependencies: + spdx-correct: "npm:^3.0.0" + spdx-expression-parse: "npm:^3.0.0" + checksum: 10/86242519b2538bb8aeb12330edebb61b4eb37fd35ef65220ab0b03a26c0592c1c8a7300d32da3cde5abd08d18d95e8dabfad684b5116336f6de9e6f207eec224 + languageName: node + linkType: hard + +"validate-npm-package-name@npm:^5.0.0": + version: 5.0.1 + resolution: "validate-npm-package-name@npm:5.0.1" + checksum: 10/0d583a1af23aeffea7748742cf22b6802458736fb8b60323ba5949763824d46f796474b0e1b9206beb716f9d75269e19dbd7795d6b038b29d561be95dd827381 + languageName: node + linkType: hard + +"vscode-oniguruma@npm:^1.7.0": + version: 1.7.0 + resolution: "vscode-oniguruma@npm:1.7.0" + checksum: 10/7da9d21459f9788544b258a5fd1b9752df6edd8b406a19eea0209c6bf76507d5717277016799301c4da0d536095f9ca8c06afd1ab8f4001189090c804ca4814e + languageName: node + linkType: hard + +"vscode-textmate@npm:^8.0.0": + version: 8.0.0 + resolution: "vscode-textmate@npm:8.0.0" + checksum: 10/9fa7d66d6042cb090d116c2d8820d34c8870cfcbaed6e404da89f66b899970ed0ac47b59a2e30fc40a25af5414822bb3ea27974f714e9b91910d69c894be95f7 + languageName: node + linkType: hard + +"w3c-hr-time@npm:^1.0.2": + version: 1.0.2 + resolution: "w3c-hr-time@npm:1.0.2" + dependencies: + browser-process-hrtime: "npm:^1.0.0" + checksum: 10/03851d90c236837c24c2983f5a8806a837c6515b21d52e5f29776b07cc08695779303d481454d768308489f00dd9d3232d595acaa5b2686d199465a4d9f7b283 + languageName: node + linkType: hard + +"w3c-xmlserializer@npm:^2.0.0": + version: 2.0.0 + resolution: "w3c-xmlserializer@npm:2.0.0" + dependencies: + xml-name-validator: "npm:^3.0.0" + checksum: 10/400c18b75ce6af269168f964e7d1eb196a7422e134032906540c69d83b802f38dc64e18fc259c02966a334687483f416398d2ad7ebe9d19ab434a7a0247c71c3 + languageName: node + linkType: hard + +"walker@npm:^1.0.7": + version: 1.0.8 + resolution: "walker@npm:1.0.8" + dependencies: + makeerror: "npm:1.0.12" + checksum: 10/ad7a257ea1e662e57ef2e018f97b3c02a7240ad5093c392186ce0bcf1f1a60bbadd520d073b9beb921ed99f64f065efb63dfc8eec689a80e569f93c1c5d5e16c + languageName: node + linkType: hard + +"webidl-conversions@npm:^5.0.0": + version: 5.0.0 + resolution: "webidl-conversions@npm:5.0.0" + checksum: 10/cea864dd9cf1f2133d82169a446fb94427ba089e4676f5895273ea085f165649afe587ae3f19f2f0370751a724bba2d96e9956d652b3e41ac1feaaa4376e2d70 + languageName: node + linkType: hard + +"webidl-conversions@npm:^6.1.0": + version: 6.1.0 + resolution: "webidl-conversions@npm:6.1.0" + checksum: 10/4454b73060a6d83f7ec1f1db24c480b7ecda33880306dd32a3d62d85b36df4789a383489f1248387e5451737dca17054b8cbf2e792ba89e49d76247f0f4f6380 + languageName: node + linkType: hard + +"whatwg-encoding@npm:^1.0.5": + version: 1.0.5 + resolution: "whatwg-encoding@npm:1.0.5" + dependencies: + iconv-lite: "npm:0.4.24" + checksum: 10/5be4efe111dce29ddee3448d3915477fcc3b28f991d9cf1300b4e50d6d189010d47bca2f51140a844cf9b726e8f066f4aee72a04d687bfe4f2ee2767b2f5b1e6 + languageName: node + linkType: hard + +"whatwg-mimetype@npm:^2.3.0": + version: 2.3.0 + resolution: "whatwg-mimetype@npm:2.3.0" + checksum: 10/3582c1d74d708716013433bbab45cb9b31ef52d276adfbe2205d948be1ec9bb1a4ac05ce6d9045f3acc4104489e1344c857b14700002385a4b997a5673ff6416 + languageName: node + linkType: hard + +"whatwg-url@npm:^8.0.0, whatwg-url@npm:^8.5.0": + version: 8.7.0 + resolution: "whatwg-url@npm:8.7.0" + dependencies: + lodash: "npm:^4.7.0" + tr46: "npm:^2.1.0" + webidl-conversions: "npm:^6.1.0" + checksum: 10/512a8b2703dffbf13a9a247bf2fb27c3048a3ceb5ece09f88b737c8260afaba4b2f6775c2f1cfc29c2ba4859f2454a9de73fac08e239b00ae2b42cd6b8bb0d35 + languageName: node + linkType: hard + +"which@npm:^1.2.14": + version: 1.3.1 + resolution: "which@npm:1.3.1" + dependencies: + isexe: "npm:^2.0.0" + bin: + which: ./bin/which + checksum: 10/549dcf1752f3ee7fbb64f5af2eead4b9a2f482108b7de3e85c781d6c26d8cf6a52d37cfbe0642a155fa6470483fe892661a859c03157f24c669cf115f3bbab5e + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 10/4782f8a1d6b8fc12c65e968fea49f59752bf6302dc43036c3bf87da718a80710f61a062516e9764c70008b487929a73546125570acea95c5b5dcc8ac3052c70f + languageName: node + linkType: hard + +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: 10/f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10/cebdaeca3a6880da410f75209e68cd05428580de5ad24535f22696d7d9cab134d1f8498599f344c3cf0fb37c1715807a183778d8c648d6cc0cb5ff2bb4236540 + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 10/7b1e4b35e9bb2312d2ee9ee7dc95b8cb5f8b4b5a89f7dde5543fe66c1e3715663094defa50d75454ac900bd210f702d575f15f3f17fa9ec0291806d2578d1ddf + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10/159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + languageName: node + linkType: hard + +"write-file-atomic@npm:^3.0.0": + version: 3.0.3 + resolution: "write-file-atomic@npm:3.0.3" + dependencies: + imurmurhash: "npm:^0.1.4" + is-typedarray: "npm:^1.0.0" + signal-exit: "npm:^3.0.2" + typedarray-to-buffer: "npm:^3.1.5" + checksum: 10/0955ab94308b74d32bc252afe69d8b42ba4b8a28b8d79f399f3f405969f82623f981e35d13129a52aa2973450f342107c06d86047572637584e85a1c0c246bf3 + languageName: node + linkType: hard + +"write-file-atomic@npm:^5.0.0": + version: 5.0.1 + resolution: "write-file-atomic@npm:5.0.1" + dependencies: + imurmurhash: "npm:^0.1.4" + signal-exit: "npm:^4.0.1" + checksum: 10/648efddba54d478d0e4330ab6f239976df3b9752b123db5dc9405d9b5af768fa9d70ce60c52fdbe61d1200d24350bc4fbcbaf09288496c2be050de126bd95b7e + languageName: node + linkType: hard + +"ws@npm:^7.4.6": + version: 7.5.10 + resolution: "ws@npm:7.5.10" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10/9c796b84ba80ffc2c2adcdfc9c8e9a219ba99caa435c9a8d45f9ac593bba325563b3f83edc5eb067cc6d21b9a6bf2c930adf76dd40af5f58a5ca6859e81858f0 + languageName: node + linkType: hard + +"xml-name-validator@npm:^3.0.0": + version: 3.0.0 + resolution: "xml-name-validator@npm:3.0.0" + checksum: 10/24f5d38c777ad9239dfe99c4ca3cd155415b65ac583785d1514e04b9f86d6d09eaff983ed373e7a779ceefd1fca0fd893f2fc264999e9aeaac36b6e1afc397ed + languageName: node + linkType: hard + +"xmlchars@npm:^2.2.0": + version: 2.2.0 + resolution: "xmlchars@npm:2.2.0" + checksum: 10/4ad5924974efd004a47cce6acf5c0269aee0e62f9a805a426db3337af7bcbd331099df174b024ace4fb18971b8a56de386d2e73a1c4b020e3abd63a4a9b917f1 + languageName: node + linkType: hard + +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 10/5f1b5f95e3775de4514edbb142398a2c37849ccfaf04a015be5d75521e9629d3be29bd4432d23c57f37e5b61ade592fb0197022e9993f81a06a5afbdcda9346d + languageName: node + linkType: hard + +"yallist@npm:^3.0.2": + version: 3.1.1 + resolution: "yallist@npm:3.1.1" + checksum: 10/9af0a4329c3c6b779ac4736c69fae4190ac03029fa27c1aef4e6bcc92119b73dea6fe5db5fe881fb0ce2a0e9539a42cdf60c7c21eda04d1a0b8c082e38509efb + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 10/4cb02b42b8a93b5cf50caf5d8e9beb409400a8a4d85e83bb0685c1457e9ac0b7a00819e9f5991ac25ffabb56a78e2f017c1acc010b3a1babfe6de690ba531abd + languageName: node + linkType: hard + +"yaml@npm:^1.10.0": + version: 1.10.2 + resolution: "yaml@npm:1.10.2" + checksum: 10/e088b37b4d4885b70b50c9fa1b7e54bd2e27f5c87205f9deaffd1fb293ab263d9c964feadb9817a7b129a5bf30a06582cb08750f810568ecc14f3cdbabb79cb3 + languageName: node + linkType: hard + +"yargs-parser@npm:20.x, yargs-parser@npm:^20.2.2": + version: 20.2.9 + resolution: "yargs-parser@npm:20.2.9" + checksum: 10/0188f430a0f496551d09df6719a9132a3469e47fe2747208b1dd0ab2bb0c512a95d0b081628bbca5400fb20dbf2fabe63d22badb346cecadffdd948b049f3fcc + languageName: node + linkType: hard + +"yargs-parser@npm:^21.1.1": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: 10/9dc2c217ea3bf8d858041252d43e074f7166b53f3d010a8c711275e09cd3d62a002969a39858b92bbda2a6a63a585c7127014534a560b9c69ed2d923d113406e + languageName: node + linkType: hard + +"yargs@npm:17.7.2, yargs@npm:^17.0.1, yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: "npm:^8.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.3" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^21.1.1" + checksum: 10/abb3e37678d6e38ea85485ed86ebe0d1e3464c640d7d9069805ea0da12f69d5a32df8e5625e370f9c96dd1c2dc088ab2d0a4dd32af18222ef3c4224a19471576 + languageName: node + linkType: hard + +"yargs@npm:^16.0.0, yargs@npm:^16.2.0": + version: 16.2.0 + resolution: "yargs@npm:16.2.0" + dependencies: + cliui: "npm:^7.0.2" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.0" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^20.2.2" + checksum: 10/807fa21211d2117135d557f95fcd3c3d390530cda2eca0c840f1d95f0f40209dcfeb5ec18c785a1f3425896e623e3b2681e8bb7b6600060eda1c3f4804e7957e + languageName: node + linkType: hard + +"yn@npm:3.1.1": + version: 3.1.1 + resolution: "yn@npm:3.1.1" + checksum: 10/2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6 + languageName: node + linkType: hard + +"yocto-queue@npm:^0.1.0": + version: 0.1.0 + resolution: "yocto-queue@npm:0.1.0" + checksum: 10/f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 + languageName: node + linkType: hard