From a61c02481f3ee194ab7d2f5e19b9c19feb3901e8 Mon Sep 17 00:00:00 2001 From: Frostebite Date: Mon, 11 Apr 2022 00:00:37 +0100 Subject: [PATCH] Cloud Runner v0 - Reliable and trimmed down cloud runner (#353) * Update cloud-runner-aws-pipeline.yml * Update cloud-runner-k8s-pipeline.yml * yarn build * yarn build * correct branch ref * correct branch ref passed to target repo * Create k8s-tests.yml * Delete k8s-tests.yml * correct branch ref passed to target repo * correct branch ref passed to target repo * Always describe AWS tasks for now, because unstable error handling * Remove unused tree commands * Use lfs guid sum * Simple override cache push * Simple override cache push and pull override to allow pure cloud storage driven caching * Removal of early branch (breaks lfs caching) * Remove unused tree commands * Update action.yml * Update action.yml * Support cache and input override commands as input + full support custom hooks * Increase k8s timeout * replace filename being appended for unknclear reason * cache key should not contain whitespaces * Always try and deploy rook for k8s * Apply k8s files for rook * Update action.yml * Apply k8s files for rook * Apply k8s files for rook * cache test and action description for kuber storage class * Correct test and implement dependency health check and start * GCP-secret run, cache key * lfs smudge set explicit and undo explicit * Run using external secret provider to speed up input * Update cloud-runner-aws-pipeline.yml * Add nodejs as build step dependency * Add nodejs as build step dependency * Cloud Runner Tests must be specified to capture logs from cloud runner for tests * Cloud Runner Tests must be specified to capture logs from cloud runner for tests * Refactor and cleanup - no async input, combined setup/build, removed github logs for cli runs * Refactor and cleanup - no async input, combined setup/build, removed github logs for cli runs * Refactor and cleanup - no async input, combined setup/build, removed github logs for cli runs * Refactor and cleanup - no async input, combined setup/build, removed github logs for cli runs * Refactor and cleanup - no async input, combined setup/build, removed github logs for cli runs * better defaults for new inputs * better defaults * merge latest * force build update * use npm n to update node in unity builder * use npm n to update node in unity builder * use npm n to update node in unity builder * correct new line * quiet zipping * quiet zipping * default secrets for unity username and password * default secrets for unity username and password * ls active directory before lfs install * Get cloud runner secrets from * Get cloud runner secrets from * Cleanup setup of default secrets * Various fixes * Cleanup setup of default secrets * Various fixes * Various fixes * Various fixes * Various fixes * Various fixes * Various fixes * Various fixes * Various fixes * Various fixes * Various fixes * Various fixes * Various fixes * Various fixes * Various fixes * AWS secrets manager support * less caching logs * default k8s storage class to pd-standard * more readable build commands * Capture aws exit code 1 reliably * Always replace /head from branch * k8s default storage class to standard-rwo * cleanup * further cleanup input * further cleanup input * further cleanup input * further cleanup input * further cleanup input * folder sizes to inspect caching * dir command for local cloud runner test * k8s wait for pending because pvc will not create earlier * prefer k8s standard storage * handle empty string as cloud runner cluster input * local-system is now used for cloud runner test implementation AND correctly unset test CLI input * local-system is now used for cloud runner test implementation AND correctly unset test CLI input * fix unterminated quote * fix unterminated quote * do not share build parameters in tests - in cloud runner this will cause conflicts with resouces of the same name * remove head and heads from branch prefix * fix reversed caching direction of cache-push * fixes * fixes * fixes * cachePull cli * fixes * fixes * fixes * fixes * fixes * order cache test to be first * order cache test to be first * fixes * populate cache key instead of using branch * cleanup cli * garbage-collect-aws cli can iterate over aws resources and cli scans all ts files * import cli methods * import cli files explicitly * import cli files explicitly * import cli files explicitly * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * import cli methods * log parameters in cloud runner parameter test * log parameters in cloud runner parameter test * log parameters in cloud runner parameter test * Cloud runner param test before caching because we have a fast local cache test now * Using custom build path relative to repo root rather than project root * aws-garbage-collect at end of pipeline * aws-garbage-collect do not actually delete anything for now - just list * remove some legacy du commands * Update cloud-runner-aws-pipeline.yml * log contents after cache pull and fix some scenarios with duplicate secrets * log contents after cache pull and fix some scenarios with duplicate secrets * log contents after cache pull and fix some scenarios with duplicate secrets * PR comments * Replace guid with uuid package * use fileExists lambda instead of stat to check file exists in caching * build failed results in core error message * Delete sample.txt --- .../workflows/cloud-runner-aws-pipeline.yml | 11 +- .../workflows/cloud-runner-k8s-pipeline.yml | 13 +- action.yml | 36 +- dist/index.js | Bin 21807569 -> 21829738 bytes dist/index.js.map | Bin 16167023 -> 16201632 bytes package-lock.json | 6956 +++++++++++++++++ package.json | 6 +- src/index.ts | 19 +- src/model/build-parameters.ts | 49 +- src/model/cli/cli-decorator.ts | 23 - src/model/cli/cli-functions-repository.ts | 44 + src/model/cli/cli.ts | 125 +- .../remote-client-services/caching.ts | 117 - .../cloud-runner-system.ts | 37 - .../setup-cloud-runner-repository.ts | 81 - .../{state => }/cloud-runner-step-state.ts | 4 +- src/model/cloud-runner/cloud-runner.test.ts | 87 +- src/model/cloud-runner/cloud-runner.ts | 89 +- .../cloud-runner/error/cloud-runner-error.ts | 12 +- .../{ => providers}/aws/aws-base-stack.ts | 2 +- .../aws/aws-cloud-formation-templates.ts} | 2 +- .../{ => providers}/aws/aws-error.ts | 6 +- .../{ => providers}/aws/aws-job-stack.ts | 20 +- .../{ => providers}/aws/aws-task-runner.ts | 74 +- .../aws/cloud-formations/base-setup.yml | 0 .../cloud-formations/task-def-formation.yml | 0 .../aws/cloud-runner-aws-task-def.ts | 0 .../aws/commands/aws-cli-commands.ts | 30 + .../cloud-runner/{ => providers}/aws/index.ts | 18 +- .../cloud-runner/{ => providers}/k8s/index.ts | 20 +- .../k8s/kubernetes-job-spec-factory.ts | 12 +- .../{ => providers}/k8s/kubernetes-secret.ts | 2 +- .../k8s/kubernetes-service-account.ts | 0 .../{ => providers}/k8s/kubernetes-storage.ts | 14 +- .../k8s/kubernetes-task-runner.ts | 8 +- .../providers/local-docker/index.ts | 48 + .../cloud-runner/providers/local/index.ts | 48 + .../provider-interface.ts} | 10 +- .../cloud-runner/providers/test/index.ts | 49 + .../remote-client/caching.test.ts | 63 + .../cloud-runner/remote-client/caching.ts | 171 + src/model/cloud-runner/remote-client/index.ts | 95 + .../remote-client}/remote-client-logger.ts | 2 +- .../cloud-runner-build-command-process.ts | 20 +- .../services/cloud-runner-folders.ts | 73 + ...nner-namespace.ts => cloud-runner-guid.ts} | 2 +- .../services/cloud-runner-query-override.ts | 59 + .../services/cloud-runner-system.ts | 45 + .../services/depdency-override-service.ts | 21 + .../services}/lfs-hashing.ts | 23 +- .../services/task-parameter-serializer.ts | 64 +- .../cloud-runner/state/cloud-runner-state.ts | 81 - src/model/cloud-runner/steps/build-step.ts | 77 - src/model/cloud-runner/steps/setup-step.ts | 65 - .../cloud-runner/steps/step-interface.ts | 8 - .../workflows/build-automation-workflow.ts | 115 +- .../cloud-runner/workflows/custom-workflow.ts | 49 +- .../workflows/workflow-composition-root.ts | 24 +- .../workflows/workflow-interface.ts | 2 +- src/model/image-tag.ts | 11 +- .../input-readers/generic-input-reader.ts | 7 + src/model/input-readers/git-repo.ts | 22 +- src/model/input-readers/github-cli.ts | 6 +- src/model/input.ts | 148 +- yarn.lock | 12 +- 65 files changed, 8435 insertions(+), 902 deletions(-) create mode 100644 package-lock.json delete mode 100644 src/model/cli/cli-decorator.ts create mode 100644 src/model/cli/cli-functions-repository.ts delete mode 100644 src/model/cli/remote-client/remote-client-services/caching.ts delete mode 100644 src/model/cli/remote-client/remote-client-services/cloud-runner-system.ts delete mode 100644 src/model/cli/remote-client/setup-cloud-runner-repository.ts rename src/model/cloud-runner/{state => }/cloud-runner-step-state.ts (70%) rename src/model/cloud-runner/{ => providers}/aws/aws-base-stack.ts (98%) rename src/model/cloud-runner/{aws/aws-templates.ts => providers/aws/aws-cloud-formation-templates.ts} (95%) rename src/model/cloud-runner/{ => providers}/aws/aws-error.ts (75%) rename src/model/cloud-runner/{ => providers}/aws/aws-job-stack.ts (82%) rename src/model/cloud-runner/{ => providers}/aws/aws-task-runner.ts (78%) rename src/model/cloud-runner/{ => providers}/aws/cloud-formations/base-setup.yml (100%) rename src/model/cloud-runner/{ => providers}/aws/cloud-formations/task-def-formation.yml (100%) rename src/model/cloud-runner/{ => providers}/aws/cloud-runner-aws-task-def.ts (100%) create mode 100644 src/model/cloud-runner/providers/aws/commands/aws-cli-commands.ts rename src/model/cloud-runner/{ => providers}/aws/index.ts (85%) rename src/model/cloud-runner/{ => providers}/k8s/index.ts (91%) rename src/model/cloud-runner/{ => providers}/k8s/kubernetes-job-spec-factory.ts (90%) rename src/model/cloud-runner/{ => providers}/k8s/kubernetes-secret.ts (91%) rename src/model/cloud-runner/{ => providers}/k8s/kubernetes-service-account.ts (100%) rename src/model/cloud-runner/{ => providers}/k8s/kubernetes-storage.ts (90%) rename src/model/cloud-runner/{ => providers}/k8s/kubernetes-task-runner.ts (92%) create mode 100644 src/model/cloud-runner/providers/local-docker/index.ts create mode 100644 src/model/cloud-runner/providers/local/index.ts rename src/model/cloud-runner/{services/cloud-runner-provider-interface.ts => providers/provider-interface.ts} (85%) create mode 100644 src/model/cloud-runner/providers/test/index.ts create mode 100644 src/model/cloud-runner/remote-client/caching.test.ts create mode 100644 src/model/cloud-runner/remote-client/caching.ts create mode 100644 src/model/cloud-runner/remote-client/index.ts rename src/model/{cli/remote-client/remote-client-services => cloud-runner/remote-client}/remote-client-logger.ts (84%) create mode 100644 src/model/cloud-runner/services/cloud-runner-folders.ts rename src/model/cloud-runner/services/{cloud-runner-namespace.ts => cloud-runner-guid.ts} (81%) create mode 100644 src/model/cloud-runner/services/cloud-runner-query-override.ts create mode 100644 src/model/cloud-runner/services/cloud-runner-system.ts create mode 100644 src/model/cloud-runner/services/depdency-override-service.ts rename src/model/{cli/remote-client/remote-client-services => cloud-runner/services}/lfs-hashing.ts (62%) delete mode 100644 src/model/cloud-runner/state/cloud-runner-state.ts delete mode 100644 src/model/cloud-runner/steps/build-step.ts delete mode 100644 src/model/cloud-runner/steps/setup-step.ts delete mode 100644 src/model/cloud-runner/steps/step-interface.ts create mode 100644 src/model/input-readers/generic-input-reader.ts diff --git a/.github/workflows/cloud-runner-aws-pipeline.yml b/.github/workflows/cloud-runner-aws-pipeline.yml index 45341a4d..37e0df24 100644 --- a/.github/workflows/cloud-runner-aws-pipeline.yml +++ b/.github/workflows/cloud-runner-aws-pipeline.yml @@ -61,12 +61,15 @@ jobs: aws-region: eu-west-2 - run: yarn - run: yarn run cli --help + - run: yarn run test "caching" - run: yarn run test-i-aws env: UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} PROJECT_PATH: ${{ matrix.projectPath }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TARGET_PLATFORM: ${{ matrix.targetPlatform }} + cloudRunnerTests: true + versioning: None - uses: ./ id: aws-fargate-unity-build timeout-minutes: 25 @@ -87,9 +90,8 @@ jobs: aws s3 ls aws s3 ls game-ci-test-storage ls /data/cache/$CACHE_KEY - echo "/data/cache/$CACHE_KEY/build-$BUILD_GUID.zip s3://game-ci-test-storage/$CACHE_KEY/$BUILD_FILE" - aws s3 cp /data/cache/$CACHE_KEY/build-$BUILD_GUID.zip s3://game-ci-test-storage/$CACHE_KEY/build-$BUILD_GUID.zip - aws s3 cp /data/cache/$CACHE_KEY s3://game-ci-test-storage/$CACHE_KEY/$BUILD_GUID + ls /data/cache/$CACHE_KEY/build + aws s3 cp /data/cache/$CACHE_KEY/build/build-$BUILD_GUID.zip s3://game-ci-test-storage/$CACHE_KEY/build-$BUILD_GUID.zip secrets: - name: awsAccessKeyId value: ${{ secrets.AWS_ACCESS_KEY_ID }} @@ -98,8 +100,9 @@ jobs: - name: awsDefaultRegion value: eu-west-2 - run: | - aws s3 cp s3://game-ci-test-storage/${{ steps.aws-fargate-unity-build.outputs.BRANCH }}/build-${{ steps.aws-fargate-unity-build.outputs.BUILD_GUID }}.zip build-${{ steps.aws-fargate-unity-build.outputs.BUILD_GUID }}.zip + aws s3 cp s3://game-ci-test-storage/${{ steps.aws-fargate-unity-build.outputs.CACHE_KEY }}/build-${{ steps.aws-fargate-unity-build.outputs.BUILD_GUID }}.zip build-${{ steps.aws-fargate-unity-build.outputs.BUILD_GUID }}.zip ls + - run: yarn run cli -m aws-garbage-collect ########################### # Upload # ########################### diff --git a/.github/workflows/cloud-runner-k8s-pipeline.yml b/.github/workflows/cloud-runner-k8s-pipeline.yml index b8b308e3..1b5b1509 100644 --- a/.github/workflows/cloud-runner-k8s-pipeline.yml +++ b/.github/workflows/cloud-runner-k8s-pipeline.yml @@ -50,7 +50,7 @@ jobs: ########################### # Setup # ########################### - - uses: google-github-actions/setup-gcloud@master + - uses: google-github-actions/setup-gcloud@v0 with: version: '288.0.0' service_account_email: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_EMAIL }} @@ -66,6 +66,7 @@ jobs: node-version: 12.x - run: yarn - run: yarn run cli --help + - run: yarn run test "caching" - name: Cloud Runner Test Suite run: yarn run test-i-k8s --detectOpenHandles --forceExit env: @@ -75,6 +76,8 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} KUBE_CONFIG: ${{ steps.read-base64.outputs.base64 }} unityVersion: ${{ matrix.unityVersion }} + cloudRunnerTests: true + versioning: None ########################### # Cloud Runner Build Test # @@ -101,9 +104,9 @@ jobs: aws configure set region $AWS_DEFAULT_REGION --profile default aws s3 ls aws s3 ls game-ci-test-storage - ls /data/cache/$BRANCH - echo "/data/cache/$BRANCH/build-$BUILD_GUID.zip s3://game-ci-test-storage/$BRANCH/$BUILD_FILE" - aws s3 cp /data/cache/$BRANCH/build-$BUILD_GUID.zip s3://game-ci-test-storage/$BRANCH/build-$BUILD_GUID.zip + ls /data/cache/$CACHE_KEY + echo "/data/cache/$CACHE_KEY/build/build-$BUILD_GUID.zip s3://game-ci-test-storage/$CACHE_KEY/$BUILD_FILE" + aws s3 cp /data/cache/$CACHE_KEY/build/build-$BUILD_GUID.zip s3://game-ci-test-storage/$CACHE_KEY/build-$BUILD_GUID.zip secrets: - name: awsAccessKeyId value: ${{ secrets.AWS_ACCESS_KEY_ID }} @@ -112,7 +115,7 @@ jobs: - name: awsDefaultRegion value: eu-west-2 - run: | - aws s3 cp s3://game-ci-test-storage/${{ steps.k8s-unity-build.outputs.BRANCH }}/build-${{ steps.k8s-unity-build.outputs.BUILD_GUID }}.zip build-${{ steps.k8s-unity-build.outputs.BUILD_GUID }}.zip + aws s3 cp s3://game-ci-test-storage/${{ steps.k8s-unity-build.outputs.CACHE_KEY }}/build-${{ steps.k8s-unity-build.outputs.BUILD_GUID }}.zip build-${{ steps.k8s-unity-build.outputs.BUILD_GUID }}.zip ls ########################### # Upload # diff --git a/action.yml b/action.yml index d1a94a97..953bd58b 100644 --- a/action.yml +++ b/action.yml @@ -98,6 +98,10 @@ inputs: required: false default: '' description: 'Run a pre build job after the repository setup but before the build job (in yaml format with the keys image, secrets (name, value object array), command line string)' + customJobHooks: + required: false + default: '' + description: 'Specify custom commands and trigger hooks (injects commands into jobs)' customJob: required: false default: '' @@ -118,10 +122,22 @@ inputs: default: '750M' required: false description: 'Amount of memory to assign the remote build container' - githubToken: + cachePushOverrideCommand: default: '' required: false - description: 'GitHub token for cloning, only needed when kubeconfig is used.' + description: 'A command run every time a file is pushed to cache, formatted with input file path and remote cache path' + cachePullOverrideCommand: + default: '' + required: false + description: 'A command run every time before a file is being pulled from cache, formatted with request cache file and destination path' + readInputFromOverrideList: + default: '' + required: false + description: 'Comma separated list of input value names to read from "input override command"' + readInputOverrideCommand: + default: '' + required: false + description: 'Extend game ci by specifying a command to execute to pull input from external source e.g cloud provider secret managers' kubeConfig: default: '' required: false @@ -130,10 +146,26 @@ inputs: default: '' required: false description: 'Supply a Persistent Volume Claim name to use for the Unity build.' + kubeStorageClass: + default: '' + required: false + description: 'Kubernetes storage class to use for cloud runner jobs, leave empty to install rook cluster.' kubeVolumeSize: default: '5Gi' required: false description: 'Amount of disc space to assign the Kubernetes Persistent Volume' + cacheKey: + default: '' + required: false + description: 'Cache key to indicate bucket for cache' + checkDependencyHealthOverride: + default: '' + required: false + description: 'Use to specify a way to check depdency services health to enable resilient self-starting jobs' + startDependenciesOverride: + default: '' + required: false + description: 'Use to specify a way to start depdency services health to enable resilient self-starting jobs' outputs: volume: description: 'The Persistent Volume (PV) where the build artifacts have been stored by Kubernetes' diff --git a/dist/index.js b/dist/index.js index 62556407d5ecdd4a3a92535276e929c9ff471b82..b8a2d03df15e99a482749325f6f95b96e6b845ce 100644 GIT binary patch delta 27591 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 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..2b81a3fd --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6956 @@ +{ + "name": "unity-builder", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@actions/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", + "integrity": "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==", + "requires": { + "@actions/http-client": "^1.0.11" + } + }, + "@actions/exec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.0.tgz", + "integrity": "sha512-LImpN9AY0J1R1mEYJjVJfSZWU4zYOlEcwSTgPve1rFQqK5AwrEs6uWW5Rv70gbDIQIAUwI86z6B+9mPK4w9Sbg==", + "requires": { + "@actions/io": "^1.0.1" + } + }, + "@actions/github": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.0.tgz", + "integrity": "sha512-QvE9eAAfEsS+yOOk0cylLBIO/d6WyWIOvsxxzdrPFaud39G6BOkUwScXZn1iBzQzHyu9SBkkLSWlohDWdsasAQ==", + "requires": { + "@actions/http-client": "^1.0.11", + "@octokit/core": "^3.4.0", + "@octokit/plugin-paginate-rest": "^2.13.3", + "@octokit/plugin-rest-endpoint-methods": "^5.1.1" + }, + "dependencies": { + "@octokit/core": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", + "requires": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.0", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + } + } + }, + "@actions/http-client": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz", + "integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==", + "requires": { + "tunnel": "0.0.6" + } + }, + "@actions/io": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.0.tgz", + "integrity": "sha512-PspSX7Z9zh2Fyyuf3F6BsYeXcYHfc/VJ1vwy2vouas95efHVd42M6UfBFRs+jY0uiMDXhAoUtATn9g2r1MaWBQ==" + }, + "@ampproject/remapping": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", + "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.0" + } + }, + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/compat-data": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", + "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", + "dev": true + }, + "@babel/core": { + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", + "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.7", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helpers": "^7.17.8", + "@babel/parser": "^7.17.8", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0" + }, + "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/eslint-parser": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz", + "integrity": "sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA==", + "dev": true, + "requires": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", + "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", + "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", + "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + } + } + }, + "@babel/helper-plugin-utils": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", + "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", + "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", + "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", + "dev": true, + "requires": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" + }, + "dependencies": { + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + } + } + }, + "@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", + "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.7" + } + }, + "@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.17.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", + "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@eslint/eslintrc": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", + "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.19", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + } + }, + "@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + } + }, + "@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dev": true, + "requires": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + } + }, + "@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "requires": { + "@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": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@kubernetes/client-node": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.16.3.tgz", + "integrity": "sha512-L7IckuyuPfhd+/Urib8MRas9D6sfKEq8IaITYcaE6LlU+Y8MeD7MTbuW6Yb2WdeRuFN8HPSS47mxPnOUNYBXEg==", + "requires": { + "@types/js-yaml": "^4.0.1", + "@types/node": "^10.12.0", + "@types/request": "^2.47.1", + "@types/stream-buffers": "^3.0.3", + "@types/tar": "^4.0.3", + "@types/underscore": "^1.8.9", + "@types/ws": "^6.0.1", + "byline": "^5.0.0", + "execa": "5.0.0", + "isomorphic-ws": "^4.0.1", + "js-yaml": "^4.1.0", + "jsonpath-plus": "^0.19.0", + "openid-client": "^4.1.1", + "request": "^2.88.0", + "rfc4648": "^1.3.0", + "shelljs": "^0.8.5", + "stream-buffers": "^3.0.2", + "tar": "^6.1.11", + "tmp-promise": "^3.0.2", + "tslib": "^1.9.3", + "underscore": "^1.9.1", + "ws": "^7.3.1" + }, + "dependencies": { + "@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" + }, + "@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" + }, + "execa": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", + "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "requires": { + "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" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + }, + "jose": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", + "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", + "requires": { + "@panva/asn1.js": "^1.0.0" + }, + "dependencies": { + "@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==" + } + } + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "keyv": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.0.tgz", + "integrity": "sha512-mcRm0yqY2Z2FdE3Tkb7hNEUN7J7VdedNZ8F6vS5jX04gNo2pyOWqfyW+chW9amiS3gbULPucyRzVq0gjPUmhTA==", + "requires": { + "compress-brotli": "^1.3.6", + "json-buffer": "3.0.1" + } + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" + }, + "openid-client": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-4.9.1.tgz", + "integrity": "sha512-DYUF07AHjI3QDKqKbn2F7RqozT4hyi4JvmpodLrq0HHoNP7t/AjeG/uqiBK1/N2PZSAQEThVjDLHSmJN4iqu/w==", + "requires": { + "aggregate-error": "^3.1.0", + "got": "^11.8.0", + "jose": "^2.0.5", + "lru-cache": "^6.0.0", + "make-error": "^1.3.6", + "object-hash": "^2.0.1", + "oidc-token-hash": "^5.0.1" + }, + "dependencies": { + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "got": { + "version": "11.8.3", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.3.tgz", + "integrity": "sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==", + "requires": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" + }, + "oidc-token-hash": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz", + "integrity": "sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==" + } + } + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "requires": { + "@octokit/types": "^6.0.3" + } + }, + "@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "requires": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "requires": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", + "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" + }, + "@octokit/plugin-paginate-rest": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", + "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", + "requires": { + "@octokit/types": "^6.34.0" + } + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", + "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", + "requires": { + "@octokit/types": "^6.34.0", + "deprecation": "^2.3.1" + } + }, + "@octokit/request": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", + "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "requires": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "6.34.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", + "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "requires": { + "@octokit/openapi-types": "^11.2.0" + } + }, + "@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==" + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "@types/babel__core": { + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "dev": true, + "requires": { + "@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.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "@types/caseless": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", + "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" + }, + "@types/got": { + "version": "9.6.12", + "resolved": "https://registry.npmjs.org/@types/got/-/got-9.6.12.tgz", + "integrity": "sha512-X4pj/HGHbXVLqTpKjA2ahI4rV/nNBc9mGO2I/0CgAra+F2dKgMXnENv2SRpemScBzBAI4vMelIVYViQxlSE6xA==", + "requires": { + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "dev": true, + "requires": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "pretty-format": { + "version": "27.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.2.tgz", + "integrity": "sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw==", + "dev": true, + "requires": { + "@jest/types": "^27.4.2", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + } + } + } + }, + "@types/js-yaml": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", + "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==" + }, + "@types/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "requires": { + "@types/node": "*" + } + }, + "@types/minipass": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/minipass/-/minipass-3.1.2.tgz", + "integrity": "sha512-foLGjgrJkUjLG/o2t2ymlZGEoBNBa/TfoUZ7oCTkOjP1T43UGBJspovJou/l3ZuHvye2ewR5cZNtp2zyWgILMA==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + }, + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "@types/prettier": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.4.tgz", + "integrity": "sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==", + "dev": true + }, + "@types/request": { + "version": "2.48.8", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.8.tgz", + "integrity": "sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==", + "requires": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "requires": { + "@types/node": "*" + } + }, + "@types/semver": { + "version": "7.3.9", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz", + "integrity": "sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "@types/stream-buffers": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/stream-buffers/-/stream-buffers-3.0.4.tgz", + "integrity": "sha512-qU/K1tb2yUdhXkLIATzsIPwbtX6BpZk0l3dPW6xqWyhfzzM1ECaQ/8faEnu3CNraLiQ9LHyQQPBGp7N9Fbs25w==", + "requires": { + "@types/node": "*" + } + }, + "@types/tar": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tar/-/tar-4.0.5.tgz", + "integrity": "sha512-cgwPhNEabHaZcYIy5xeMtux2EmYBitfqEceBUi2t5+ETy4dW6kswt6WX4+HqLeiiKOo42EXbGiDmVJ2x+vi37Q==", + "requires": { + "@types/minipass": "*", + "@types/node": "*" + } + }, + "@types/tough-cookie": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", + "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==" + }, + "@types/underscore": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.4.tgz", + "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg==" + }, + "@types/ws": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.4.tgz", + "integrity": "sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==", + "requires": { + "@types/node": "*" + } + }, + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.0.tgz", + "integrity": "sha512-U8SP9VOs275iDXaL08Ln1Fa/wLXfj5aTr/1c0t0j6CdbOnxh+TruXu1p4I0NAvdPBQgoPjHsgKn28mOi0FzfoA==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.22.0", + "@typescript-eslint/scope-manager": "4.22.0", + "debug": "^4.1.1", + "functional-red-black-tree": "^1.0.1", + "lodash": "^4.17.15", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", + "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.22.0", + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/typescript-estree": "4.22.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.8.1.tgz", + "integrity": "sha512-QND8XSVetATHK9y2Ltc/XBl5Ro7Y62YuZKnPEwnNPB8E379fDsvzJ1dMJ46fg/VOmk0hXhatc+GXs5MaXuL5Uw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.8.1", + "@typescript-eslint/types": "4.8.1", + "@typescript-eslint/typescript-estree": "4.8.1", + "debug": "^4.1.1" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.8.1.tgz", + "integrity": "sha512-r0iUOc41KFFbZdPAdCS4K1mXivnSZqXS5D9oW+iykQsRlTbQRfuFRSW20xKDdYiaCoH+SkSLeIF484g3kWzwOQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.8.1", + "@typescript-eslint/visitor-keys": "4.8.1" + } + }, + "@typescript-eslint/types": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.8.1.tgz", + "integrity": "sha512-ave2a18x2Y25q5K05K/U3JQIe2Av4+TNi/2YuzyaXLAsDx6UZkz1boZ7nR/N6Wwae2PpudTZmHFXqu7faXfHmA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.8.1.tgz", + "integrity": "sha512-bJ6Fn/6tW2g7WIkCWh3QRlaSU7CdUUK52shx36/J7T5oTQzANvi6raoTsbwGM11+7eBbeem8hCCKbyvAc0X3sQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.8.1", + "@typescript-eslint/visitor-keys": "4.8.1", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.8.1.tgz", + "integrity": "sha512-3nrwXFdEYALQh/zW8rFwP4QltqsanCDz4CwWMPiIZmwlk9GlvBeueEIbq05SEq4ganqM0g9nh02xXgv5XI3PeQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.8.1", + "eslint-visitor-keys": "^2.0.0" + } + } + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", + "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/visitor-keys": "4.22.0" + } + }, + "@typescript-eslint/types": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", + "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", + "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/visitor-keys": "4.22.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", + "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.22.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "@vercel/ncc": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.33.3.tgz", + "integrity": "sha512-JGZ11QV+/ZcfudW2Cz2JVp54/pJNXbsuWRgSh2ZmmZdQBKXqBtIGrwI1Wyx8nlbzAiEFe7FHi4K1zX4//jxTnQ==", + "dev": true + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==" + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + } + } + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + } + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + } + }, + "asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async-wait-until": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/async-wait-until/-/async-wait-until-2.0.12.tgz", + "integrity": "sha512-SXy/vDs6UPJMG6YeEYOQ4ilA/JnGxk187KPGqFx9O+qVxsjkSl+jH+3P50qSNyMpEmDgr8qOFGOKCJckWb1i7A==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sdk": { + "version": "2.1082.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1082.0.tgz", + "integrity": "sha512-aDrUZ63O/ocuC827ursDqFQAm3jhqsJu1DvMCCFg73y+FK9pXXNHp2mwdi3UeeHvtfxISCLCjuyO3VFd/tpVfA==", + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.16.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "requires": { + "@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": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "requires": { + "@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": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "before-after-hook": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "browserslist": { + "version": "4.20.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", + "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "dev": true, + "requires": { + "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": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=" + }, + "cac": { + "version": "6.7.12", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.12.tgz", + "integrity": "sha512-rM7E2ygtMkJqD9c7WnFU6fruFcN3xe4FM5yUmgxhZzIKJk4uHl9U/fhwdajGFQbQuv43FAUo1Fe8gX/oIKDeSA==" + }, + "cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "requires": { + "lowercase-keys": "^1.0.0" + }, + "dependencies": { + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + } + } + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001324", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001324.tgz", + "integrity": "sha512-/eYp1J6zYh1alySQB4uzYFkLmxxI8tk0kxldbNHXp8+v+rdMKdUBNjRLz7T7fz6Iox+1lIdYpc7rq6ZcXfTukg==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "requires": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz", + "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true + }, + "slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + } + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz", + "integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==" + }, + "commander-ts": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/commander-ts/-/commander-ts-0.2.0.tgz", + "integrity": "sha512-9XaUF3/3nmVtkDmAkijjhgEcwrMwKewaAJtN+GyTJBG3CJ5DfGB/JsXCVZcBW6SZB+QqiJxbK3e2/62tweMO8g==", + "requires": { + "commander": "^7.2.0" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + } + } + }, + "compress-brotli": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.6.tgz", + "integrity": "sha512-au99/GqZtUtiCBliqLFbWlhnCxn+XSYjwZ77q6mKN4La4qOXDoLVPZ50iXr0WmAyMxl8yqoq3Yq4OeQNPPkyeQ==", + "requires": { + "@types/json-buffer": "~3.0.0", + "json-buffer": "~3.0.1" + }, + "dependencies": { + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "electron-to-chromium": { + "version": "1.4.103", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", + "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", + "dev": true + }, + "emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", + "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + } + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "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" + } + } + } + }, + "eslint": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.17.0.tgz", + "integrity": "sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@eslint/eslintrc": "^0.2.2", + "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", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.0", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.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": "^4.17.19", + "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.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-config-prettier": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.1.0.tgz", + "integrity": "sha512-oKMhGv3ihGbCIimCAjqkdzx2Q+jthoqnXSP+d86M9tptwugycmTFdVR4IpLgq2c4SHifbwO90z2fQ8/Aio73yw==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "eslint-plugin-eslint-comments": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz", + "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "ignore": "^5.0.5" + }, + "dependencies": { + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + } + } + }, + "eslint-plugin-github": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-github/-/eslint-plugin-github-4.1.3.tgz", + "integrity": "sha512-90MZbFt61jO+hCprPAPH1VSLylQPsynmMId79z/fCGQEhm3qzbAkUG3NqhNK8ltWZfFbXFYuXB4S5BnNttYGhQ==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "^4.20.0", + "@typescript-eslint/parser": "^4.20.0", + "eslint-config-prettier": ">=8.0.0", + "eslint-plugin-eslint-comments": "^3.2.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-prettier": "^3.3.1", + "eslint-rule-documentation": ">=1.0.0", + "prettier": "^2.2.1", + "svg-element-attributes": "^1.3.1" + }, + "dependencies": { + "@typescript-eslint/parser": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.22.0.tgz", + "integrity": "sha512-z/bGdBJJZJN76nvAY9DkJANYgK3nlRstRRi74WHm3jjgf2I8AglrSY+6l7ogxOmn55YJ6oKZCLLy+6PW70z15Q==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.22.0", + "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/typescript-estree": "4.22.0", + "debug": "^4.1.1" + } + }, + "eslint-config-prettier": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.2.0.tgz", + "integrity": "sha512-dWV9EVeSo2qodOPi1iBYU/x6F6diHv8uujxbxr77xExs3zTAlNXvVZKiyLsQGNz7yPV2K49JY5WjPzNIuDc2Bw==", + "dev": true + }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + } + } + }, + "eslint-plugin-jest": { + "version": "24.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.1.3.tgz", + "integrity": "sha512-dNGGjzuEzCE3d5EPZQ/QGtmlMotqnYWD/QpCZ1UuZlrMAdhG5rldh0N0haCvhGnUkSeuORS5VNROwF9Hrgn3Lg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "^4.0.1" + } + }, + "eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-unicorn": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-28.0.2.tgz", + "integrity": "sha512-k4AoFP7n8/oq6lBXkdc9Flid6vw2B8j7aXFCxgzJCyKvmaKrCUFb1TFPhG9eSJQFZowqmymMPRtl8oo9NKLUbw==", + "dev": true, + "requires": { + "ci-info": "^2.0.0", + "clean-regexp": "^1.0.0", + "eslint-template-visitor": "^2.2.2", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "import-modules": "^2.1.0", + "lodash": "^4.17.20", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.22", + "reserved-words": "^0.1.2", + "safe-regex": "^2.1.1", + "semver": "^7.3.4" + }, + "dependencies": { + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-rule-documentation": { + "version": "1.0.23", + "resolved": "https://registry.npmjs.org/eslint-rule-documentation/-/eslint-rule-documentation-1.0.23.tgz", + "integrity": "sha512-pWReu3fkohwyvztx/oQWWgld2iad25TfUdi6wvhhaDPIQjHU/pyvlKgXFw1kX31SQK2Nq9MH+vRDWB0ZLy8fYw==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "eslint-template-visitor": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", + "dev": true, + "requires": { + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", + "eslint-visitor-keys": "^2.0.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + } + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "requires": { + "@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": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "requires": { + "minipass": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "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" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + } + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + } + } + }, + "graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" + }, + "husky": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", + "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "import-modules": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.1.0.tgz", + "integrity": "sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.0.tgz", + "integrity": "sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", + "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isomorphic-ws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", + "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "dev": true, + "requires": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + }, + "dependencies": { + "jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "dev": true, + "requires": { + "@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-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dev": true, + "requires": { + "@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-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "requires": { + "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" + } + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + } + } + }, + "jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true + }, + "jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "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" + } + }, + "jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dev": true, + "requires": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true + }, + "jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "dev": true + }, + "jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "dev": true, + "requires": { + "@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-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + } + }, + "jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + } + } + }, + "jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + } + }, + "jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "dev": true, + "requires": { + "@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": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" + }, + "jose": { + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-1.28.1.tgz", + "integrity": "sha512-6JK28rFu5ENp/yxMwM+iN7YeaInnY9B9Bggjkz5fuwLiJhbVrl2O4SJr65bdNBPl9y27fdC3Mymh+FVCvozLIg==", + "requires": { + "@panva/asn1.js": "^1.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.5.3.tgz", + "integrity": "sha512-Qj1H+PEvUsOtdPJ056ewXM4UJPCi4hhLA8wpiz9F2YvsRBhuFsXxtrIFAgGBDynQA9isAMGE91PfUYbdMPXuTA==", + "requires": { + "abab": "^2.0.5", + "acorn": "^8.1.0", + "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", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.9", + "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.4", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true + }, + "jsonpath-plus": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-0.19.0.tgz", + "integrity": "sha512-GSVwsrzW9LsA5lzsqe4CkuZ9wp+kxBb2GwNniaWzI2YFn5Ig42rSW8ZxVpWXaAfakXNrx5pgY5AbQq7kzX29kg==" + }, + "jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "requires": { + "json-buffer": "3.0.0" + } + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "kubernetes-client": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/kubernetes-client/-/kubernetes-client-9.0.0.tgz", + "integrity": "sha512-Qy8o42dZVHB9P+cIiKdWpQbz/65l/qW1fDYvlzzeSLftmL1Ne3HEiM+0TmKAwNuRW0pTJN2tRWhcccToclxJ8g==", + "requires": { + "@kubernetes/client-node": "0.10.2", + "camelcase": "^6.0.0", + "deepmerge": "^4.2.2", + "depd": "^2.0.0", + "js-yaml": "^3.13.1", + "json-stream": "^1.0.0", + "openid-client": "^3.14.0", + "pump": "^3.0.0", + "qs": "^6.9.0", + "request": "^2.88.2", + "swagger-fluent": "^5.0.3", + "url-join": "^4.0.1", + "ws": "^7.2.3" + }, + "dependencies": { + "@kubernetes/client-node": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.10.2.tgz", + "integrity": "sha512-JvsmxbTwiMqsh9LyuXMzT5HjoENFbB3a/JroJsobuAzkxN162UqAOvg++/AA+ccIMWRR2Qln4FyaOJ0a4eKyXg==", + "requires": { + "@types/js-yaml": "^3.12.1", + "@types/node": "^10.12.0", + "@types/request": "^2.47.1", + "@types/underscore": "^1.8.9", + "@types/ws": "^6.0.1", + "isomorphic-ws": "^4.0.1", + "js-yaml": "^3.13.1", + "json-stream": "^1.0.0", + "jsonpath-plus": "^0.19.0", + "request": "^2.88.0", + "shelljs": "^0.8.2", + "tslib": "^1.9.3", + "underscore": "^1.9.1", + "ws": "^6.1.0" + }, + "dependencies": { + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "@types/js-yaml": { + "version": "3.12.7", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-3.12.7.tgz", + "integrity": "sha512-S6+8JAYTE1qdsc9HMVsfY7+SgSuUU/Tp6TYTmITW0PZxiyIMvol3Gy//y69Wkhs0ti4py5qgR3uZH6uz/DNzJQ==" + }, + "@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-stream/-/json-stream-1.0.0.tgz", + "integrity": "sha1-GjhU4o0rvuqzHMfd9oPS3cVlJwg=" + }, + "ws": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz", + "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==" + } + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "dependencies": { + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + } + } + }, + "lilconfig": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz", + "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==", + "dev": true + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "lint-staged": { + "version": "12.3.4", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.4.tgz", + "integrity": "sha512-yv/iK4WwZ7/v0GtVkNb3R82pdL9M+ScpIbJLJNyCXkJ1FGaXvRCOg/SeL59SZtPpqZhE7BD6kPKFLIDUhDx2/w==", + "dev": true, + "requires": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.16", + "commander": "^8.3.0", + "debug": "^4.3.3", + "execa": "^5.1.1", + "lilconfig": "2.0.4", + "listr2": "^4.0.1", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "object-inspect": "^1.12.0", + "string-argv": "^0.3.1", + "supports-color": "^9.2.1", + "yaml": "^1.10.2" + }, + "dependencies": { + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true + }, + "supports-color": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.1.tgz", + "integrity": "sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + } + } + }, + "listr2": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.4.tgz", + "integrity": "sha512-vJOm5KD6uZXjSsrwajr+mNacIjf87gWvlBEltPWLbTkslUscWAzquyK4xfe9Zd4RDgO5nnwFyV06FC+uVR+5mg==", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.4", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, + "slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime-db": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + }, + "mime-types": { + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", + "requires": { + "mime-db": "1.51.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "multimap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz", + "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", + "dev": true + }, + "nanoid": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", + "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + }, + "dependencies": { + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + } + } + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-releases": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "requires": { + "path-key": "^3.0.0" + } + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "oidc-token-hash": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz", + "integrity": "sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "openid-client": { + "version": "3.15.10", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-3.15.10.tgz", + "integrity": "sha512-C9r6/iVzNQ7aGp0krS5mFIY5nY8AH6ajYCH0Njns6AXy2fM3Khw/dY97QlaFJWW2QLhec6xfEk23LZw9EeX66Q==", + "requires": { + "@types/got": "^9.6.9", + "base64url": "^3.0.1", + "got": "^9.6.0", + "jose": "^1.27.1", + "lru-cache": "^6.0.0", + "make-error": "^1.3.6", + "object-hash": "^2.0.1", + "oidc-token-hash": "^5.0.0", + "p-any": "^3.0.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + } + } + }, + "p-any": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-any/-/p-any-3.0.0.tgz", + "integrity": "sha512-5rqbqfsRWNb0sukt0awwgJMlaep+8jV45S15SKKB34z4UuzjcofIfnriCBhWjZP2jbVtjt9yRl7buB6RlKsu9w==", + "requires": { + "p-cancelable": "^2.0.0", + "p-some": "^5.0.0" + } + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-some": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-some/-/p-some-5.0.0.tgz", + "integrity": "sha512-Js5XZxo6vHjB9NOYAzWDYAIyyiPvva0DWESAIWIK7uhSpGsyg5FwUPxipU/SOQx5x9EqhOh545d1jo6cVkitig==", + "requires": { + "aggregate-error": "^3.0.0", + "p-cancelable": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@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": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "prettier": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", + "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", + "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "requires": { + "resolve": "^1.1.6" + } + }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + }, + "regexp-tree": { + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.23.tgz", + "integrity": "sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==", + "dev": true + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "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" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" + } + } + }, + "request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "requires": { + "lodash": "^4.17.19" + } + }, + "request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "reserved-words": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", + "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "dev": true + }, + "responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rfc4648": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/rfc4648/-/rfc4648-1.5.1.tgz", + "integrity": "sha512-60e/YWs2/D3MV1ErdjhJHcmlgnyLUiG4X/14dgsfm9/zmCWLN16xI6YqJYSCd/OANM7bUNzJqPY5B8/02S9Ibw==" + }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "requires": { + "xmlchars": "^2.2.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "requires": { + "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": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, + "stream-buffers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-3.0.2.tgz", + "integrity": "sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==" + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "svg-element-attributes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/svg-element-attributes/-/svg-element-attributes-1.3.1.tgz", + "integrity": "sha512-Bh05dSOnJBf3miNMqpsormfNtfidA/GxQVakhtn0T4DECWKeXQRQUceYjJ+OxYiiLdGe4Jo9iFV8wICFapFeIA==", + "dev": true + }, + "swagger-fluent": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/swagger-fluent/-/swagger-fluent-5.0.3.tgz", + "integrity": "sha512-i43ADMtPi7dxAN75Lw50SlncMB31FgaVwXqKioR8SWs+Yon2RbiLU1J1PGMXA4N8cSt9Vz5RHzaoKjz/+iW88g==", + "requires": { + "deepmerge": "^4.2.2", + "is-plain-object": "^3.0.0", + "request": "^2.88.0" + }, + "dependencies": { + "is-plain-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==" + } + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "table": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.3.1.tgz", + "integrity": "sha512-kNpMVSN4fj9KY4G6tNDVIT59uaG8ZELGQ+cmFSqivmWkCXJLd00VfRmtyHa8X7AeM75PQ/6/TtEtWjTDs1jXJw==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "lodash.clonedeep": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "requires": { + "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": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "requires": { + "rimraf": "^3.0.0" + } + }, + "tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "requires": { + "tmp": "^0.2.0" + } + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "requires": { + "punycode": "^2.1.1" + } + }, + "ts-jest": { + "version": "27.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", + "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", + "dev": true, + "requires": { + "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" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "ts-node": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz", + "integrity": "sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A==", + "dev": true, + "requires": { + "@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", + "yn": "3.1.1" + }, + "dependencies": { + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + } + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", + "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "underscore": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.2.tgz", + "integrity": "sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==" + }, + "unity-changeset": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unity-changeset/-/unity-changeset-1.6.0.tgz", + "integrity": "sha512-ke90Zhr2C5q2SPvinDKTr1dwgAPI0R6kxcO7gHPgQXntbx/Ag8hR0xLwd9K6UR2ykGFmDnUVjdbWfYlkhX8tFQ==", + "requires": { + "cac": "^6.6.1", + "jsdom": "^16.4.0", + "node-fetch": "^2.6.1" + } + }, + "universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + } + } + }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "ws": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==" + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "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-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json index 675a2dd3..a9596179 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,9 @@ "lint": "prettier --check \"src/**/*.{js,ts}\" && eslint src/**/*.ts", "format": "prettier --write \"src/**/*.{js,ts}\"", "cli": "yarn ts-node src/index.ts -m cli", + "gcp-secrets-tests": "cross-env cloudRunnerCluster=aws cloudRunnerTests=true readInputOverrideCommand=\"gcloud secrets versions access 1 --secret=\"{0}\"\" populateOverride=true readInputFromOverrideList=UNITY_EMAIL,UNITY_SERIAL,UNITY_PASSWORD yarn test -i -t \"cloud runner\"", + "gcp-secrets-cli": "cross-env cloudRunnerTests=true readInputOverrideCommand=\"gcloud secrets versions access 1 --secret=\"{0}\"\" yarn ts-node src/index.ts -m cli --populateOverride true --readInputFromOverrideList UNITY_EMAIL,UNITY_SERIAL,UNITY_PASSWORD", + "aws-secrets-cli": "cross-env cloudRunnerTests=true readInputOverrideCommand=\"aws secretsmanager get-secret-value --secret-id {0}\" yarn ts-node src/index.ts -m cli --populateOverride true --readInputFromOverrideList UNITY_EMAIL,UNITY_SERIAL,UNITY_PASSWORD", "cli-aws": "cross-env cloudRunnerCluster=aws yarn run test-cli", "cli-k8s": "cross-env cloudRunnerCluster=k8s yarn run test-cli", "test-cli": "cross-env cloudRunnerTests=true yarn ts-node src/index.ts -m cli --projectPath test-project", @@ -37,12 +40,13 @@ "reflect-metadata": "^0.1.13", "semver": "^7.3.5", "unity-changeset": "^1.6.0", + "uuid": "^8.3.2", "yaml": "^1.10.2" }, "devDependencies": { "@arkweid/lefthook": "^0.7.7", "@types/jest": "^27.4.1", - "@types/node": "^17.0.21", + "@types/node": "^17.0.23", "@types/semver": "^7.3.9", "@typescript-eslint/parser": "4.8.1", "@vercel/ncc": "^0.33.3", diff --git a/src/index.ts b/src/index.ts index 8459f9fd..25a63433 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,14 @@ import * as core from '@actions/core'; import { Action, BuildParameters, Cache, Docker, ImageTag, Output, CloudRunner } from './model'; -import { CLI } from './model/cli/cli'; +import { Cli } from './model/cli/cli'; import MacBuilder from './model/mac-builder'; import PlatformSetup from './model/platform-setup'; async function runMain() { try { + if (Cli.InitCliMode()) { + await Cli.RunCli(); + return; + } Action.checkCompatibility(); Cache.verify(); @@ -13,11 +17,7 @@ async function runMain() { const buildParameters = await BuildParameters.create(); const baseImage = new ImageTag(buildParameters); - if ( - buildParameters.cloudRunnerCluster && - buildParameters.cloudRunnerCluster !== '' && - buildParameters.cloudRunnerCluster !== 'local' - ) { + if (buildParameters.cloudRunnerCluster !== 'local') { await CloudRunner.run(buildParameters, baseImage.toString()); } else { core.info('Building locally'); @@ -35,9 +35,4 @@ async function runMain() { core.setFailed((error as Error).message); } } -const options = CLI.SetupCli(); -if (CLI.isCliMode(options)) { - CLI.RunCli(options); -} else { - runMain(); -} +runMain(); diff --git a/src/model/build-parameters.ts b/src/model/build-parameters.ts index 064c5080..f5ab630e 100644 --- a/src/model/build-parameters.ts +++ b/src/model/build-parameters.ts @@ -1,12 +1,14 @@ import { customAlphabet } from 'nanoid'; -import * as core from '@actions/core'; import AndroidVersioning from './android-versioning'; import CloudRunnerConstants from './cloud-runner/services/cloud-runner-constants'; -import CloudRunnerNamespace from './cloud-runner/services/cloud-runner-namespace'; +import CloudRunnerBuildGuid from './cloud-runner/services/cloud-runner-guid'; import Input from './input'; import Platform from './platform'; import UnityVersioning from './unity-versioning'; import Versioning from './versioning'; +import { GitRepoReader } from './input-readers/git-repo'; +import { GithubCliReader } from './input-readers/github-cli'; +import { Cli } from './cli/cli'; class BuildParameters { public editorVersion!: string; @@ -33,15 +35,22 @@ class BuildParameters { public cloudRunnerCluster!: string; public awsBaseStackName!: string; public gitPrivateToken!: string; - public remoteBuildCluster!: string; public awsStackName!: string; public kubeConfig!: string; - public githubToken!: string; public cloudRunnerMemory!: string; public cloudRunnerCpu!: string; public kubeVolumeSize!: string; public kubeVolume!: string; + public kubeStorageClass!: string; public chownFilesTo!: string; + public customJobHooks!: string; + public cachePushOverrideCommand!: string; + public cachePullOverrideCommand!: string; + public readInputFromOverrideList!: string; + public readInputOverrideCommand!: string; + public checkDependencyHealthOverride!: string; + public startDependenciesOverride!: string; + public cacheKey!: string; public postBuildSteps!: string; public preBuildSteps!: string; @@ -52,6 +61,10 @@ class BuildParameters { public gitSha!: string; public logId!: string; public buildGuid!: string; + public cloudRunnerBranch!: string; + public cloudRunnerIntegrationTests!: boolean; + public cloudRunnerBuilderPlatform!: string | undefined; + public isCliMode!: boolean; static async create(): Promise { const buildFile = this.parseBuildFile(Input.buildName, Input.targetPlatform, Input.androidAppBundle); @@ -63,7 +76,7 @@ class BuildParameters { // Todo - Don't use process.env directly, that's what the input model class is for. // --- let unitySerial = ''; - if (!process.env.UNITY_SERIAL) { + if (!process.env.UNITY_SERIAL && Input.githubInputEnabled && Cli.options === undefined) { //No serial was present so it is a personal license that we need to convert if (!process.env.UNITY_LICENSE) { throw new Error(`Missing Unity License File and no Serial was found. If this @@ -75,8 +88,6 @@ class BuildParameters { } else { unitySerial = process.env.UNITY_SERIAL!; } - core.setSecret(unitySerial); - // --- return { editorVersion, @@ -101,12 +112,12 @@ class BuildParameters { androidSdkManagerParameters, customParameters: Input.customParameters, sshAgent: Input.sshAgent, - gitPrivateToken: await Input.gitPrivateToken(), + gitPrivateToken: Input.gitPrivateToken || (await GithubCliReader.GetGitHubAuthToken()), chownFilesTo: Input.chownFilesTo, cloudRunnerCluster: Input.cloudRunnerCluster, + cloudRunnerBuilderPlatform: Input.cloudRunnerBuilderPlatform, awsBaseStackName: Input.awsBaseStackName, kubeConfig: Input.kubeConfig, - githubToken: await Input.githubToken(), cloudRunnerMemory: Input.cloudRunnerMemory, cloudRunnerCpu: Input.cloudRunnerCpu, kubeVolumeSize: Input.kubeVolumeSize, @@ -115,14 +126,24 @@ class BuildParameters { preBuildSteps: Input.preBuildSteps, customJob: Input.customJob, runNumber: Input.runNumber, - branch: await Input.branch(), - // Todo - move this out of UserInput and into some class that determines additional information (as needed) - githubRepo: await Input.githubRepo(), - remoteBuildCluster: Input.cloudRunnerCluster, + branch: Input.branch.replace('/head', '') || (await GitRepoReader.GetBranch()), + cloudRunnerBranch: Input.cloudRunnerBranch.split('/').reverse()[0], + cloudRunnerIntegrationTests: Input.cloudRunnerTests, + githubRepo: Input.githubRepo || (await GitRepoReader.GetRemote()) || 'game-ci/unity-builder', + isCliMode: Cli.isCliMode, awsStackName: Input.awsBaseStackName, gitSha: Input.gitSha, logId: customAlphabet(CloudRunnerConstants.alphabet, 9)(), - buildGuid: CloudRunnerNamespace.generateBuildName(Input.runNumber, Input.targetPlatform), + buildGuid: CloudRunnerBuildGuid.generateGuid(Input.runNumber, Input.targetPlatform), + customJobHooks: Input.customJobHooks(), + cachePullOverrideCommand: Input.cachePullOverrideCommand(), + cachePushOverrideCommand: Input.cachePushOverrideCommand(), + readInputOverrideCommand: Input.readInputOverrideCommand(), + readInputFromOverrideList: Input.readInputFromOverrideList(), + kubeStorageClass: Input.kubeStorageClass, + checkDependencyHealthOverride: Input.checkDependencyHealthOverride, + startDependenciesOverride: Input.startDependenciesOverride, + cacheKey: Input.cacheKey, }; } diff --git a/src/model/cli/cli-decorator.ts b/src/model/cli/cli-decorator.ts deleted file mode 100644 index 7a2d54cd..00000000 --- a/src/model/cli/cli-decorator.ts +++ /dev/null @@ -1,23 +0,0 @@ -const targets = new Array(); -export function CliFunction(key: string, description: string) { - return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { - targets.push({ - target, - propertyKey, - descriptor, - key, - description, - }); - }; -} -export function GetCliFunctions(key) { - return targets.find((x) => x.key === key); -} -export function GetAllCliModes() { - return targets.map((x) => { - return { - key: x.key, - description: x.description, - }; - }); -} diff --git a/src/model/cli/cli-functions-repository.ts b/src/model/cli/cli-functions-repository.ts new file mode 100644 index 00000000..a308ebe6 --- /dev/null +++ b/src/model/cli/cli-functions-repository.ts @@ -0,0 +1,44 @@ +export class CliFunctionsRepository { + private static targets: any[] = []; + public static PushCliFunction( + target: any, + propertyKey: string, + descriptor: PropertyDescriptor, + key: string, + description: string, + ) { + CliFunctionsRepository.targets.push({ + target, + propertyKey, + descriptor, + key, + description, + }); + } + + public static GetCliFunctions(key) { + const results = CliFunctionsRepository.targets.find((x) => x.key === key); + if (results === undefined || results.length === 0) { + throw new Error(`no CLI mode found for ${key}`); + } + return results; + } + + public static GetAllCliModes() { + return CliFunctionsRepository.targets.map((x) => { + return { + key: x.key, + description: x.description, + }; + }); + } + + // eslint-disable-next-line no-unused-vars + public static PushCliFunctionSource(cliFunction: any) {} +} + +export function CliFunction(key: string, description: string) { + return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { + CliFunctionsRepository.PushCliFunction(target, propertyKey, descriptor, key, description); + }; +} diff --git a/src/model/cli/cli.ts b/src/model/cli/cli.ts index ed1b39d5..6faf35b4 100644 --- a/src/model/cli/cli.ts +++ b/src/model/cli/cli.ts @@ -3,55 +3,85 @@ import { BuildParameters, CloudRunner, ImageTag, Input } from '..'; import * as core from '@actions/core'; import { ActionYamlReader } from '../input-readers/action-yaml'; import CloudRunnerLogger from '../cloud-runner/services/cloud-runner-logger'; -import { CliFunction, GetAllCliModes, GetCliFunctions } from './cli-decorator'; -import { RemoteClientLogger } from './remote-client/remote-client-services/remote-client-logger'; -import { CloudRunnerState } from '../cloud-runner/state/cloud-runner-state'; -import { SetupCloudRunnerRepository } from './remote-client/setup-cloud-runner-repository'; -import * as SDK from 'aws-sdk'; +import CloudRunnerQueryOverride from '../cloud-runner/services/cloud-runner-query-override'; +import { CliFunction, CliFunctionsRepository } from './cli-functions-repository'; +import { AwsCliCommands } from '../cloud-runner/providers/aws/commands/aws-cli-commands'; +import { Caching } from '../cloud-runner/remote-client/caching'; +import { LfsHashing } from '../cloud-runner/services/lfs-hashing'; +import { RemoteClient } from '../cloud-runner/remote-client'; -export class CLI { - static async RunCli(options: any): Promise { - Input.githubInputEnabled = false; - - const results = GetCliFunctions(options.mode); - - if (results === undefined || results.length === 0) { - throw new Error('no CLI mode found'); +export class Cli { + public static options; + static get isCliMode() { + return Cli.options !== undefined && Cli.options.mode !== undefined && Cli.options.mode !== ''; + } + public static query(key, alternativeKey) { + if (Cli.options && Cli.options[key] !== undefined) { + return Cli.options[key]; } - - CloudRunnerLogger.log(`Entrypoint: ${results.key}`); - - options.versioning = 'None'; - Input.cliOptions = options; - return await results.target[results.propertyKey](); - } - static isCliMode(options: any) { - return options.mode !== undefined && options.mode !== ''; + if (Cli.options && alternativeKey && Cli.options[alternativeKey] !== undefined) { + return Cli.options[alternativeKey]; + } + return; } - public static SetupCli() { + public static InitCliMode() { + CliFunctionsRepository.PushCliFunctionSource(AwsCliCommands); + CliFunctionsRepository.PushCliFunctionSource(Caching); + CliFunctionsRepository.PushCliFunctionSource(LfsHashing); + CliFunctionsRepository.PushCliFunctionSource(RemoteClient); const program = new Command(); program.version('0.0.1'); const properties = Object.getOwnPropertyNames(Input); - core.info(`\n`); - core.info(`INPUT:`); const actionYamlReader: ActionYamlReader = new ActionYamlReader(); for (const element of properties) { program.option(`--${element} <${element}>`, actionYamlReader.GetActionYamlValue(element)); - if (Input[element] !== undefined && Input[element] !== '' && typeof Input[element] !== `function`) { + } + program.option( + '-m, --mode ', + CliFunctionsRepository.GetAllCliModes() + .map((x) => `${x.key} (${x.description})`) + .join(` | `), + ); + program.option('--populateOverride ', 'should use override query to pull input false by default'); + program.option('--cachePushFrom ', 'cache push from source folder'); + program.option('--cachePushTo ', 'cache push to caching folder'); + program.option('--artifactName ', 'caching artifact name'); + program.parse(process.argv); + Cli.options = program.opts(); + return Cli.isCliMode; + } + + static async RunCli(): Promise { + Input.githubInputEnabled = false; + if (Cli.options['populateOverride'] === `true`) { + await CloudRunnerQueryOverride.PopulateQueryOverrideInput(); + } + Cli.logInput(); + const results = CliFunctionsRepository.GetCliFunctions(Cli.options.mode); + CloudRunnerLogger.log(`Entrypoint: ${results.key}`); + Cli.options.versioning = 'None'; + return await results.target[results.propertyKey](); + } + + @CliFunction(`print-input`, `prints all input`) + private static logInput() { + core.info(`\n`); + core.info(`INPUT:`); + const properties = Object.getOwnPropertyNames(Input); + for (const element of properties) { + if ( + Input[element] !== undefined && + Input[element] !== '' && + typeof Input[element] !== `function` && + element !== 'length' && + element !== 'cliOptions' && + element !== 'prototype' + ) { core.info(`${element} ${Input[element]}`); } } core.info(`\n`); - program.option( - '-m, --mode ', - GetAllCliModes() - .map((x) => `${x.key} (${x.description})`) - .join(` | `), - ); - program.parse(process.argv); - - return program.opts(); } @CliFunction(`cli`, `runs a cloud runner build`) @@ -60,29 +90,4 @@ export class CLI { const baseImage = new ImageTag(buildParameter); return await CloudRunner.run(buildParameter, baseImage.toString()); } - - @CliFunction(`remote-cli`, `sets up a repository, usually before a game-ci build`) - static async runRemoteClientJob() { - const buildParameter = JSON.parse(process.env.BUILD_PARAMETERS || '{}'); - RemoteClientLogger.log(`Build Params: - ${JSON.stringify(buildParameter, undefined, 4)} - `); - CloudRunnerState.setup(buildParameter); - await SetupCloudRunnerRepository.run(); - } - - @CliFunction(`cach-push`, `push to cache`) - static async cachePush() {} - - @CliFunction(`cach-pull`, `pull from cache`) - static async cachePull() {} - - @CliFunction(`garbage-collect-aws`, `garbage collect aws`) - static async garbageCollectAws() { - process.env.AWS_REGION = Input.region; - const CF = new SDK.CloudFormation(); - - const stacks = await CF.listStacks().promise(); - CloudRunnerLogger.log(JSON.stringify(stacks, undefined, 4)); - } } diff --git a/src/model/cli/remote-client/remote-client-services/caching.ts b/src/model/cli/remote-client/remote-client-services/caching.ts deleted file mode 100644 index dda7feeb..00000000 --- a/src/model/cli/remote-client/remote-client-services/caching.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { assert } from 'console'; -import fs from 'fs'; -import path from 'path'; -import { Input } from '../../..'; -import CloudRunnerLogger from '../../../cloud-runner/services/cloud-runner-logger'; -import { CloudRunnerState } from '../../../cloud-runner/state/cloud-runner-state'; -import { CloudRunnerSystem } from './cloud-runner-system'; -import { LFSHashing } from './lfs-hashing'; -import { RemoteClientLogger } from './remote-client-logger'; - -export class Caching { - public static async PushToCache(cacheFolder: string, sourceFolder: string, cacheKey: string) { - const startPath = process.cwd(); - try { - if (!fs.existsSync(cacheFolder)) { - await CloudRunnerSystem.Run(`mkdir -p ${cacheFolder}`); - } - process.chdir(path.resolve(sourceFolder, '..')); - - if (Input.cloudRunnerTests) { - CloudRunnerLogger.log( - `Hashed cache folder ${await LFSHashing.hashAllFiles(sourceFolder)} ${sourceFolder} ${path.basename( - sourceFolder, - )}`, - ); - } - - if (Input.cloudRunnerTests) { - await CloudRunnerSystem.Run(`ls ${path.basename(sourceFolder)}`); - } - await CloudRunnerSystem.Run(`zip ${cacheKey}.zip ${path.basename(sourceFolder)}`); - assert(fs.existsSync(`${cacheKey}.zip`), 'cache zip exists'); - assert(fs.existsSync(path.basename(sourceFolder)), 'source folder exists'); - await CloudRunnerSystem.Run(`mv ${cacheKey}.zip ${cacheFolder}`); - RemoteClientLogger.log(`moved ${cacheKey}.zip to ${cacheFolder}`); - assert(fs.existsSync(`${path.join(cacheFolder, cacheKey)}.zip`), 'cache zip exists inside cache folder'); - - if (Input.cloudRunnerTests) { - await CloudRunnerSystem.Run(`ls ${cacheFolder}`); - } - } catch (error) { - process.chdir(`${startPath}`); - throw error; - } - process.chdir(`${startPath}`); - } - public static async PullFromCache(cacheFolder: string, destinationFolder: string, cacheKey: string = ``) { - const startPath = process.cwd(); - RemoteClientLogger.log(`Caching for ${path.basename(destinationFolder)}`); - try { - if (!fs.existsSync(cacheFolder)) { - fs.mkdirSync(cacheFolder); - } - - if (!fs.existsSync(destinationFolder)) { - fs.mkdirSync(destinationFolder); - } - - const latestInBranch = await (await CloudRunnerSystem.Run(`ls -t "${cacheFolder}" | grep .zip$ | head -1`)) - .replace(/\n/g, ``) - .replace('.zip', ''); - - process.chdir(cacheFolder); - - const cacheSelection = cacheKey !== `` && fs.existsSync(`${cacheKey}.zip`) ? cacheKey : latestInBranch; - await CloudRunnerLogger.log(`cache key ${cacheKey} selection ${cacheSelection}`); - - if (fs.existsSync(`${cacheSelection}.zip`)) { - const resultsFolder = `results${CloudRunnerState.buildParams.buildGuid}`; - await CloudRunnerSystem.Run(`mkdir -p ${resultsFolder}`); - if (Input.cloudRunnerTests) { - await CloudRunnerSystem.Run(`tree ${destinationFolder}`); - } - RemoteClientLogger.log(`cache item exists ${cacheFolder}/${cacheSelection}.zip`); - assert(`${fs.existsSync(destinationFolder)}`); - assert(`${fs.existsSync(`${cacheSelection}.zip`)}`); - const fullResultsFolder = path.join(cacheFolder, resultsFolder); - if (Input.cloudRunnerTests) { - await CloudRunnerSystem.Run(`tree ${cacheFolder}`); - } - await CloudRunnerSystem.Run(`unzip ${cacheSelection}.zip -d ${path.basename(resultsFolder)}`); - RemoteClientLogger.log(`cache item extracted to ${fullResultsFolder}`); - assert(`${fs.existsSync(fullResultsFolder)}`); - const destinationParentFolder = path.resolve(destinationFolder, '..'); - if (fs.existsSync(destinationFolder)) { - fs.rmSync(destinationFolder, { recursive: true, force: true }); - } - await CloudRunnerSystem.Run( - `mv "${fullResultsFolder}/${path.basename(destinationFolder)}" "${destinationParentFolder}"`, - ); - if (Input.cloudRunnerTests) { - await CloudRunnerSystem.Run(`tree ${destinationParentFolder}`); - } - } else { - RemoteClientLogger.logWarning(`cache item ${cacheKey} doesn't exist ${destinationFolder}`); - if (cacheSelection !== ``) { - if (Input.cloudRunnerTests) { - await CloudRunnerSystem.Run(`tree ${cacheFolder}`); - } - RemoteClientLogger.logWarning(`cache item ${cacheKey}.zip doesn't exist ${destinationFolder}`); - throw new Error(`Failed to get cache item, but cache hit was found: ${cacheSelection}`); - } - } - } catch (error) { - process.chdir(`${startPath}`); - throw error; - } - process.chdir(`${startPath}`); - } - - public static handleCachePurging() { - if (process.env.PURGE_REMOTE_BUILDER_CACHE !== undefined) { - RemoteClientLogger.log(`purging ${CloudRunnerState.purgeRemoteCaching}`); - fs.rmdirSync(CloudRunnerState.cacheFolder, { recursive: true }); - } - } -} diff --git a/src/model/cli/remote-client/remote-client-services/cloud-runner-system.ts b/src/model/cli/remote-client/remote-client-services/cloud-runner-system.ts deleted file mode 100644 index ed119487..00000000 --- a/src/model/cli/remote-client/remote-client-services/cloud-runner-system.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { exec } from 'child_process'; -import { RemoteClientLogger } from './remote-client-logger'; - -export class CloudRunnerSystem { - public static async Run(command: string, suppressError = false) { - for (const element of command.split(`\n`)) { - RemoteClientLogger.log(element); - } - return await new Promise((promise) => { - let output = ''; - const child = exec(command, (error, stdout, stderr) => { - if (error && !suppressError) { - throw error; - } - if (stderr) { - const diagnosticOutput = `${stderr.toString()}`; - RemoteClientLogger.logCliDiagnostic(diagnosticOutput); - output += diagnosticOutput; - return; - } - const outputChunk = `${stdout}`; - output += outputChunk; - }); - child.on('close', function (code) { - RemoteClientLogger.log(`[Exit code ${code}]`); - if (code !== 0 && !suppressError) { - throw new Error(output); - } - const outputLines = output.split(`\n`); - for (const element of outputLines) { - RemoteClientLogger.log(element); - } - promise(output); - }); - }); - } -} diff --git a/src/model/cli/remote-client/setup-cloud-runner-repository.ts b/src/model/cli/remote-client/setup-cloud-runner-repository.ts deleted file mode 100644 index b08b9d7e..00000000 --- a/src/model/cli/remote-client/setup-cloud-runner-repository.ts +++ /dev/null @@ -1,81 +0,0 @@ -import fs from 'fs'; -import { CloudRunnerState } from '../../cloud-runner/state/cloud-runner-state'; -import { Caching } from './remote-client-services/caching'; -import { LFSHashing } from './remote-client-services/lfs-hashing'; -import { CloudRunnerSystem } from './remote-client-services/cloud-runner-system'; -import { Input } from '../..'; -import { RemoteClientLogger } from './remote-client-services/remote-client-logger'; -import path from 'path'; -import { assert } from 'console'; - -export class SetupCloudRunnerRepository { - public static async run() { - try { - await CloudRunnerSystem.Run(`mkdir -p ${CloudRunnerState.buildPathFull}`); - await CloudRunnerSystem.Run(`mkdir -p ${CloudRunnerState.repoPathFull}`); - await CloudRunnerSystem.Run(`mkdir -p ${CloudRunnerState.cacheFolderFull}`); - - process.chdir(CloudRunnerState.repoPathFull); - if (Input.cloudRunnerTests) { - await CloudRunnerSystem.Run(`ls -lh`); - await CloudRunnerSystem.Run(`tree`); - } - await SetupCloudRunnerRepository.cloneRepoWithoutLFSFiles(); - if (Input.cloudRunnerTests) { - await CloudRunnerSystem.Run(`ls -lh`); - await CloudRunnerSystem.Run(`tree`); - } - const lfsHashes = await LFSHashing.createLFSHashFiles(); - if (fs.existsSync(CloudRunnerState.libraryFolderFull)) { - RemoteClientLogger.logWarning(`!Warning!: The Unity library was included in the git repository`); - } - await Caching.PullFromCache( - CloudRunnerState.lfsCacheFolderFull, - CloudRunnerState.lfsDirectoryFull, - `${lfsHashes.lfsGuid}`, - ); - await SetupCloudRunnerRepository.pullLatestLFS(); - await Caching.PushToCache( - CloudRunnerState.lfsCacheFolderFull, - CloudRunnerState.lfsDirectoryFull, - `${lfsHashes.lfsGuid}`, - ); - await Caching.PullFromCache(CloudRunnerState.libraryCacheFolderFull, CloudRunnerState.libraryFolderFull); - Caching.handleCachePurging(); - } catch (error) { - throw error; - } - } - - private static async cloneRepoWithoutLFSFiles() { - try { - process.chdir(`${CloudRunnerState.repoPathFull}`); - RemoteClientLogger.log(`Initializing source repository for cloning with caching of LFS files`); - await CloudRunnerSystem.Run(`git config --global advice.detachedHead false`); - RemoteClientLogger.log(`Cloning the repository being built:`); - await CloudRunnerSystem.Run(`git lfs install --skip-smudge`); - await CloudRunnerSystem.Run( - `git clone -b ${CloudRunnerState.branchName} ${CloudRunnerState.targetBuildRepoUrl} ${path.resolve( - `..`, - path.basename(CloudRunnerState.repoPathFull), - )}`, - ); - assert(fs.existsSync(`.git`)); - RemoteClientLogger.log(`${CloudRunnerState.buildParams.branch}`); - await CloudRunnerSystem.Run(`git checkout ${CloudRunnerState.buildParams.branch}`); - assert(fs.existsSync(path.join(`.git`, `lfs`)), 'LFS folder should not exist before caching'); - RemoteClientLogger.log(`Checked out ${process.env.GITHUB_SHA}`); - } catch (error) { - throw error; - } - } - - private static async pullLatestLFS() { - await CloudRunnerSystem.Run(`ls -lh ${CloudRunnerState.lfsDirectoryFull}/..`); - process.chdir(CloudRunnerState.repoPathFull); - await CloudRunnerSystem.Run(`git lfs pull`); - RemoteClientLogger.log(`pulled latest LFS files`); - assert(fs.existsSync(CloudRunnerState.lfsDirectoryFull)); - await CloudRunnerSystem.Run(`ls -lh ${CloudRunnerState.lfsDirectoryFull}/..`); - } -} diff --git a/src/model/cloud-runner/state/cloud-runner-step-state.ts b/src/model/cloud-runner/cloud-runner-step-state.ts similarity index 70% rename from src/model/cloud-runner/state/cloud-runner-step-state.ts rename to src/model/cloud-runner/cloud-runner-step-state.ts index d09461b8..94f744bb 100644 --- a/src/model/cloud-runner/state/cloud-runner-step-state.ts +++ b/src/model/cloud-runner/cloud-runner-step-state.ts @@ -1,5 +1,5 @@ -import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable'; -import CloudRunnerSecret from '../services/cloud-runner-secret'; +import CloudRunnerEnvironmentVariable from './services/cloud-runner-environment-variable'; +import CloudRunnerSecret from './services/cloud-runner-secret'; export class CloudRunnerStepState { public image: string; diff --git a/src/model/cloud-runner/cloud-runner.test.ts b/src/model/cloud-runner/cloud-runner.test.ts index 2be7e292..917eddc6 100644 --- a/src/model/cloud-runner/cloud-runner.test.ts +++ b/src/model/cloud-runner/cloud-runner.test.ts @@ -4,6 +4,9 @@ import Input from '../input'; import { CloudRunnerStatics } from './cloud-runner-statics'; import { TaskParameterSerializer } from './services/task-parameter-serializer'; import UnityVersioning from '../unity-versioning'; +import { Cli } from '../cli/cli'; +import CloudRunnerLogger from './services/cloud-runner-logger'; +import { v4 as uuidv4 } from 'uuid'; describe('Cloud Runner', () => { it('responds', () => {}); @@ -13,10 +16,12 @@ describe('Cloud Runner', () => { const testSecretValue = 'testSecretValue'; if (Input.cloudRunnerTests) { it('All build parameters sent to cloud runner as env vars', async () => { - Input.cliOptions = { + // build parameters + Cli.options = { versioning: 'None', projectPath: 'test-project', unityVersion: UnityVersioning.read('test-project'), + targetPlatform: 'StandaloneLinux64', customJob: ` - name: 'step 1' image: 'alpine' @@ -27,9 +32,13 @@ describe('Cloud Runner', () => { `, }; Input.githubInputEnabled = false; + // setup parameters const buildParameter = await BuildParameters.create(); + Input.githubInputEnabled = true; const baseImage = new ImageTag(buildParameter); + // run the job const file = await CloudRunner.run(buildParameter, baseImage.toString()); + // assert results expect(file).toContain(JSON.stringify(buildParameter)); expect(file).toContain(`${Input.ToEnvVarFormat(testSecretName)}=${testSecretValue}`); const environmentVariables = TaskParameterSerializer.readBuildEnvironmentVariables(); @@ -41,10 +50,86 @@ describe('Cloud Runner', () => { if (typeof element.value === `string`) { element.value = element.value.replace(/\s+/g, ''); } + CloudRunnerLogger.log(`checking input/build param ${element.name} ${element.value}`); + } + } + for (const element of environmentVariables) { + if (element.value !== undefined && typeof element.value !== 'function') { + expect(newLinePurgedFile).toContain(`${element.name}`); expect(newLinePurgedFile).toContain(`${element.name}=${element.value}`); } } + delete Cli.options; + }, 1000000); + it('Run one build it should not use cache, run subsequent build which should use cache', async () => { + Cli.options = { + versioning: 'None', + projectPath: 'test-project', + unityVersion: UnityVersioning.determineUnityVersion('test-project', UnityVersioning.read('test-project')), + targetPlatform: 'StandaloneLinux64', + cacheKey: `test-case-${uuidv4()}`, + }; + Input.githubInputEnabled = false; + const buildParameter = await BuildParameters.create(); + const baseImage = new ImageTag(buildParameter); + const results = await CloudRunner.run(buildParameter, baseImage.toString()); + const libraryString = 'Rebuilding Library because the asset database could not be found!'; + const buildSucceededString = 'Build succeeded'; + expect(results).toContain(libraryString); + expect(results).toContain(buildSucceededString); + CloudRunnerLogger.log(`run 1 succeeded`); + const buildParameter2 = await BuildParameters.create(); + const baseImage2 = new ImageTag(buildParameter2); + const results2 = await CloudRunner.run(buildParameter2, baseImage2.toString()); + CloudRunnerLogger.log(`run 2 succeeded`); + expect(results2).toContain(buildSucceededString); + expect(results2).toEqual(expect.not.stringContaining(libraryString)); Input.githubInputEnabled = true; + delete Cli.options; }, 1000000); } + it('Local cloud runner returns commands', async () => { + // build parameters + Cli.options = { + versioning: 'None', + projectPath: 'test-project', + unityVersion: UnityVersioning.read('test-project'), + cloudRunnerCluster: 'local-system', + targetPlatform: 'StandaloneLinux64', + customJob: ` + - name: 'step 1' + image: 'alpine' + commands: 'dir' + secrets: + - name: '${testSecretName}' + value: '${testSecretValue}' + `, + }; + Input.githubInputEnabled = false; + // setup parameters + const buildParameter = await BuildParameters.create(); + const baseImage = new ImageTag(buildParameter); + // run the job + await expect(CloudRunner.run(buildParameter, baseImage.toString())).resolves.not.toThrow(); + Input.githubInputEnabled = true; + delete Cli.options; + }, 1000000); + it('Test cloud runner returns commands', async () => { + // build parameters + Cli.options = { + versioning: 'None', + projectPath: 'test-project', + unityVersion: UnityVersioning.read('test-project'), + cloudRunnerCluster: 'test', + targetPlatform: 'StandaloneLinux64', + }; + Input.githubInputEnabled = false; + // setup parameters + const buildParameter = await BuildParameters.create(); + const baseImage = new ImageTag(buildParameter); + // run the job + await expect(CloudRunner.run(buildParameter, baseImage.toString())).resolves.not.toThrow(); + Input.githubInputEnabled = true; + delete Cli.options; + }, 1000000); }); diff --git a/src/model/cloud-runner/cloud-runner.ts b/src/model/cloud-runner/cloud-runner.ts index f6d1285c..eaf9a695 100644 --- a/src/model/cloud-runner/cloud-runner.ts +++ b/src/model/cloud-runner/cloud-runner.ts @@ -1,35 +1,58 @@ -import AWSBuildPlatform from './aws'; -import { BuildParameters } from '..'; -import { CloudRunnerState } from './state/cloud-runner-state'; -import Kubernetes from './k8s'; +import AwsBuildPlatform from './providers/aws'; +import { BuildParameters, Input } from '..'; +import Kubernetes from './providers/k8s'; import CloudRunnerLogger from './services/cloud-runner-logger'; -import { CloudRunnerStepState } from './state/cloud-runner-step-state'; +import { CloudRunnerStepState } from './cloud-runner-step-state'; import { WorkflowCompositionRoot } from './workflows/workflow-composition-root'; import { CloudRunnerError } from './error/cloud-runner-error'; import { TaskParameterSerializer } from './services/task-parameter-serializer'; import * as core from '@actions/core'; +import CloudRunnerSecret from './services/cloud-runner-secret'; +import { ProviderInterface } from './providers/provider-interface'; +import CloudRunnerEnvironmentVariable from './services/cloud-runner-environment-variable'; +import TestCloudRunner from './providers/test'; +import LocalCloudRunner from './providers/local'; +import LocalDockerCloudRunner from './providers/local-docker'; class CloudRunner { + public static Provider: ProviderInterface; + static buildParameters: BuildParameters; + public static defaultSecrets: CloudRunnerSecret[]; + public static cloudRunnerEnvironmentVariables: CloudRunnerEnvironmentVariable[]; private static setup(buildParameters: BuildParameters) { CloudRunnerLogger.setup(); - CloudRunnerState.setup(buildParameters); + CloudRunner.buildParameters = buildParameters; CloudRunner.setupBuildPlatform(); - const parameters = TaskParameterSerializer.readBuildEnvironmentVariables(); - for (const element of parameters) { - core.setOutput(element.name, element.value); + CloudRunner.defaultSecrets = TaskParameterSerializer.readDefaultSecrets(); + CloudRunner.cloudRunnerEnvironmentVariables = TaskParameterSerializer.readBuildEnvironmentVariables(); + if (!buildParameters.isCliMode) { + const buildParameterPropertyNames = Object.getOwnPropertyNames(buildParameters); + for (const element of CloudRunner.cloudRunnerEnvironmentVariables) { + core.setOutput(Input.ToEnvVarFormat(element.name), element.value); + } + for (const element of buildParameterPropertyNames) { + core.setOutput(Input.ToEnvVarFormat(element), buildParameters[element]); + } } } private static setupBuildPlatform() { - switch (CloudRunnerState.buildParams.cloudRunnerCluster) { + CloudRunnerLogger.log(`Cloud Runner platform selected ${CloudRunner.buildParameters.cloudRunnerCluster}`); + switch (CloudRunner.buildParameters.cloudRunnerCluster) { case 'k8s': - CloudRunnerLogger.log('Cloud Runner platform selected Kubernetes'); - CloudRunnerState.CloudRunnerProviderPlatform = new Kubernetes(CloudRunnerState.buildParams); + CloudRunner.Provider = new Kubernetes(CloudRunner.buildParameters); break; - default: case 'aws': - CloudRunnerLogger.log('Cloud Runner platform selected AWS'); - CloudRunnerState.CloudRunnerProviderPlatform = new AWSBuildPlatform(CloudRunnerState.buildParams); + CloudRunner.Provider = new AwsBuildPlatform(CloudRunner.buildParameters); + break; + case 'test': + CloudRunner.Provider = new TestCloudRunner(); + break; + case 'local-system': + CloudRunner.Provider = new LocalCloudRunner(); + break; + case 'local-docker': + CloudRunner.Provider = new LocalDockerCloudRunner(); break; } } @@ -37,33 +60,29 @@ class CloudRunner { static async run(buildParameters: BuildParameters, baseImage: string) { CloudRunner.setup(buildParameters); try { - core.startGroup('Setup remote runner'); - await CloudRunnerState.CloudRunnerProviderPlatform.setupSharedResources( - CloudRunnerState.buildParams.buildGuid, - CloudRunnerState.buildParams, - CloudRunnerState.branchName, - CloudRunnerState.defaultSecrets, + if (!CloudRunner.buildParameters.isCliMode) core.startGroup('Setup shared cloud runner resources'); + await CloudRunner.Provider.setup( + CloudRunner.buildParameters.buildGuid, + CloudRunner.buildParameters, + CloudRunner.buildParameters.branch, + CloudRunner.defaultSecrets, ); - core.endGroup(); + if (!CloudRunner.buildParameters.isCliMode) core.endGroup(); const output = await new WorkflowCompositionRoot().run( - new CloudRunnerStepState( - baseImage, - TaskParameterSerializer.readBuildEnvironmentVariables(), - CloudRunnerState.defaultSecrets, - ), + new CloudRunnerStepState(baseImage, CloudRunner.cloudRunnerEnvironmentVariables, CloudRunner.defaultSecrets), ); - core.startGroup('Cleanup'); - await CloudRunnerState.CloudRunnerProviderPlatform.cleanupSharedResources( - CloudRunnerState.buildParams.buildGuid, - CloudRunnerState.buildParams, - CloudRunnerState.branchName, - CloudRunnerState.defaultSecrets, + if (!CloudRunner.buildParameters.isCliMode) core.startGroup('Cleanup shared cloud runner resources'); + await CloudRunner.Provider.cleanup( + CloudRunner.buildParameters.buildGuid, + CloudRunner.buildParameters, + CloudRunner.buildParameters.branch, + CloudRunner.defaultSecrets, ); CloudRunnerLogger.log(`Cleanup complete`); - core.endGroup(); + if (!CloudRunner.buildParameters.isCliMode) core.endGroup(); return output; } catch (error) { - core.endGroup(); + if (!CloudRunner.buildParameters.isCliMode) core.endGroup(); await CloudRunnerError.handleException(error); throw error; } diff --git a/src/model/cloud-runner/error/cloud-runner-error.ts b/src/model/cloud-runner/error/cloud-runner-error.ts index 9486b9c1..c290dcce 100644 --- a/src/model/cloud-runner/error/cloud-runner-error.ts +++ b/src/model/cloud-runner/error/cloud-runner-error.ts @@ -1,16 +1,16 @@ import CloudRunnerLogger from '../services/cloud-runner-logger'; -import { CloudRunnerState } from '../state/cloud-runner-state'; import * as core from '@actions/core'; +import CloudRunner from '../cloud-runner'; export class CloudRunnerError { public static async handleException(error: unknown) { CloudRunnerLogger.error(JSON.stringify(error, undefined, 4)); core.setFailed('Cloud Runner failed'); - await CloudRunnerState.CloudRunnerProviderPlatform.cleanupSharedResources( - CloudRunnerState.buildParams.buildGuid, - CloudRunnerState.buildParams, - CloudRunnerState.branchName, - CloudRunnerState.defaultSecrets, + await CloudRunner.Provider.cleanup( + CloudRunner.buildParameters.buildGuid, + CloudRunner.buildParameters, + CloudRunner.buildParameters.branch, + CloudRunner.defaultSecrets, ); } } diff --git a/src/model/cloud-runner/aws/aws-base-stack.ts b/src/model/cloud-runner/providers/aws/aws-base-stack.ts similarity index 98% rename from src/model/cloud-runner/aws/aws-base-stack.ts rename to src/model/cloud-runner/providers/aws/aws-base-stack.ts index 55bb4412..74ee166c 100644 --- a/src/model/cloud-runner/aws/aws-base-stack.ts +++ b/src/model/cloud-runner/providers/aws/aws-base-stack.ts @@ -1,4 +1,4 @@ -import CloudRunnerLogger from '../services/cloud-runner-logger'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; import * as core from '@actions/core'; import * as SDK from 'aws-sdk'; import * as fs from 'fs'; diff --git a/src/model/cloud-runner/aws/aws-templates.ts b/src/model/cloud-runner/providers/aws/aws-cloud-formation-templates.ts similarity index 95% rename from src/model/cloud-runner/aws/aws-templates.ts rename to src/model/cloud-runner/providers/aws/aws-cloud-formation-templates.ts index efd25815..c138aeeb 100644 --- a/src/model/cloud-runner/aws/aws-templates.ts +++ b/src/model/cloud-runner/providers/aws/aws-cloud-formation-templates.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; -export class AWSTemplates { +export class AWSCloudFormationTemplates { public static getParameterTemplate(p1) { return ` ${p1}: diff --git a/src/model/cloud-runner/aws/aws-error.ts b/src/model/cloud-runner/providers/aws/aws-error.ts similarity index 75% rename from src/model/cloud-runner/aws/aws-error.ts rename to src/model/cloud-runner/providers/aws/aws-error.ts index d84868be..7acbe3c5 100644 --- a/src/model/cloud-runner/aws/aws-error.ts +++ b/src/model/cloud-runner/providers/aws/aws-error.ts @@ -1,13 +1,13 @@ -import CloudRunnerLogger from '../services/cloud-runner-logger'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; import * as SDK from 'aws-sdk'; import * as core from '@actions/core'; -import { Input } from '../..'; +import CloudRunner from '../../cloud-runner'; export class AWSError { static async handleStackCreationFailure(error: any, CF: SDK.CloudFormation, taskDefStackName: string) { CloudRunnerLogger.log('aws error: '); core.error(JSON.stringify(error, undefined, 4)); - if (Input.cloudRunnerTests) { + if (CloudRunner.buildParameters.cloudRunnerIntegrationTests) { CloudRunnerLogger.log('Getting events and resources for task stack'); const events = (await CF.describeStackEvents({ StackName: taskDefStackName }).promise()).StackEvents; CloudRunnerLogger.log(JSON.stringify(events, undefined, 4)); diff --git a/src/model/cloud-runner/aws/aws-job-stack.ts b/src/model/cloud-runner/providers/aws/aws-job-stack.ts similarity index 82% rename from src/model/cloud-runner/aws/aws-job-stack.ts rename to src/model/cloud-runner/providers/aws/aws-job-stack.ts index 0350a9dd..9940c79b 100644 --- a/src/model/cloud-runner/aws/aws-job-stack.ts +++ b/src/model/cloud-runner/providers/aws/aws-job-stack.ts @@ -1,8 +1,8 @@ import * as SDK from 'aws-sdk'; import CloudRunnerAWSTaskDef from './cloud-runner-aws-task-def'; -import CloudRunnerSecret from '../services/cloud-runner-secret'; -import { AWSTemplates } from './aws-templates'; -import CloudRunnerLogger from '../services/cloud-runner-logger'; +import CloudRunnerSecret from '../../services/cloud-runner-secret'; +import { AWSCloudFormationTemplates } from './aws-cloud-formation-templates'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; import { AWSError } from './aws-error'; export class AWSJobStack { @@ -22,7 +22,7 @@ export class AWSJobStack { secrets: CloudRunnerSecret[], ): Promise { const taskDefStackName = `${this.baseStackName}-${buildGuid}`; - let taskDefCloudFormation = AWSTemplates.readTaskCloudFormationTemplate(); + let taskDefCloudFormation = AWSCloudFormationTemplates.readTaskCloudFormationTemplate(); for (const secret of secrets) { secret.ParameterKey = `${buildGuid.replace(/[^\dA-Za-z]/g, '')}${secret.ParameterKey.replace( /[^\dA-Za-z]/g, @@ -35,20 +35,20 @@ export class AWSJobStack { secrets = secrets.filter((x) => x !== secret); continue; } - taskDefCloudFormation = AWSTemplates.insertAtTemplate( + taskDefCloudFormation = AWSCloudFormationTemplates.insertAtTemplate( taskDefCloudFormation, 'p1 - input', - AWSTemplates.getParameterTemplate(secret.ParameterKey), + AWSCloudFormationTemplates.getParameterTemplate(secret.ParameterKey), ); - taskDefCloudFormation = AWSTemplates.insertAtTemplate( + taskDefCloudFormation = AWSCloudFormationTemplates.insertAtTemplate( taskDefCloudFormation, 'p2 - secret', - AWSTemplates.getSecretTemplate(`${secret.ParameterKey}`), + AWSCloudFormationTemplates.getSecretTemplate(`${secret.ParameterKey}`), ); - taskDefCloudFormation = AWSTemplates.insertAtTemplate( + taskDefCloudFormation = AWSCloudFormationTemplates.insertAtTemplate( taskDefCloudFormation, 'p3 - container def', - AWSTemplates.getSecretDefinitionTemplate(secret.EnvironmentVariable, secret.ParameterKey), + AWSCloudFormationTemplates.getSecretDefinitionTemplate(secret.EnvironmentVariable, secret.ParameterKey), ); } const secretsMappedToCloudFormationParameters = secrets.map((x) => { diff --git a/src/model/cloud-runner/aws/aws-task-runner.ts b/src/model/cloud-runner/providers/aws/aws-task-runner.ts similarity index 78% rename from src/model/cloud-runner/aws/aws-task-runner.ts rename to src/model/cloud-runner/providers/aws/aws-task-runner.ts index 115106f1..58e920e7 100644 --- a/src/model/cloud-runner/aws/aws-task-runner.ts +++ b/src/model/cloud-runner/providers/aws/aws-task-runner.ts @@ -1,13 +1,13 @@ import * as AWS from 'aws-sdk'; -import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable'; +import CloudRunnerEnvironmentVariable from '../../services/cloud-runner-environment-variable'; import * as core from '@actions/core'; import CloudRunnerAWSTaskDef from './cloud-runner-aws-task-def'; import * as zlib from 'zlib'; -import CloudRunnerLogger from '../services/cloud-runner-logger'; -import { Input } from '../..'; -import { CloudRunnerState } from '../state/cloud-runner-state'; -import { CloudRunnerStatics } from '../cloud-runner-statics'; -import { CloudRunnerBuildCommandProcessor } from '../services/cloud-runner-build-command-process'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; +import { Input } from '../../..'; +import CloudRunner from '../../cloud-runner'; +import { CloudRunnerStatics } from '../../cloud-runner-statics'; +import { CloudRunnerBuildCommandProcessor } from '../../services/cloud-runner-build-command-process'; class AWSTaskRunner { static async runTask( @@ -39,7 +39,7 @@ class AWSTaskRunner { { name: taskDef.taskDefStackName, environment, - command: ['-c', CloudRunnerBuildCommandProcessor.ProcessCommands(commands, CloudRunnerState.buildParams)], + command: ['-c', CloudRunnerBuildCommandProcessor.ProcessCommands(commands, CloudRunner.buildParameters)], }, ], }, @@ -52,10 +52,32 @@ class AWSTaskRunner { }, }, }).promise(); - - CloudRunnerLogger.log('Cloud runner job is starting'); const taskArn = task.tasks?.[0].taskArn || ''; + CloudRunnerLogger.log('Cloud runner job is starting'); + await AWSTaskRunner.waitUntilTaskRunning(ECS, taskArn, cluster); + CloudRunnerLogger.log( + `Cloud runner job status is running ${(await AWSTaskRunner.describeTasks(ECS, cluster, taskArn))?.lastStatus}`, + ); + const output = await this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName); + const taskData = await AWSTaskRunner.describeTasks(ECS, cluster, taskArn); + const exitCode = taskData.containers?.[0].exitCode; + const wasSuccessful = exitCode === 0 || (exitCode === undefined && taskData.lastStatus === 'RUNNING'); + if (wasSuccessful) { + CloudRunnerLogger.log(`Cloud runner job has finished successfully`); + return output; + } else { + if (taskData.stoppedReason === 'Essential container in task exited' && exitCode === 1) { + throw new Error('Container exited with code 1'); + } + const message = `Cloud runner job exit code ${exitCode}`; + taskData.overrides = undefined; + taskData.attachments = undefined; + CloudRunnerLogger.log(`${message} ${JSON.stringify(taskData, undefined, 4)}`); + throw new Error(message); + } + } + private static async waitUntilTaskRunning(ECS: AWS.ECS, taskArn: string, cluster: string) { try { await ECS.waitFor('tasksRunning', { tasks: [taskArn], cluster }).promise(); } catch (error_) { @@ -70,24 +92,6 @@ class AWSTaskRunner { core.setFailed(error); core.error(error); } - CloudRunnerLogger.log(`Cloud runner job is running`); - - const output = await this.streamLogsUntilTaskStops(ECS, CF, taskDef, cluster, taskArn, streamName); - const exitCode = (await AWSTaskRunner.describeTasks(ECS, cluster, taskArn)).containers?.[0].exitCode; - CloudRunnerLogger.log(`Cloud runner job exit code ${exitCode}`); - if (exitCode !== 0 && exitCode !== undefined) { - core.error( - `job failed with exit code ${exitCode} ${JSON.stringify( - await ECS.describeTasks({ tasks: [taskArn], cluster }).promise(), - undefined, - 4, - )}`, - ); - throw new Error(`job failed with exit code ${exitCode}`); - } else { - CloudRunnerLogger.log(`Cloud runner job has finished successfully`); - return output; - } } static async describeTasks(ECS: AWS.ECS, clusterName: string, taskArn: string) { @@ -114,10 +118,6 @@ class AWSTaskRunner { const stream = await AWSTaskRunner.getLogStream(kinesis, kinesisStreamName); let iterator = await AWSTaskRunner.getLogIterator(kinesis, stream); - CloudRunnerLogger.log( - `Cloud runner job status is ${(await AWSTaskRunner.describeTasks(ECS, clusterName, taskArn))?.lastStatus}`, - ); - const logBaseUrl = `https://${Input.region}.console.aws.amazon.com/cloudwatch/home?region=${CF.config.region}#logsV2:log-groups/log-group/${taskDef.taskDefStackName}`; CloudRunnerLogger.log(`You can also see the logs at AWS Cloud Watch: ${logBaseUrl}`); let shouldReadLogs = true; @@ -156,6 +156,9 @@ class AWSTaskRunner { } private static checkStreamingShouldContinue(taskData: AWS.ECS.Task, timestamp: number, shouldReadLogs: boolean) { + if (taskData?.lastStatus === 'UNKNOWN') { + CloudRunnerLogger.log('## Cloud runner job unknwon'); + } if (taskData?.lastStatus !== 'RUNNING') { if (timestamp === 0) { CloudRunnerLogger.log('## Cloud runner job stopped, streaming end of logs'); @@ -185,14 +188,19 @@ class AWSTaskRunner { if (json.messageType === 'DATA_MESSAGE') { for (let logEventsIndex = 0; logEventsIndex < json.logEvents.length; logEventsIndex++) { let message = json.logEvents[logEventsIndex].message; - if (json.logEvents[logEventsIndex].message.includes(`---${CloudRunnerState.buildParams.logId}`)) { + if (json.logEvents[logEventsIndex].message.includes(`---${CloudRunner.buildParameters.logId}`)) { CloudRunnerLogger.log('End of log transmission received'); shouldReadLogs = false; } else if (message.includes('Rebuilding Library because the asset database could not be found!')) { core.warning('LIBRARY NOT FOUND!'); + } else if (message.includes('Build succeeded')) { + core.setOutput('build-result', 'success'); + } else if (message.includes('Build fail')) { + core.setOutput('build-result', 'failed'); + core.error('BUILD FAILED!'); } message = `[${CloudRunnerStatics.logPrefix}] ${message}`; - if (Input.cloudRunnerTests) { + if (CloudRunner.buildParameters.cloudRunnerIntegrationTests) { output += message; } CloudRunnerLogger.log(message); diff --git a/src/model/cloud-runner/aws/cloud-formations/base-setup.yml b/src/model/cloud-runner/providers/aws/cloud-formations/base-setup.yml similarity index 100% rename from src/model/cloud-runner/aws/cloud-formations/base-setup.yml rename to src/model/cloud-runner/providers/aws/cloud-formations/base-setup.yml diff --git a/src/model/cloud-runner/aws/cloud-formations/task-def-formation.yml b/src/model/cloud-runner/providers/aws/cloud-formations/task-def-formation.yml similarity index 100% rename from src/model/cloud-runner/aws/cloud-formations/task-def-formation.yml rename to src/model/cloud-runner/providers/aws/cloud-formations/task-def-formation.yml diff --git a/src/model/cloud-runner/aws/cloud-runner-aws-task-def.ts b/src/model/cloud-runner/providers/aws/cloud-runner-aws-task-def.ts similarity index 100% rename from src/model/cloud-runner/aws/cloud-runner-aws-task-def.ts rename to src/model/cloud-runner/providers/aws/cloud-runner-aws-task-def.ts diff --git a/src/model/cloud-runner/providers/aws/commands/aws-cli-commands.ts b/src/model/cloud-runner/providers/aws/commands/aws-cli-commands.ts new file mode 100644 index 00000000..3c0d237b --- /dev/null +++ b/src/model/cloud-runner/providers/aws/commands/aws-cli-commands.ts @@ -0,0 +1,30 @@ +import AWS from 'aws-sdk'; +import { CliFunction } from '../../../../cli/cli-functions-repository'; +import Input from '../../../../input'; +import CloudRunnerLogger from '../../../services/cloud-runner-logger'; + +export class AwsCliCommands { + @CliFunction(`aws-garbage-collect`, `garbage collect aws`) + static async garbageCollectAws() { + process.env.AWS_REGION = Input.region; + CloudRunnerLogger.log(`Cloud Formation stacks`); + const CF = new AWS.CloudFormation(); + const stacks = + (await CF.listStacks().promise()).StackSummaries?.filter((_x) => _x.StackStatus !== 'DELETE_COMPLETE') || []; + for (const element of stacks) { + CloudRunnerLogger.log(JSON.stringify(element, undefined, 4)); + } + CloudRunnerLogger.log(`ECS Clusters`); + const ecs = new AWS.ECS(); + const clusters = (await ecs.listClusters().promise()).clusterArns || []; + if (stacks === undefined) { + return; + } + for (const element of clusters) { + const input: AWS.ECS.ListTasksRequest = { + cluster: element, + }; + CloudRunnerLogger.log(JSON.stringify(await ecs.listTasks(input).promise(), undefined, 4)); + } + } +} diff --git a/src/model/cloud-runner/aws/index.ts b/src/model/cloud-runner/providers/aws/index.ts similarity index 85% rename from src/model/cloud-runner/aws/index.ts rename to src/model/cloud-runner/providers/aws/index.ts index 597a0026..ab53c6db 100644 --- a/src/model/cloud-runner/aws/index.ts +++ b/src/model/cloud-runner/providers/aws/index.ts @@ -1,22 +1,22 @@ import * as SDK from 'aws-sdk'; -import CloudRunnerSecret from '../services/cloud-runner-secret'; -import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable'; +import CloudRunnerSecret from '../../services/cloud-runner-secret'; +import CloudRunnerEnvironmentVariable from '../../services/cloud-runner-environment-variable'; import CloudRunnerAWSTaskDef from './cloud-runner-aws-task-def'; import AWSTaskRunner from './aws-task-runner'; -import { CloudRunnerProviderInterface } from '../services/cloud-runner-provider-interface'; -import BuildParameters from '../../build-parameters'; -import CloudRunnerLogger from '../services/cloud-runner-logger'; +import { ProviderInterface } from '../provider-interface'; +import BuildParameters from '../../../build-parameters'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; import { AWSJobStack } from './aws-job-stack'; import { AWSBaseStack } from './aws-base-stack'; -import { Input } from '../..'; +import { Input } from '../../..'; -class AWSBuildEnvironment implements CloudRunnerProviderInterface { +class AWSBuildEnvironment implements ProviderInterface { private baseStackName: string; constructor(buildParameters: BuildParameters) { this.baseStackName = buildParameters.awsBaseStackName; } - async cleanupSharedResources( + async cleanup( // eslint-disable-next-line no-unused-vars buildGuid: string, // eslint-disable-next-line no-unused-vars @@ -26,7 +26,7 @@ class AWSBuildEnvironment implements CloudRunnerProviderInterface { // eslint-disable-next-line no-unused-vars defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], ) {} - async setupSharedResources( + async setup( // eslint-disable-next-line no-unused-vars buildGuid: string, // eslint-disable-next-line no-unused-vars diff --git a/src/model/cloud-runner/k8s/index.ts b/src/model/cloud-runner/providers/k8s/index.ts similarity index 91% rename from src/model/cloud-runner/k8s/index.ts rename to src/model/cloud-runner/providers/k8s/index.ts index 5fe6931b..9a3d7589 100644 --- a/src/model/cloud-runner/k8s/index.ts +++ b/src/model/cloud-runner/providers/k8s/index.ts @@ -1,19 +1,20 @@ import * as k8s from '@kubernetes/client-node'; -import { BuildParameters, Output } from '../..'; +import { BuildParameters, Output } from '../../..'; import * as core from '@actions/core'; -import { CloudRunnerProviderInterface } from '../services/cloud-runner-provider-interface'; -import CloudRunnerSecret from '../services/cloud-runner-secret'; +import { ProviderInterface } from '../provider-interface'; +import CloudRunnerSecret from '../../services/cloud-runner-secret'; import KubernetesStorage from './kubernetes-storage'; -import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable'; +import CloudRunnerEnvironmentVariable from '../../services/cloud-runner-environment-variable'; import KubernetesTaskRunner from './kubernetes-task-runner'; import KubernetesSecret from './kubernetes-secret'; import waitUntil from 'async-wait-until'; import KubernetesJobSpecFactory from './kubernetes-job-spec-factory'; import KubernetesServiceAccount from './kubernetes-service-account'; -import CloudRunnerLogger from '../services/cloud-runner-logger'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; import { CoreV1Api } from '@kubernetes/client-node'; +import DependencyOverrideService from '../../services/depdency-override-service'; -class Kubernetes implements CloudRunnerProviderInterface { +class Kubernetes implements ProviderInterface { private kubeConfig: k8s.KubeConfig; private kubeClient: k8s.CoreV1Api; private kubeClientBatch: k8s.BatchV1Api; @@ -38,7 +39,7 @@ class Kubernetes implements CloudRunnerProviderInterface { this.namespace = 'default'; this.buildParameters = buildParameters; } - public async setupSharedResources( + public async setup( buildGuid: string, buildParameters: BuildParameters, // eslint-disable-next-line no-unused-vars @@ -50,6 +51,9 @@ class Kubernetes implements CloudRunnerProviderInterface { this.pvcName = `unity-builder-pvc-${buildGuid}`; this.cleanupCronJobName = `unity-builder-cronjob-${buildGuid}`; this.serviceAccountName = `service-account-${buildGuid}`; + if (await DependencyOverrideService.CheckHealth()) { + await DependencyOverrideService.TryStartDependencies(); + } await KubernetesStorage.createPersistentVolumeClaim( buildParameters, this.pvcName, @@ -170,7 +174,7 @@ class Kubernetes implements CloudRunnerProviderInterface { } catch {} } - async cleanupSharedResources( + async cleanup( buildGuid: string, buildParameters: BuildParameters, // eslint-disable-next-line no-unused-vars diff --git a/src/model/cloud-runner/k8s/kubernetes-job-spec-factory.ts b/src/model/cloud-runner/providers/k8s/kubernetes-job-spec-factory.ts similarity index 90% rename from src/model/cloud-runner/k8s/kubernetes-job-spec-factory.ts rename to src/model/cloud-runner/providers/k8s/kubernetes-job-spec-factory.ts index cfee9b93..9ebcf339 100644 --- a/src/model/cloud-runner/k8s/kubernetes-job-spec-factory.ts +++ b/src/model/cloud-runner/providers/k8s/kubernetes-job-spec-factory.ts @@ -1,9 +1,9 @@ import { V1EnvVar, V1EnvVarSource, V1SecretKeySelector } from '@kubernetes/client-node'; -import BuildParameters from '../../build-parameters'; -import { CloudRunnerBuildCommandProcessor } from '../services/cloud-runner-build-command-process'; -import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable'; -import CloudRunnerSecret from '../services/cloud-runner-secret'; -import { CloudRunnerState } from '../state/cloud-runner-state'; +import BuildParameters from '../../../build-parameters'; +import { CloudRunnerBuildCommandProcessor } from '../../services/cloud-runner-build-command-process'; +import CloudRunnerEnvironmentVariable from '../../services/cloud-runner-environment-variable'; +import CloudRunnerSecret from '../../services/cloud-runner-secret'; +import CloudRunner from '../../cloud-runner'; class KubernetesJobSpecFactory { static getJobSpec( @@ -103,7 +103,7 @@ class KubernetesJobSpecFactory { name: 'main', image, command: ['/bin/sh'], - args: ['-c', CloudRunnerBuildCommandProcessor.ProcessCommands(command, CloudRunnerState.buildParams)], + args: ['-c', CloudRunnerBuildCommandProcessor.ProcessCommands(command, CloudRunner.buildParameters)], workingDir: `${workingDirectory}`, resources: { diff --git a/src/model/cloud-runner/k8s/kubernetes-secret.ts b/src/model/cloud-runner/providers/k8s/kubernetes-secret.ts similarity index 91% rename from src/model/cloud-runner/k8s/kubernetes-secret.ts rename to src/model/cloud-runner/providers/k8s/kubernetes-secret.ts index fcac7345..ca8e583c 100644 --- a/src/model/cloud-runner/k8s/kubernetes-secret.ts +++ b/src/model/cloud-runner/providers/k8s/kubernetes-secret.ts @@ -1,5 +1,5 @@ import { CoreV1Api } from '@kubernetes/client-node'; -import CloudRunnerSecret from '../services/cloud-runner-secret'; +import CloudRunnerSecret from '../../services/cloud-runner-secret'; import * as k8s from '@kubernetes/client-node'; const base64 = require('base-64'); diff --git a/src/model/cloud-runner/k8s/kubernetes-service-account.ts b/src/model/cloud-runner/providers/k8s/kubernetes-service-account.ts similarity index 100% rename from src/model/cloud-runner/k8s/kubernetes-service-account.ts rename to src/model/cloud-runner/providers/k8s/kubernetes-service-account.ts diff --git a/src/model/cloud-runner/k8s/kubernetes-storage.ts b/src/model/cloud-runner/providers/k8s/kubernetes-storage.ts similarity index 90% rename from src/model/cloud-runner/k8s/kubernetes-storage.ts rename to src/model/cloud-runner/providers/k8s/kubernetes-storage.ts index 3ed889dc..1ea8d904 100644 --- a/src/model/cloud-runner/k8s/kubernetes-storage.ts +++ b/src/model/cloud-runner/providers/k8s/kubernetes-storage.ts @@ -1,8 +1,8 @@ import waitUntil from 'async-wait-until'; import * as core from '@actions/core'; import * as k8s from '@kubernetes/client-node'; -import BuildParameters from '../../build-parameters'; -import CloudRunnerLogger from '../services/cloud-runner-logger'; +import BuildParameters from '../../../build-parameters'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; import YAML from 'yaml'; class KubernetesStorage { @@ -24,7 +24,9 @@ class KubernetesStorage { CloudRunnerLogger.log(JSON.stringify(pvcList, undefined, 4)); if (pvcList.includes(pvcName)) { CloudRunnerLogger.log(`pvc ${pvcName} already exists`); - core.setOutput('volume', pvcName); + if (!buildParameters.isCliMode) { + core.setOutput('volume', pvcName); + } return; } CloudRunnerLogger.log(`Creating PVC ${pvcName} (does not exist)`); @@ -48,10 +50,10 @@ class KubernetesStorage { CloudRunnerLogger.log(`${await this.getPVCPhase(kubeClient, name, namespace)}`); await waitUntil( async () => { - return (await this.getPVCPhase(kubeClient, name, namespace)) !== 'Pending'; + return (await this.getPVCPhase(kubeClient, name, namespace)) === 'Pending'; }, { - timeout: 500000, + timeout: 750000, intervalBetweenAttempts: 15000, }, ); @@ -83,7 +85,7 @@ class KubernetesStorage { }; pvc.spec = { accessModes: ['ReadWriteOnce'], - storageClassName: process.env.K8s_STORAGE_CLASS || 'standard', + storageClassName: buildParameters.kubeStorageClass === '' ? 'standard' : buildParameters.kubeStorageClass, resources: { requests: { storage: buildParameters.kubeVolumeSize, diff --git a/src/model/cloud-runner/k8s/kubernetes-task-runner.ts b/src/model/cloud-runner/providers/k8s/kubernetes-task-runner.ts similarity index 92% rename from src/model/cloud-runner/k8s/kubernetes-task-runner.ts rename to src/model/cloud-runner/providers/k8s/kubernetes-task-runner.ts index 7dece875..00075321 100644 --- a/src/model/cloud-runner/k8s/kubernetes-task-runner.ts +++ b/src/model/cloud-runner/providers/k8s/kubernetes-task-runner.ts @@ -1,10 +1,10 @@ import { CoreV1Api, KubeConfig, Log } from '@kubernetes/client-node'; import { Writable } from 'stream'; -import CloudRunnerLogger from '../services/cloud-runner-logger'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; import * as core from '@actions/core'; -import { CloudRunnerStatics } from '../cloud-runner-statics'; +import { CloudRunnerStatics } from '../../cloud-runner-statics'; import waitUntil from 'async-wait-until'; -import { Input } from '../..'; +import CloudRunner from '../../cloud-runner'; class KubernetesTaskRunner { static async runTask( @@ -24,7 +24,7 @@ class KubernetesTaskRunner { didStreamAnyLogs = true; let message = chunk.toString().trimRight(`\n`); message = `[${CloudRunnerStatics.logPrefix}] ${message}`; - if (Input.cloudRunnerTests) { + if (CloudRunner.buildParameters.cloudRunnerIntegrationTests) { output += message; } logCallback(message); diff --git a/src/model/cloud-runner/providers/local-docker/index.ts b/src/model/cloud-runner/providers/local-docker/index.ts new file mode 100644 index 00000000..c8042030 --- /dev/null +++ b/src/model/cloud-runner/providers/local-docker/index.ts @@ -0,0 +1,48 @@ +import BuildParameters from '../../../build-parameters'; +import { CloudRunnerSystem } from '../../services/cloud-runner-system'; +import CloudRunnerEnvironmentVariable from '../../services/cloud-runner-environment-variable'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; +import { ProviderInterface } from '../provider-interface'; +import CloudRunnerSecret from '../../services/cloud-runner-secret'; + +class LocalDockerCloudRunner implements ProviderInterface { + cleanup( + // eslint-disable-next-line no-unused-vars + buildGuid: string, + // eslint-disable-next-line no-unused-vars + buildParameters: BuildParameters, + // eslint-disable-next-line no-unused-vars + branchName: string, + // eslint-disable-next-line no-unused-vars + defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], + ) {} + setup( + // eslint-disable-next-line no-unused-vars + buildGuid: string, + // eslint-disable-next-line no-unused-vars + buildParameters: BuildParameters, + // eslint-disable-next-line no-unused-vars + branchName: string, + // eslint-disable-next-line no-unused-vars + defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], + ) {} + public runTask( + commands: string, + buildGuid: string, + // eslint-disable-next-line no-unused-vars + image: string, + // eslint-disable-next-line no-unused-vars + mountdir: string, + // eslint-disable-next-line no-unused-vars + workingdir: string, + // eslint-disable-next-line no-unused-vars + environment: CloudRunnerEnvironmentVariable[], + // eslint-disable-next-line no-unused-vars + secrets: CloudRunnerSecret[], + ): Promise { + CloudRunnerLogger.log(buildGuid); + CloudRunnerLogger.log(commands); + return CloudRunnerSystem.Run(commands, false, false); + } +} +export default LocalDockerCloudRunner; diff --git a/src/model/cloud-runner/providers/local/index.ts b/src/model/cloud-runner/providers/local/index.ts new file mode 100644 index 00000000..9ad041e3 --- /dev/null +++ b/src/model/cloud-runner/providers/local/index.ts @@ -0,0 +1,48 @@ +import BuildParameters from '../../../build-parameters'; +import { CloudRunnerSystem } from '../../services/cloud-runner-system'; +import CloudRunnerEnvironmentVariable from '../../services/cloud-runner-environment-variable'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; +import { ProviderInterface } from '../provider-interface'; +import CloudRunnerSecret from '../../services/cloud-runner-secret'; + +class LocalCloudRunner implements ProviderInterface { + cleanup( + // eslint-disable-next-line no-unused-vars + buildGuid: string, + // eslint-disable-next-line no-unused-vars + buildParameters: BuildParameters, + // eslint-disable-next-line no-unused-vars + branchName: string, + // eslint-disable-next-line no-unused-vars + defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], + ) {} + public setup( + // eslint-disable-next-line no-unused-vars + buildGuid: string, + // eslint-disable-next-line no-unused-vars + buildParameters: BuildParameters, + // eslint-disable-next-line no-unused-vars + branchName: string, + // eslint-disable-next-line no-unused-vars + defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], + ) {} + public async runTask( + buildGuid: string, + image: string, + commands: string, + // eslint-disable-next-line no-unused-vars + mountdir: string, + // eslint-disable-next-line no-unused-vars + workingdir: string, + // eslint-disable-next-line no-unused-vars + environment: CloudRunnerEnvironmentVariable[], + // eslint-disable-next-line no-unused-vars + secrets: CloudRunnerSecret[], + ): Promise { + CloudRunnerLogger.log(image); + CloudRunnerLogger.log(buildGuid); + CloudRunnerLogger.log(commands); + return await CloudRunnerSystem.Run(commands); + } +} +export default LocalCloudRunner; diff --git a/src/model/cloud-runner/services/cloud-runner-provider-interface.ts b/src/model/cloud-runner/providers/provider-interface.ts similarity index 85% rename from src/model/cloud-runner/services/cloud-runner-provider-interface.ts rename to src/model/cloud-runner/providers/provider-interface.ts index b89bfa6e..f6e9d171 100644 --- a/src/model/cloud-runner/services/cloud-runner-provider-interface.ts +++ b/src/model/cloud-runner/providers/provider-interface.ts @@ -1,9 +1,9 @@ import BuildParameters from '../../build-parameters'; -import CloudRunnerEnvironmentVariable from './cloud-runner-environment-variable'; -import CloudRunnerSecret from './cloud-runner-secret'; +import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable'; +import CloudRunnerSecret from '../services/cloud-runner-secret'; -export interface CloudRunnerProviderInterface { - cleanupSharedResources( +export interface ProviderInterface { + cleanup( // eslint-disable-next-line no-unused-vars buildGuid: string, // eslint-disable-next-line no-unused-vars @@ -13,7 +13,7 @@ export interface CloudRunnerProviderInterface { // eslint-disable-next-line no-unused-vars defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], ); - setupSharedResources( + setup( // eslint-disable-next-line no-unused-vars buildGuid: string, // eslint-disable-next-line no-unused-vars diff --git a/src/model/cloud-runner/providers/test/index.ts b/src/model/cloud-runner/providers/test/index.ts new file mode 100644 index 00000000..1afec435 --- /dev/null +++ b/src/model/cloud-runner/providers/test/index.ts @@ -0,0 +1,49 @@ +import BuildParameters from '../../../build-parameters'; +import CloudRunnerEnvironmentVariable from '../../services/cloud-runner-environment-variable'; +import CloudRunnerLogger from '../../services/cloud-runner-logger'; +import { ProviderInterface } from '../provider-interface'; +import CloudRunnerSecret from '../../services/cloud-runner-secret'; + +class TestCloudRunner implements ProviderInterface { + cleanup( + // eslint-disable-next-line no-unused-vars + buildGuid: string, + // eslint-disable-next-line no-unused-vars + buildParameters: BuildParameters, + // eslint-disable-next-line no-unused-vars + branchName: string, + // eslint-disable-next-line no-unused-vars + defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], + ) {} + setup( + // eslint-disable-next-line no-unused-vars + buildGuid: string, + // eslint-disable-next-line no-unused-vars + buildParameters: BuildParameters, + // eslint-disable-next-line no-unused-vars + branchName: string, + // eslint-disable-next-line no-unused-vars + defaultSecretsArray: { ParameterKey: string; EnvironmentVariable: string; ParameterValue: string }[], + ) {} + public async runTask( + commands: string, + buildGuid: string, + image: string, + // eslint-disable-next-line no-unused-vars + mountdir: string, + // eslint-disable-next-line no-unused-vars + workingdir: string, + // eslint-disable-next-line no-unused-vars + environment: CloudRunnerEnvironmentVariable[], + // eslint-disable-next-line no-unused-vars + secrets: CloudRunnerSecret[], + ): Promise { + CloudRunnerLogger.log(image); + CloudRunnerLogger.log(buildGuid); + CloudRunnerLogger.log(commands); + return await new Promise((result) => { + result(commands); + }); + } +} +export default TestCloudRunner; diff --git a/src/model/cloud-runner/remote-client/caching.test.ts b/src/model/cloud-runner/remote-client/caching.test.ts new file mode 100644 index 00000000..d0534c28 --- /dev/null +++ b/src/model/cloud-runner/remote-client/caching.test.ts @@ -0,0 +1,63 @@ +import fs from 'fs'; +import path from 'path'; +import BuildParameters from '../../build-parameters'; +import { Cli } from '../../cli/cli'; +import Input from '../../input'; +import UnityVersioning from '../../unity-versioning'; +import CloudRunner from '../cloud-runner'; +import { CloudRunnerSystem } from '../services/cloud-runner-system'; +import { Caching } from './caching'; +import { v4 as uuidv4 } from 'uuid'; + +describe('Cloud Runner Caching', () => { + it('responds', () => {}); +}); +describe('Cloud Runner Caching', () => { + if (process.platform === 'linux') { + it('Simple caching works', async () => { + Cli.options = { + versioning: 'None', + projectPath: 'test-project', + unityVersion: UnityVersioning.read('test-project'), + targetPlatform: 'StandaloneLinux64', + cacheKey: `test-case-${uuidv4()}`, + }; + Input.githubInputEnabled = false; + const buildParameter = await BuildParameters.create(); + CloudRunner.buildParameters = buildParameter; + + // create test folder + const testFolder = path.resolve(__dirname, Cli.options.cacheKey); + fs.mkdirSync(testFolder); + + // crate cache folder + const cacheFolder = path.resolve(__dirname, `cache-${Cli.options.cacheKey}`); + fs.mkdirSync(cacheFolder); + + // add test has file to test folders + fs.writeFileSync(path.resolve(testFolder, 'test.txt'), Cli.options.cacheKey); + await Caching.PushToCache(cacheFolder, testFolder, `${Cli.options.cacheKey}`); + + // delete test folder + fs.rmdirSync(testFolder, { recursive: true }); + await Caching.PullFromCache( + cacheFolder.replace(/\\/g, `/`), + testFolder.replace(/\\/g, `/`), + `${Cli.options.cacheKey}`, + ); + await CloudRunnerSystem.Run(`du -h ${__dirname}`); + await CloudRunnerSystem.Run(`tree ${testFolder}`); + await CloudRunnerSystem.Run(`tree ${cacheFolder}`); + + // compare validity to original hash + expect(fs.readFileSync(path.resolve(testFolder, 'test.txt'), { encoding: 'utf8' }).toString()).toContain( + Cli.options.cacheKey, + ); + fs.rmdirSync(testFolder, { recursive: true }); + fs.rmdirSync(cacheFolder, { recursive: true }); + + Input.githubInputEnabled = true; + delete Cli.options; + }, 1000000); + } +}); diff --git a/src/model/cloud-runner/remote-client/caching.ts b/src/model/cloud-runner/remote-client/caching.ts new file mode 100644 index 00000000..58c8a9f5 --- /dev/null +++ b/src/model/cloud-runner/remote-client/caching.ts @@ -0,0 +1,171 @@ +import { assert } from 'console'; +import fs from 'fs'; +import path from 'path'; +import CloudRunner from '../cloud-runner'; +import CloudRunnerLogger from '../services/cloud-runner-logger'; +import { CloudRunnerFolders } from '../services/cloud-runner-folders'; +import { CloudRunnerSystem } from '../services/cloud-runner-system'; +import { LfsHashing } from '../services/lfs-hashing'; +import { RemoteClientLogger } from './remote-client-logger'; +import { Cli } from '../../cli/cli'; +import { CliFunction } from '../../cli/cli-functions-repository'; +// eslint-disable-next-line github/no-then +const fileExists = async (fpath) => !!(await fs.promises.stat(fpath).catch(() => false)); + +export class Caching { + @CliFunction(`cache-push`, `push to cache`) + static async cachePush() { + try { + const buildParameter = JSON.parse(process.env.BUILD_PARAMETERS || '{}'); + CloudRunner.buildParameters = buildParameter; + await Caching.PushToCache( + Cli.options['cachePushTo'], + Cli.options['cachePushFrom'], + Cli.options['artifactName'] || '', + ); + } catch (error: any) { + CloudRunnerLogger.log(`${error}`); + } + } + + @CliFunction(`cache-pull`, `pull from cache`) + static async cachePull() { + try { + const buildParameter = JSON.parse(process.env.BUILD_PARAMETERS || '{}'); + CloudRunner.buildParameters = buildParameter; + await Caching.PullFromCache( + Cli.options['cachePushFrom'], + Cli.options['cachePushTo'], + Cli.options['artifactName'] || '', + ); + } catch (error: any) { + CloudRunnerLogger.log(`${error}`); + } + } + + public static async PushToCache(cacheFolder: string, sourceFolder: string, cacheArtifactName: string) { + cacheArtifactName = cacheArtifactName.replace(' ', ''); + const startPath = process.cwd(); + try { + if (!(await fileExists(cacheFolder))) { + await CloudRunnerSystem.Run(`mkdir -p ${cacheFolder}`); + } + process.chdir(path.resolve(sourceFolder, '..')); + + if (CloudRunner.buildParameters.cloudRunnerIntegrationTests) { + CloudRunnerLogger.log( + `Hashed cache folder ${await LfsHashing.hashAllFiles(sourceFolder)} ${sourceFolder} ${path.basename( + sourceFolder, + )}`, + ); + } + // eslint-disable-next-line func-style + const formatFunction = function (format: string) { + const arguments_ = Array.prototype.slice.call( + [path.resolve(sourceFolder, '..'), cacheFolder, cacheArtifactName], + 1, + ); + return format.replace(/{(\d+)}/g, function (match, number) { + return typeof arguments_[number] != 'undefined' ? arguments_[number] : match; + }); + }; + await CloudRunnerSystem.Run(`zip -q -r ${cacheArtifactName}.zip ${path.basename(sourceFolder)}`); + assert(await fileExists(`${cacheArtifactName}.zip`), 'cache zip exists'); + assert(await fileExists(path.basename(sourceFolder)), 'source folder exists'); + if (CloudRunner.buildParameters.cachePushOverrideCommand) { + await CloudRunnerSystem.Run(formatFunction(CloudRunner.buildParameters.cachePushOverrideCommand)); + } + await CloudRunnerSystem.Run(`mv ${cacheArtifactName}.zip ${cacheFolder}`); + RemoteClientLogger.log(`moved ${cacheArtifactName}.zip to ${cacheFolder}`); + assert( + await fileExists(`${path.join(cacheFolder, cacheArtifactName)}.zip`), + 'cache zip exists inside cache folder', + ); + } catch (error) { + process.chdir(`${startPath}`); + throw error; + } + process.chdir(`${startPath}`); + } + public static async PullFromCache(cacheFolder: string, destinationFolder: string, cacheArtifactName: string = ``) { + cacheArtifactName = cacheArtifactName.replace(' ', ''); + const startPath = process.cwd(); + RemoteClientLogger.log(`Caching for ${path.basename(destinationFolder)}`); + try { + if (!(await fileExists(cacheFolder))) { + await fs.promises.mkdir(cacheFolder); + } + + if (!(await fileExists(destinationFolder))) { + await fs.promises.mkdir(destinationFolder); + } + + const latestInBranch = await (await CloudRunnerSystem.Run(`ls -t "${cacheFolder}" | grep .zip$ | head -1`)) + .replace(/\n/g, ``) + .replace('.zip', ''); + + process.chdir(cacheFolder); + + const cacheSelection = + cacheArtifactName !== `` && (await fileExists(`${cacheArtifactName}.zip`)) ? cacheArtifactName : latestInBranch; + await CloudRunnerLogger.log(`cache key ${cacheArtifactName} selection ${cacheSelection}`); + + // eslint-disable-next-line func-style + const formatFunction = function (format: string) { + const arguments_ = Array.prototype.slice.call( + [path.resolve(destinationFolder, '..'), cacheFolder, cacheArtifactName], + 1, + ); + return format.replace(/{(\d+)}/g, function (match, number) { + return typeof arguments_[number] != 'undefined' ? arguments_[number] : match; + }); + }; + + if (CloudRunner.buildParameters.cachePullOverrideCommand) { + await CloudRunnerSystem.Run(formatFunction(CloudRunner.buildParameters.cachePullOverrideCommand)); + } + + if (await fileExists(`${cacheSelection}.zip`)) { + const resultsFolder = `results${CloudRunner.buildParameters.buildGuid}`; + await CloudRunnerSystem.Run(`mkdir -p ${resultsFolder}`); + RemoteClientLogger.log(`cache item exists ${cacheFolder}/${cacheSelection}.zip`); + const fullResultsFolder = path.join(cacheFolder, resultsFolder); + await CloudRunnerSystem.Run(`unzip -q ${cacheSelection}.zip -d ${path.basename(resultsFolder)}`); + RemoteClientLogger.log(`cache item extracted to ${fullResultsFolder}`); + assert(await fileExists(fullResultsFolder), `cache extraction results folder exists`); + const destinationParentFolder = path.resolve(destinationFolder, '..'); + + if (await fileExists(destinationFolder)) { + await fs.promises.rmdir(destinationFolder, { recursive: true }); + } + await CloudRunnerSystem.Run( + `mv "${path.join(fullResultsFolder, path.basename(destinationFolder))}" "${destinationParentFolder}"`, + ); + await CloudRunnerSystem.Run(`du -sh ${path.join(destinationParentFolder, path.basename(destinationFolder))}`); + const contents = await fs.promises.readdir( + path.join(destinationParentFolder, path.basename(destinationFolder)), + ); + CloudRunnerLogger.log( + `There is ${contents.length} files/dir in the cache pulled contents for ${path.basename(destinationFolder)}`, + ); + } else { + RemoteClientLogger.logWarning(`cache item ${cacheArtifactName} doesn't exist ${destinationFolder}`); + if (cacheSelection !== ``) { + RemoteClientLogger.logWarning(`cache item ${cacheArtifactName}.zip doesn't exist ${destinationFolder}`); + throw new Error(`Failed to get cache item, but cache hit was found: ${cacheSelection}`); + } + } + } catch (error) { + process.chdir(`${startPath}`); + throw error; + } + process.chdir(`${startPath}`); + } + + public static async handleCachePurging() { + if (process.env.PURGE_REMOTE_BUILDER_CACHE !== undefined) { + RemoteClientLogger.log(`purging ${CloudRunnerFolders.purgeRemoteCaching}`); + fs.promises.rmdir(CloudRunnerFolders.cacheFolder, { recursive: true }); + } + } +} diff --git a/src/model/cloud-runner/remote-client/index.ts b/src/model/cloud-runner/remote-client/index.ts new file mode 100644 index 00000000..bf80fbc7 --- /dev/null +++ b/src/model/cloud-runner/remote-client/index.ts @@ -0,0 +1,95 @@ +import fs from 'fs'; +import CloudRunner from '../cloud-runner'; +import { CloudRunnerFolders } from '../services/cloud-runner-folders'; +import { Caching } from './caching'; +import { LfsHashing } from '../services/lfs-hashing'; +import { RemoteClientLogger } from './remote-client-logger'; +import path from 'path'; +import { assert } from 'console'; +import CloudRunnerLogger from '../services/cloud-runner-logger'; +import { CliFunction } from '../../cli/cli-functions-repository'; +import { CloudRunnerSystem } from '../services/cloud-runner-system'; + +export class RemoteClient { + public static async bootstrapRepository() { + try { + await CloudRunnerSystem.Run(`mkdir -p ${CloudRunnerFolders.uniqueCloudRunnerJobFolderAbsolute}`); + await CloudRunnerSystem.Run(`mkdir -p ${CloudRunnerFolders.repoPathAbsolute}`); + await CloudRunnerSystem.Run(`mkdir -p ${CloudRunnerFolders.cacheFolderFull}`); + process.chdir(CloudRunnerFolders.repoPathAbsolute); + await RemoteClient.cloneRepoWithoutLFSFiles(); + await RemoteClient.sizeOfFolder('repo before lfs cache pull', CloudRunnerFolders.repoPathAbsolute); + const lfsHashes = await LfsHashing.createLFSHashFiles(); + if (fs.existsSync(CloudRunnerFolders.libraryFolderAbsolute)) { + RemoteClientLogger.logWarning(`!Warning!: The Unity library was included in the git repository`); + } + await Caching.PullFromCache( + CloudRunnerFolders.lfsCacheFolderFull, + CloudRunnerFolders.lfsFolderAbsolute, + `${lfsHashes.lfsGuidSum}`, + ); + await RemoteClient.sizeOfFolder('repo after lfs cache pull', CloudRunnerFolders.repoPathAbsolute); + await RemoteClient.pullLatestLFS(); + await RemoteClient.sizeOfFolder('repo before lfs git pull', CloudRunnerFolders.repoPathAbsolute); + await Caching.PushToCache( + CloudRunnerFolders.lfsCacheFolderFull, + CloudRunnerFolders.lfsFolderAbsolute, + `${lfsHashes.lfsGuidSum}`, + ); + await Caching.PullFromCache(CloudRunnerFolders.libraryCacheFolderFull, CloudRunnerFolders.libraryFolderAbsolute); + await RemoteClient.sizeOfFolder('repo after library cache pull', CloudRunnerFolders.repoPathAbsolute); + await Caching.handleCachePurging(); + } catch (error) { + throw error; + } + } + + private static async sizeOfFolder(message: string, folder: string) { + CloudRunnerLogger.log(`Size of ${message}`); + await CloudRunnerSystem.Run(`du -sh ${folder}`); + } + + private static async cloneRepoWithoutLFSFiles() { + try { + process.chdir(`${CloudRunnerFolders.repoPathAbsolute}`); + RemoteClientLogger.log(`Initializing source repository for cloning with caching of LFS files`); + await CloudRunnerSystem.Run(`git config --global advice.detachedHead false`); + RemoteClientLogger.log(`Cloning the repository being built:`); + await CloudRunnerSystem.Run(`git config --global filter.lfs.smudge "git-lfs smudge --skip -- %f"`); + await CloudRunnerSystem.Run(`git config --global filter.lfs.process "git-lfs filter-process --skip"`); + await CloudRunnerSystem.Run( + `git clone -q ${CloudRunnerFolders.targetBuildRepoUrl} ${path.resolve( + `..`, + path.basename(CloudRunnerFolders.repoPathAbsolute), + )}`, + ); + await CloudRunnerSystem.Run(`git lfs install`); + assert(fs.existsSync(`.git`), 'git folder exists'); + RemoteClientLogger.log(`${CloudRunner.buildParameters.branch}`); + await CloudRunnerSystem.Run(`git checkout ${CloudRunner.buildParameters.branch}`); + assert(fs.existsSync(path.join(`.git`, `lfs`)), 'LFS folder should not exist before caching'); + RemoteClientLogger.log(`Checked out ${process.env.GITHUB_SHA}`); + } catch (error) { + throw error; + } + } + + private static async pullLatestLFS() { + process.chdir(CloudRunnerFolders.repoPathAbsolute); + await CloudRunnerSystem.Run(`git config --global filter.lfs.smudge "git-lfs smudge -- %f"`); + await CloudRunnerSystem.Run(`git config --global filter.lfs.process "git-lfs filter-process"`); + await CloudRunnerSystem.Run(`git lfs pull`); + RemoteClientLogger.log(`pulled latest LFS files`); + assert(fs.existsSync(CloudRunnerFolders.lfsFolderAbsolute)); + } + + @CliFunction(`remote-cli`, `sets up a repository, usually before a game-ci build`) + static async runRemoteClientJob() { + const buildParameter = JSON.parse(process.env.BUILD_PARAMETERS || '{}'); + RemoteClientLogger.log(`Build Params: + ${JSON.stringify(buildParameter, undefined, 4)} + `); + CloudRunner.buildParameters = buildParameter; + await RemoteClient.bootstrapRepository(); + } +} diff --git a/src/model/cli/remote-client/remote-client-services/remote-client-logger.ts b/src/model/cloud-runner/remote-client/remote-client-logger.ts similarity index 84% rename from src/model/cli/remote-client/remote-client-services/remote-client-logger.ts rename to src/model/cloud-runner/remote-client/remote-client-logger.ts index b46d184c..5581b8bc 100644 --- a/src/model/cli/remote-client/remote-client-services/remote-client-logger.ts +++ b/src/model/cloud-runner/remote-client/remote-client-logger.ts @@ -1,4 +1,4 @@ -import CloudRunnerLogger from '../../../cloud-runner/services/cloud-runner-logger'; +import CloudRunnerLogger from '../services/cloud-runner-logger'; export class RemoteClientLogger { public static log(message: string) { diff --git a/src/model/cloud-runner/services/cloud-runner-build-command-process.ts b/src/model/cloud-runner/services/cloud-runner-build-command-process.ts index e6149588..1b05b4e3 100644 --- a/src/model/cloud-runner/services/cloud-runner-build-command-process.ts +++ b/src/model/cloud-runner/services/cloud-runner-build-command-process.ts @@ -1,25 +1,27 @@ -import { BuildParameters, Input } from '../..'; +import { BuildParameters } from '../..'; import YAML from 'yaml'; import CloudRunnerSecret from './cloud-runner-secret'; +import CloudRunner from '../cloud-runner'; export class CloudRunnerBuildCommandProcessor { public static ProcessCommands(commands: string, buildParameters: BuildParameters): string { - const hooks = CloudRunnerBuildCommandProcessor.getHooks().filter((x) => x.step.includes(`all`)); + const hooks = CloudRunnerBuildCommandProcessor.getHooks(buildParameters.customJobHooks).filter((x) => + x.step.includes(`all`), + ); return `echo "---" echo "start cloud runner init" - ${Input.cloudRunnerTests ? '' : '#'} printenv - echo "start cloud runner job" + ${CloudRunner.buildParameters.cloudRunnerIntegrationTests ? '' : '#'} printenv + echo "start of cloud runner job" ${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '} ${commands} ${hooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '} - echo "end of cloud runner job - ---${buildParameters.logId}" - `; + echo "end of cloud runner job" + echo "---${buildParameters.logId}"`; } - public static getHooks(): Hook[] { - const experimentHooks = process.env.EXPERIMENTAL_HOOKS; + public static getHooks(customJobHooks): Hook[] { + const experimentHooks = customJobHooks; let output = new Array(); if (experimentHooks && experimentHooks !== '') { try { diff --git a/src/model/cloud-runner/services/cloud-runner-folders.ts b/src/model/cloud-runner/services/cloud-runner-folders.ts new file mode 100644 index 00000000..5bdc36ca --- /dev/null +++ b/src/model/cloud-runner/services/cloud-runner-folders.ts @@ -0,0 +1,73 @@ +import path from 'path'; +import { CloudRunner } from '../..'; + +export class CloudRunnerFolders { + public static readonly repositoryFolder = 'repo'; + + // only the following paths that do not start a path.join with another "Full" suffixed property need to start with an absolute / + + public static get uniqueCloudRunnerJobFolderAbsolute(): string { + return path.join(`/`, CloudRunnerFolders.buildVolumeFolder, CloudRunner.buildParameters.buildGuid); + } + + public static get cacheFolderFull(): string { + return path.join( + '/', + CloudRunnerFolders.buildVolumeFolder, + CloudRunnerFolders.cacheFolder, + CloudRunner.buildParameters.cacheKey, + ); + } + + public static get builderPathAbsolute(): string { + return path.join(CloudRunnerFolders.uniqueCloudRunnerJobFolderAbsolute, `builder`); + } + + public static get repoPathAbsolute(): string { + return path.join(CloudRunnerFolders.uniqueCloudRunnerJobFolderAbsolute, CloudRunnerFolders.repositoryFolder); + } + + public static get projectPathAbsolute(): string { + return path.join(CloudRunnerFolders.repoPathAbsolute, CloudRunner.buildParameters.projectPath); + } + + public static get libraryFolderAbsolute(): string { + return path.join(CloudRunnerFolders.projectPathAbsolute, `Library`); + } + + public static get projectBuildFolderAbsolute(): string { + return path.join(CloudRunnerFolders.repoPathAbsolute, CloudRunner.buildParameters.buildPath); + } + + public static get lfsFolderAbsolute(): string { + return path.join(CloudRunnerFolders.repoPathAbsolute, `.git`, `lfs`); + } + + public static get purgeRemoteCaching(): boolean { + return process.env.PURGE_REMOTE_BUILDER_CACHE !== undefined; + } + + public static get lfsCacheFolderFull() { + return path.join(CloudRunnerFolders.cacheFolderFull, `lfs`); + } + + public static get libraryCacheFolderFull() { + return path.join(CloudRunnerFolders.cacheFolderFull, `Library`); + } + + public static get unityBuilderRepoUrl(): string { + return `https://${CloudRunner.buildParameters.gitPrivateToken}@github.com/game-ci/unity-builder.git`; + } + + public static get targetBuildRepoUrl(): string { + return `https://${CloudRunner.buildParameters.gitPrivateToken}@github.com/${CloudRunner.buildParameters.githubRepo}.git`; + } + + public static get buildVolumeFolder() { + return 'data'; + } + + public static get cacheFolder() { + return 'cache'; + } +} diff --git a/src/model/cloud-runner/services/cloud-runner-namespace.ts b/src/model/cloud-runner/services/cloud-runner-guid.ts similarity index 81% rename from src/model/cloud-runner/services/cloud-runner-namespace.ts rename to src/model/cloud-runner/services/cloud-runner-guid.ts index ab5b9059..1a1df1a5 100644 --- a/src/model/cloud-runner/services/cloud-runner-namespace.ts +++ b/src/model/cloud-runner/services/cloud-runner-guid.ts @@ -2,7 +2,7 @@ import { customAlphabet } from 'nanoid'; import CloudRunnerConstants from './cloud-runner-constants'; class CloudRunnerNamespace { - static generateBuildName(runNumber: string | number, platform: string) { + static generateGuid(runNumber: string | number, platform: string) { const nanoid = customAlphabet(CloudRunnerConstants.alphabet, 4); return `${runNumber}-${platform.toLowerCase().replace('standalone', '')}-${nanoid()}`; } diff --git a/src/model/cloud-runner/services/cloud-runner-query-override.ts b/src/model/cloud-runner/services/cloud-runner-query-override.ts new file mode 100644 index 00000000..65e906c3 --- /dev/null +++ b/src/model/cloud-runner/services/cloud-runner-query-override.ts @@ -0,0 +1,59 @@ +import Input from '../../input'; +import { GenericInputReader } from '../../input-readers/generic-input-reader'; + +const formatFunction = (value, arguments_) => { + for (const element of arguments_) { + value = value.replace(`{${element.key}}`, element.value); + } + return value; +}; + +class CloudRunnerQueryOverride { + static queryOverrides: any; + + public static query(key, alternativeKey) { + if (CloudRunnerQueryOverride.queryOverrides && CloudRunnerQueryOverride.queryOverrides[key] !== undefined) { + return CloudRunnerQueryOverride.queryOverrides[key]; + } + if ( + CloudRunnerQueryOverride.queryOverrides && + alternativeKey && + CloudRunnerQueryOverride.queryOverrides[alternativeKey] !== undefined + ) { + return CloudRunnerQueryOverride.queryOverrides[alternativeKey]; + } + return; + } + + private static shouldUseOverride(query) { + if (Input.readInputOverrideCommand() !== '') { + if (Input.readInputFromOverrideList() !== '') { + const doesInclude = + Input.readInputFromOverrideList().split(',').includes(query) || + Input.readInputFromOverrideList().split(',').includes(Input.ToEnvVarFormat(query)); + return doesInclude ? true : false; + } else { + return true; + } + } + } + + private static async queryOverride(query) { + if (!this.shouldUseOverride(query)) { + throw new Error(`Should not be trying to run override query on ${query}`); + } + + return await GenericInputReader.Run(formatFunction(Input.readInputOverrideCommand(), [{ key: 0, value: query }])); + } + + public static async PopulateQueryOverrideInput() { + const queries = Input.readInputFromOverrideList().split(','); + CloudRunnerQueryOverride.queryOverrides = new Array(); + for (const element of queries) { + if (CloudRunnerQueryOverride.shouldUseOverride(element)) { + CloudRunnerQueryOverride.queryOverrides[element] = await CloudRunnerQueryOverride.queryOverride(element); + } + } + } +} +export default CloudRunnerQueryOverride; diff --git a/src/model/cloud-runner/services/cloud-runner-system.ts b/src/model/cloud-runner/services/cloud-runner-system.ts new file mode 100644 index 00000000..cc99197d --- /dev/null +++ b/src/model/cloud-runner/services/cloud-runner-system.ts @@ -0,0 +1,45 @@ +import { exec } from 'child_process'; +import { RemoteClientLogger } from '../remote-client/remote-client-logger'; + +export class CloudRunnerSystem { + public static async Run(command: string, suppressError = false, suppressLogs = false) { + for (const element of command.split(`\n`)) { + if (!suppressLogs) { + RemoteClientLogger.log(element); + } + } + return await new Promise((promise, throwError) => { + let output = ''; + const child = exec(command, (error, stdout, stderr) => { + if (!suppressError && error) { + RemoteClientLogger.log(error.toString()); + throwError(error); + } + if (stderr) { + const diagnosticOutput = `${stderr.toString()}`; + if (!suppressLogs) { + RemoteClientLogger.logCliDiagnostic(diagnosticOutput); + } + output += diagnosticOutput; + } + const outputChunk = `${stdout}`; + output += outputChunk; + }); + child.on('close', (code) => { + if (!suppressLogs) { + RemoteClientLogger.log(`[${code}]`); + } + if (code !== 0 && !suppressError) { + throwError(output); + } + const outputLines = output.split(`\n`); + for (const element of outputLines) { + if (!suppressLogs) { + RemoteClientLogger.log(element); + } + } + promise(output); + }); + }); + } +} diff --git a/src/model/cloud-runner/services/depdency-override-service.ts b/src/model/cloud-runner/services/depdency-override-service.ts new file mode 100644 index 00000000..cbacb712 --- /dev/null +++ b/src/model/cloud-runner/services/depdency-override-service.ts @@ -0,0 +1,21 @@ +import Input from '../../input'; +import { CloudRunnerSystem } from './cloud-runner-system'; + +class DependencyOverrideService { + public static async CheckHealth() { + if (Input.checkDependencyHealthOverride) { + try { + await CloudRunnerSystem.Run(Input.checkDependencyHealthOverride); + } catch { + return false; + } + } + return true; + } + public static async TryStartDependencies() { + if (Input.startDependenciesOverride) { + await CloudRunnerSystem.Run(Input.startDependenciesOverride); + } + } +} +export default DependencyOverrideService; diff --git a/src/model/cli/remote-client/remote-client-services/lfs-hashing.ts b/src/model/cloud-runner/services/lfs-hashing.ts similarity index 62% rename from src/model/cli/remote-client/remote-client-services/lfs-hashing.ts rename to src/model/cloud-runner/services/lfs-hashing.ts index 343d852f..0538ea7d 100644 --- a/src/model/cli/remote-client/remote-client-services/lfs-hashing.ts +++ b/src/model/cloud-runner/services/lfs-hashing.ts @@ -1,12 +1,12 @@ import path from 'path'; -import { CloudRunnerState } from '../../../cloud-runner/state/cloud-runner-state'; +import { CloudRunnerFolders } from './cloud-runner-folders'; import { CloudRunnerSystem } from './cloud-runner-system'; import fs from 'fs'; import { assert } from 'console'; -import { Input } from '../../..'; -import { RemoteClientLogger } from './remote-client-logger'; +import { Cli } from '../../cli/cli'; +import { CliFunction } from '../../cli/cli-functions-repository'; -export class LFSHashing { +export class LfsHashing { public static async createLFSHashFiles() { try { await CloudRunnerSystem.Run(`git lfs ls-files -l | cut -d ' ' -f1 | sort > .lfs-assets-guid`); @@ -15,16 +15,13 @@ export class LFSHashing { assert(fs.existsSync(`.lfs-assets-guid`)); const lfsHashes = { lfsGuid: fs - .readFileSync(`${path.join(CloudRunnerState.repoPathFull, `.lfs-assets-guid`)}`, 'utf8') + .readFileSync(`${path.join(CloudRunnerFolders.repoPathAbsolute, `.lfs-assets-guid`)}`, 'utf8') .replace(/\n/g, ``), lfsGuidSum: fs - .readFileSync(`${path.join(CloudRunnerState.repoPathFull, `.lfs-assets-guid-sum`)}`, 'utf8') + .readFileSync(`${path.join(CloudRunnerFolders.repoPathAbsolute, `.lfs-assets-guid-sum`)}`, 'utf8') + .replace(' .lfs-assets-guid', '') .replace(/\n/g, ``), }; - if (Input.cloudRunnerTests) { - RemoteClientLogger.log(lfsHashes.lfsGuid); - RemoteClientLogger.log(lfsHashes.lfsGuidSum); - } return lfsHashes; } catch (error) { throw error; @@ -39,4 +36,10 @@ export class LFSHashing { process.chdir(startPath); return result; } + + @CliFunction(`hash`, `hash all folder contents`) + static async hash() { + const folder = Cli.options['cachePushFrom']; + LfsHashing.hashAllFiles(folder); + } } diff --git a/src/model/cloud-runner/services/task-parameter-serializer.ts b/src/model/cloud-runner/services/task-parameter-serializer.ts index 5e85a34a..f46f397d 100644 --- a/src/model/cloud-runner/services/task-parameter-serializer.ts +++ b/src/model/cloud-runner/services/task-parameter-serializer.ts @@ -1,24 +1,24 @@ -import { Input } from '../..'; +import { CloudRunner, Input } from '../..'; import ImageEnvironmentFactory from '../../image-environment-factory'; import CloudRunnerEnvironmentVariable from './cloud-runner-environment-variable'; -import { CloudRunnerState } from '../state/cloud-runner-state'; import { CloudRunnerBuildCommandProcessor } from './cloud-runner-build-command-process'; +import CloudRunnerSecret from './cloud-runner-secret'; +import CloudRunnerQueryOverride from './cloud-runner-query-override'; export class TaskParameterSerializer { public static readBuildEnvironmentVariables(): CloudRunnerEnvironmentVariable[] { - TaskParameterSerializer.setupDefaultSecrets(); return [ { name: 'ContainerMemory', - value: CloudRunnerState.buildParams.cloudRunnerMemory, + value: CloudRunner.buildParameters.cloudRunnerMemory, }, { name: 'ContainerCpu', - value: CloudRunnerState.buildParams.cloudRunnerCpu, + value: CloudRunner.buildParameters.cloudRunnerCpu, }, { name: 'BUILD_TARGET', - value: CloudRunnerState.buildParams.targetPlatform, + value: CloudRunner.buildParameters.targetPlatform, }, ...TaskParameterSerializer.serializeBuildParamsAndInput, ]; @@ -27,7 +27,7 @@ export class TaskParameterSerializer { let array = new Array(); array = TaskParameterSerializer.readBuildParameters(array); array = TaskParameterSerializer.readInput(array); - const configurableHooks = CloudRunnerBuildCommandProcessor.getHooks(); + const configurableHooks = CloudRunnerBuildCommandProcessor.getHooks(CloudRunner.buildParameters.customJobHooks); const secrets = configurableHooks.map((x) => x.secrets).filter((x) => x !== undefined && x.length > 0); if (secrets.length > 0) { // eslint-disable-next-line unicorn/no-array-reduce @@ -46,14 +46,14 @@ export class TaskParameterSerializer { } private static readBuildParameters(array: any[]) { - const keys = Object.keys(CloudRunnerState.buildParams); + const keys = Object.keys(CloudRunner.buildParameters); for (const element of keys) { array.push({ name: element, - value: CloudRunnerState.buildParams[element], + value: CloudRunner.buildParameters[element], }); } - array.push({ name: 'buildParameters', value: JSON.stringify(CloudRunnerState.buildParams) }); + array.push({ name: 'buildParameters', value: JSON.stringify(CloudRunner.buildParameters) }); return array; } @@ -70,16 +70,40 @@ export class TaskParameterSerializer { return array; } - private static setupDefaultSecrets() { - if (CloudRunnerState.defaultSecrets === undefined) - CloudRunnerState.defaultSecrets = ImageEnvironmentFactory.getEnvironmentVariables( - CloudRunnerState.buildParams, - ).map((x) => { - return { - ParameterKey: x.name, - EnvironmentVariable: x.name, - ParameterValue: x.value, - }; + public static readDefaultSecrets(): CloudRunnerSecret[] { + let array = new Array(); + array = TaskParameterSerializer.tryAddInput(array, 'UNITY_SERIAL'); + array = TaskParameterSerializer.tryAddInput(array, 'UNITY_EMAIL'); + array = TaskParameterSerializer.tryAddInput(array, 'UNITY_PASSWORD'); + array.push( + ...ImageEnvironmentFactory.getEnvironmentVariables(CloudRunner.buildParameters) + .filter((x) => array.every((y) => y.ParameterKey !== x.name)) + .map((x) => { + return { + ParameterKey: x.name, + EnvironmentVariable: x.name, + ParameterValue: x.value, + }; + }), + ); + return array; + } + private static getValue(key) { + return CloudRunnerQueryOverride.queryOverrides !== undefined && + CloudRunnerQueryOverride.queryOverrides[key] !== undefined + ? CloudRunnerQueryOverride.queryOverrides[key] + : process.env[key]; + } + s; + private static tryAddInput(array, key): CloudRunnerSecret[] { + const value = TaskParameterSerializer.getValue(key); + if (value !== undefined && value !== '') { + array.push({ + ParameterKey: key, + EnvironmentVariable: key, + ParameterValue: value, }); + } + return array; } } diff --git a/src/model/cloud-runner/state/cloud-runner-state.ts b/src/model/cloud-runner/state/cloud-runner-state.ts deleted file mode 100644 index 26648b93..00000000 --- a/src/model/cloud-runner/state/cloud-runner-state.ts +++ /dev/null @@ -1,81 +0,0 @@ -import path from 'path'; -import { BuildParameters } from '../..'; -import { CloudRunnerProviderInterface } from '../services/cloud-runner-provider-interface'; -import CloudRunnerSecret from '../services/cloud-runner-secret'; - -export class CloudRunnerState { - public static CloudRunnerProviderPlatform: CloudRunnerProviderInterface; - public static buildParams: BuildParameters; - public static defaultSecrets: CloudRunnerSecret[]; - public static readonly repositoryFolder = 'repo'; - - // only the following paths that do not start a path.join with another "Full" suffixed property need to start with an absolute / - - public static get buildPathFull(): string { - return path.join(`/`, CloudRunnerState.buildVolumeFolder, CloudRunnerState.buildParams.buildGuid); - } - - public static get cacheFolderFull(): string { - return path.join( - '/', - CloudRunnerState.buildVolumeFolder, - CloudRunnerState.cacheFolder, - CloudRunnerState.branchName, - ); - } - - static setup(buildParameters: BuildParameters) { - CloudRunnerState.buildParams = buildParameters; - } - - public static get branchName(): string { - return CloudRunnerState.buildParams.branch; - } - public static get builderPathFull(): string { - return path.join(CloudRunnerState.buildPathFull, `builder`); - } - - public static get repoPathFull(): string { - return path.join(CloudRunnerState.buildPathFull, CloudRunnerState.repositoryFolder); - } - - public static get projectPathFull(): string { - return path.join(CloudRunnerState.repoPathFull, CloudRunnerState.buildParams.projectPath); - } - - public static get libraryFolderFull(): string { - return path.join(CloudRunnerState.projectPathFull, `Library`); - } - - public static get lfsDirectoryFull(): string { - return path.join(CloudRunnerState.repoPathFull, `.git`, `lfs`); - } - - public static get purgeRemoteCaching(): boolean { - return process.env.PURGE_REMOTE_BUILDER_CACHE !== undefined; - } - - public static get lfsCacheFolderFull() { - return path.join(CloudRunnerState.cacheFolderFull, `lfs`); - } - - public static get libraryCacheFolderFull() { - return path.join(CloudRunnerState.cacheFolderFull, `Library`); - } - - public static get unityBuilderRepoUrl(): string { - return `https://${CloudRunnerState.buildParams.githubToken}@github.com/game-ci/unity-builder.git`; - } - - public static get targetBuildRepoUrl(): string { - return `https://${CloudRunnerState.buildParams.githubToken}@github.com/${CloudRunnerState.buildParams.githubRepo}.git`; - } - - public static get buildVolumeFolder() { - return 'data'; - } - - public static get cacheFolder() { - return 'cache'; - } -} diff --git a/src/model/cloud-runner/steps/build-step.ts b/src/model/cloud-runner/steps/build-step.ts deleted file mode 100644 index 0b85d2aa..00000000 --- a/src/model/cloud-runner/steps/build-step.ts +++ /dev/null @@ -1,77 +0,0 @@ -import path from 'path'; -import { Input } from '../..'; -import { CloudRunnerBuildCommandProcessor } from '../services/cloud-runner-build-command-process'; -import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable'; -import CloudRunnerLogger from '../services/cloud-runner-logger'; -import CloudRunnerSecret from '../services/cloud-runner-secret'; -import { CloudRunnerState } from '../state/cloud-runner-state'; -import { CloudRunnerStepState } from '../state/cloud-runner-step-state'; -import { StepInterface } from './step-interface'; - -export class BuildStep implements StepInterface { - async run(cloudRunnerStepState: CloudRunnerStepState) { - return await BuildStep.BuildStep( - cloudRunnerStepState.image, - cloudRunnerStepState.environment, - cloudRunnerStepState.secrets, - ); - } - - private static async BuildStep( - image: string, - environmentVariables: CloudRunnerEnvironmentVariable[], - secrets: CloudRunnerSecret[], - ) { - CloudRunnerLogger.logLine(` `); - CloudRunnerLogger.logLine('Starting part 2/2 (build unity project)'); - const hooks = CloudRunnerBuildCommandProcessor.getHooks().filter((x) => x.step.includes(`setup`)); - return await CloudRunnerState.CloudRunnerProviderPlatform.runTask( - CloudRunnerState.buildParams.buildGuid, - image, - `${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '} - export GITHUB_WORKSPACE="${CloudRunnerState.repoPathFull}" - cp -r "${path - .join(CloudRunnerState.builderPathFull, 'dist', 'default-build-script') - .replace(/\\/g, `/`)}" "/UnityBuilderAction" - cp -r "${path - .join(CloudRunnerState.builderPathFull, 'dist', 'platforms', 'ubuntu', 'entrypoint.sh') - .replace(/\\/g, `/`)}" "/entrypoint.sh" - cp -r "${path - .join(CloudRunnerState.builderPathFull, 'dist', 'platforms', 'ubuntu', 'steps') - .replace(/\\/g, `/`)}" "/steps" - chmod -R +x "/entrypoint.sh" - chmod -R +x "/steps" - /entrypoint.sh - apt-get update - apt-get install -y -q zip tree - cd "${CloudRunnerState.libraryFolderFull.replace(/\\/g, `/`)}/.." - zip -r "lib-${CloudRunnerState.buildParams.buildGuid}.zip" "Library" - mv "lib-${CloudRunnerState.buildParams.buildGuid}.zip" "${CloudRunnerState.cacheFolderFull.replace( - /\\/g, - `/`, - )}/Library" - cd "${CloudRunnerState.repoPathFull.replace(/\\/g, `/`)}" - ${Input.cloudRunnerTests ? '' : '#'} tree -lh - zip -r "build-${CloudRunnerState.buildParams.buildGuid}.zip" "build" - ${Input.cloudRunnerTests ? '' : '#'} tree -lh - ${Input.cloudRunnerTests ? '' : '#'} tree -lh "${CloudRunnerState.cacheFolderFull.replace(/\\/g, `/`)}" - mv "build-${CloudRunnerState.buildParams.buildGuid}.zip" "${CloudRunnerState.cacheFolderFull.replace( - /\\/g, - `/`, - )}" - chmod +x ${path.join(CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)} - node ${path - .join(CloudRunnerState.builderPathFull, 'dist', `index.js`) - .replace(/\\/g, `/`)} -m cache-push "Library" "lib-${ - CloudRunnerState.buildParams.buildGuid - }.zip" "${CloudRunnerState.cacheFolderFull.replace(/\\/g, `/`)}/Library" - ${Input.cloudRunnerTests ? '' : '#'} tree -lh "${CloudRunnerState.cacheFolderFull}" - ${hooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '} - `, - `/${CloudRunnerState.buildVolumeFolder}`, - `/${CloudRunnerState.projectPathFull}`, - environmentVariables, - secrets, - ); - } -} diff --git a/src/model/cloud-runner/steps/setup-step.ts b/src/model/cloud-runner/steps/setup-step.ts deleted file mode 100644 index b0da16da..00000000 --- a/src/model/cloud-runner/steps/setup-step.ts +++ /dev/null @@ -1,65 +0,0 @@ -import path from 'path'; -import { Input } from '../..'; -import { CloudRunnerBuildCommandProcessor } from '../services/cloud-runner-build-command-process'; -import CloudRunnerEnvironmentVariable from '../services/cloud-runner-environment-variable'; -import CloudRunnerLogger from '../services/cloud-runner-logger'; -import CloudRunnerSecret from '../services/cloud-runner-secret'; -import { CloudRunnerState } from '../state/cloud-runner-state'; -import { CloudRunnerStepState } from '../state/cloud-runner-step-state'; -import { StepInterface } from './step-interface'; - -export class SetupStep implements StepInterface { - async run(cloudRunnerStepState: CloudRunnerStepState) { - try { - return await SetupStep.downloadRepository( - cloudRunnerStepState.image, - cloudRunnerStepState.environment, - cloudRunnerStepState.secrets, - ); - } catch (error) { - throw error; - } - } - - private static getCloudRunnerBranch() { - return process.env.CLOUD_RUNNER_BRANCH?.includes('/') - ? process.env.CLOUD_RUNNER_BRANCH.split('/').reverse()[0] - : process.env.CLOUD_RUNNER_BRANCH; - } - - private static async downloadRepository( - image: string, - environmentVariables: CloudRunnerEnvironmentVariable[], - secrets: CloudRunnerSecret[], - ) { - try { - CloudRunnerLogger.log(` `); - CloudRunnerLogger.logLine('Starting step 1/2 (setup game files from repository)'); - const hooks = CloudRunnerBuildCommandProcessor.getHooks().filter((x) => x.step.includes(`setup`)); - return await CloudRunnerState.CloudRunnerProviderPlatform.runTask( - CloudRunnerState.buildParams.buildGuid, - image, - `apk update -q - apk add git-lfs jq tree zip unzip nodejs -q - ${hooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '} - export GIT_DISCOVERY_ACROSS_FILESYSTEM=1 - mkdir -p ${CloudRunnerState.builderPathFull.replace(/\\/g, `/`)} - git clone -q -b ${SetupStep.getCloudRunnerBranch()} ${ - CloudRunnerState.unityBuilderRepoUrl - } "${CloudRunnerState.builderPathFull.replace(/\\/g, `/`)}" - ${Input.cloudRunnerTests ? '' : '#'} tree ${CloudRunnerState.builderPathFull.replace(/\\/g, `/`)} - chmod +x ${path.join(CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)} - node ${path.join(CloudRunnerState.builderPathFull, 'dist', `index.js`).replace(/\\/g, `/`)} -m remote-cli - ${hooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '} - `, - `/${CloudRunnerState.buildVolumeFolder}`, - `/${CloudRunnerState.buildVolumeFolder}/`, - environmentVariables, - secrets, - ); - } catch (error) { - CloudRunnerLogger.logLine(`Failed download repository step 1/2`); - throw error; - } - } -} diff --git a/src/model/cloud-runner/steps/step-interface.ts b/src/model/cloud-runner/steps/step-interface.ts deleted file mode 100644 index 7e6fc450..00000000 --- a/src/model/cloud-runner/steps/step-interface.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { CloudRunnerStepState } from '../state/cloud-runner-step-state'; - -export interface StepInterface { - run( - // eslint-disable-next-line no-unused-vars - cloudRunnerStepState: CloudRunnerStepState, - ); -} diff --git a/src/model/cloud-runner/workflows/build-automation-workflow.ts b/src/model/cloud-runner/workflows/build-automation-workflow.ts index 22bc8ded..6a1b33c0 100644 --- a/src/model/cloud-runner/workflows/build-automation-workflow.ts +++ b/src/model/cloud-runner/workflows/build-automation-workflow.ts @@ -1,12 +1,12 @@ import CloudRunnerLogger from '../services/cloud-runner-logger'; -import { TaskParameterSerializer } from '../services/task-parameter-serializer'; -import { CloudRunnerState } from '../state/cloud-runner-state'; -import { CloudRunnerStepState } from '../state/cloud-runner-step-state'; -import { BuildStep } from '../steps/build-step'; -import { SetupStep } from '../steps/setup-step'; +import { CloudRunnerFolders } from '../services/cloud-runner-folders'; +import { CloudRunnerStepState } from '../cloud-runner-step-state'; import { CustomWorkflow } from './custom-workflow'; import { WorkflowInterface } from './workflow-interface'; import * as core from '@actions/core'; +import { CloudRunnerBuildCommandProcessor } from '../services/cloud-runner-build-command-process'; +import path from 'path'; +import CloudRunner from '../cloud-runner'; export class BuildAutomationWorkflow implements WorkflowInterface { async run(cloudRunnerStepState: CloudRunnerStepState) { @@ -21,41 +21,36 @@ export class BuildAutomationWorkflow implements WorkflowInterface { try { CloudRunnerLogger.log(`Cloud Runner is running standard build automation`); - core.startGroup('pre build steps'); + if (!CloudRunner.buildParameters.isCliMode) core.startGroup('pre build steps'); let output = ''; - if (CloudRunnerState.buildParams.preBuildSteps !== '') { - output += await CustomWorkflow.runCustomJob(CloudRunnerState.buildParams.preBuildSteps); + if (CloudRunner.buildParameters.preBuildSteps !== '') { + output += await CustomWorkflow.runCustomJob(CloudRunner.buildParameters.preBuildSteps); } - core.endGroup(); + if (!CloudRunner.buildParameters.isCliMode) core.endGroup(); CloudRunnerLogger.logWithTime('Configurable pre build step(s) time'); - core.startGroup('setup'); - output += await new SetupStep().run( - new CloudRunnerStepState( - 'alpine/git', - TaskParameterSerializer.readBuildEnvironmentVariables(), - CloudRunnerState.defaultSecrets, - ), - ); - core.endGroup(); - CloudRunnerLogger.logWithTime('Download repository step time'); + if (!CloudRunner.buildParameters.isCliMode) core.startGroup('build'); + CloudRunnerLogger.log(baseImage.toString()); + CloudRunnerLogger.logLine(` `); + CloudRunnerLogger.logLine('Starting build automation job'); - core.startGroup('build'); - output += await new BuildStep().run( - new CloudRunnerStepState( - baseImage, - TaskParameterSerializer.readBuildEnvironmentVariables(), - CloudRunnerState.defaultSecrets, - ), + output += await CloudRunner.Provider.runTask( + CloudRunner.buildParameters.buildGuid, + baseImage.toString(), + BuildAutomationWorkflow.BuildWorkflow, + `/${CloudRunnerFolders.buildVolumeFolder}`, + `/${CloudRunnerFolders.buildVolumeFolder}/`, + CloudRunner.cloudRunnerEnvironmentVariables, + CloudRunner.defaultSecrets, ); - core.endGroup(); + if (!CloudRunner.buildParameters.isCliMode) core.endGroup(); CloudRunnerLogger.logWithTime('Build time'); - core.startGroup('post build steps'); - if (CloudRunnerState.buildParams.postBuildSteps !== '') { - output += await CustomWorkflow.runCustomJob(CloudRunnerState.buildParams.postBuildSteps); + if (!CloudRunner.buildParameters.isCliMode) core.startGroup('post build steps'); + if (CloudRunner.buildParameters.postBuildSteps !== '') { + output += await CustomWorkflow.runCustomJob(CloudRunner.buildParameters.postBuildSteps); } - core.endGroup(); + if (!CloudRunner.buildParameters.isCliMode) core.endGroup(); CloudRunnerLogger.logWithTime('Configurable post build step(s) time'); CloudRunnerLogger.log(`Cloud Runner finished running standard build automation`); @@ -65,4 +60,62 @@ export class BuildAutomationWorkflow implements WorkflowInterface { throw error; } } + + private static get BuildWorkflow() { + const setupHooks = CloudRunnerBuildCommandProcessor.getHooks(CloudRunner.buildParameters.customJobHooks).filter( + (x) => x.step.includes(`setup`), + ); + const buildHooks = CloudRunnerBuildCommandProcessor.getHooks(CloudRunner.buildParameters.customJobHooks).filter( + (x) => x.step.includes(`build`), + ); + const builderPath = path.join(CloudRunnerFolders.builderPathAbsolute, 'dist', `index.js`).replace(/\\/g, `/`); + return `apt-get update > /dev/null + apt-get install -y zip tree npm git-lfs jq unzip git > /dev/null + npm install -g n > /dev/null + n stable > /dev/null + ${setupHooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '} + export GITHUB_WORKSPACE="${CloudRunnerFolders.repoPathAbsolute.replace(/\\/g, `/`)}" + ${BuildAutomationWorkflow.setupCommands(builderPath)} + ${setupHooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '} + ${buildHooks.filter((x) => x.hook.includes(`before`)).map((x) => x.commands) || ' '} + ${BuildAutomationWorkflow.BuildCommands(builderPath, CloudRunner.buildParameters.buildGuid)} + ${buildHooks.filter((x) => x.hook.includes(`after`)).map((x) => x.commands) || ' '}`; + } + + private static setupCommands(builderPath) { + return `export GIT_DISCOVERY_ACROSS_FILESYSTEM=1 + echo "game ci cloud runner clone" + mkdir -p ${CloudRunnerFolders.builderPathAbsolute.replace(/\\/g, `/`)} + git clone -q -b ${CloudRunner.buildParameters.cloudRunnerBranch} ${ + CloudRunnerFolders.unityBuilderRepoUrl + } "${CloudRunnerFolders.builderPathAbsolute.replace(/\\/g, `/`)}" + chmod +x ${builderPath} + echo "game ci cloud runner bootstrap" + node ${builderPath} -m remote-cli`; + } + + private static BuildCommands(builderPath, guid) { + const linuxCacheFolder = CloudRunnerFolders.cacheFolderFull.replace(/\\/g, `/`); + const distFolder = path.join(CloudRunnerFolders.builderPathAbsolute, 'dist'); + const ubuntuPlatformsFolder = path.join(CloudRunnerFolders.builderPathAbsolute, 'dist', 'platforms', 'ubuntu'); + return `echo "game ci cloud runner init" + mkdir -p ${`${CloudRunnerFolders.projectBuildFolderAbsolute}/build`.replace(/\\/g, `/`)} + cd ${CloudRunnerFolders.projectPathAbsolute} + cp -r "${path.join(distFolder, 'default-build-script').replace(/\\/g, `/`)}" "/UnityBuilderAction" + cp -r "${path.join(ubuntuPlatformsFolder, 'entrypoint.sh').replace(/\\/g, `/`)}" "/entrypoint.sh" + cp -r "${path.join(ubuntuPlatformsFolder, 'steps').replace(/\\/g, `/`)}" "/steps" + chmod -R +x "/entrypoint.sh" + chmod -R +x "/steps" + echo "game ci cloud runner start" + /entrypoint.sh + echo "game ci cloud runner push library to cache" + chmod +x ${builderPath} + node ${builderPath} -m cache-push --cachePushFrom ${ + CloudRunnerFolders.libraryFolderAbsolute + } --artifactName lib-${guid} --cachePushTo ${linuxCacheFolder}/Library + echo "game ci cloud runner push build to cache" + node ${builderPath} -m cache-push --cachePushFrom ${ + CloudRunnerFolders.projectBuildFolderAbsolute + } --artifactName build-${guid} --cachePushTo ${`${linuxCacheFolder}/build`.replace(/\\/g, `/`)}`; + } } diff --git a/src/model/cloud-runner/workflows/custom-workflow.ts b/src/model/cloud-runner/workflows/custom-workflow.ts index 996b0cb5..1da7533c 100644 --- a/src/model/cloud-runner/workflows/custom-workflow.ts +++ b/src/model/cloud-runner/workflows/custom-workflow.ts @@ -1,44 +1,43 @@ import CloudRunnerLogger from '../services/cloud-runner-logger'; import CloudRunnerSecret from '../services/cloud-runner-secret'; -import { CloudRunnerState } from '../state/cloud-runner-state'; +import { CloudRunnerFolders } from '../services/cloud-runner-folders'; import YAML from 'yaml'; -import { Input } from '../..'; -import { TaskParameterSerializer } from '../services/task-parameter-serializer'; +import { CloudRunner, Input } from '../..'; export class CustomWorkflow { public static async runCustomJob(buildSteps) { try { CloudRunnerLogger.log(`Cloud Runner is running in custom job mode`); - if (Input.cloudRunnerTests) { + if (CloudRunner.buildParameters.cloudRunnerIntegrationTests) { CloudRunnerLogger.log(`Parsing build steps: ${buildSteps}`); } try { buildSteps = YAML.parse(buildSteps); - let output = ''; - for (const step of buildSteps) { - const stepSecrets: CloudRunnerSecret[] = step.secrets.map((x) => { - const secret: CloudRunnerSecret = { - ParameterKey: x.name, - EnvironmentVariable: Input.ToEnvVarFormat(x.name), - ParameterValue: x.value, - }; - return secret; - }); - output += await CloudRunnerState.CloudRunnerProviderPlatform.runTask( - CloudRunnerState.buildParams.buildGuid, - step['image'], - step['commands'], - `/${CloudRunnerState.buildVolumeFolder}`, - `/${CloudRunnerState.buildVolumeFolder}/`, - TaskParameterSerializer.readBuildEnvironmentVariables(), - [...CloudRunnerState.defaultSecrets, ...stepSecrets], - ); - } - return output; } catch (error) { CloudRunnerLogger.log(`failed to parse a custom job "${buildSteps}"`); throw error; } + let output = ''; + for (const step of buildSteps) { + const stepSecrets: CloudRunnerSecret[] = step.secrets.map((x) => { + const secret: CloudRunnerSecret = { + ParameterKey: x.name, + EnvironmentVariable: Input.ToEnvVarFormat(x.name), + ParameterValue: x.value, + }; + return secret; + }); + output += await CloudRunner.Provider.runTask( + CloudRunner.buildParameters.buildGuid, + step['image'], + step['commands'], + `/${CloudRunnerFolders.buildVolumeFolder}`, + `/${CloudRunnerFolders.buildVolumeFolder}/`, + CloudRunner.cloudRunnerEnvironmentVariables, + [...CloudRunner.defaultSecrets, ...stepSecrets], + ); + } + return output; } catch (error) { throw error; } diff --git a/src/model/cloud-runner/workflows/workflow-composition-root.ts b/src/model/cloud-runner/workflows/workflow-composition-root.ts index f4b01fdd..98f8b028 100644 --- a/src/model/cloud-runner/workflows/workflow-composition-root.ts +++ b/src/model/cloud-runner/workflows/workflow-composition-root.ts @@ -1,10 +1,8 @@ -import { CloudRunnerState } from '../state/cloud-runner-state'; -import { CloudRunnerStepState } from '../state/cloud-runner-step-state'; +import { CloudRunnerStepState } from '../cloud-runner-step-state'; import { CustomWorkflow } from './custom-workflow'; import { WorkflowInterface } from './workflow-interface'; import { BuildAutomationWorkflow } from './build-automation-workflow'; -import { TaskParameterSerializer } from '../services/task-parameter-serializer'; -import { SetupStep } from '../steps/setup-step'; +import CloudRunner from '../cloud-runner'; export class WorkflowCompositionRoot implements WorkflowInterface { async run(cloudRunnerStepState: CloudRunnerStepState) { @@ -17,23 +15,11 @@ export class WorkflowCompositionRoot implements WorkflowInterface { private static async runJob(baseImage: any) { try { - if (CloudRunnerState.buildParams.customJob === `setup`) { - return await new SetupStep().run( - new CloudRunnerStepState( - baseImage, - TaskParameterSerializer.readBuildEnvironmentVariables(), - CloudRunnerState.defaultSecrets, - ), - ); - } else if (CloudRunnerState.buildParams.customJob !== '') { - return await CustomWorkflow.runCustomJob(CloudRunnerState.buildParams.customJob); + if (CloudRunner.buildParameters.customJob !== '') { + return await CustomWorkflow.runCustomJob(CloudRunner.buildParameters.customJob); } return await new BuildAutomationWorkflow().run( - new CloudRunnerStepState( - baseImage, - TaskParameterSerializer.readBuildEnvironmentVariables(), - CloudRunnerState.defaultSecrets, - ), + new CloudRunnerStepState(baseImage, CloudRunner.cloudRunnerEnvironmentVariables, CloudRunner.defaultSecrets), ); } catch (error) { throw error; diff --git a/src/model/cloud-runner/workflows/workflow-interface.ts b/src/model/cloud-runner/workflows/workflow-interface.ts index 0192a60e..3e8763ed 100644 --- a/src/model/cloud-runner/workflows/workflow-interface.ts +++ b/src/model/cloud-runner/workflows/workflow-interface.ts @@ -1,4 +1,4 @@ -import { CloudRunnerStepState } from '../state/cloud-runner-step-state'; +import { CloudRunnerStepState } from '../cloud-runner-step-state'; export interface WorkflowInterface { run( diff --git a/src/model/image-tag.ts b/src/model/image-tag.ts index ae4e7508..15a6320f 100644 --- a/src/model/image-tag.ts +++ b/src/model/image-tag.ts @@ -1,9 +1,11 @@ import Platform from './platform'; + import BuildParameters from './build-parameters'; class ImageTag { public repository: string; public name: string; + public cloudRunnerBuilderPlatform!: string | undefined; public editorVersion: string; public targetPlatform: any; public builderPlatform: string; @@ -12,7 +14,7 @@ class ImageTag { public imagePlatformPrefix: string; constructor(imageProperties: Partial) { - const { editorVersion = '2019.2.11f1', targetPlatform, customImage } = imageProperties; + const { editorVersion = '2019.2.11f1', targetPlatform, customImage, cloudRunnerBuilderPlatform } = imageProperties; if (!ImageTag.versionPattern.test(editorVersion)) { throw new Error(`Invalid version "${editorVersion}".`); @@ -27,8 +29,12 @@ class ImageTag { this.name = 'editor'; this.editorVersion = editorVersion; this.targetPlatform = targetPlatform; + this.cloudRunnerBuilderPlatform = cloudRunnerBuilderPlatform; + const isCloudRunnerLocal = cloudRunnerBuilderPlatform === 'local' || cloudRunnerBuilderPlatform === undefined; this.builderPlatform = ImageTag.getTargetPlatformToTargetPlatformSuffixMap(targetPlatform, editorVersion); - this.imagePlatformPrefix = ImageTag.getImagePlatformPrefixes(process.platform); + this.imagePlatformPrefix = ImageTag.getImagePlatformPrefixes( + isCloudRunnerLocal ? process.platform : cloudRunnerBuilderPlatform, + ); this.imageRollingVersion = 1; // will automatically roll to the latest non-breaking version. } @@ -155,5 +161,4 @@ class ImageTag { return `${image}:${tag}`; // '0' here represents the docker repo version } } - export default ImageTag; diff --git a/src/model/input-readers/generic-input-reader.ts b/src/model/input-readers/generic-input-reader.ts new file mode 100644 index 00000000..0bd84e11 --- /dev/null +++ b/src/model/input-readers/generic-input-reader.ts @@ -0,0 +1,7 @@ +import { CloudRunnerSystem } from '../cloud-runner/services/cloud-runner-system'; + +export class GenericInputReader { + public static async Run(command) { + return await CloudRunnerSystem.Run(command, false, true); + } +} diff --git a/src/model/input-readers/git-repo.ts b/src/model/input-readers/git-repo.ts index bc6ab9fc..2ba87457 100644 --- a/src/model/input-readers/git-repo.ts +++ b/src/model/input-readers/git-repo.ts @@ -1,22 +1,22 @@ import { assert } from 'console'; -import System from '../system'; import fs from 'fs'; -import { CloudRunnerSystem } from '../cli/remote-client/remote-client-services/cloud-runner-system'; +import { CloudRunnerSystem } from '../cloud-runner/services/cloud-runner-system'; +import CloudRunnerLogger from '../cloud-runner/services/cloud-runner-logger'; export class GitRepoReader { - static GetSha() { - return ''; - } - public static async GetRemote() { - return (await CloudRunnerSystem.Run(`git remote -v`)) - .split(' ')[1] - .split('https://github.com/')[1] - .split('.git')[0]; + assert(fs.existsSync(`.git`)); + const value = (await CloudRunnerSystem.Run(`git remote -v`, false, true)).replace(/ /g, ``); + CloudRunnerLogger.log(`value ${value}`); + assert(value.includes('github.com')); + return value.split('github.com/')[1].split('.git')[0]; } public static async GetBranch() { assert(fs.existsSync(`.git`)); - return (await System.run(`git branch`, [], {}, false)).split('*')[1].split(`\n`)[0].replace(/ /g, ``); + return (await CloudRunnerSystem.Run(`git branch --show-current`, false, true)) + .split('\n')[0] + .replace(/ /g, ``) + .replace('/head', ''); } } diff --git a/src/model/input-readers/github-cli.ts b/src/model/input-readers/github-cli.ts index 5b56eb29..0f5b77ec 100644 --- a/src/model/input-readers/github-cli.ts +++ b/src/model/input-readers/github-cli.ts @@ -1,14 +1,14 @@ -import { CloudRunnerSystem } from '../cli/remote-client/remote-client-services/cloud-runner-system'; +import { CloudRunnerSystem } from '../cloud-runner/services/cloud-runner-system'; import * as core from '@actions/core'; export class GithubCliReader { static async GetGitHubAuthToken() { try { - const authStatus = await CloudRunnerSystem.Run(`gh auth status`, true); + const authStatus = await CloudRunnerSystem.Run(`gh auth status`, true, true); if (authStatus.includes('You are not logged') || authStatus === '') { return ''; } - return (await CloudRunnerSystem.Run(`gh auth status -t`)) + return (await CloudRunnerSystem.Run(`gh auth status -t`, false, true)) .split(`Token: `)[1] .replace(/ /g, '') .replace(/\n/g, ''); diff --git a/src/model/input.ts b/src/model/input.ts index 2c52abd9..2be9b92d 100644 --- a/src/model/input.ts +++ b/src/model/input.ts @@ -1,7 +1,7 @@ import fs from 'fs'; import path from 'path'; -import { GitRepoReader } from './input-readers/git-repo'; -import { GithubCliReader } from './input-readers/github-cli'; +import { Cli } from './cli/cli'; +import CloudRunnerQueryOverride from './cloud-runner/services/cloud-runner-query-override'; import Platform from './platform'; const core = require('@actions/core'); @@ -14,64 +14,69 @@ const core = require('@actions/core'); * Todo: rename to UserInput and remove anything that is not direct input from the user / ci workflow */ class Input { - public static cliOptions; public static githubInputEnabled: boolean = true; - // also enabled debug logging for cloud runner - static get cloudRunnerTests(): boolean { - return Input.getInput(`cloudRunnerTests`) || Input.getInput(`CloudRunnerTests`) || false; - } + public static getInput(query) { + if (Input.githubInputEnabled) { + const coreInput = core.getInput(query); + if (coreInput && coreInput !== '') { + return coreInput; + } + } + const alternativeQuery = Input.ToEnvVarFormat(query); - private static getInput(query) { - const coreInput = core.getInput(query); - if (Input.githubInputEnabled && coreInput && coreInput !== '') { - return coreInput; + // query input sources + if (Cli.query(query, alternativeQuery)) { + return Cli.query(query, alternativeQuery); } - return Input.cliOptions !== undefined && Input.cliOptions[query] !== undefined - ? Input.cliOptions[query] - : process.env[query] !== undefined - ? process.env[query] - : process.env[Input.ToEnvVarFormat(query)] - ? process.env[Input.ToEnvVarFormat(query)] - : ''; + if (CloudRunnerQueryOverride.query(query, alternativeQuery)) { + return CloudRunnerQueryOverride.query(query, alternativeQuery); + } + + if (process.env[query] !== undefined) { + return process.env[query]; + } + + if (alternativeQuery !== query && process.env[alternativeQuery] !== undefined) { + return process.env[alternativeQuery]; + } + + return; } static get region(): string { return Input.getInput('region') || 'eu-west-2'; } - static async githubRepo() { - return ( - Input.getInput('GITHUB_REPOSITORY') || - Input.getInput('GITHUB_REPO') || - // todo - move this to some class specific for determining additional information - (await GitRepoReader.GetRemote()) || - 'game-ci/unity-builder' - ); + static get githubRepo() { + return Input.getInput('GITHUB_REPOSITORY') || Input.getInput('GITHUB_REPO') || undefined; } - - static async branch() { - if (await GitRepoReader.GetBranch()) { - // todo - move this to some class specific for determining additional information - return await GitRepoReader.GetBranch(); - } else if (Input.getInput(`GITHUB_REF`)) { - return Input.getInput(`GITHUB_REF`).replace('refs/', '').replace(`head/`, ''); + static get branch() { + if (Input.getInput(`GITHUB_REF`)) { + return Input.getInput(`GITHUB_REF`).replace('refs/', '').replace(`head/`, '').replace(`heads/`, ''); } else if (Input.getInput('branch')) { return Input.getInput('branch'); } else { - return 'main'; + return ''; } } + static get cloudRunnerBuilderPlatform() { + const input = Input.getInput('cloudRunnerBuilderPlatform'); + if (input) { + return input; + } + if (Input.cloudRunnerCluster !== 'local') { + return 'linux'; + } + return; + } static get gitSha() { if (Input.getInput(`GITHUB_SHA`)) { return Input.getInput(`GITHUB_SHA`); } else if (Input.getInput(`GitSHA`)) { return Input.getInput(`GitSHA`); - } else if (GitRepoReader.GetSha()) { - // todo - move this to some class specific for determining additional information - return GitRepoReader.GetSha(); } } @@ -88,7 +93,7 @@ class Input { } static get customImage() { - return Input.getInput('customImage'); + return Input.getInput('customImage') || ''; } static get projectPath() { @@ -165,8 +170,36 @@ class Input { return Input.getInput('sshAgent') || ''; } - static async gitPrivateToken() { - return Input.getInput('gitPrivateToken') || (await Input.githubToken()); + static get gitPrivateToken() { + return core.getInput('gitPrivateToken') || false; + } + + static get customJob() { + return Input.getInput('customJob') || ''; + } + + static customJobHooks() { + return Input.getInput('customJobHooks') || ''; + } + + static cachePushOverrideCommand() { + return Input.getInput('cachePushOverrideCommand') || ''; + } + + static cachePullOverrideCommand() { + return Input.getInput('cachePullOverrideCommand') || ''; + } + + static readInputFromOverrideList() { + return Input.getInput('readInputFromOverrideList') || ''; + } + + static readInputOverrideCommand() { + return Input.getInput('readInputOverrideCommand') || ''; + } + + static get cloudRunnerBranch() { + return Input.getInput('cloudRunnerBranch') || 'cloud-runner-develop'; } static get chownFilesTo() { @@ -187,15 +220,14 @@ class Input { return Input.getInput('preBuildSteps') || ''; } - static get customJob() { - return Input.getInput('customJob') || ''; - } - static get awsBaseStackName() { return Input.getInput('awsBaseStackName') || 'game-ci'; } static get cloudRunnerCluster() { + if (Cli.isCliMode) { + return Input.getInput('cloudRunnerCluster') || 'aws'; + } return Input.getInput('cloudRunnerCluster') || 'local'; } @@ -207,11 +239,6 @@ class Input { return Input.getInput('cloudRunnerMemory') || '750M'; } - static async githubToken() { - // Todo - move GitHubCLI out of the simple input class. It is in fact not input from the user. - return Input.getInput('githubToken') || (await GithubCliReader.GetGitHubAuthToken()) || ''; - } - static get kubeConfig() { return Input.getInput('kubeConfig') || ''; } @@ -224,7 +251,30 @@ class Input { return Input.getInput('kubeVolumeSize') || '5Gi'; } + static get kubeStorageClass(): string { + return Input.getInput('kubeStorageClass') || ''; + } + + static get checkDependencyHealthOverride(): string { + return Input.getInput('checkDependencyHealthOverride') || ''; + } + + static get startDependenciesOverride(): string { + return Input.getInput('startDependenciesOverride') || ''; + } + + static get cacheKey(): string { + return Input.getInput('cacheKey') || Input.branch; + } + + static get cloudRunnerTests(): boolean { + return Input.getInput(`cloudRunnerTests`) || false; + } + public static ToEnvVarFormat(input: string) { + if (input.toUpperCase() === input) { + return input; + } return input .replace(/([A-Z])/g, ' $1') .trim() diff --git a/yarn.lock b/yarn.lock index 7d6c5fa5..d9f157e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1157,7 +1157,7 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@^17.0.21": +"@types/node@*": version "17.0.21" resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.21.tgz#864b987c0c68d07b4345845c3e63b75edd143644" integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ== @@ -1167,6 +1167,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== +"@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/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz" @@ -5366,6 +5371,11 @@ uuid@^3.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz"