From a75b22afdaaab59ce47ec02b7aec06eeb53759f9 Mon Sep 17 00:00:00 2001 From: Alireza Assadzadeh Date: Mon, 31 Aug 2020 13:26:02 -0400 Subject: [PATCH] Update to version v1.0.0 --- .github/ISSUE_TEMPLATE/bug_report.md | 42 + .github/ISSUE_TEMPLATE/feature_request.md | 17 + .github/PULL_REQUEST_TEMPLATE.md | 5 + CHANGELOG.md | 9 + CODE_OF_CONDUCT.md | 4 +- CONTRIBUTING.md | 6 +- LICENSE => LICENSE.txt | 2 +- NOTICE | 1 - NOTICE.txt | 19 + README.md | 115 +- architecture-diagram.png | Bin 0 -> 268415 bytes deployment/build-s3-dist.sh | 92 + ...rofiles-export-reference-architecture.yaml | 895 +++ deployment/run-unit-tests.sh | 58 + deployment/stack-set-template.yaml | 2217 ++++++++ .../custom-resources/check-stackset-status.js | 123 + .../custom-resources/global-table-checker.js | 109 + .../custom-resources/global-table-creator.js | 125 + source/custom-resources/package-lock.json | 4919 ++++++++++++++++ source/custom-resources/package.json | 28 + source/custom-resources/solution-constants.js | 45 + source/custom-resources/stack-checker.js | 117 + source/custom-resources/stackset-constants.js | 35 + source/custom-resources/stackset-manager.js | 198 + .../test/check-stackset-status.spec.js | 282 + .../test/global-table-checker.spec.js | 251 + .../test/global-table-creator.spec.js | 197 + .../test/solution-constants.spec.js | 77 + .../test/stack-checker.spec.js | 330 ++ .../test/stackset-constants.spec.js | 92 + .../test/stackset-manager.spec.js | 226 + .../utils/custom-resource-helper-functions.js | 83 + source/utils/helper-functions.js | 111 + source/utils/metrics.js | 42 + source/utils/package-lock.json | 4729 ++++++++++++++++ source/utils/package.json | 22 + .../custom-resource-helper-functions.spec.js | 145 + source/utils/test/helper-functions.spec.js | 109 + source/utils/test/metrics.spec.js | 53 + .../check-state-machine-executions.js | 33 + .../workflow-common/check-workflow-queues.js | 58 + source/workflow-common/message-broker.js | 174 + source/workflow-common/package-lock.json | 4781 ++++++++++++++++ source/workflow-common/package.json | 25 + .../check-state-machine-executions.spec.js | 113 + .../test/check-workflow-queues.spec.js | 135 + .../test/message-broker.spec.js | 227 + .../workflow-export/backup-table-cleanup.js | 197 + .../workflow-export/check-user-pool-config.js | 39 + source/workflow-export/export-group.js | 56 + .../workflow-export/export-users-in-group.js | 175 + source/workflow-export/export-users.js | 237 + source/workflow-export/list-groups.js | 59 + source/workflow-export/package-lock.json | 4823 ++++++++++++++++ source/workflow-export/package.json | 26 + .../test/backup-table-cleanup.spec.js | 265 + .../test/check-user-pool-config.spec.js | 117 + .../workflow-export/test/export-group.spec.js | 57 + .../test/export-users-in-group.spec.js | 187 + .../workflow-export/test/export-users.spec.js | 475 ++ .../workflow-export/test/list-groups.spec.js | 134 + source/workflow-import/check-new-user-pool.js | 56 + source/workflow-import/import-users.js | 333 ++ source/workflow-import/package-lock.json | 4926 +++++++++++++++++ source/workflow-import/package.json | 27 + source/workflow-import/scan-table.js | 165 + .../test/check-new-user-pool.spec.js | 132 + .../workflow-import/test/import-users.spec.js | 447 ++ .../workflow-import/test/scan-table.spec.js | 348 ++ .../test/update-new-users.spec.js | 373 ++ source/workflow-import/update-new-users.js | 173 + 71 files changed, 35289 insertions(+), 14 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 CHANGELOG.md rename LICENSE => LICENSE.txt (99%) delete mode 100644 NOTICE create mode 100644 NOTICE.txt create mode 100644 architecture-diagram.png create mode 100755 deployment/build-s3-dist.sh create mode 100644 deployment/cognito-user-profiles-export-reference-architecture.yaml create mode 100755 deployment/run-unit-tests.sh create mode 100644 deployment/stack-set-template.yaml create mode 100644 source/custom-resources/check-stackset-status.js create mode 100644 source/custom-resources/global-table-checker.js create mode 100644 source/custom-resources/global-table-creator.js create mode 100644 source/custom-resources/package-lock.json create mode 100644 source/custom-resources/package.json create mode 100644 source/custom-resources/solution-constants.js create mode 100644 source/custom-resources/stack-checker.js create mode 100644 source/custom-resources/stackset-constants.js create mode 100644 source/custom-resources/stackset-manager.js create mode 100644 source/custom-resources/test/check-stackset-status.spec.js create mode 100644 source/custom-resources/test/global-table-checker.spec.js create mode 100644 source/custom-resources/test/global-table-creator.spec.js create mode 100644 source/custom-resources/test/solution-constants.spec.js create mode 100644 source/custom-resources/test/stack-checker.spec.js create mode 100644 source/custom-resources/test/stackset-constants.spec.js create mode 100644 source/custom-resources/test/stackset-manager.spec.js create mode 100644 source/utils/custom-resource-helper-functions.js create mode 100644 source/utils/helper-functions.js create mode 100644 source/utils/metrics.js create mode 100644 source/utils/package-lock.json create mode 100644 source/utils/package.json create mode 100644 source/utils/test/custom-resource-helper-functions.spec.js create mode 100644 source/utils/test/helper-functions.spec.js create mode 100644 source/utils/test/metrics.spec.js create mode 100644 source/workflow-common/check-state-machine-executions.js create mode 100644 source/workflow-common/check-workflow-queues.js create mode 100644 source/workflow-common/message-broker.js create mode 100644 source/workflow-common/package-lock.json create mode 100644 source/workflow-common/package.json create mode 100644 source/workflow-common/test/check-state-machine-executions.spec.js create mode 100644 source/workflow-common/test/check-workflow-queues.spec.js create mode 100644 source/workflow-common/test/message-broker.spec.js create mode 100644 source/workflow-export/backup-table-cleanup.js create mode 100644 source/workflow-export/check-user-pool-config.js create mode 100644 source/workflow-export/export-group.js create mode 100644 source/workflow-export/export-users-in-group.js create mode 100644 source/workflow-export/export-users.js create mode 100644 source/workflow-export/list-groups.js create mode 100644 source/workflow-export/package-lock.json create mode 100644 source/workflow-export/package.json create mode 100644 source/workflow-export/test/backup-table-cleanup.spec.js create mode 100644 source/workflow-export/test/check-user-pool-config.spec.js create mode 100644 source/workflow-export/test/export-group.spec.js create mode 100644 source/workflow-export/test/export-users-in-group.spec.js create mode 100644 source/workflow-export/test/export-users.spec.js create mode 100644 source/workflow-export/test/list-groups.spec.js create mode 100644 source/workflow-import/check-new-user-pool.js create mode 100644 source/workflow-import/import-users.js create mode 100644 source/workflow-import/package-lock.json create mode 100644 source/workflow-import/package.json create mode 100644 source/workflow-import/scan-table.js create mode 100644 source/workflow-import/test/check-new-user-pool.spec.js create mode 100644 source/workflow-import/test/import-users.spec.js create mode 100644 source/workflow-import/test/scan-table.spec.js create mode 100644 source/workflow-import/test/update-new-users.spec.js create mode 100644 source/workflow-import/update-new-users.js diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..c48a607 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,42 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior. + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Please complete the following information about the solution:** +- [ ] Version: [e.g. v1.0.0] + +To get the version of the solution, you can look at the description of the created CloudFormation stack. For example, "_(SO0126) - Cognito User Profiles Export Reference Architecture. Version **v1.0.0**_". If the description does not contain the version information, you can look at the mappings section of the template: + +```yaml +Mappings: + SourceCode: + General: + S3Bucket: "solutions" + KeyPrefix: "cognito-user-profiles-export-reference-architecture/v1.0.0" +``` + +- [ ] Region: [e.g. us-east-1] +- [ ] Was the solution modified from the version published on this repository? +- [ ] If the answer to the previous question was yes, are the changes available on GitHub? +- [ ] Have you checked your [service quotas](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html) for the sevices this solution uses? +- [ ] Were there any errors in the CloudWatch Logs? + +**Screenshots** +If applicable, add screenshots to help explain your problem (please **DO NOT include sensitive information**). + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..d3d209f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this solution +title: '' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the feature you'd like** +A clear and concise description of what you want to happen. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..de50e4d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,5 @@ +*Issue #, if available:* + +*Description of changes:* + +By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..02d203d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# Change Log +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.0.0] - 2020-08-31 +### Added +- Launch Cognito User Profiles Export Reference Architecture \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 5b627cf..3b64466 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,4 +1,4 @@ ## Code of Conduct -This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). -For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact +This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). +For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact opensource-codeofconduct@amazon.com with any additional questions or comments. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 914e074..1837f9d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ information to effectively respond to your bug report or contribution. We welcome you to use the GitHub issue tracker to report bugs or suggest features. -When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already +When filing an issue, please check [existing open](https://github.com/awslabs/cognito-user-profiles-export-reference-architecture/issues), or [recently closed](https://github.com/awslabs/cognito-user-profiles-export-reference-architecture/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: * A reproducible test case or series of steps @@ -41,7 +41,7 @@ GitHub provides additional document on [forking a repository](https://help.githu ## Finding contributions to work on -Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. +Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels ((enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/awslabs/cognito-user-profiles-export-reference-architecture/labels/help%20wanted) issues is a great place to start. ## Code of Conduct @@ -56,6 +56,6 @@ If you discover a potential security issue in this project we ask that you notif ## Licensing -See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. +See the [LICENSE](https://github.com/awslabs/cognito-user-profiles-export-reference-architecture/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. diff --git a/LICENSE b/LICENSE.txt similarity index 99% rename from LICENSE rename to LICENSE.txt index 67db858..19dc35b 100644 --- a/LICENSE +++ b/LICENSE.txt @@ -172,4 +172,4 @@ of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. + of your accepting any such warranty or additional liability. \ No newline at end of file diff --git a/NOTICE b/NOTICE deleted file mode 100644 index b8d0d46..0000000 --- a/NOTICE +++ /dev/null @@ -1 +0,0 @@ -Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/NOTICE.txt b/NOTICE.txt new file mode 100644 index 0000000..d17a10e --- /dev/null +++ b/NOTICE.txt @@ -0,0 +1,19 @@ +Cognito User Profiles Export Reference Architecture +Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. +Licensed under the Apache License Version 2.0 (the "License"). You may not use this file except +in compliance with the License. A copy of the License is located at http://www.apache.org/licenses/ +or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the License for the +specific language governing permissions and limitations under the License. + +********************** +THIRD PARTY COMPONENTS +********************** +This software includes third party software subject to the following copyrights: + +aws-sdk under the Apache License Version 2.0 +axios under the Massachusetts Institute of Technology (MIT) license +axios-mock-adapter under the Massachusetts Institute of Technology (MIT) license +jest under the Massachusetts Institute of Technology (MIT) license +moment under the Massachusetts Institute of Technology (MIT) license +uuid under the Massachusetts Institute of Technology (MIT) license \ No newline at end of file diff --git a/README.md b/README.md index 8f46b7c..1aac2e9 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,114 @@ -## My Project +# Cognito User Profiles Export Reference Architecture +This solution uses an [AWS Step Functions](https://aws.amazon.com/step-functions/) workflow (`ExportWorkflow`) to periodically export user profiles, groups, and group membership details from your user pool to an [Amazon DynamoDB global table](https://aws.amazon.com/dynamodb/global-tables/) with automatic, asynchronous replication to a backup Region for added resiliency. This solution is designed to provide a framework for exporting user profile and group information from your user pool, allowing you to focus on extending the solution’s functionality rather than managing the underlying infrastructure operation. -TODO: Fill this README out! +This solution’s `ImportWorkflow` Step Functions workflow can be used to populate a new, empty user pool with data from the global table, allowing you to easily recover user profiles, groups, and group memberships. The `ImportWorkflow` Step Functions workflow can be run in either the primary or backup Region. -Be sure to: +> **_NOTE:_** Some data loss will result when running the `ImportWorkflow` Step Functions workflow because this solution runs periodically. For example, if you schedule exports daily, you will lose up to a day’s worth of user pool updates depending on when the `ImportWorkflow` Step Functions workflow was run. -* Change the title in this README -* Edit your repository description on GitHub +For more information and a detailed deployment guide visit the [solution home page](https://aws.amazon.com/solutions/implementations/cognito-user-profiles-export-reference-architecture/). -## License +## On This Page +- [Architecture Overview](#architecture-overview) +- [Getting Started](#getting-started) +- [File Structure](#file-structure) +- [License](#license) + +## Architecture Overview + +![Architecture](architecture-diagram.png) + +## Getting Started +### 1. Prerequsites +The following procedures assumes that all of the OS-level configuration has been completed. They are: +- [AWS Command Line Interface](https://aws.amazon.com/cli/) +- Node.js 12.x + +The Cognito User Profiles Export Reference Architecture is developed with Node.js for the microservices that run in AWS Lambda. The latest version has been tested with Node.js 12.x. + +### 2. Clone the Cognito User Profiles Export Reference Architecture repository +Clone the ```cognito-user-profiles-export-reference-architecture``` GitHub repositroy, then make the desired code changes. + +```bash +git clone https://github.com/awslabs/cognito-user-profiles-export-reference-architecture.git +``` + +### 3. Run unit tests +* Next, run unit tests to make sure added customization passes the tests. +```bash +cd ./deployment +chmod +x ./run-unit-tests.sh +./run-unit-tests.sh +``` -This project is licensed under the Apache-2.0 License. +### 4. Declare environment variables +```bash +export REGION=aws-region-code # the AWS region to launch the solution (e.g. us-east-1) +export DIST_OUTPUT_BUCKET=my-bucket-name # bucket where customized code will reside +export SOLUTION_NAME=my-solution-name +export VERSION=my-version # version number for the customized code +``` + +### 5. Create an Amazon S3 bucket +The AWS CloudFormation template is configured to pull the AWS Lambda deployment packages from Amazon S3 bucket in the region the template is being launched in. Create a bucket in the desitred region name appended to the name of the bucket. _Note:_ you must have the AWS Command Line Interface installed. +```bash +aws s3 mb s3://$DIST_OUTPUT_BUCKET-$REGION --region $REGION +``` + +### 6. Build the Cognito User Profiles Export Reference Architecture for deployment +```bash +chmod +x ./build-s3-dist.sh +./build-s3-dist.sh $DIST_OUTPUT_BUCKET $SOLUTION_NAME $VERSION +``` + +### 7. Upload deployment assets to your Amazon S3 bucket +* Deploy the distributable to an Amazon S3 bucket in your account. _Note:_ you must have the AWS Command Line Interface installed. +```bash +aws s3 cp ./regional-s3-assets/ s3://$DIST_OUTPUT_BUCKET-$REGION/$SOLUTION_NAME/$VERSION/ --recursive --acl bucket-owner-full-control +``` + +### 8. Launch the Cognito User Profiles Export Reference Architecture +- Get the link of cognito-user-profiles-export-reference-architecture.template uploaded to your Amazon S3 bucket. +- Deploy the Cognito User Profiles Export Reference Architecture to your account by launching a new AWS CloudFormation stack using the S3 link of cognito-user-profiles-export-reference-architecture.template. + +## File Structure +``` +|- deployment/ + |- cognito-user-profiles-export-reference-architecture.yaml [ solution CloudFormation deployment template ] + |- stack-set-template.yaml [ CloudFormation template for the StackSet that is deployed in each region ] + |- build-s3-dist.sh [ shell script for packaging distribution assets ] + |- run-unit-tests.sh [ shell script for executing unit tests ] +|- source/ + |- custom-resources/ + |- check-stackset-status.js [ Checks the status of the solution's StackSets and when ready, responds to CloudFormation ] + |- global-table-checker.js [ Checks the status of the Backup Table replica and when active, response to CloudFormation ] + |- global-table-creator.js [ Adds a replica to the Backup Table in the Secondary Region ] + |- solution-constants.js [ Generates values to be used within the solution ] + |- stack-checker.js [ Custom Resource that checks to see if the current stack update is supported ] + |- stackset-constants.js [ Retrieves solutions constants from SSM parameter store so they can be used within the StackSet instance ] + |- stackset-manager.js [ Manages the solution's StackSet during solution create/update/deletes ] + |- utils/ + |- custom-resource-helper-functions.js [ Exports common functions that can be used within custom resource lambda functions ] + |- helper-functions.js [ Exports utility functions to be used throughout the solution ] + |- metrics.js [ Client for sending anonymous operational metrics ] + |- workflow-common/ + |- check-state-machine-executions.js [ Checks whether a state machine has multiple executions running ] + |- check-workflow-queues.js [ Checks whether the SQS queues used by the workflow are empty prior to proceeding ] + |- message-broker.js [ Publishes info and error messages to the solution's SNS topic and if enabled, sends anonymous operational metrics ] + |- workflow-export/ + |- backup-table-cleanup.js [ Cleans up the Backup Table by identifying items that were not updated during the most recent export and removing them ] + |- check-user-pool-config.js [ Checks the configuration of the primary user pool to ensure it is supported by the solution ] + |- export-group.js [ Exports the supplied group name to the backup table ] + |- export-users.js [ Exports user profiles to the backup table ] + |- export-users-in-group.js [ Exports group memberships to the backup table ] + |- list-groups.js [ Lists group in a user pool and returns group details so they can be processed by the Export Workflow ] + |- workflow-import/ + |- check-new-user-pool.js [ Checks the new user pool to ensure it has no users or groups ] + |- import-users.js [ Imports users into the new user pool ] + |- scan-table.js [ Scans the backup table and queues items for the Import Workflow ] + |- update-new-users.js [ Updates users that have been imported to the new user pool ] +``` + +## License +Cognito User Profiles Export Reference Architecture is distributed under the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0). +See [LICENSE](./LICENSE.txt) and [NOTICE](./NOTICE.txt) for more information. \ No newline at end of file diff --git a/architecture-diagram.png b/architecture-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..0ca001eb8a4e3ea3a97f268052385eb057a9df6d GIT binary patch literal 268415 zcmbq*cOcY%{C|nau8gwFr-+QQvPo#zGh`*3yUa81LQ#BBSxHv19Wu_iJ4DFd+Z`qI zaQ5Nu_?=4Y^ZovQfBgPPr{4E|z248)LW*v(A~OuL+{8DO8Ai@ z!^pG`t>7)ogDL|Urs!{Y2tC@2p494qTyDx`CR{=APommZ`1HYJ05KkS65yijJ^ zTldK{_3Mp-2GQr;9Zyp*tER;zQMn81ge$$!^V5z=-p3}QMqDl?i4WP8;sZZ-v?DzH zXT|y+*r$TfC;si%O{;l7Sa0

}*sNzPjTAiBG(K9+1`%pS&S~^ zOSwm*KsU`x9uPyjg-dw~?7;p(odJ^S5fpZ(n?wfZ>}XumDUABSu9{c4xeFQg0$1=s z6VZggNvzG-qgrBeMfB7ttqld@-kj7F5m$8tQPl^F z8Ga&=DRe-URYvPOVBW+mDq$+N%ZtNzAMI>E47~XW!hLXWo3N$_2U|J@;oipAO{gm< zdhCln#cB75Sc5$o)6xTK6{(a|b`}j;q%NnYYrBbW+}fL(C3G{!guW90_!TEso9e3* zLMajYWj18DDf))IX*1pFm(8Ldvrl+4te(Ecl&2_w^cviy5Hp%xkO3|fjQgaYoSD*} ztA5&6sZgo##W}tEIVJ>?(d~6I!7cD%;K!ls>F0(hht$(C=Y^+sCwHF~J-ObXSF1qH zDP}t(AK#->1K}noZETC1g@Jk{?Xe}b_~Yzza&(^^sZt4u#tF(jg_VQT4crM3^>)ch zzdim?WJlKSsdhflQBO9gy2;pE>xsmr2cz#dZ11lR#=9*AqXI|HV9q}}LPo{&^M{M# zQ53J>oSqG|W9oA4$@Q&#Ww+&LSo&QeVg;pK8&jhE8$zyx7eSC#^_6n?+Que<&E zN%gXl)QoC?dk)**SBD5Ng5p>~$5-t4Q^SL@Ep5~xA*#R7d+>>0@@VxH?Ua+KPlCfp1(SC1zgM>9)0w#I?4>z7HZo)! zhk6h4s`L9IFFMvgaK2sTk9&n*=jpQ9V-u7d zXoQN{l0?Dp=>t4`IRjYLF?7=+CRg=Q4LySQST)*zSGAz?jQp!ya4K)UqARFRVaj)* zETjMYCgvY1nU-;cZd&%WPVnys)_7@B-usDD4&2E$L?}RkSM!v1fu{w3vuU(@C&sJt2KFR@vi9OjZWG|3G8A2#}j z*hq^7rOpZizBI8 zV)8?J*58HTCqx49Etwx+8t3j~UC0G!PgKoHk9nYhE-e$r>V319sI-1R-0xB&Uto8J z7S0FA;&=1j=8st!@jLMYkFAyYkL#fQAFne>#qMvM3;>C~%6=2b`%@WtL?2LGmG?H+ z&y)8)xu|84NP03M2_C6cS=uhSoBQLhHDQj)^9I- zTlHz^T1akJ&F_*<<0C`c3=tet-#d4*Jr4`?*NY3f8_(~oXDGF1&1gi~vIc%tvpx?Q zy#!>px0H9Y#1F$k6~u|yox-&F7Gu0M#)a&68GSnuScFo)4mz)2>|QN4Ds+vg)q4E5 zHTi)@vF`A*ic09ysnNFo_jfe$TLzuNzK^iNc_Yd! z18gFYvkU%WCT3z{N$nyJyAt_+9X|dpcRF2>1C|fHlCNbUOcggDfOXg`)libxB zA74gPQ3h&@6rx-@pu~yk5pRWedlTm7Q=doYw(HrovNvlg=@tN=>CBMRz%7)%6pKY+ zTW_76RPz1Y;(8cN4v>&azzHV^hb5N2rhgy)utJMLf-}_U+`4C*^OjSaKGGBGxsH7E z!FTZjNB%jTn^q%$>?o(RS8Dw9hfAin?OCA%R|!D^;6?V4yEnVZTEci@JStT)!Y zoxOE`Oq=T~KIEvk{rc|@Au4{L$Q|oO3*|Mv!F9*b6nd&z?Us2KV(!TU5~v4e6&5`i zk2ZItB4O01^MDCL7Mhl4fD@(USccs;{LJu6S)f${=VV>!c#U@OGl6Ej=U_IOPhP{!VXBHQu# ziC38rx#>jJ=-6wNVPQYaTk;8V<&Y-}h5k#sn#n@fefMd)b!ynNHY1yJeP^O55;Q2G z@lJsql7)eFg>w043Q_4}caxe{DMYSN|H4|h`XejQ+Pyh7g&)3Sp=h3mT`FJ*V6#Zm zti4>+v4!#G3UoxGc83Lt)g9o8yH z=O&APvnzLTz8#{+?c8mWNxVz3jP|nIe7ewo;Sx=kF>gXoqMzNqsI4HhRzE}B@1|9* zO1oYu>2b5KaKgZ!yX{%!?-n$x9-3jRN8~e_$r4ItcBNDsnmn{Dxpa673aL}&F+yX@(#j&WD*RN3B$zHGSh2EUcb)m4Y&oKNjBBR|P5l~9U4Mv9Y zf%1EWoMCsbZTX>?jOR`~QS^3Bb~oi8zuMEQj9>n2=K9!>cA`OVOT>M>iN}!oC32{V z7N65p#L2|fIh9si+Lta=>{2ue!o-o+8aVhf5cd`zidvt6Eu6r*u(G+98cJ%`1|$fj zihFE*5M(QKNNPCq1GupWr9c~~1+PS}5!9tvwLIz0o)6srk$7zMyYQOyfd0E?6U+vY zgwjCpe2aJE1|Qr%+@z3|Ogsup!Iu9s%otNn`{=)TemEHs>d9O5$tf;nS*vrtVt%`2 zIkE$~)ieVo!cb^Hj^65&xtf3bu#2WnV#I$uVMok$f*Kwyt! zK#VG?R1C-li0E=c+aYW5m(-0zj_WB04a^TDBVzCrLXhYVlijD8dWxS4l3o{no+O7$ zM^k8XKcVux_;A8v7OX^P1kPau6<$dISJkA|f)we65Si1PLJZt{qtWQQc9h1UF=z>s zw)qLrf(Eg}FB&Lznw&w{QeplL2=V^Qd}8yMc?gazq?7)o`w#Op2MOx7^nD;9X-&BA zins}2!taavBUIU1&3eRR8C;Vy&9cjrRgejMPXBN(W{0wQRfC%av91jv`@L7W0cKI} zxoEnt)iggS_-Rv_o+v%T4XYN*`o_(xDbUt0M0LS0ur3lk2@h~xTzg^W0c|$O2^~df z)m#I%L?10FJZehhgjD#a_#;zca&<{255FLdCN`dLtqD&HjDgyN*wFUP9h`RRoWv_M z^|7vwH7J2FWJAFhS_*qudSF7s%`N~P=GsH3dtI-Z*EjU2mD>R%Z!Z!Cax+EJH#x3 z+fCdbQ7}^qdhZ*>Y3muK@%xMxY)VP)f1Ic=^EPYN(S5I77I0_981Aw_TpEnzo4FiV zlo>1!l|Xi~yxA_Ttn6ywv)q5SBZ zE&|OS zUW3B!?@V|(q!d*{*4lF~(bQymO>l7n7zvnHxBQFBnL*~FH|SHHen$O75mK6S--*9g z7l%OWC?v*@zL5oI;a8eBO$OluvX^#iCJU>?M>TGHfnGPQqT=pLA9~5OO7h!?X5nB| zqgRzHZuDNj;=6lk_^>u(lZHSM7o5z7YZ&!g)5#A2IspP_shv89jFIxNs(`2$5L_A@ zm#sRzmvMi%k@`7UNqLz4ZHaZ(kto|>R7~@7+T;o@W6f&VScn;HI`*lI>?!q<9J|8( z$N>@Q;rehJCUK-N_4Y2pU`xFN%{mMbmhP?b{u0_Qui^3MHo z$7skW1B#Xt!`;|~MJY#HFRb*R^sm%N>Xr36J&(W|I6yrG7{ncR08~sw9`hggC%)9g1kczy#H~}1v zJT=hm$s!ms0a36NTmKR~iT7 zSIQcUB)75A_o_kBiTa^*cht25fu;$5D|5!|Z;zh~lk4mDwC_j^iyX0TkKO=Iut(3O zs;%rVr;4wCP%#p}moRpO_b?7nl0MO`19lLPt=)JBnd4g4u2z@7m1+$tQ;GJAK-qGp z%FNxG+8|&E!DDK}ufiKHYj73?=Da9}8raN-^)v1@aiPQph2+gQ$1aU}$^_I2C+}JH z`=e@PA^$jisx9ACF!Sln*nvki&5Ebw;L)g!-HL?8-qXP7)-`tbu=$JSrN(0epZhk2 z>Oa3Ok}OVVE6)OU6IT>vT#AY)#G|s^0xXNp4XS@nCxU`beovAZ+HJ-Dfyo3;m@h>% zV>t)BMp}oKXezuB6M_rJswQDqs!e3CS2!j1SC>ykT7uKY64sVG1`%inS?nA0+!$pm z%Qb(c%nsAp6R3M!X^tqK(YqAY3HbqhsHaXrDI zV!)ZEWPW=fVrZgjw^A&R4_kVpc3W%ZK9QQx6nMI;W|I`!Aels(8Gq&jY2p;2J}NuU zMoQPJp?BABz{UELn&wxJFC=O8BHyyb9d~-l$?7y`$=t88mlwDi)yJH+)ii6K?M+wP zFw~zhyy5U9P<_w=9#N(os9_uuP$~i%*0EX_hlH~wVQL1hepn`ij>qp>QdBFxvu*mi za7JQ=zQ)PxjzW&b3}C*vqlT&bT1wMuU={f8&qQu6v#!{pu-QrFo>i*3`bfDwq9KHN ztCu}#X)#sd9nLFEWi|%^$E2;@Mipp>PNO6SeXBaEz)UbC9h+pVysXZ~5-S#OqJe ziGxN!8415pKcl_}@~VLebz9vE%?qKDP^Cq6mpyTLd8oL3i?}>G5I$qfe{I(yu6^@9 zo&W{*u2sL^U{bJynnjhgp(`$mK~p#HC}wUJMrMV~p{zMWPzqwcwAMPAOI++wW9h{y zHj7h{&5C-=sh^@?cm15Zf=l2=fvpSdQq4)dotxv;pre2ouK=v>PEv-i^>AKcOYKXu zXhA>v+(a7wR`Dnp3V&6ESI%|EvVN$@=`4!-!yw$SS)k;kvVZ9;MDeKD7UcXb2 z4`mw9T?dy=d+F~BLf4}lz#wpYwaSO;Yu%gx1I~S+B6ge-ba%5;lA@H@vTd-yCX1D& z^zQw#mjDBsLj%`0hB8otQk?_drIx~v%LOor&Y*?Pt5h4MbwvNGT4bMM`W0rQRfMAdvdbIFC4L zC&lSNleJfhQdsA^ic1^`ov7vp^kC|$PxEw5s2NWwue3OLpDFAHow+j*g5t`XqMiQi z)U~fNfMpyg3Ox3x5H>U*$JQJX*R*PG{##M#`0YnlIHeYrRquRt+EVU-uS)raY<6a* zz1~}q3}bDWq=?ccFU_Uu5yK12U+I`#Ixw$CozbuNG(H?#;j8L1Qv@VTQ`8efL1vfA zBw)UMVeY7KOUcc%6t@P53BJ$uS1l=IX0klpDJ?M35v|udvvW@87&Pr!YilSY&KY#)-{hG0qs*eQpJ3VH}{$jM*`kEwj`weaf%OYB>=v71JWuV<2^=f=%EV~XAVG` zr;WAEXd~5>HyXsZPPk&olS()0a-1dEB_;d`ubIJ@Sm(C9gk^V3lFHv1X@^V{d5sR$ z&9dIk4c9lk7njHkmKW(>QcY*$Z`YTP>Q=CKhyYfYUra7=r|2Kc9D)vXc2HCY4k8>q z%Fz_2+OwBl<(xW2rYe%Q$KT(kEcxWKe3*j2`4|>jiJ)xYwX9q&w~guA3Ez{p;DoZ= zT}nRPl@b$x1u;mry#3+UbQZ~!yVKGv%Aw}9xx@LliMy6oH%XDP3u1X-*;&>vkea@s zXT*Pf8@&P=ESV<2Y{du1n&!cZT;vrCH4n>{MF+$Z+3t3w7FxWF6|Q!C7s-Z)yoS8Y zLc0X91(|K^il>e#bU3czw_QS<{BKQ|BZgQyx6SZRcC7_y6NX<)aF;oEwjx3c0Q2ho zljD}U;%eq;{#`B$En4cm$v399?>=i;~auHQ`W?CR#A$y7{KGb8e}+&vE0F0+5TEc^@rV;O=9?^@}jv+$)f9urn)_Vms30y|&# z;b#FeQ=F8##?y(po*3ec_FX;?hv<(H&NjfvriRH$7n2D2RX>$6!s08+{*aX}&Q@8$ zPjZ1NiSTnvC@GM}yy!Z4byo|*7)rcq?PK|25NEyOV)sFGY78utbx^czd>7I;b$fm+ zUvO%*hBnoACK8(~yCL<~bq*OU`?%pPpaWl`IryX48+4xKm6TUJ+rQw8to(vs^7P90 zn9u0ZO$%MSAq5(7p~QF;PXJ-4q$J|K$SyIYccX^elqa&ky02+I3tfLT7wWc4g?!r< z?56AHK)19UStREi6FkU@L7O0x=W7ifK0v^|8>BT$nH{zYTjY^xO@qw~@Q9;So)~=S z%uMMR5g$pm{&`>3f9v>U>FbNCQ>dMj5>X6=J*)N}w~>AGaSww0Y9joD)`x;jwu|He z9Kfvxm*lIFQyI@5Ol{{@84IaKPMP(VzwiJpEVp@PyCD?CCrP^s5KqKqJe=~;XWh`H zzGxRpxbd^HI&49fOfdu-+KT`xl8S=Dq{?!tlRAs#^sYt52;ZV>9}fCVas%m~TEVTD zW&sPA_Qj!=^d`-tkU2?-vz}9{|3cA(i1EImrT8{2^3VED!YfQzycFZ_3eZYAr6$H| z)jofPk-E+<8{0_X5#Yv_!I>Vt*l}wro61sFwM`L~s z*s_%M_WbFmUCc~uxt}g`lVdyE=`0Nr+@HYDP%T|rGSjvJ@jb!gTb`1w8>hq~M>GnC zde=bgDUrsMejvZ*jeE`KMNSMHxjq(!9bk<))HHH3@R%d*+GzaFp#)5Iko^@Iu>pY85Wjbn$EerUbA4f z!E#kdv0|yk4)})40BIOm7(GbDUv#yJjR)fQE>qFBy7WP^#ELFB3l{S`$mcs+dfnP9 zQKcJLw^y4=HB5sGmGgHmAzSEfQ1{>53)i<;D4rJ$Otuh-_eJTd&NcVpi2hSPo0)b( zpCdVI#Q6KKDVSUWaul(@(g_#=MUcxSzU+TNI zXWZjM;C13qTuNPi0GNxMI;NjN#nwElaYp$^p#9}rpgpQkz{;>QIe0^At-2wXdgBDL zzc&}iZO_UnCM{E-sDOVxFtK`LmHP|9kuUdU;I*?K6#cxO=ib9CX&Et?$t3o?uLRF$ zhO2dTb~wO&?_fITk8-8}E@vdIj-Ovrmyr(L>0353cGY%5Rm_DhTt@ouULUi?-eOaf zGgZ{suZ#idR!juAJGt)C;g=oVCeda!kd_&7g+g{B_XCV??toCBDRe02sO$dKbo?b| zyJLF_Otx#t==)1*&7~0Lm;S|Wg*5dQu7Qpb>Dxb z3Xv1_c3)6MWoJ)nX^BO}-vr5^AynySKGjnVhP=~;`sekmx!Gmx-Dyi60*s_cYBA_j z&MaG)g)lF{n6)?l@ktJ6i{6qS=D^BA&V)j`QrjcL;w`bq4ENT@5rt|F99Wqy=8JFL z0<2kY|0rdq@slH(3r}g0!(;f2zZK>yD5zf2Yy^&)-2`IAORm})*I3Fw63pyNH(!ZR z-+Ya^`gH7xHI}}l0&_uoaq$AT3yo)(WBKhGlZbI>O!0XAOjriUXGlV!h<#dKhHlH- zkQJLHM>T_K3baT1`@PQW)i0~n5USt6#SF}EZe;d>3qUXNr-xbd3#)@eRQ+bRViG|B z`wF(nN1tCM+Bvc3-^?F3T?)j+VEXyB?9oXMj5PKXppK}4GG9(0;T(O&HZ{UuTBv+JX}4JtB>zH+c|&WUjn}1l&XMsrk8s$cgwic&Lz+8 zq1Orbq}^W{8k!d@_b56sfBxvwvEf~)9+~Re$w|q4 z@BVNx4D`mVGH>!K(|MiiWPYtzQR#fb~UyaI?C;mzO z5G$tT(NuwLTcIRyfl1STnRN_zV}=eXkLDbH(?ElJxYgLi>FTZj`8djY`?0GgcbeG_ zPv7*-fCJ+a;k1m>PtkgBHR$!U{?-qR}lc|M-7UBt+`^#>aa_7`^G^ZcVOYY zvl7<&_#IMP$f|{*9?ZV%{{dVn=aIU#M{FLOjY<@!D(9~-4+XYxt_~L4toY8pw+sh7 z7o#zpiCp0+g^fK}T-0n`#H zsT`r++J*c%uZmW;l%@CY^HO2l+a4pFui1aNd5hE;*-c$NIv>${V%4XXR%Hz8DjS5h z)&A9YoC5~kci`Wj)^p%j#KX+J03}65)Rtv}U9B5e52D?4+mwG+PIG0+I9j=a=33^B z2UJE|>4#Jq$GPMikuzQr{9WG9ILWj5l>)rswojiZyp-F@ z4_}fRU@n#p0ZHZ$$EeB+6zkQn1y+^lq4-<1E~x(13RzyO~+@ialC=W_(X8lIvx%i!&2fS9I9Wn{o?WeQG%0fd6Qm5$Mj?>7lj+ z`x?YEmTn|;qHiWU{A6ld>LO{FB|cYs%%xVHp*}*4!nzc>JI?DW<}a-_wQW)V{@1{T z5`>Bt6CGI`na*2WE>Sj`s_;NFRi+&+p4D0?KgB6Ygka0FEl}4y>F@Ioh;!~mn|eSr z47sxEFpfr72;vkElb8W)T%4h`Q+I;+R8u#~+(c!lTP+lp-g9w&$%~U3TlOzQV%zFv z7km3GmU|@qN>)N8EMdAf#AN%Ja??1v=xQ@rh0%|LD`Jx4OqKK-{q_$Z$5%}>+4?<= zxb9M;LjX|Cb7^+!@CQ_w768 zMMjI`hoEoQ8d#2}>if=c!3Jtl$1Kxd+{qT|0g+2NSfV3Fwd{EJja7T1Nqrd7pK!7N2bQuJ6juT{lS^v00`(%(ztx*1P*iPq%&j-6mtx7gi2OQngmkiWNCtF1>O4+wvcDN6%x(i zFu)t0i&9CmD%NuVH%xz+Ov&uHM4?-XeGglNtyPF#PjD*88fN!jr-8jvki+n zR}rknG5{Ft+HYfi0^^rLFP$u(+4?HnQIrM0*8vZp>7%}Aug}O~Uz%VCXp+~d1rzsV zs#QntHnT9Lqwaqm%y8ZFX1uvfOUd1k*E4%c`^diRB`8e+D!`2 zmVLQGQ`Iya!>-|YvpC?(a%wNgt_N{9h zTo>{$p=%<@bl8Z~(?t?~N4yN&xFA+>3*Ii?c#eDTTEX|YA*HAQjBIeX0uWt#_YK0$ zZ#+$=?;25;!dc2J@5@Qf4af~#wDlG~z0%DOu{_Aa@VJ&q^SF0)Y3elWzBGmEc?+HZ&-YU#7Y#;8qpvB@rnVHGm5S=p@FOL|QfsYC3*RA=4w<>kHQVD*IA3D9_<6kYi%k5t`sTt)Jya zm~d(SoWyGkygS*#-n>sNXHcCY{OX|d`vu((f5<`^f6znk|1uD~?biP#$5?Ubi%34Y zcpoth^d6X}oD20T3!Dw19Bu{^(iFOI>rsBCRXh68OC3&CUWIb=5|Q?%y0g^lYFDwd z3qDIELp>jW-05R=7EGoLpV7t_&-epUSv2$eDdxRk7kv6_yx&gr zH|7$(E4*k|O3<$h#Dc4_-nwXsDOaRzjUU9Y8v!A_^0%^Ro z*Vu5j2j0LS8=#oq-8W<1Xt`mlGLt1~A0Jl&^`4;h(m&(E>9 z*3nl%dZoD)A2fO?&bguzmbPA)Z|(-)`Lel*oW*sPG`dEreK|{en6r2uOg(MBTexXf zUUF`%8|E1W6;VGW5z8RbfARJfJft$6P-MsT(wSe82*-_73!$D~+G>QsF~`xxRYa&K zz!3N^*W-O1rQwkLwgPE__r_y4z|lybsg034UBw0~nt>K6v59f6Zvda&H*ap4$g3ht zYs^25+t{;ZE3ycIc3L1q&L#B420rC^533ihAYA)CJMT()Jd@uU1-aY0*|=iMFOT?) zV)tjoEz-J1q}19dKMXA*umm2zFMfOdSWNDs5Vd=Ll%zrha?X5Wek2d4EPzM6Eq$UG z6P6CyD(b23Gi+`@Cc;(60R3PQILc1$$!nVoAG-$bJcWW7T#l6FkczStB}%S0t?sWz z5M4bt<7A|qHn_`x@-G}YEP)9rgop6kzEj%~0GUy>=mFWz5Zv5dv`~X48#@29RJjY1 zBdYJAD*#!DK)MlTf%0`~w6&&ff}c``)-9|U+U%aOHA8Y$rnZxt7d{+0%Mx(yx)~{N zj7mLun6_L$NL%t_;KAqRPLAc@u6{9bp%_RJRPD%~<~dNi2;^39kb+x}(0H#3CF0*5 z9UYLAlHLDGTtqa8$%_YK7zAA``t--{WoOg4phvF)h{0$5ZYPNIknMFYe*R!nU8SF9 zf$d9?avd{Iq`Rr=SEUOqPoXZ17}Uz%H^g@DS;K`$U0Zcm)*9BhC!hBha$l~GcG#0b z@oJ{K3OjF7=aLdMRNjb=ci;c48wPdo$!UwDZofwwi#Q%bzadN>{md>5X4jB4NR0BG z_XF3muDqrC)?5mDc{0a2Kozp@Tu|=&rrKu)3r0UfZN9v4HVIL(#~~DtrB`^16{&$@ zugFO#y!WePYh@S(QIcj1-bXggo2L#=&Cr+fM*HM1JA+DvVD%}1#6<6+r3JsG`ZnqK4F}W-%a8DqRJ zV?<$UB~^W2|29#Ey|74b=JL`zHv}0|JBvmWnJiW;^V{V*Vw}EQ!D>|#_B4z+CroR`1z5-E_iimqwL437#jkM%$0Wp=DqQ(i_e-Lpc0}mcN)JH(#Dlm>nvOBvDuFUhG(G-$b-(Ee>hhfVPPuy zeruy!4>TVbVc0q)D4+)tPV(s_KmbmAyU#@StyGM|-1jYJJ9X>>_X_I*r>1+;&D}nQ zhjKUe9a=@wu=44&bUC`|w&l0nkB^c35>Hy`okMlKbre<0-=t@AFiF4aDqL>!&#*j| zy*OB8OE@DeY4-l@jDFLtP*OfM)l#?LER)3<02P1ZaZ|d zWq^G#WpXUyXHh2!d0AD-bxS=n(V1{jOM>S<*-q0B2p{{?sy z1JXw22n7ywA{=X$;8TG3!PDr$5;ZLOM#5+Uxb_k8<0m`Dx!YE)VnZmueXd!KleDEt zo1UQlfmFq5sF$z~H#Mt4B$u`14iEcCi`oW*n=@mU$m^1~pBJ=P(toLF8aIUl|3vhw z>9SleXH(b3VLGRqg*COuYKOQ+NeQnCo}lZ0nDJW4k{$_7|Eb0Nqf`OcT+KF1^z;kH zxhHk?j$O_|U70agvA4}~kF9B3KN19Hx%Ob%3t|o%%f(Wu_qUhuc%=uA%K|)D(_d25 zmK56#e&`bR3rK1!{fYE=B}VbPXN<;1HcaOO9QZ8>vpM|EJ{=}|7BZVN2IomT zy5N3Zn)c_8Cdom7Qqi(TheFMjBwMo*X%HT*o>?Y;c z5kQHU;6-g1=U}EfPemP+(X)>a2Sx=&x?$64;J}PWlb5AG>JaLGhPT# zZtvnMm#l~Y_DVOuYgb@;{8><25e~2@bJ-*N_s0yj(meHJST|Yz`x8^F7@iZ}&GxTD z*M95W9aPNuy}wTvgVxCUBLmJn9!Lb=ixEpy`&Lc2a-g1TS^BIju<1bzWX}!o-lUhc zC`atRnV1h8uVv_iMrWFZ7&0@@Z$g!wJ{EgcMpR2pNEJ^$7q#sZALo^E+H_a&U3}44=8H1>Ghc7do#xDE=4GuF>ug=wXPN~QPoS8M~a31L|rb4ZqT;z(PQ{<(SsF~ zzm-9Eo&2d%Sn~coy!Ph+=5LpN|2Lf`GPx1+CcadaZ*x3z$#o?ysl#Hlg7lgu-BW5d z^L3_X6)sh{6+=b8bdWzbwcHds-5oCKb??kO`V!G`Gwp}b6+A0^wH2W(g*_|2)9Ur2 z1bxPLor8ovynUAo#ZQ;|y?gQN*Py+VB;JT()b~r$G{~2ed|=h9h1<>oRC)d$pSU=+ z>5BY_Xq4jnF6(^2wmlHm!;RtCZGVd|=jSEi`1sN$gc@pwuns7WKqY)yvW z6mezl+F#s?wZmto`SL zHspsJ=2r{y)wgH1DbG3m`;i_j{q3%tq#5SQ2Q3<opVXZPG`#2eaWC4}2jjIr)d|2==EpP^<;ZX8V*hye_tR6d zC%b^QVg0cD_1Vxjf=f0$#^cp@F!P*al#`xL#3n!IU-Wd}`Rc)CXd?i5oAgsyEIj)U_8QNTMj5|cW9UDu^nRxz2pteyPA;OiF4Ud+4o?@U zpenoEv+#jsE+g2+HqcWhhe|Lt@WB9+S&bLm@D=BO=mtO661_<#zjr?H`9cfeyRYN- z4U%1|v>u4rs*$A%ZfF9U}>)@;9`Y z2EG|K{=lF-L^OS8{NY}pFp}zw<=AF> zgM1I~NecKc91yM2m!plp&v(PiwWKfKP}y<6*2cm68{#w1eLpWPi!9PJbmVP#{y!O3 zZ>&H8TaN#C=WxKP0;Rk>>>V9y9m$78k!Vp^hwCSP+XEF-_IE=Hza}E<^yKI1AEL2Q z;9zK0UaX(y*L{wXzdX|0;FfNjOWCW2`SMfj4|5cPYJXCrT;{+Y_ znCw57J|z!M`%qszI#@XInCkZ@H~?DX#RGGs=J`DaP`_xu>A5S&x9r@kg|2FFf@AM8 z$0hG>t$ME{ffhyg@og5x7%U`RMVjL8&AJ#L*e2H@;(M{bci_iETH{&f4@3kjP{MKJ zxvg6eeJ^*0s`>XB0v#S#2Np%;Og{dHdN*cyz*fDE;w~~Bv5Ih#0`5~Y&2y1#(mTFT zr{7gjiSp3H{)BvW*ogvQ_ytr zU&{j5(~D6-|8JCV{?q1vg%~oO@AsbN7qQ?_B1*akER-B=hPdC!fkARVHi)jWWBMHu z-{Cf#Me?K-w?6){JDq>N!6onJtK8#%{Kx--7!--yhH@2P`Dq3I3+2O=`B_M$N0E3j zW%<9a;g|eHsbe-9$YJ<$U*>Zh-lzq^^=?!qs4fP}b#RrlgUk^ImO zmD`U1?J?PRNM&5_B5fA2$iK8kY2-w|)S#((-;VdzrlBop(VX)ki6iDSiWKCX`Qx z1*24^uanH@@0T4su@1)p%Q9+RN$5AJDOrtu^Qze2z0lv^{NvnJFV@AND72m`)><-? zDA=utuUyk24=ayZlz~ZfsADy!y$>#@4OX)H%!SjI!PUZ%nC^>n$q6V;*{ug-)>go! zy{rxr=V*4JJGfXj?u3wB8Q<7)r=-d8LzMj2%G6LZE(-HhUeOq78k{kKSv4(?m0tSZ zQ{)k3?0-jwZ&!Lq9u%qf$X5xrv`H5{Nm!;VhSz>ox?8OI!!Vq=@f~53Y*#?nPLM3C zQg1dHTPyBa^dF2ov!f*bwtiP+fZpS8uAihq#S+9=id-X#2*I^*fAPHL+={FuDaDw3 zj{0}jX?O)gT{o0K?iLl<4LS_>$0lOh6xZ*!y+-nl2?}s0ycvp_FP7N!(T=w_Io!yX zgAzE~7j;pqf$Vg`qn;A$KWtap*g=kBF#d^8^}C1sboy1v8eV%sYW~e>y>w3Y$MXj0 z0zhP_vOuy{#oo+8fO@W~-alo3_4PD~`J!?6WD3V)>*$bq-HNZu+p{Vu&OSUF+w!D6I1ZC$e$pHR4Fs3+-^xzZ6WTkjyKxXpYDyF*qt0WgHlXQLS_P z(-Acal0ensar&o8G$}LH-u?SVkCdtoY}|O!ktpt8SP4q!Jy@O`9@d$8Q}bKwb6nYK z6K?qd(MPlHxXD?}-(z&hq-= z(St>-_-P)01}HOfkOnoac`${z$BMGg$Lz=cqhCL@#Pj0w1()N~|N8~M^ouF~h_?4H z8fW9V?%oo9`GPfEqi*7teAUt3A|^{{&dDFPa3hJ7ZO_FC4;;Ka06cb){a080yUL`c z9;DXiejY+>d0lMW1jO`6%1;8W($0wkA~AvfHShP(`Da*rM&JN;_TlV1@2LLfjZX_4 zgh&YN~^mHGC^KT{eaC1^x&Ye{NSPZJbmEv0OGj(j5H@ zjCI|l5ivX~$p+5qz03M*agq(BJ+OhHrAnN?A9|YX!M0y6L>+DWbu|C`CmoH0_-Nim zhxHG&{k5~-J_P|zkO<}#ukL;?4*!PQt4vhE$7vdz%-~@Cvt06Fe`TyXUk^@$@9F=1 z8lt54Hn_`sMzR08;lZc0Z4z~suj{1L+O3m+yQEgb?{DCE2mKz?BnYa6O=YDAP@bax zLl!p=6yO5C-qweF7OAxm`>vE1E$^3poN+9xsZ4YoBi~lh!_@`ukJCbjLdPPzc*1nN6 zVG=}?+^7xmOe^@M1SZ~b@W<>Lr(I8yRo$^~)fT`zi<5}`N;{BPJ^|L-rG|5}(;iRk z=&YVN*W^zyfdaT(iYv)X0T(An80tZsH*E_>8U*u}?{i0J2!4{gx9rilz~sG3e- z^oEAQi~rYmQ7Cnh&ov?JEiNCJ&e)7Pyk~dH)P{WI${Li&BmXvHee1k&*k|` zIY&;=3c`8OgGW7hYlY6u@IE>)C>k7V*%F$?vO&FVEhkKYiEG=7yA{sEX@uCdo6|Uc z%K|yAout;iGTdgX$`y&+-c&ub$&PC)M88v;>tob0lm!@3LP>~Gp0f$e(#u~1X1qre zuieZ~9)cU1e2Nq6>n2`^+&BJ0wcN9z9Tzw^`^C9cN&slUdst0AFLylQJ(QUz&jHVOVSo*ktGGbeBN1;oiHod(#ir_&ktf3vsPQ0@_Afd~U?~ zad@nyK~!G~o3xhiyS0W^u5O`N1RfI@JCP@MYouZ`r$i)mzrP6BoG@Z!noW@+Q2ZRE zzNF3Szp{gEWe})+_eNv&N=@3?{5U=V?sP;fY{Y1)Ixf6YQrU{Ghmi5tZ2d*g)S}qrTQ3g{si3gZDvn&%zJNnMbHd<;)lVLpk&4 zvSm1tmQ=7@V6%L`o7HVMVbs@UX6Hdt;yN9sm9!$t{lYdQbeO`@(H`rO5`uEb#eltg z)3PN~3Y@b*hw+eEsjqR3>wwPAKAr@vq2bcj)vG%Ve1^-)eb;<-u0p`}Q@D?U55j2Lx0AZNymoNFv=%}%$u_HM{c6PPR+ z?iierodNb0^|>Zb5SFfdN2QY6iHFhmwgX6sN0ia>m2)j2eJM3Xa{417plpHt>s30t?y&CE&`qm3gXtHote3cp0@Btj z4l)rmIAe^zR(g&8m_OK>%%7IkPKf-gDsD( zi_;0Q@;efrBdG}-!p2+2kF3YZzp4payKSr8Yjoh0Sl7N}3#bCFD}{`WxBXrqEe_(#(2L32UVV85bfzP5P75_R1w&5nQ%S z%q4K^z^p%yjFznP$77EzmUq~uV@tAoTB9%d@7$lhM!d;uF%z`>-p$(E=UM0~EJ~~W zj+US3U`S34!7?@w;A(>mL|OY!%xC*L%?S1e@(DrtuvRzx_3rDv&DV zjr$vfR;}^YG!hWknzB|z$?z{cfv>h^z33d|e)9M7VqN#?Nv^6D>4wZ=n#|vWGM#{L z0V5?_I715Cw^W-pOR3zOi_!xxs%MyN?E`gV(H$u{v)gu?R{C8y0}jW5+|kKkroj=d3k zd!-cUaAruvj7i=EAt&nwzV}LMW0D9FsQ4OZo-DPjz3Cl?&`L?^qTQXgw~Wr^i+g%( z!m{u7j&_@3_Iy>c%criu#Q;zARX*Ehq~JsC|3leZ$2I*$|Ko}x5{dyLjUrMKO6RaZ zq#Gp$A|Tz2o``~gfP{1-9Yc_Ak&s3@M+iu50)sIY{5C+v_xJPpJ-*+6d`#W$>)vzE zd7kHqdtW|DLb4`tNLO>Y45S;{tt9OsSf6`CTDd(`KYP}|AQ!g|NYcQNrY0#*lu1NJxy@GGJ$6kGw0u?yu{_UZl!o_ zXTNO7TT`j_c{+Bg{u`ozO!y`lb3fu+2fi_6@2e#I=D3Eb*##`daeCK2L`8dAXRM~& zC(JQ%j@@E@+3lyw#r?-)r#9;Wl+Fz~4B7VuFEPh3Yus_S-@3Wr_W`NUGx(XrEwXKP z!cKc4<@If~DsVm4vF{PkHfMgHsC-Wcg3riRbg11eTl~d&H7elZgbj z&Z9roZv6N;#+9S9!(O#D5QGU_bHm)I04XFZ@_c)>h9D8DeKh7*IYGu`t`m5M6N|`h z2vgm``e>r=E?_=;PQM0(=yS9z;HV%Z+#)}CK6BYgGHstgT`{F}^)z`|^c^5L;5UT^ zm8nikLX+(p@&`vuRxBq_ThnnOYVA$*;=2PF2N_Ab4USRoT(a}(OqmRTA?*9ssT;}; zG7}*;xtJ4@HeUPpnze0_)YWNkR%~c1y=%Wx(3R33vT<*u7IFo!Tvxc7Mqgue)GLDz zXQv0B_!aB8{81HrNe<=GlTIvHJ2Ex-pW)e^t*B3j!H7<%A>GTDfJ#s&*+nge_jrD5nomz zWzJbs;r6W9SdFTAT#tFQK>uOMrNjs~fT$D8x_5Gnk!;OM!!V9yhdfiXJs}ZEL%pl9 zZt@|UBPD0eLf-5>8bui*Rj}r}-TWa;dq?wUEpp-MH|w(b-X4rNZye{?_!vdUVSI7* zJJEJX*_AV_HbWg}^fVK!XGA|z7OH&6PV-9H)ulb|%E~ij0-+5T@YhZ$93@G7H!r_U zS=pH>0&pgJ0n3Bk`nHKp!N8pcZg#&Zt`&{V6IKj;*re8dB~(={&mxG;AY2EQv9B_A zYBIS<4W}(QywMiv{?OA((gy%CbSUz)fd^GL_{E7>C8Tt~y8Oy;uf5EdPjvsvo{*YK zrlrD+O_&6wRP#|)PG>hJOB$`K#Ch6#MQmCw;PqHe$>;8LB}o%p6Zf)&+g<06RCZMTC z%Tu7wHy7p`_o}|d#p7Q1mSEDe*1n3-g{n=bdV$JsfiI9Ws%XznL{)Hkrb+^~cb>{G z+1xn4iH_XpHSYu@ivXCmi@syyicO?vwIE@k50 zjuekNuA~I8uAe5Uh^p&gIxYQZY@i}4C8(8b|An@LT`1>t7Kj_BlF(-8BlUG+;6)7; zka?Pg1;FoBoV8S@S2F+AuH+%wEP$zTr<#3$S###(&k7FDB$(Qc{}oiO$Vd>Rfzyr^ z-d`zV`^(wg?1GCQSlM-w#BgM6Z21G7hruzi;1e1n0=>r*YWxU7FpN)P_0`8_tw-v<=gBXQJq8 zQO2D#v$t5F0^ePwwJeBk*k}hI^wew)u1=A*D~xKs@3!oF6IiUDH=9}V+;$u3|; z-|jgsNp)0q$Fx!fI}~gxXtq=7k0;a`VpZL4;!Jy7bz(Outvwl;HqLRZr`P6hW^}Z1 zw=HaZ%I6^4NiLk#>geT$L%d=)JxnRjKvZ|4fE9}Ji{={BUnB6|?gg$Ev*A{SXJ_?A zBnUu00|~0m8ej^YzTFYSjmEQL&bc!rFn%Qzvcn-rNnE0*QqqvuFznjD!TnznBEwAl zO1cQ>kv}3-|Lm?R;mS?xCW`&*i3fa+zmjOa3|;p@>Mc5U^9p|RIc=OvO5nXIKe{Pj zSvuByn)tCtjc_4_w-;kAKMR1rj1^*+cVRc}Ue25}0NNENd+a!k3|O^v zvvWW+l$juC)Q%S}vSVKr-vCCKi>e{fwo=R!e0x#65D60)R<{=b`mtgaLeM@s)61zuGcA>)bUemQ@1TMc1s zqn}53ndZc)u5nzL2LTPo8N%g)%}-L#AAe*YBVnfUE^RMO|C@w476$!Ev~k?TCuUll zg>%S{FZX!P?wGn&5Yk_IinspTjUYoy=xcdnd~jm|MOgCv|KzMW90}Q<%U}Oz$>ERQ zYgaLexBa&sfgzB_rT-6;fjBse|mB$q%Mu!$)ZF=bp-MZ@&`HPh)S#{7S}>i*gV{?k=K z{NDS?_J$rXfycT==8O}dC_t=etF}_F4vudjdabro5QC>+3D6{-PG*MOz?xEG4MF{6 zM))^ruMZHe5w2b>pMXu;4%D)PlAAYk_Z1IpwrQKUy^5<>fj`8&jrK?oGP&e`)o_sV z!~F3QJ7Fpw2O9P6Z?azM^3~iHxW=@eSfN+x=0FDtH!}pow(zZEKW}Xr58Ht$p zM@1iB$BPI0&A`?6->BgCMn%;$#t_d;d3nanwB6+AZSUDa$(b&>HdxArC&QX`Z16#lN4>UKLsJ4=BzegfF3Ol6UOBmX@6Qu2=hzjL9j2G^JJ$PZ zB&YYXItz+6Eb%9Z!HnnrYUV*^){u~{LrzjW>aGlDzMw5k2zR5xUxGH)PtJ9cGdQJ| z(3EU}V@1Hm&({|nk_is1LwLiIfk_zmq=g-tf)jZ$J=AtC$yWJeKd)r znd4BeO<4(*q#=-S%4Yi_v4l)0Um&3gAYBUTvl4o^ez#>X73A>yP z^|G9#rdM+Z_o^PG_yqqr zibIz}?5oMiaJudAfimG|cQr=$yM`AgiCpN?N=!QvqQD8U`~F$rWS%Ydny{|WC6F=f zq4$`aYvdHu$E|1tZ_n=%r>gBi6B_=?IsOpM@?7BT88P%(1Vqj(ovM zIUISkp43FbJ*lQ!+1{;1VpiT_jKXdIN$v0p;vJl%doo5g`OwA5z=`V%wXk&)0o>q+ zD9MFve8?Q8zT=#|S=O(MW(HX}zS;a}?ZANPQC>WQU#2bV)Kz!o&et7GZedV*oNx%B z2;Z@NfQP=07YJs_f7RmXX8i^G_9^jJ#rr7BWH)&974qXPER9BF_WO5Y_xy_O8p0t~ z;?SOYd{FoJaHv!fq7P3kiZ-8`QeJ6u_iKfy7HPw7p$2B^Yr%1Aa5(JNwlnj7{yCH@ zc53F$_f;+giYcd8Wjb?Dc47A_CeYmFF-BJUtR>-`3{UJQaqyL+v=8E*5oMvk6O`!!b%$OQTH+i+y7uJg=>?Y#$PQ>> zjOh>n_EYL4P8Q_f`qi*6xnyRO!0VhrJbsh-0TppIQHhQWM-cgSu2Dg){`W)X z`xmE6rIy^Kd*wxYJub8xpX_LtGC$8c?dfXFeVo+%NS5)90mimUB5lQ<9qg~FE)o3) zhJ8DZn6!F-W>Xmb%9FpkU;9!(XZa!D0nEF5${(t{q2_VMLF+d<7=f4Bn%Mce73iW8k+DL$y``qju{@t#V zr#&vDev$~icUPMCi}>-ChTB2?5;qE1U<^>gh@8|H=u^-Q|eMYBA58qOgq*gI{5MOP4wh*6w{p zbly9Lr(`&Ea(j-uEKIsO$l@XTR-5mUWcv7gA%#9;x)S|2^w{ILd#A=BPGW!0PaN6J zwJS!?K@6jD`R{}d_afME)q#2VfKE8xYdq8RVdayn{c>eEK%Jm9?dWRYfZeJ`()Pb-u$)eC5NK>c)CDI$%JY2lB}zf#?ez6 z`$%>5tP=D2CtP7n)xj6;{Hp;ch)!L`YX?mBk9Nq|l06uRt*9uwQz9X<6`*^lZmL&_ zI%)I`uaaK-N8j<1dcz@O0+Q6>Y;Sw0dmxeayC;_vbNZ)lhM&a?z6o>f@!{;K-Zg$7 z8fqPLEOj?2%+0sujdeaJe9bwExqxNqctcSm?h?nZP4bYb4f?=8>gUTqRorUvyh6w( zE7qdRi68v-2(E}(XS%dJe#E}WQZ&pI>>o|)(G~B=X4^g9&*-a9^Lxbi$49hp^`{%P zxpbGFwdUA}XQ?Xj8%!?gCx3)h2h%6Mp*pibLsvuo(~ynx;9r{MS%gX?_#eJoV^SVd zetMMBViCb>R|-8!=GJjrFoF`)%UE!<-tJ`RA)jDbI$cnf7N&V;tOwlb#0z?R;lDd` zC^o#6;x44V@&a=>9bGC_!aF19imq@KD3MtGeELsZ@L#ohPeY_=l1wx9;Kt$9esawu zk`@|{GoFqPwKA~K{oR&rP4-7Ydd!Mn|FrLwNP&L_hG@s2i3~=eni6`vu;!J z48$%O?Ob3xL-YMiYP3U$CE{erU zJvd~ZzF#itR#%UU>e&k06$rTub-#%$zMJ(r6n_@zhx2g+8nrtzRUdY>eq;Uo z>-x{68sqW@8*J0#?zn%r^w0z(ZobTs5FVvPu~L4zEQ^Pk1WhI#*74!vXBrL zIK;P3#)Tz zJWZzmGIWzTx#`9MUqA9vL`P6Y>zbe@`{< zWm#Ek6q!RR+a{np3lcVD)`M6drf^(qddxK>G;(l??3ATtooKyGcc*7r2njE zCz8PG@W2C=qxvy_z2Lw;ex$y1if`5DnI3+M_nXH(6Q0!3THTE2jMU*&5_HWLhz{Mf zAeBBYEtU}io4IEK!kjs#?;^wz(ocs8p0f0}r+g`Mm%LA{KD9LF>oKOLs(J`oHK{P| zOMV1-@#~)!%#lD?3{lFuQpPB`J~Sg2$|9RJvpe0Ps4{O@f% zLSRd&%_86*zIGOG;Gkn7 zV<)z@q;u+Qhb49~T|WdinY6RFfcEZbH{Lk^$B9uT;|cPHWad8zBd=rvD_Hn&aAmx;#tn=|GF<3Z2~0__(x{E z{KkkL*!xx(Ll;x}QJ6h@pcb+C%XEN{D&yy% ze+Esgdfdx!5OqXx;59=`;s07Qmcyrlo?a)(kc;{a*uGz`q-J;-FY)CbOG~D{KYa)` z*QN?S9vnqA8a*o-vR00lHn^!+UXb+95jw|*c(+p(arx`-bJPa|@30Zp!_|&-IaPdQ z_6$^g;KoSlr`HH%7xbGxA5+C6@eD!W#vlZhDLEUVl_)kL}+`80}(vjag9+b+5}`17?U0miS@_F zpWUaq(3>M9(YLRih?-WZcZTzUE2{;#dLFRW%n!t(FHTvW*pDlxdDDu`+j6V_Bk@xQ z+(qwzyL?~9yQ_2m8>yX=^;_`pp>W5j6QlCA-b1c#S~(m!{GIFey}gj!p%XCha6(nE z(gloH6Pizg*SqrEyXi3-1X;HfYmJH*+%!^A?U$9%`>_6Gtp@BEWqr7GvdSNP@V!O0 z8@dUsSsF0w?78AuYrOcZ^gywfymL+#?iJ$Z@cZ{xL1sZNy!@kDH{x-yEa$UWA zosXJ?gwT@r(?|cfb$r74|K!{cW^fWKhT_<%6mfPAVaog_&xo*SA=i6|CuVfI#rxPfW~wW$7o(6svkA>#jj-Q z&r04lk$1UJnKR1=oKuv%c=cVQfyOHnSc*C(P`+kLBgMVEO!%szQDU%6GU?jc$g*sa z;r^M31+SW4UwS`?gwfwev2+%l4v?uQpS*31^DyxvjRe&TdJn_)bT*}=z7i00G=-=F z`(msJ>t1)S?uv`_oA}a?gzomAyfR5Dpv&cJdN0GL99YeZz9$wRC8Qn?R#L8>{gESc z-CoDy-cq0#omBc8y!Q5>5(EZZ%i>teYo3srn44mWPQR5oPktkwr`O{Cdw}VDn`V@M zOW?J$@hlf*Si*=OH}{Ft$KQXo7<4n?7bbtc6)K!&!5uO+#(tAP9E{w~s*VUqZpLX|e<=ezowJ3%PE;n0^OtWu zK2k-r&fsspZI}1WGJtim%2mFhTQIQKh!+tGh)LP}-ccwvg z;yx#Fd{DywU!5jmyXmfRwOWl@soMj7>o4LQ8Bi4)Aw&WENw&6uKK(va@LNM0?Jw!> zjt}TiWFsQ9|DB63<`UldBm?njG$!cR|0H5h5H+jK^n8*7{wUx{C|wv!V2^su)7+n$ zEhsQo$4*^-ERw(%jL4{VWq@=w^Ps8Y2{p6$a)Q47aT5ohnq`f2RI3M{2;hbs=Is*t zK7VM1g(jMRMHi!}S<;Su`A36{FC`-LlY~#OxYLJEW(O$~*ZxsPBq6lF?yI&1ecqag za=lE&-W4jh|7^Mv&6%OYl6nx!{N|UNpPjGEf_R z^$azm=qH4NXE(6_=wGS^1@Y5*ji4SXJ=4NH*+ZZ zox8`*QkQ?`NJ2kcbezF!tj3Ww;_E+`IUK1%stVEIHX<<4@9^*KPw;T>By9B-Z&^Rm z8}E`Y#g-RNbS-j&%@psvOW*BKqKst>+i!U%0k-9pjXMf)f6L-fwutL81}c2~)`y`u zi^^$y5?|#`&e?@Yv?Xds+q4jNX5EJqh4_qijQi( z7~e#wi<^|tdUxn`6=lf3Z@11+%mcB>%IZ7Rbp;E zYGpW>Iq^07rO^yN$KmMivCXya%a6ZAzj~y3e;$wcX zS)O1LoE7ric#|L@n8bbFNLhkOTqQp;iH$m??-ylK^I!5P$8ONnH=j0TGXNnA zIOznwC_csX7>53=9%GAKEYo8W_-0cJE6%5|I&Qo%Cs?PqxEtQ`;2#1cJj8A~^5DgO zz7)Ph%s&-OK(dBg_$rfsMPvKCS-b@l^`hb8dF(g|+AGwGvYT6E8oD$u_V)!#fAP}D z2)`c`T_L4MHo=a!i7n2Gw}j;s%3Oc@#cp?UA8!UYw)_z;F}DJ-mFUb?SAEt)hjdJr z5A8w*Ze=u1V$l znu!$)4OoRb4KuC!*-X*m))*m!u(!ZxQ-~J0(zucJOawT#&SxQV0~@Br>#jG`b*n+j z+7A2zmsPzq-zKT{#3{(Z)$9w~Nbl2z&5C6#K!_%~tAIhQH*QAP>Q#mKe0e}C?ppCW zIMx7&Y(qGBqq@v=y{in%L!U^P^sA+DiW>uGiCf=Ph!j=&#Kj_Ata;bK&t$vBT1Pq8 z*I`YUMGAMVc)xOv%=ZCH%d}`hNvC4BT@ZGltS9!jGU&Zy^6HI%C9fLoZT{gp{tDxkQx1h~*+6v*n`H|h z^kl2mDq@rnam{Uk1zeGwe+-;eIwOEwi$EJ}6b3c|PX8r}$`(jX$SUbxOLBoCA zD@)8ga$l9V)=trS77I(|lS@t|PL>I8RsNju#Qhc>mGVRtM+PcRBwIT4Otg({VnY<{RYKa1ciXv z-ND5Pwx-#lD_e8mNlSevtC)4~r=L7N_HM8}8ijKQvG2Wz)``8iNbTfO!9lXad}%o6 zHqY*xojO2$LwjYWa52r^dU<7g%06-fpMT#sU}%$w(M|JKGeKU~$fs0@Lh-M!eU1_u zzL6do+*REXPhVd1qfN!GV8WbjRpyJwk3RBFg&^+wX9ZGbuGk=C>wGPA*rwlo6AP<{ zn0G%3Fx(w5P0(H#1m}A=X(od;+@%2=x53$;`$y~G6vEisHNA=2&!>Lsxxf?Cp=lh5 z*U6@u7sL%=cAt9m^Fl_Dvn33NoL5G~_YFkK`(Z_h^-)DA;PiQ21C{f%h$|nqxMC7> z9gUM9K!+Zj(n6a>b^>}rAWY?Si`>uHrwukXL+NE3OU@Tw{k{v}BuSW3zO;C8Q&`4a zRw-=uTg)W*d-N)>ha%(Sm*lKF7F4npR?AZ3$h|wzKEo$lTHZjj!jL?-ok3I%EceA% zZY#4}RrbpBWysaoI^NDRSBJ-GhqkQWSB}5=){rn&xw%ni`1~yB%-uOTGM~YEzVKah z#z-f8^;+yo&5utvAMHv)^T2|xa0w?Ra5qNg?6x|pY=zqo0as4{_`FctGD%>&`bNl< zxBb%l*=qzIl@h~ODOn$gFD`R1_-?XN-X;NWGF&eIOdCT{!*(n8%(~jv^q@^mijO1* zkFee3_D2hk4uAr}i8N`$xMt@$KxGmTfWFvLtv=Yd4#|-%=|uDwe$vY*gsZV4NIg=; zzcI&Dy$~$x5L!%Hw&CJPio_-35E&{%zg!FWSe{&-Uax?PnDmc6xKJ<<9k?#wD*zQGxCbHDoD4spq;deNnb z$6IiZ;I|ab5lY(zWZ89$HGm4_VveL%GOEq7C6R5Fh+2TleA!2gjcjxo*)}ex_>)P5 z)YEI2Pxj>j^ffCV@V<}xy7L0--s@V&Aypq4}kIp_(a$n$D$0 zREudu#VYGvUO{c6;N*TO@7Q3;_B9RRv3-&H!PmYJ`0||^L$&ZJjfRZJ@pBh5&6i{8 z?=<&u3}|GmiXzu0X>@E6=)pcL4`aQcOQNTt3omFHEgS-qR&;Pru_V12+gLE1vw`fj z$f*-@(eDM2Flb*W(0)tJOX2vD@hetq8QSN>l|cq+K$OE@+QOUEdINe!5O~(_ES3>8 z+?ylLqbfD4kf)wMutp{k0JD6p|BHxNx=%z7*S^$e^BLbf@YKDddoiRetH>jT^{f-e z;sbn=Ywubyj@hz%wZU*=NuV{+B{2@=r-DT7?)uvB)!E|gyP$0%OI_8a4}-C%^6282 zhr>`@?`mBP7Sbclg$AW!Y2}qXUBas8d<@X+5UDj20dqUd2Kh2pAS*0BJ7Pc=s+y0j zpY>cc3E&mK?!@I3!{8LLx0y%r15H1gV_bFpQDQ#Hd?1;*`S&;Q*b!B9fO9O)$;Pz1 zfuojh1zO9VccnX74_I;23A~6r8L%+OerNl2GVP=<+O|8mbQL1C)%eipr4Fp6e{3CY z2{P#r7PMYXY_)!=GxM40^jDu32=r zDJ|~mw1qU-+#4AF*>D?6p2i<$_SMsPkvkWE!z1QOYEiZoPD*sWd0rD55ntC62hE+H z*VG#EdMxK+v6hUTv#A-@9+FHC3Lnry&e7LEmM=wUm{gD@Sx(rE$c5AOK{K%ibTvav zG%k(90`~=rn^GWW)`KzGEAcC~5TIJ=t$8hLl`dU`X^5+j@<>6SZ_1#tr_CDE3tcim zjHM^0=4Vl&2H2($^esD+y=~8*5viQd;AB6#IKIirgQC*GNmTJs;bLsvp_ z3qlQP-m5IL6p39|ojK)gfiK9I_vmNtyQ$zSZ|GbRd>$B0s3k~|MKOvEy_1sjvBA+S{rv+Yu`V81w@9 zw@QZPV8O$KgWvs$DwokXhm?g#w0Zg*YCEI`Ke?tT>Yd)$R{K z)25r}Cla4{f7!E2*=~F8xdE5w6J9rYI)175qtd{LTdm{9M6jZ$hfc}1$}-X@bAI&u z@W*MUj828eU8KB%c4~lr8tann@Ud09UA;X_SFh>H1s~jJwzjH9PN+ff=9)_BsulBN z=2DTiV(+hMErC0J=cU~S_v2#HmkYmV$F)&bIoI-VN~;arVa%1jU?)m1J*5jp{2=Mh z;~ik3xG_z)3=|eGCck%?A+5`X{L8Q28vRZUi{PF|&R$RS%61ut-wZFM@U3MdA#vrE zT#sG{0Os`2lAO>M7}qG*P~*0K6w%D~OVh*a-a zVF?XpL+{i|hf0xd`>XlTs*#&oN^zyFL!WyrbT=M|`wT4 z(cpu=`X!bPLdJE6=Y6k>l(dU!;AYs*3{4ltgaV8G>hWA=)&7llZTY-Xj)qv5UQ@Cc zW_6yLIg$nwUIr>lC9W$d*1;1@LeKMSFi?%KaZgYU_QRu&+CEw+3eb6K`N|MqDePPCL=73F4GJ-)R6&voEYd<;6=`4drGe zZohjJRa-W7dSYPv#j6>zSliQ@m|J@N&1fs}T-o;Wy0^TBrFLhyomIu`75Xz1+Yz$B zm@1yCI#j5$=tghNP2e5JFK-_RN~APol@-?5s5(~~O7TnQS!+x0iPH_yVugHcy}W@A zU0HIN@q(qwqZCCO9FUHu(DzyGe?gPXTY=7wDW~|vbDlxklxu%b2y8TG!?t6+*R7{8 zdG6~vVer-B0ywkQ6PF?~UXs-&X=_^$D2gUmzW0oI4*xG-lJiA4>%EgBK;01c!d1l( zyA#Md4{tjtGkV=e?P|R_1ngX|cP^X0Y+*Fi1{z$x8o=~jS$;d$B}vNLzzDZO&NS|s zZkMP8$dOAxm`pFO8hWRfEb3E-%9gX)m^Zt7fESluesK(B=H_Wb*?XO;ZFxHT_1lN0ZMp<>n4vsWCV|Ts@i?#3{|H|LvnPA2WpI zB1UzB=I5E6Hzk}t2|x@sPZaRex=-4nwLLJazqUU`kXFYz>5_NB<{Y~twwR_b3bzTA*W1|HZ4@lw95|jB-qK^BM5^RI!rPG0)+>OKsNf zYgJs(!vL1!)=Ak~8f~8lIy~{Dz=z7!iy0l`%Owlz@m26^Lkca_uU_uSFNmuv$cS`7 zae&f0x=4psKaZEkz>!Nr^_5PYU3s_bH$0*gZbZLGZ8^08dQ(vz59WOw%kI^-KBWgL zM{RjLJ%f*AIylX_l^fLcGaha;?Juv=Pm7@C`;)qA<9X)U&APrwRIbKm16zEB69tV4&8U~IEY33vcm^s;&w02_@p$x0 z9$SOAj>0NQ#vXmclVCoiN?!aP`4F;JVH=dY!eqlNcKwq^=`9~y*XAIr%O;OiR=YnH zOfqJR7fUFGZ=IWu^osQfJVQY>#=Jako>hMKaWLI zlV`}YDg>fy+rNaiR!!HDIfDc7JVkWax@g}9jtIsB$wI7tj!rIQ^g49Cl8YfPjQ|k1 zYfLK)Q$-!fNp$x4-Bi;7ZnLHFB_;m!L8=h?A-1ny+wW+Idq-G|6%XA2!C)o5loHcb z`1d%}7fGmFtz5H=kZ?`NUIKs0p7Na1_W7#mG{^%Sn18x5Ylpvap-EXNlxL?Yj|Ns( z&!55c79eEX1zr)W@Otp%Gd!=WGjHUFl*g#J9Az|nW<|c5S31$7b2cCzP{Q+XXX^NN zJ1r-ryTgj4>OK{XA=L*@O<04Kzpup&KaOOa$|9ME|MUoaEwDPQH9VQNxFa#47n#3g zm*+Xn45%=ExH3BcSu>@5q}vnwG!u8<TuY@d!<+pCSka@uUSZ+0Qk~bn(yYkp&hESKA_LSk`|9V}DIP+g zh%)qEF2d)2u6jw=sm-F1r5frsKf%Yla$Jb1a3<^;eMpA0p1{2TK%t3Ue>HOzxL!md ziYoupRAQY-Tk_oJEXxh_!Y6CtyDv`3NgpH+a7VHO2Lufhl%IHpIG~uk^%^Y@DH$6-;|$o`_nvceqMz z>80HHx?=rDaMhRMLrj>_&np>AcDg8YX7)FwePBy>8RRa#-=l$mH>p4xblw-biSn9- zkxbUdHB>JLXXm{h&SdXRacg_QMrR}7NC(6DXiRWVT;^w#t4Ki)`m!uJ-rDn9k4Iq({N@~m1Ljz6x}Q0~QBzZyfHP@vkFV|Yh3P{Ls#ucrgD z*P3J{6bYpt7b!2`$YXx8a9>MID*lW9LRZc7#^d!+7iyufl~|4R^*rH?Hqpz8EA$JR zH@!ur6yhQ5PgbKR(@IuI%HVVT9|Tl%t<3U_g=*0srq(G@9^s*5%RaNsqZ4=D7Z3X4 z_6xXiMMYTR79A}j+Yc)ibT$rK=fONe&ijuYB%V0f>WEbrImsrdxLen7(Ohr zY9^$KpL3E;uiPaMn$+<=9m5$O$wgUpccNEIDojK-w`*9&f5w|^{!!A_eWAI1;P=n) zmQPl7d6Xj~X`|QC+%2<(5tbi@!l>hv@=nyxrkCUs|ATVv9jot{=JM%Nl^ic{W^dHLji%pu)gQU zXTz2rD_@|*mlXMkzKO(lInlVdC$H4PaxRD7k(>TST)L4U62DFNHVw5r-lbnDgc`>5A+^Maqzb4&NtImOfc@v)37U2R8tuN z52VcFL;#L2y6@K8-*J2`r4aVgqsJNiYrrV~lQf{{F21YkhaLCJT{HKd446j*JouJE9s zbfwtOa}rKwrY+`*ejDdPX@i-5PIO6ld0|@dR*7hhh=?$cDl%z}iP`^(g&KY^}+F{c~U#3h7gq%7v-v?FuMS!G8{2B?zlZtakba80v* zw1-Fg)AX)-F(cl^_vRFDGK=GGO_2m37q7m#h`zY}RA@LX8ChA;v2)5oPwASg(seaN z=W%f?8i@ zqgXEtY}8M^7Xn)vR9Dw`C<*0LfUsZk>GaN)z>xBTWtl3KIhC`UoYBf z+kI%-^-)|B3UP!Hi+8G+G6}h^jyhp{>Tqky`?;JMaP5#j&OD;cQgr5uFi~N)>om2u zE5^-5r*n>!^>K$w0lZe~zA@O4aR31Dd7f^NVb82Xj)0WICpY}2v-p@5br}U(uzoAr zyc(hz`rk22iRVV7*O~|0*D1LSEU9*+zXc1J`P8Vh#zV9j8?&|e?B8T*?^{UPZq_=u zHkZZhYHY(T85`u=tcE4g_s{L<9Agen~wnO*|**yy7qyfMly_vtPNv{w4NNByhMuUaD|7M8bI{;KP^w9%d5q>uf@GDoLG6dohC3aQJG z8ru{Od0nrb`38_xE(@UCp!^cZvXRR4tGTWA(jdM0%U<6 zM)>N66rWTCGx4O0Lpkr%+ci*P<#KiRz3Q9d9Q;l-Op~kQ9P7)=&{)IXpKa$em$SM= zdnR;iw55E2n|E*6@DGD!r4)y9o4_FB-7@F<6+npHB<>WoVSTRJw#ObqKI|yu#-FWi`B<~ zRmq#xKIY-VdQOuDKF<~h?;3BG7S_1NP*glVQ6aKFY)3xPoHN}P6M#iWXI#w88{R-` zk~K_#vuFSwdgr|1TCA{^aiqYT(r)-bl?Q8rY}hImn!zm#fI+V%OJ`T~TKi{yZfFC_ zIauzxGgIfbL+SEIbTaG4QA6- zWAm8fAfa&PksogHzPH^=p~H}ts+^t&I+eGl`qq1ai*`xn<$T|~V(jJOQwKpgKT8m7 z(?P#FaW~jj3|6^fyyiZ2utj34ZKgNNo;x|lXFUQ;LfUAiChFCmDCC{*ZP3v(?%Li6 zock!w^@ciRa>ToeUtCbIf@cdWaV9*gy!=Onx7;OwmGPoPlgoMunchd`vu3^xKCy!4 z+4R*JR!F2AU|y6X4A&Yme{ocW=plMp9OXotk1Q0&pPy)1;_pehaRGl@!%u@$%rDOV znzD(C+-7|z!ABLHO@(^X{Fz!La{G5cr%hY3UUWU$TIppLR#F)AB-SeVIK`CzG)^1KyS<{1z8G#DqLd|qTlBJB!yoU;$U&mPACyWymG9^Z%-ZRW6l4bm8~9)jE5O}WTZHU}GFJc6v0BXQ*oHegqx=R10Da}0>Yn<$$!!$J4UduAeXpyyr?<}K%^ z1IxTxgs+)9ccVxJ&R59{QIceqk7sC(Y=tee4i*dFLu+c5Zw)I##B6)^s8uqNZ(1kk ztzK#3q=p-UdakgkpQ2B67sLjAf?5}NtFsya)vjKCEIV4|Ti9o@l4#S_Nw$hyF8-dP z=3al>Lus_z!w%H{lUBei|MmvO2RlHj=!lBE^XcTBFtH! ze5RmgGVsY(cF#S~TDtMo-M!?ly`*g?pnlcuE&lz-0z)*Yy#f*Tp!B`uvN-fSRA}_a zgs~@DWqtzdq59cMLuCS8+AUJc9cu8!A#Zh~Os!+I=b~iZmv<{!n%Vt4^*$E@iq%0rTu=oo^PJ=+f~be^*br#%=1LU%Y3pR<|W^P1T<%JD>$psn!Oq4&+a5Xqe)J~(#=H1x9}|k z=d(>4E!5e=rxNI}b^SJKvD9Rubdnj>m081mZZRkMup#qCl4ls?l^+Tb^{L#E=%B+YfuZO(~pLo$~ zI>`czSa7NQp((i?wG`5GeELeoM3_Cy#xA8oZ@+PREB)daqz#$Vw+gkIs>;#XpkUUb ze&=e2AcIW;`uNBktTpxfPI;>szg}-zy^DDLOd&6CaK1`<2tC0(5#xrQcOBf{_M`rw z1yyDG|JZxWsJfPBZ5xN+?v@bTgS)#25AN>n5CR0(;O_2ji{S3=?(WXJ$lm)r`#I1D#*62j#s{jDJvVqQ0*k;vnq(Jl|G^)a{i?=n)G2^e20FDfQQ4X*BdXr@yFwhUM`ARG6fRk;ECZ!MSluhL6LrWQpVOUy9u@G998XmExaxl72>06tx4~Sgmn?v6gTMt z6h)AmLqr~W;*J<_j=oLBZG^sQ=k&ix&0#C@PSVI1Ty!v0E-&{U&4kJ`=^b_E#J;2bmFrvh zHcT5QCFnxVQL=>VyNC3=H#2uit+6KZD4w-zuAHZV_@XR#eTm?w^jlBEu~ks-BLn=J zO~wui`$bT63SeR9gijbEvCXNLJCM?Q!K(P13s1_Yy|e#`{V^&QOryMQiJ8q3$97p$ zW74vP&Ha|h7W;*V5e0(kS$N2}&hAy?*^^~H{vb;#+=CS*4yyfps{kc3-Wh9EBl~M~ zyn1h0vo74`$WwhbJi`mCtoIr|B}Upqd}xmg-Lk z8#d}@U!U3Zq&Z&?#&RX3!zD>ZUnpT&+DN1_Mn#bB)3Ruks0LcGGFPo~%UEsn{6 zd2pE!7d?gZCNKlg0H*l3e80!P$u1vxU#I>TsIB9tC2;Un88*_#Y59JMjM*x$s)d9a z=OP_&$ISSC$Rkx$q!W)t30+!#^pJ_D*)&&_)_Sv3ZUf!<87QwZ=^_%J^SD@hB4J&c z{YCh!b2Qv{v>Vw5MXx3{ap$CyF)ZJ+N$Nei*@vr{kL5}k-XSgJHyk28Iun^8xWBrH zW`L1X&*kC3m~GnIMoW3*ZHgsgoW|OFw}TL`MTWKOQo;7n)_NqX`1GOR@sVKd7`3FF zI<02d$?{ZX4$Z2;*xcObzOTH%M2~hRafy_8Mp^m@KXt-LZcSBbu2SOR)_CTa0H5zD zTF3&CiWYXSwz)eHZB}Qg0;LbuCA5=ZuT$5PdwJTuxLwTcTypH`uFc8XYXz5}u0u|w z+&kzDUh|x8XYWbrjYWm-t@O@s4cUjNk*K3;l)$4PqKQHr!lVS#!4D8~SbK_~=@BLW zD>>aoZf4l`ELcBtjyZib%Kh!JV=DI}X&XJQUZPT)qHXdAur`}zZ`YHsWaSz>RbeOT zwv5@U^w(ZH211@b-!iw4|E!V+09VQRBHk;>z0vi2a9KA$zE@mw&@kMYe!nHRL)px9dK2h8cFP<*z-lMp3<^jE|ezG_`=>kfUl+L&= zKehxX>4}`-&ry^P1O01tcKLO#yT344+h}N_o!C}`Gi<+2e0I5_EiXs2QFuu;_s)nj zzrn~GimnI|NrC#Y(dk#HZ2FA+o$ju8U53v3m4?~jF?Mv5kIvehvNF9R-34jdnYD$Q zoqJ!crQAU)wG-gw>)jG$$d&|808>lV=^L}wt3z``iL?*|<+z;6)Y;{9SW81yR?gNb!RFo7bG>_mhmXBJhV~9I13Ap=+<=ARKk> z{A<+klQvE-q(XcG7H5mKKIPMyZd2={QUvOB>9a^)tx(+hAy4IQ2`Y_(MXYQqkBG^i zr)z~Fd7>J-6-g=%lc@;Q%`z4QBVhZ}@}<5?Hq$q_9^b##4Xt;+|g|Ql4S%uUXpy&(y-L`J_LL zO9!4Tl$?D)Yxz1uwwq~P;Zk!;`w4GZe?$kPgG+gB_sG4OriWC;Ukf#ZR>i;389%;> zX*aQn`Z2w@ZvuVC?;^bS?U!3e&Q!v^>SEh~&6FK4(qo&c{KyFBfmPNA0Aq{y&e%22 zV}bhltCl}__9G4!`qLvJplvAI<3^=PE7yWv1>Un+JAKX8$}z&2*%erBf;R2eHFsCY zCuWYxN7ON%J79IkL`XALdjLmm!JErj=+->W5=mr#;P2h+;F+-j_(82_bX@gP+0u8rwMo6oBm z_n|%Sd)HS$Id3$u=qtg16yYQu}qgYBb&)U)++ z_hd|itDzZlAN9Z&D3t|e!U zQ0H*&?AhPa=d8hk|8a&lW2%n=z*qYGDqlM$qPS4ta`VE(Y}ITchdD^OH&Xb}C>u8D zXHPi=X_5{QWWXqeTZv>O^fiij+fmcMXA?S1l9@u>v7 z?WuRMSfuY7{i@9h&lUgatg6Aa@-M>PPZ0T>WYqcjiVK zCqdDPXHZBPA@NX2dr`x~eE;@oms$IX>leMw`PxjY%%XG zjrVjZ>$3uM_?45?tB2?3lTiY$)2~fF4Uy5>inkgwp`HV5==4)+zIBRYL>IzFBa|2z z282_u(VV~)QV)lUv!8_0YE)wdhaS?=Hm2e63`I_PyLhhs zIfvvWO2wJA&QXI4oq5|F^-K9J6XK&4lI+uYqp-YV9a2BupL|zZAL64_ak<#?lySD57-(&iIP&W!TaubBRWdCw*!!++A=uPb46z$Nl_zsJTr>!car|wTU|A z+KUG!V%BoE9b|fe>5F65>QdT$E|TzoMPddcPt)3N0&&%ewhW*YT0$`wddo0YMl>LQ zdUbm2G4Nz9NnJThbUO1JlJnK|*Utn@y{3*Q))R@7!7#ibn!Z&ZzkaTiO^hQEuZ>)y{vdG4}{lpUPXQr{4KmTbj|wt+7d40u_1Z-vlKh`8H@iSa9bC!hOl z@v8mhj`Fk*!ss_svdFsK4Hb|0Q6IG>(d7tGWp-=t*2v4lpsOv18c8R|cDL}ed-$bQ z(&e370Ed_??#b!5E@#Ch4K)Hq7oUl4S^PU}duO@3~?_Zw2LE-lKxgJx~9sdsn`)6uaP5NG>TK&tHCg7^O zHknCDhp`LV#Ol)hZDA-oyH&mD^1>biuolCym26Y1()5M{Sji{>KRaZE2dpeAky~Qr zLvb47yFSh;bIrxgwN7EG&-l$t2xKlOg||uOsHG_9(<%f#UK6)shG%QpUj}BhrrWtE zRQSUV;m+J8UKA7EXANGxEzYK=vbl7Hcqr=tD`K{~9`B40S{rTC%FM=(He|=Eii!xd z?gwfbG}op{KTU-2)RcB|H`HhEnmrH{$e`ubvLspFkR;XA-{TxI=WJ#eIoEEw23&4` z*$K9Zi##NO^2l1asY5c0yG9u7iiGNYO=+i(Q79>ATM8WIdwu@Dq!&#g=-&)!% zq;tolz{=!B9CGK+Gb8ut^?KuB@5!$-c7DXkiaU?&#U{%1kQDmtLW^X$8VL-P9C)hF z5;bDlMLIui2H%9_q;;wXb(k=IwZGv18HY4r+o6L!>F@)DX#T1;mf%;UAt;5ujP*)p z33ynAsT+eUQ7p z);3}3s2eS=&?*gFf0NrNo0u|IN|eVRy3w)dKO)hVZm%7=!$Wwmttv&wBi|8lxtVs zY)^r6l2G?3K8d|y#YVi^iwql^!jt3hB{$1mtY4p>i*aLPlTz+(y?|vW%7cAlk6`|z zG|@HmmZvexZ0M1A*$!pN&Rhx8ERNA(Rz+zc7Umj{iYYHbE*hqhs;-em1xKbnL=;SY z2kuLCC!y{c<1Ui|ce{!0@uICR+Ea3R@s1n#8GDjv6ah{AdPMXkSe^yGCpYw(n|LNu zdP5Z?)=v=)HXzP=S034(<2=QVB6qEwcW2=~D!3;1ohRv)E#4kkSqCURTfa;##LiZ) zQJS&NB)nWSY%B^r*xOcoZrNlGpVA~1#oA2*XJQv9>C2YQWw39;ZdG!qOLz~)6!;z@ zY^4utNQie-`)+w2*4Ee`GocPAP!M?ks$=>ei1^l@U*3>!oqlVmX6Xpey|h3=ET^oj zPIhNWDQSs}H)b{c@tET75aicb3ya~C0W&&l4N7aDf#*ZbLQ_*Q*ZnUr_koOp%chJs z?w^MYo?24#-iynD7K%<-ufE#xz(VI`EG49KQL)M#X45VtM23dBibmlX$VC%v)zo72 z8YX2V7Qu_hbns($HQ=JqH@75OYiPG^ z?FB5-=>?74+x|)f9n5(K#qH&a>8S)-WI3n3Py{=#VOA52uVPWfO!BEM(>Sf;m0r=E zZ{~4Wv+Xjf5-g5*IgjnPOw1$BaV84vJnUp$N{!~jr>NzJXLRyL8x4->xV1BCHsPBV z%6%rMA7VE+YH*JTLp!H|sd=s&S&O@mD~jzk0f!#Lo(scDxb@V}L?^Zj+1yDrM{&WM)cXJOwE|)Q&zPBo)`V-6c~s2)Re$r9^Kl zRcdo6?ZE+SNOz8ExT>oh{>J$NyLW^UBP$oA z(FRYcz}RW2d5cza^Z4Y>X_&F(x#(#y$BQ(41s;FE=((XsR5E=%3w;J3Gj=`AzdHB% zmaX)?&Se=hJhio|>Of@8Hr2j8Ypn?fHi!u|wy$7HffB4-yfV z;{-~wL$m8^;IG4QuG*n5O=(PJkA>Nv5*pjuPjSi$I6oO)RC^bfPr}Mz?Zhm(Ftfha zH7N9WI2==Q@-D|rY$)U}v@_rJ{KE6#G|pVgW=~i;U`2_rTs3=JUgBDV#`U(@LoiBq zZ!z|1*b~CvG8=r>;KP3s2&H=)dSe~8~Mytk}qtmRMDm@KF_JA?WGxVU!a+r zN;|pF8v+IYkkFj&SBNme;SC~U8X7sxJ*#1DQ|e*8KzvC1h!$@wLXFE(W}a-d*5-8^ z%9h7jZ}Rz~N{H9qR9@-JNYX8!OlPe%%c9T2U{+ek-a3i_aEow@Ys;`xK9CTGucLiE z`=Z>pULZw;64zRk$8)jV4&`U~xr9&W1i1F5Vua?b@1b$;X>%5~nqYv0Rcnz?Tka^b zao_ux&)0pl;LhHzlk!ZBT!!~hA79_Swte|sR>k8Yie4x=pQeYGXmj4+>y*z?kQ9My zB#cl~RmT$Vdoew?)Y$|1O-wOE1>n`_YK;hg-VyhL0hr(M`-s*59J#@d*Ww>y&vbKz zC46>#D)mDQu(e+Z`gF7A=oKJWu}7BXb`S($EW>NzQN44Q+(mp9$|#CXS=$OJ%RT*}d)FXN@jb3Z++SvnS5**O2T>uETiXw@ucDQPBp=|9>knUxUEka*`}4Z+IrH46;=EQ-u#gXm2n@QQD9O$ z73Do!3#>mHP7@Udg40A0WS-l#KvKGk%|~CmX``KD5QDsZ0bl!0o$1Emj1doDXTbZ} zpB*u}Ljr+%7D-_o;y=>oQ9{7Wj%5uKQvn;kgZLfF|E%km;k}u!>^-=~hvE9=T|W`M z`MqWv0hZ@YoalXqE#o&q4(O>hWp-)KS_*30iZ&U!g-&NQkmVywN%%wqi0^7@(xQS+=OMhTs({;vXn9caD0igv`nyU`uKg?_V?L`pGzuOTPzD{Kx&$$d#2y*`Eoepoy<)8zX`s_-QLxQsT?Wei4ynT#%}PO^b2 zrSGo#-$-$n<~v^f3`P9#uP?TN;%`8syQHLl$CUs3A7F@WGa;XU-f0O8{KCE9z2xr; zIQmEo&q7Dfb`wmj7$Z ze=HdIt6vdlDQN{bVzvKO#0C5Y+x*|ee^xu@#{a(X_&X}Sr9V51yGJ$rAJ+fh7t>|` zK;wCGKpm*){*Imhy8-yU|7f&S{Ey{aN_F7G9@fU_Ostw%#!7H*9HRw;|L0`YRR0Iq zFNI3)^JCoPiDZf_1opMBus_OY)fMHL!htJpfCiF33kR2ynSZoK2mp8q<>joS@qg>} z3Gi_D#13+T1yC`xctfVCz_K_c6ej_q2RhY|DoVia9g;paW2|*Y=r3E6RN^s zG9w#1?>GxJ{@>3vF87bMcmpLJ|9@-w+lv2bo&RsG^kK1iL{`V=hA^%Qsg|rbS6mXdxk4}Y=EdJLq z|NS!FPx>ypjR_Rd`#*u=wxmO9X|#y~#!B5(5N+S*_01!mj=JsaDk$J_&dpVjS_19! zvx(&gNBKhk7ZZA^@ul|txO=yQn^V1feLZQxpwCWa-RUsK-7H?O>HYV#3iiz>lYyiB zFBd$yavDsbzqSqO>AF)*^0MzFa>%lauH*IWH%T zd>Gej%Os9k1N{L)nh)Cx)T^^|_4yz1x<4H`vE2J$@qf2aln>a+$&M7p(M9h!1FvhL zw<(;xFjf(bXRJ4$Ezg#~2uYjUwH%S9oEoh@ck>d7$5|9w1$G6HZwieHAl?~>cY6os z6O0E(q&Y{qqYfcI*G}K^$}<+rYZRq8zq}?o&MW-nrR1G_44Xtvyq*4)J@j-!fbz3b zLW>LIjbia}5#?onaiZ!~+(-KphBdkmQAHU0qtN8uuU~S25ulp%iA;4##9G(&TJ7~(<8*lh$u$bW%7Y6NEI+UXybAy% z9;1=3=l1{;Z=F83G(BfcrpK18H_Ru11TWRA{%h(mpa57mAC4 zYOU^mYtgGiVO?QAZAnp8N{i*?j{aaP&qoge4KmZ=#jOZ%P^8P*IbnBj^~_UIA!R3GYUSb_!vq$Wu*40t5{E>(U>MyL;@OLfkDVKOErE}V~Uoi18qcr14pBm0ZLMU#e;s#!k)#whg|V4OOM^K{Ls zQ+RTpz8bd}RnLQ|*-sedpIQSuk99b?mX#K*FV1e>37MP=C*7NC;$5v1~sID7rdDaDm-kynwy zJL&@@LMAUHb*St5`b4C}Jag`!LJN(Spk4-kZsp6bLhQu|vt-=|YOS?!2l%R3U}Hv@aap7>hZ)`to?Ap&J<^BjX44VZ~3$ zJh%p)pMt+*qb6XZDWxMRq=%qlVDWFhTR7pM>Z@*85t5ZYA~5!*oRvp6K;~{N200Q>bo`LKFKNA`ZT0lX`GJI z4`T@N1q{b8j9-+PBnsueDvaOS+2yUF?Vy#-F}C{kg@l2J$BpsyQLVfVizxc%^t0qV z=J)33ozR*uIB-l`oAgmhuE)RAXuq+Cd*3z|gZubA z0&g%@SyM?mnS)4$MUg?=4I5sZ+pFu3oP}qj!mcbVx4)!!s{xLsmE;8 zZy>^lDv1H6FiZ1*LP7+8yl@0{G`cG5OPNM3<(A`R3Ye^5R{vpru)c$`*)>P~{yLLQ zF$yO!Pjx`ZL1Yu}i;Gs}7^{?3MVpS*ThF$)ewW7SLfK}1#>r{Lfx*l(y%D!~(pevj zX5IGmRTUi`ufvFpDh*!hU|+X~4$Xx~IbLv5*v&afx?XPy3bc&=JwN!llR9v5h088Y61xL5582vyE3UN|9 zoq%Elyh%}#h2w@1HtYdxiU8TB0q4OK9Y>C3n}w)g>!{470IKHtM>C&RznsfX^@&Tr&2)IHhcavK9Jtp?rCCgXJx&Q`$X2OsCb zi8q_6mpeGz^FRpNVtZXW;skn0COcPNe-BY3@tLKm`kCcA+NaxJ$57#>j%l=_?OaZ% z-b-9c8+A)uR zfpnG&wR;ELb>|C)!)S4c$8NLX)LxCHaq;U=)J*Z)HiFh?`&c|Dv|s!;NuCo4)^8(U z3GZAWoNp1eev*z&BIHQ%)m!#8FCX86>=B$jJ*C{f+Yauc(=X@0MIB_@FwY{AsVVd{4{X}&Rf^u_{>!g9i2Pa!w{`p?j(FX8 zOh+@YaeV#B!Jr?)+nW|vUX;`5und$dTT8i_&+<-MRQ-*sDL+gwQutEjPd6kVvl?kCN9%*}=&}RqxX!wtl$9i}ZP>;zT4wlN(e`3q<4h-{^x~@@LH!QnXxdk8c zq=B(tUcHfm-kczLDXAd1n*wXva2isRar(9pY8v0EQuTxDaDsv5h3JM$twNKhA<57+ z^k7_Uu7V(9AUumEW_aGlA=L~}%p`_H4}LNFyBE+#sy+kh3vMNh+Y=I9Cl2cn@XoPW1~?(Vju|Bw zGl6MRnCZdfRGG$j(WTx>if(@iJ>s1GeAJrDXy#`sg5Lzc9WsU$n%yFEX!~S|z^AWA z>0~;`PY^1zmxCnz@oe-bnTI3Pmre75WNCwvL8(c{Z_zs{TEa&GH*4JE6APW>&UNux zbTz>4NOzZ{<7!maB@SPsvshM<^>DgZAhSya6CdpdTdA7Y+130`p77URc!D4Ji|~yH z^>U|;iKND;iTg;gLnY#C50R2d!##%%1v;mI`|z|Awf%{YD4J3w%lYzUTFkLL&M5YA z4I>e~B2(#oe>y(~7m`d4y7TCM>dy$NqzK?3Y)!#!j0xf5(PjFakdQ0g>eMwdLUAy} zxV3B`maw^_u6WDk25{fH0*eYR$&@*ww)s+w#o*ffBGc8~6`aq53nn!|+d3OObV^zKtoEJlx3eC2hS577XeVwvK^R-}MS;~YYF7L0$Eg<0^MxRCH3C`-2 zg$s^SkF}bXAm7DRfZv4Fl80~J4*!k5FOF|406nH|y*p^Uwxe-Nsl0b=V6^l~}6ZG89p9>BTe)yY5a z#yA9J*o@*|45c2H$Y^VS9v4Oi#fqYv5)=7U{6H}z?O%%2nxD{_2)~}Oi@P4JtyIi| zYzUTGf1uB52!}8Wl`N+chDhafkkQmlLeJgIRa%E@%2ygiXk;sqxr0P1uvO4IJXB3v zH%pGo;1>VKsB17l(|(sJYO?2C#S_jy3{9odI7h@ldGe=KOA~BnhNwCwnBWMGlR+mmLZ0rADLmJRW!d z!12H_>*LI4m8}X-EARLNYO5B$y8}LG;;K#lDz686t^62nf>)_9PEB5X$M&}8g75J> zDopP#3at(S=EH4sC!4tbgF=kXQULEL`vY}Y(`E!iAahDAoSc3;P4NI8x&r9W=co+G zU+Q9))eAx^7n-grUZ!x&Ur`PL7Jwl^w`TY;=45ZCfla@=hH9s30-g?d4SClaN1^#lp&@ci5zs_@tquVLAG>1@yWgAyw~j~<5RZ`IB5cdmN8A75+p&RqTSRodX48s zq!<2zcRP9Rhh^*?cr z-w;9C7#-e%u^799iop+13=&WR|DYAfp?D6Zf>-xsdbPZ6bc%d-nKiPrsLc2sxpCB; zHsvLPk@3CRT&?P5?Cu3D6v(JG!u@H>KF4Nt84A+bCz%HuGX7-`!Vs5fD@-Ue9Qlgi zSWxxY_XfyD*!uE{;_U0+C78qPfA@)y89jK@=3#?!u(y1Tq38>sJsWqf2JS+Kj0C9? zX%NKya|H|03TPD9;6A@AqVZMHN4)OGAgS>gs8@+@$;vqgGm+j7(S|0@$dKr>aC+4o zlJ@Zjj5Tqu{&?Y62-{Og!gKU(O3LL)bsKhJIY+;+g7S=EKT69f9IMO;gg6oD{Ve5X)RC;x@W@AsDnzoMc8NH~|{)wZ{~g5I!> z7qLuzakvBu(q@6+xY`gw?2XVNY<=vYeW-{vXtrQ3ko0)tV$^^}f1mD!LBaNTA66gC z2~Poyd-A7I*=2YFza>AHY&OAavGBOab`De(pX?P+Mj{Egv7A_6as3xxW2z5Nm4`yLlrHWDB)JFizfxEyzv-7JX#Og& zf<<8Qo}8JbRsM6g#vj3)y(f_`e49qU?c6M5U=~Khb55uqb>PDEMLOrgeDR~eaQ#dJ zscnAI=+(t!W>X2itenuT?(kGejk8FO@b+ExHFmRIe%cchIuTFfI3|l|$pS#ikJCkd zXc7aNfTX>!#CND?^#}D5rLZsJS^oHKX7AwV~+;4nZXFvs+_2ZhJ4^N?`_9GPd zRHBEnBhG?&AiQFW#*78;-Y@lYcX_VdOFM}sbs?)Hrye0Q}Q?@~oDLghK=lP7=(LCx6V(AXQexqzI89lmu^lJd! zPFp@+xcMIABBc=H!l!+YFEX^et1DKcD3cKykLDEe5weYr%b~vVJkzA7pe9Ad# z`Aj345ar+O4<8ce;4_+b^Qq$zWWz^N^N8q2-1?r5Uwm-Nr9t7&!SVYLzEw1WC)*Zn zLgBX9k~4hX2G98Mje)rNV+iML??|PH_BZoI)1WdX;#eiac3<2S{N$yr4|oKx{%h=% z^mYdbfMFk1`apA#I;aK$rvX31R}7wEAqBK>+U5m**R@N3gv*Qo>A!Op$a60G*1=iA z!8eZ(Bz-pZkbI0O1HGu*=FCd7npjqDJmMb*g@CWb7Wfmjwx5!+vZ7NC$L9npnj2kx zSS~e~hqZ06*t}IU#wqHi^U>@AiwR7}*X-lI{YiD8=Ln|YViL0%Nca^*ii~Mhp-Kj~ z66c}>DmAvJ`NoKrl8kgCg(KHjq=)?CuQc{$sNS`S-(YKz5i&a6t=KeXEk&1%%;6u- ze{U9GUQ-v+E~yU#W1uk)n6u=Q2(6kbK|z76Li!@7vRgYFx1Z?tN2!*Pao_o^@UM1j zm!@>Cj;1|7tbOLomAtBom-SJ=s&Nu0H<z`5DE}3oV@4!ClBqHC&zf$Hw!XTR4%Q2}uz}*wJe!IZQ6I+`!IeE1 zY5f++OblY#3sq8;^b&P`DMUj-u?SRHF$berO%qAH=Agd7aXMU)a9743`lQe}ocjD? zdS&n3jRNi@#%goe)1^D;2@usaIU5hSZ>C#eXudWWaxNVjv5vG}1+KLLjPG*7`1S5T zc{-eS5L-Cumy~TvGef3VA#U(9UIu6%#_{4OhL(dJX)_>#vt6pT#UUc}=V8sCJ~OUC z#iDYU>C*GfNNR|8XdRlBI00&*{MS<24QoBI*Ub2Gf>()KzWUX1=W$bXliyAu;xVr(wUIU$H9aL*ZO^cR#wcGp|1+xd(v8=yRr|3$Saz$yd znRXr!M1**9sz_UI-iNHVg|Z6#sO0aQtQRcO@3I)lS~I|^m)dVER?RIx>#%^-ldGH| z6KEYcW*J(&;EZQ2Wxh?e&%FMcBIXEC=a8`q6@@+yhfv?_f z-ORSH@_VLXk9IQbeU;w1C$d;$?qhMPD!<-R;+w!g>5V+?nfe++o%DgQN$;TNbFw{r0+PqrXO% zh7jCf7&Qu5rKl3r?YN^cb( zR>NO3e@F8MPu(v%4#Y}(8ItNp3k+D!*ymO0N?+$$#cmQvc&h}M#}rvNA!e2SmD+2< z1nra1&Do&3z%GK!$YrY2V>Ruxt;Xw6;fO$T3M*{>wgqK&|5I!SJLCHTBcbvE;#S!Y^Pmav+a9&PO6P89P7+ z)}<56l+DM1=(>b*2`)(8`{wItRnSSb@5Te;cd@Sa6P>!ZVv94T!6^QH&g2U-AKre} z5#A1mj|mgM3*=K6Eb7xZO35e)=y{JMQsrGX=}2f~+I#o9jPLbaDQV104OyNO2o z;G*7`6*N7b+m+dL((`CDIW(s5(~Uxp_AMzU_vU66*@0-yaEq4eXTE+4LQG<|0PwmQ z5-Q^FnYR^r81yHEa&yi^(2&qTiOb){Vp^<%YQAHt6mf@Dq_O9A6_q zmwj(5&FfHnI+|$!YDk`>MeXy#6kQaaDa0`aR%h+`sB7*Z;^fS|fVV0=9sxEk>u+Mk zaen;#QC6KL(G*$#U#hbo#okEASk?DFzK=)VCpWGT%n{i9oOEdPpmCj&VG!<{D1DH4 zI#f^%7X;0%#ovF^+-K$LSDH^588$Yg+73tY2GJ5x3?;zpW^uT!xjU)5=^BCD? zLPtu_7>#v1;^1Y_Y1GSXGAYkmCsJ6<%Efc3geNSuvuV#-bz3&z)+0_hKPhZFX^yL{ z8zkY^@-DFJuNXBbSC>ob-RRWrM`F*gB``BK=#`<4{pq5SMKi%&Y&(}c+h!&(SFwAM zk)o-rVXdva;lfy2^DwiaZ4)kegLbss+6sxBTzxnW8nf)T_56*Jwst2c+P~m8a?EQy z+QNOXi_JLU${(yhQ8em`m)O|lvABy{@=I|kO{Qq+8;(d};_EbdJTNMU9yYqt@dBNA z9C~P4W_feF%hZW9+bXAyLO3LGz_J{IQC3${>VLnr_XZ>eLs)&pSHU(Z#Aw6~ zffa+Sh9|OH+$%4ZAg+KGDa6kHYgnQi_$ex7g$aGWsQ@zv^R04zvNr;(1Cj(bcTNBh zEKTsdVC<8K#(c>e9>ssIVsA))@2N1cng1wh;K98m>6^76PE3@G2b`##^U* zA!_S)L!45B#W^h%9YIQ3#rQn6IgX;?2D^wjzeZ?s$h$W+U4cwy4c)dWE&q^7#j{z^ zYIoc^y?m%RrCX|OQrsJzM#?C8;;nz?e-(=(jZehB4nOAWxmWjSoO;#D9Yl~nPe~mQtcjF?Ki80?mvzr-7<8e zAU#ZyK1J}XHMlR`-Nsd{z%M@!o?eEZg?%{dr+tp&`)EP(-P=>LeAbiGmd_rHY$-TM zi%P!XqRZW+FH?c8nf|8KV-&B5W$JZkC==Vbvnfc-5#g4#>G}X&r8Y54hd0# zAiW4@M^0lI)m6v*={(9{x~FiSw|mSEmmJ_(SB*MT(jw{XG`^l7PGV8K5k}jP{l4(}`%ribuXr(&=JV#$2pq)`*40JEUZ|H4g+&vI;akIrMG zijyc;*N4xcrhOhZahcmkOLZlByPCUD?Nog(+vU`#k>X-`HF{EI=Y4E_+TQ;4@yTP5 zd-+4Vp`8zo*0ich`F@{PIJl7`BW`qJ##8LoO;TzqozDGX`Q?V3RUZ^PtBt-iNXD-X zrq_Ts$La{E>kQzo>d&e;%+Vb2Aw(pf+*&O|;it|zO}`66pp_=w+CV@JZ9`Y8H|TCe ztN=F#*`1C@xd$cTm)E_#(v0HIT`!7+P4RI3D0mV`-bp;6(I`Za4$tO3xcR`d!y%{j zHT@!&bf*#nd_wcePIsHf;x?`hkK8vc*64+-Masi+xY7aE`N_^GT&_>8HnV~T)S9kq zWlao(4JoKyfSbdgkCpRaUck$H_aJmo^x1U3*uo{w=k2<_+AQ>;punJzNn32;apo}B z!^qOoinLU@bSzWqhu=jzH65)sW^l@|+?)>=cvvf3#7N|4+~U53YsKrdmda=94y zn|}?P>D3T=2XZYN`xYuFn5AFibrv>jk(`l@#d*Bi?sM&d=Vj*5 z8-K$&fb%2Aqi}6pE~Q}83EPeg;EJE_YY!cJ*O%CyK95C26&RzxY7usIA&!+%>QS_O zqNY2=H(LTBK3RtnW)-`_k!8_dDp*PbcJrtQ-6D0S?V#_hTq1tads&G+^ftI8q}Z%z zv09}wry-7XJLM;$iOG&oO|>s~kRcMfy+&<8*)?qG;+!@wU4%^q=ItG=5hiHf&z$&- z=cT+(aqsQS!-O!7YF%&8}M&o7e2|Bc2_$>H_tfJ6y6pOU&M4nkgPbQ5fR zsIviOvsuzQ?WD%PpPGXj%f(RM?Izh(!eK3ywcLzUi0sW7m*dqdEY)1qaU%r@Ea3I_ ze%Ll~iI>qhxj~L`^xD?b5)YD9;yOltO(r^L3)}F2l-Bc9n}z3nRx;R+6=5*`C%TFF zW=b6!Lb~G24;AmGe2R^5hZ772peoUsr3`&d`bLrYiJjO+WM_Mp1)WkD4rY=(dfoA9 z)z~|UASB5vSg=5=;oz1Jzq0N}sy)5*>b5kw7qPNeIbEXmoVHO9PStlNH=aTgX7vG} zeHt_VvCd<*w7Wp-ud`?5V7wsaKM+;m?RmGqe@BHjMQ}B&l<;E@llY1|r3@B?smltl zdNZo)|3%CmE#hw7{&*)y$wDyr%Ozx2&9g()MoGL$uDMufBh-xIO>{Y{6t-^boPFx^dMQ$)@P6^@ugaOqvn zSj<(w8#%{pxW>ASHUvnlvB#NNo%B%g@R64N>R;M>NQ^ed(iBArJtPk_+6$$vR@8f~ z8_O))o@iKT-IJ^PJBM;7rl%v_^p8Z|EPNF zs3^F=(NJ%Qop>>Hy2;aq?uIkH5Vc>kq93kNMOsi*;^x-QMR;xE=DDZ6=pDD&tuLwit;0$(=RPZAD$XY&_n@qV-weZSiOHqAb{fCroN zRZv+{hL6ZDZjWU}^Fg?Iu$n2S$?pMW>$M9J5Y(D^CEk4QrPzI06BWr&$UD2YT*MT_ zg680_;k@meB`)vJQpxN`haQS`}7h^(nEj=bu z#^kr=I^0=3kU$|KdJ#nXYvY!{ru=yI)}Mjde`fN)x%llm5|8`1u=(*%rNoPI{bK1` zHO7xKZw+Pc6}6@02}wuM7G>l8cx~r6VS~bA*o$#Pg?`->B$Dwd51aWgQ;#K-S(d7o zSMcIXVq1GY8((?G$}k6qaoo1D4|v)oEXfQt+fK|29fu(Oi4w^PUGZ3~=vj9uH5a2$ z9S?(>bz0VJfgJ|37Htke{N!1+Ygh$XZN}=!T$&!F*`Gk z3@I$WonjL%v~thlPW8)+xW-UQ9<4QxO%?Ml2#^D4`4e)LNIINIxvq74Ocl&%gdEi5 zWGV1VdL&7a;CCRG+#5g6V)>VpmTRG-jtq!^NUD)CVUjm;Z|_XUv#f9Jcf!u-X$bZb07#>rF6%6a))|+Ox}VcmsCh9og84d813G?c!E17xOVsW`Q(wl zm;Y?9v1+LLOR>nLSQth$spj6K4rbYTJ~4!pXrI~fsVDy;0nL}Xuef4Wb1mHmC!)w7f>dw(hq+-}Z5VOxQyEl%`qpHbAlV^n#^+<5u6 zw8ojSu6F$G1h6AqcB??j1{5q!T-0e(>7_1KxmNP-zrWW;6O%mMnt-%tSJ`H@45%Nm zM~8-c`)d?gY(s8$8qz4=1c54yeW?2VM`K9&_J81%r&WtyB(ANuw)cLb)$r))>HUg~ zzA4Xu73)GCnj9TObzv8Yr)n87hxod=iR9_me9}8s-wS`MXLc&l-vu1kUtK|`Wg;pK z9bjf(=J)ln8gCY|_d686+C7za&W`DfaMk~;WBN0b*5bkSux6Di{H)VD&iS~vKN3{1q1zc>U1hWD@U}p=^vgg1KQtxjsTi+88OA{* z`d%I1Z(r(sQa6@2iolam+t)!H17z%4YZt|gpz~PKFPURPom^p2C+lri`run~ys3|) zHKBTgGLUIJJ|h)im$!TOKG*!IX!`FC68aBRn*Sj(FD`zRVn!tPSJN)NERYSVR3X4c z={YEQY5nw(gkGX9nv^Ns$pAat>F+=@qW4#Va;^2<1q!&zaU%P&)R_cYbPb~-pxNBu zYsi!GQKdi==;otNg*_|Z3yMCaaMVmP z)!!NXcKGdIr+Gvg(M#mvh6SL`uVg9+-PW5^l`7^v2#C%vP$MAi@)M;TKjZt>x`Tu! z6g!?E(7~deDm-D1!qgitVerUg@22FirlQ$#Np8N?YHOCRr@QW{z<*5{(2POmNgp6~ zy;Ac45tSj;SqZ9AN*k^tzHOHsq-HqRsZor_0Lgdlk*?Y2^&zc&2{lhkCPL+~9)Tev zf0n?gj`?W`MgC#w?^GdIfQ(FwR}Rb>6jLM>Ro_SroEe5v7<|4b+$au z+Z6qv8pfSnEX+E8>S*+lcUr?Ay_D`^S|$}VXnM$K1O^mlg$M}nmJ99-)G)%TO-`R{ z2NCn674O#J%@tsuI^y<+wMvb4Dt_+l!CHCCGINz(A};A{@*PhI-m~*@ffJKg^y=HM zrF~l6M@4JA;K=8ah%F9kT{|2KB!@{0|5^C^b4%-%wqqo@fPyFoSZ6+0Na)uD)nBI* z%}Gj|9g95K+7;EW9Ge_*Yf^B;%X&^dE&dbq1DjIkgZV0)GrI1?dN9%0)%lnm0;?Ru zak*R0WlT$I$llwvrM9k@9(zk~h~ozZL!{SNjsukamji?{Csl_Db=nx?q_9FBxVfYo znkM>@h)`sBY^!>YjVB`l6f-G0PHt-s2@N!dS%8$FANt2Ozoin}xKa!VR*|1jb${Cv z6!bfCkvr$C-MiN>PP{pOc2&mKzYI2!oiTH_P4=GfXnPbkzs_`IeQN6Q{cUNW>;c%% z-|wJS+e2tOM>T$?8qy^g0rXN6MC~Oe**C`X&*kkc7sX|peBKrM`r}&iNs>)f2&B&`YU>lK} zcueq=ga;vCH+@~*`XPrT-aR!C%_dj)D!d-~@uTn1RdS%_u;&>GE8xM?_9*2IHI{pT zyu$0o;55p+lDNyuY%g&P{^{y3;GvG& ziPw*we5PlL;DuQPc z%xGcvifHz^qAQZ1^QW-E>V@~?U`I{lKayF>0nEI=lb7+r+MieM@1sFs`wetcO|8>9 zUwpC0_`dhsbr+tJ^4A9c`*qN@qJx`mD}gx)lYUl9Yrl-nR`x}Rw~owDk5W~6>Bcu?3LAW~U$8-@3gImyPb*OR)m=1X$6FJ)I z$j7R-YDaeTvQ*1IM7X|b3VQXb3Q2W`9P4Lyyql@J%&K_|(Y-K>e0gz0*5!cy_lv#%!#v#bOnmil2pR_v5#Qf>zQ6uK z(3qJ6$=hRPo(CXRR&NBLn%y9%;|pH!Rq1vNeMO&=2_WV!Czw;~;7*EUGCbwsJxbOsoIv|+Hd>36-5G+Ys%)8HrU(zQkx0|6syosBFPo~DWMEK?3~j0 zL$TQcD-;obFB`#p@E%)@RUuX4dSb7nwbr#81uN?1Sn|Ben}u#x`gUlb^`(Ai6uvcj zMxTG1netb?dm}9%YY9Jjj4GKqJIw0eMSm!~vsUjr94cCk-_p70A-46lZg-grel<9_ zeP;#_Q&7~ihegQ#lbr>+6j+KWK`o^9P1$LAc>{!Q_J@$PhSuS;jP4)G`p=reAzBVA zg>@WMw+S^RC(i#9lnuZWPc5=k$55`%!$`~m7OLWoic%(3J$Bo1c}>Q_>2wT@lx^e zVW$0s)eZ_;dQ=}`?|keB!Y6yWd^Mn&V|wULgI_{0i}p=d!9wLQjcbu1q)D*wqLZL# zR~2@AsyN2WyHorb<5Qzwj0tYxD2ZmJ>ljs)w;0MwNbL!i+OQEfhqMrIQ&rk(hN$2Z zE=V)kZAR;t|3I!S<*60rURxp~;_-W_y|XcE!M6ri#`Q6SJzY<|n({Wc)@{*_W;=VS zsVW?36SrgkHe@}4(|h83yLz}8aUl&i;i@dVVLtQK|2E+O&4%meFU6Z>`iN@Ufi??2 zS21V4jWW03Q!xq?fa0Sm831>?+r!Q>#;#v6?(1$+$68b(^EX-r6_ivD zsc=J;C(eU|83N^tp2+_~L_wuta)hS~t1aB_0Ns!N#6gc?f!iUOM;VO|ew<_e-CxI* zUZMw)YPw*&G^iWTp8x!OJ35fyI;Nw1A))m#t4b=_CR1uF?_i17fn+>v03&HYWcc(D zc$}XOO4tsV#jc+P4DhD?U^cT9_G=P(hH%cGairTXZ?Jp6Ol5qqe3Jod*>yk6=`ds;w1%01A z>|`V*fZ5`8rY{1^+uNJ3 z@=HUPSCw@GLM8#k*D}8Vw{i`}YEQ|SjZ*r@g#J-&Q?h1AqnC-Mv9(|9{9nmXSkS|d zFL`ZCaTW;7S|A2=qT<90DEj%@lLU6t_kx zkl{@jU#}v6$eC_VMRGu9aQhUGRV3;ZuQdlOdyJoVuzex-=?!9>7sUIX)w@pZSq}gK z@BWJ4=}*5P#UnZSw3$4_dy?=uIaBnW2|22=+wrn4wbjmy8+N|IY`i|ynQBR+C{&za zaz;{lq}4aG{TPnC7`uL%aly2gRv0#$tfYN8(j2lKd}6$c#kp%h3NGkD4E?sBxjw?< zD;R`;CIRzHiG%nlf>w@CpW)m7FF=(Oq`M8ooFZE=rS7!HDk3`8u8%O;sHd%WrJgic zK?00+$!9gNjKW^!L(6@IsV?kxt6d1_LvtSKH9n7&Nmxr{1pU_cEbS1fbXGfm@vNRL zt^u6^XuR#w#`eX3DqsVtI6e#}{qd_h?IguSH78*;w?Z*bZJ4U}IPQXtVFF1e7kDW+ zd+bMkmW{7CvYzb9NKwY!2)!|3$d@P2PUK`7$akXr@z;TY{GrY;rw?Hm6Mnj?_6Xg%!75&`9` z+pq5)Rs!};FBgv*VWO_PO!Lm|s=3LR?dT}XS(evC()kL76N5oNi`(wKJwD&*-$f_e zio{@&I=erRKd}udKJ8^#d%9N|@Txd~D}>*t_=yP3JV#iN+e3^q^70MVK!Cb=Z`V-h zt^&oK(m(tu`Ty{z3uAC94$SI~7W5$e!!=yFmo&|aoMF0bhy}|b5~W)P?^Y0xDZsIw z_bAgDJS~oz?}T@`EDc=^9~3WG!X65~qC`DRcdb&ppIb~~w05Bc2(_@JOCSOx*sRz9B^x*Wr1qr&>wm=*~%}V$* zT_A^V2E(eUdYVWmccLysADroKQC$Cb)*3lT!(2*k)7Kqv?9xuClfH=%Ta|%sSkMP| zh>7Oh^wqx$!|5}H!F?&Zld)w%dCSocmjfhlN&`&6a1Ae6+Xr7>)KA($u# z4qO^g z4L9ElA?xj+^BFHhBe>XDPCIs_Akp7#=#>^t`<0&)UB?Xc0-n9)Ktptq36p(KJBv!h zv!QLC+o2+jtNayy%ucQ+4`DUN(~?w*(I;>LTXrdke5YM8Vdn%?g~?ANRKwtkQzgIt zfVZ#tG@Q}DB9AUL&8v<1^tR2>jCh8RKiK=7@YfsXgO+=jGbSd3i!cL_;U#~>@=7Ir z+Ej`=F8=s)_ut5TfI4&0_eRxqy3>HFY`1Q0KaN`QbF=2P9p4t&!o7x!ipGFh9>+lF z273YzMNJiRB})C5v_9CBv=JKfH-ZEsxB%Qmpgtngq~ydC%tj zJ9nW!OF=aX)XdCpk@iv}f@ol)c=H?>Aqb*8Z5+`Dmo^Lb(<0OzCJoP2=$k)=iY%pZ z#SY;2NJ2LmL2PI6qQ_MnQS%cg;M+#f!i^z|Ire&7L}~cA*a+=?jBt^IM`+S{1Pf>N z7$9Tc?RtGV=e6i}iHJwsCrx>=TG~$`NH#Dg3U-W0Bf<+F|K@I+Xdc1i9Q&A&rdD!= zfhjb#7%oAIef-+d>1&MCTM_n;Cmq^5hR#zQQwzmAD7{#l!EIb`anqnPlr zx3%T0YxjOOdv%UP&cv>U1rg}^2u+cR?5uGAarR*G)BoLKOU?L&_%?ySJAyvyEwN9g z*`Fl4g1j9T=!Lvf3jeZWudPyW9R#e%H(jjL)R&~-r&106B zQ4*GKXtYmdI%D(GpGwFuUAuZGW%nkj(8w?QCzM3wl3p1?{^v)Hw*mm=*PXr zb9)bFY0JCw*hR^bO=esNFf0Do1)$u#mN>O|5r$TY{1yOz`6M&|7)}mqB6-j~5?XR$x`+ zWcjb%i7IdEIX<%dC%Xrt@+G~}WagiP=V%>>AEuTzd0)NIS8m}R>+QLDW4Kr`kQ~3g zPZK&Up+wS^?;Z-OmcdT!`HYc(4?_7wNs+&n$pYR$7UsAs*!KE-2hVMI8y9uM-tzX| z>C3BF;7_C69ns-ENP+!*c~@raI*?qH`d8a-#{<28Jsdagq1Ti{b$#$+>2{=goJB^n zaX#vd`WN6F+1zfC*qe5TV)3XPlv`9`cuxsS^K6#J)#_H*G@=C_ z0L>-6YwCG4ri)3y3reS>5Y)pGb$f9qfsqtvER>Yb=zo=@e_P==VR-mw`e-cndnNjc zT6WlBa8QJPmL;MjN9}l#?K=C$sdeCCiS?wUNAi2TQPsTaM%1W~5b6j%Gf`YZ6m!mS zQJK}ZDI`wNUp15%PC8J_+SP>>LCt+t+FpojUU6_;7*MP}foY2n@y@0NzNnP35{1Fw zf8hqUe}P`%;PuSryrqGirPU@Ujd=~SNq#F=<51CMGL_un>oG%RADQF@NqBVyl*29b zY4oA^Ro1-R8B&3vmqP?2O{mXSiU&NyD5c2B7CsDD_GzHpyxvS9c ziB@LFF;6y`ef#L7|081w;d&T*$PGu-A%TQ^O75v)TJQo&Cq7uM@dbGrO_uh(*fI=e z9;c1t&bZ{|B>V@o1QS@*z0(!r>w5iT!V2lDcx5~Znb19HTeyg0lepJs%J#?8N~Q3Q zmK`lm#ljrZ<5=E0anVVB3$H7iCn2&Wo6De(|7n!4ozjfzRMrbyWj^Qfu3OAFYH#eF z&H|a48tz8=7mT$OGaNn)Tzt`?yurHy9RYT}caJ9XKHaQN4Yk&Hgbv&UY^5>NzCdbs zGMW4Wtg$jS)Mo3b#K5>t00Ofv6CICVjmzo8Y(D+2*X1Ti@lShqzKq&;@gauRGKOyq ztksE`%c<1Z%y)JQy!X_Mm1uc4{%WBa_xbkDk!2fC-TK5vwWGBkhkILjdBN24+q->` zU@LJuY_tz%h3{4{K^$|<0;io(S1KvM>o05x@q{8ZydtIFZ4!r+ymT{}o0@#S++7z% z7Jc!42YbyWxqS-`_DQF5%QvNv*i6wWT>^Ms!tEY93ykZ#1dXzR(xQxzVoS)|tfDSA z;?u*dUPoojLXt;|tY?(dc$A?h(Z{%+n=qmnuYD(P&{49l>o)Hy5ZBYs@VWYzdbvmm zzWHWd+>E7w^z-**7n&5?wpudLSduf)Knml;zmSlaJgJ0$D^iFNItG3Xyz7+@&X=H+ zg@tbKR)2q3Iw(u}&yX1OC+9&~GDzv>;cwg*;N1Bc%C%+f+$WX9BhZAlBBS#hvi=@2 zq8=XhX`k{be|=v1j!QE~7nbogU*4hYMRSx#aD!e9;5T549M{#rDsnz8UPU=3UR3&z zLa>ptSpCOaTj(`sP12;k=CD)=zkhuFCJue_d!`c3X*@6KpIaMoWZ-6k6T%*|?FVjA zR(Hk5@(2vtsphT`*VHi2WUHwdm&XJip;vMP;+I=?i+eUf-O@GG7j+UfJho@zp7nuL z5Z*cI?&G@GgPwE67c_ah`ai2F(dMg_no=zuuU5$ z507^*9MX@FeG9u?yTxI;FDXnrL(8x`u*=#krU7Z|o8>A2`}Jo^*Ct_sOaU3fo5acK zs(2U51H9~26`(t*A?5Ed*Ddj zW{!EfLd(NA30IH|oLHMxSb0JWcx&eR8<}?qzo|YMI;H%z!+>dkg8#eHjKGzQkXwl! zID7e%Es+(GpX{Us0`ANcjRdT~Xv@B@c=E@;q_PZ+k?Gg-S46`kdwCF38;ep+LSp$A ziXZdALedxs$VBL>h~u{ZMxMWsp>cJyy%YmoF0fVz(AK6iiUR+*J5}NJpef;H%DB#D zAH(Ng2y~(aBfeYB9PQxBbpsE*Xu(Eq!Rn7Ay`E?Eux(#&4t`uKYi%P0UhbIpR6d13 z2xur7T}8wErx8)hGhSOeW1xXfp3@gY`iBBf*AgUl7%pmx1l$z4 z9Kx=zypC%J>FiWAFV1?+4$EIAjefiQk*)pyFzv>7SR;E8UO<|q`bQ{|>5P^o0z#B5 zEu>@Tw)!#)u&9ou-*D%0wNksA{O!s<{-A}_BPrdXww1axCz_#N-j=67C8+8RvTNZ( zlBWlwG^Z00Q#@r#TAD$X)4=H}XAZ140`Zg=KEssbB_ZQ!EcI6-IJVzfRGMV)ykS)L zgj$!Yf}Y9S(G)CuS?wi|>5g&+!~09kHXGx*>+J)AdHoofn0U1RT9$C%w_)$x)anN5Kg zF)pVa3ISgbxfr*TgbieX5dc>{$_y~3Z@uKN5`!UabXJDVX>~mC!Ch(m9Z?uT67%v2 zaeyd+q9|X69f5j73Rh)QPB;>Uw2vbEd9@%ydf!~p9kBAa>DJZ#LR!0ClYl_afY|}z zw-%dA8m@U-Ds%*@LLhXf{c0NH>!)0kHM}w7Qu&H?_ROGg_{Axr;eFa?onXqIY%SDucCE`+R}=P6 z9(}AtKa)rTKmAX%6vUlyr(%{(yHX}x2qf$#jYT5gRMcamW?vGkjd1CIolv_7}(p^y=zmd&Qav#EFjfb4PaSQ>gqT*+P-Z1P|f z8_3w*g$hu*2(8UNS^0jxBXn3$QS5)Tu@*V5?#4`71`c4_s4pzo#5iM-=I?~Z*cat^ zy^Yz50Qfks?mtgOwGO941KLl?2(wFnFqhUx3(VH!$WcCpDn6Zms^l_xH!Ux@p-t-8 zW<`5lG#1&35EZCw%eunOTp!gG+-quteC5?Q9tw4p@Saj)W{@FgS7&+dF$IyXdwlku zbzHU3qU%DIE9gm3C&M^K*UKLS1|_>yYgvud zx>6*CuM%Ky|J(V4sBY4oMY$xxHo>E!VRLO`+otk$s)0jN>Ie!Pb0*vH!`S^t;{Kt` zEO?%KH*cVo!%VR6i+lE{zco(-|7xBB0JxoO>m;4^S`p%FQoc>by+}kyUCUd7Ms54^qe)AOHwK36csH?D=W+-P9(MFO_d^W>mLR~wRZi`v49DVfrucGSISC!IgE z{AdQh+e8GrNxu8zj~Hpv;GFmBDdpARk?b*}^7)6!T;ykV5(>7?$`?#{E2eFtefrh9 ziLv}?@mwjJr4{(Wjw-p3{^heI2PT!o54PR~1&*)f)n%Cr%Te64Y*j9Gk-$^_ilNrM zT^*LvE*RD)T!p;6-`HF*bs8R$KcTl=4XoMManf)<|gTXN9&8ypT>G(DtD zzm_sYZzHCQr2H-v(UuA!i18K3l%l>Q1G=)aGa|#p1buue1MN93j0qcUHV&nD9OU7; z2EG$8X%P3_tUYFLdnK?$PQkVQ)-7S@2Z zSEUb23aubgsDtonz*|<4Q>78W4kv#*G%vW47;1)il29DLeidttOzkxLLv4IO$mo8A zn^(Wu&dJ6OSstSGb3|~>6565QgxeI1XIKnuHEx1Kdwzea@`g4invOTXRmS@aWiA0d z;CaHO{{VehwBxDZ6395eHAIw-o}HqycMDIjRUsa=sW5G+JpjoPeIYP<&?F@&UH*){5x$xYdC1*~D_%04gYJknCIOx&2+n@o zaGMzU7j>n?=*sm?d!YPe#@8{h_%F>x7XEG8b;k$iaRhsy?ba#R5rO2-WJm~`df)zE zQ;~4{xf+CafdOA6-Sbb%n7Aj56ww zgZ4(Mbsf|>DO)D3u4yJ|2BYDj`BXcqa;Y5(Upk|+ZltYU(;>bzHPsgS?>=Yntz}X^ zv~)koXP?9-Z8~Pf9(|Of)YW*2H`U}x?te=Yn}v8S9)C3d83*;f$u)ly@n>*lk_@CP zHPy|Cfn&D2ESM%S67$0)#V$Eok=9=LE+i=t4Xz+PqhGFkCRu!EyMUh&QrLfXxn{I~&eZ8{P+^%mgJ0ygn+D4=@<#HboznK=3yQQ#GB8PhSjRBu6}NEYuvXRlD5O z>keCXRMoHeSl03qr?4=x-+L*Rk@C9UfuE<}tl_eFzImH@of<5Qv*~?9*`MXQmUlUv zT^n`nxGJE@0s(QG+qIQJ*+_*8P_BzXo@RI^!=pqm#h{vt9=HUa=U;MpqB~&T>qJ@V)P8A z@+7&8y6b}Gf%UbKF>0Z?^~T(5n+lJ;7V_-NJ( z!#(6J`xNNU&KP&Fp>zSg*LV$+PjN~P%xA#vbvl;ijSyCM3JQTyu^Y}M%ra{P__6yxaQSl(I*=cVQmJ{(n)`2I_Wdzo@BG5sEIdhO6k!j2OrJU_aG) z0DseM+_`hcaVVdU1kek9!PTQ0xSCzCjx z?4V2go>Et**D^Xi@-AC&<8quZS)X+JA@;6&t$g98dR{BX2`xd;AlG2v;+!FF9?T9^F74`sZxB%tT zi`Jf-WnzBB?0t0bh8|=oNrOiQt-Ya_n$lbc!-Oj`BH%=gqW33=cm(i1$4{%^Nm^8A zA>%)r76)#VpXx_bRQZ;JOu91uYq_l}N|~B>6a$Yn*@h~Ld=8QekRa@Bmb2;I>hLGIV>ifRRts4<||FQYt#-HLrfEoSa=`n5PfRlF(lcQ00>rmI_ zeI9TTbaMWC=%F$TrM59~_PHE;E+$D>!0Y22m@7J>`nPWjjcWu)$;Ss#J{n2rL|iRh z*6dZbIJ~ZGqnxc($G>*ta{mjuK)*vv3nK`%j$wpM+}wz;P6W|OXjax?83tt zBGt_%#E(>89^YhcKm+SP>$j|`_o_`#|;F8uyj)S~v z%#501t0CO#f2AX4h#1nC+2n_C6)JT7jBo-7mfF02@AA1L=3c*JC8^RkmHnJ98{6;kjpf#*_knGJ&I@+CDNNAS%FRsQIcRkYb#MGE|!W zM}=w#<#o`2!fXwr#Vn4q_lZH?Ewo7LOLg#WpaFzwMP86L!H-@Wr~D zV)<_$tO9zcraHW`GS5onzS^_Muyh4td98NG$$`!#Vt9 zG`Rx0Tp!SJ7xST8rJALfLpvw)GSV&rkMgDGjjQ8E7^^NkWKq#A3YW4;V}Z29N&mhu zP{a{=?DYX#of8mW0*t6*A)HfGtZ$7~SR43XU-5=@+|w};;$hhzW2_BNt7Y9vE=xY& zmGLBbK26)W@72ZcC0dH?#9rRl65y{@!=7}aBxR1cw!ZW98&_Zas&LlfJAUZ0n%vmB znpNX{MKNH{d#VLZa1D6}^dB&5z9`Z^B^{u+nua)lv76~KxI5ZT@j(S=V;b8#n1q!q zf*v}1M_O>d-0gzilZx84MY`PU+bbheM(akBy-v}yKApoz9pQxM#1CrQ_AjDtZCq>N zxy4(zXv?rTMc~DJ^&LaDm%fMS@)dj5^IPAFNqf)Z?#Gsn;?E*&kN#yK&cJjfzm+YQ zk+>dnR8M13$PD;FHj1+7Jpbm`GA-zHM{{l41?xqy*L#_zsDbR5sG-S08ZR^V*mXj@C(< z4<>5+d;2<;`WF_kJS%fk);$Dj6{4#(9Cr7<=y2K4?j zEsUq z*Q)H#RbWY<1c`OMF;9iar_sUA2_-5PCFZC0`HZ_S^KJKsfX7fkI*5G;IPQe#2E5Yi zD_sy+cdyW#ZYzmK!xAWt8y9^{aDfzd81FglJU)NJ?*Ol;-Zy90?erMZmqGVk_CpA( z7}FDS{mrRKL~5e350c#YK_IJ_-UOxP4SdgmU3QWYH?v#D5c1o}H}A0uIIB;k?!~k=3Sr`#Ko=Em{l|H0lj)OdvwnIu68qb(%08Cp100EC#qFljCu}PJ}R6+ClpL7?$E zMK^bPLw5Wvy_b0tk*Le@-pmUbY3F-S=u9T7zqxN;4L2-^d}jdE%%;JnWQu`=A?+9! zk1*0@v#CbI0|27+8_~8K#Lk}JDSyLH`T9KyASK^HC+#nk78EwOr*r4vL0dUC2N{NKTi`%S!bVO;U{VT}W z^*|({$9I!v``V}i=kQ9?8)ugWnp=VL)bILfb1wiEWoXHMVea}@96Com_6^C}96}YE zK)ru49+b5$Jg?}UTil>rqPcC%{>qD<3xbEuDARUyBEIT5=AK%r@))h8r#}a+6qRV! zZgZ|N=8Q=~(;ZI)j|WI=-$!`N^XQ@|@&U;%2M8O8(oL{WpAD`rlWko6d}t_0rFqjW zZYGb1pO!v6HX$$IhAw^olC)y=nfG^DV|d7r>hdrdAQJ2j4H#;m6WV+^eysa2;rXVb z@`GE2&>2z(r1dit_7>1wv^8w>dgO%fWz8(bdbeWMAQh>-X-%qyLwFP#EvPQ^I2|*= z?bU7E9bbY1Y~k&E^#w)5EpiA{j#R0$@as|bH>W|o^}{$&ZP2~eYSVbgp8bqESduB< zvD@sDK=1e8@II^}!U!>BkJ*5`!5u;>RzB?+1w&u1Z>tHTSooYs`A0J**z}r8*}uoK zyq2kp%`f*XzZ}T=B)sHy@yYuYMVIgDjjjg1q{P76-*p#JqmDh>s=LO)knYO@!f%^sY*AOoFJ-iE&|N zrA*Ap(@BJ8@=ZEzft>J!_@P@$)@>_^_`H_n&xA%VS(~3zeeV^fLs>jjVNbc&*gtOR z`!*QB2U|*jPwrumZa|F7dp|Zwqw$&F+s-T^jwUt`>!XGW@6k)CPy_#*r|>I7e&?U) zp8JL<4tW*cRwyp7+lzwQVtVjc*L=Z;HKb>|4%=g^FuJDoY*p)d8!!Fsdd!^wS%XOq zQ(w$C>FUYR@v+tToA&wKwcSY%1?pX3jDNyvW;@)yC&=FPlJx->QeG?n)%OIHlnA}( zm2#`p3l;2Q^?B5(OO@Q`@>PHik+x__OWhOul#!)L;-R0^@9mesqKjmms6v}al>&u! z3vPGZ^LqRPm4W1)(63zjG&m_E&4uDWHw$w}^a}8lQu)T%c5dGE=aCa8UHQZU$^Pep zF~gFG!nV00UYH8Tb@Ok|@_~u%9clPgBT|&nR$KwEdl$mdiJf@e*MIaeZ#@zE?k@VG zZNn$)TP*8VSXxyv`A(C9V0>LO&*}4FRH0|r7Y?tji$tD!TTkN0;m^YpJ&KI&5d^SJ z;Ojsva#uXuzYfjkc;0~~K@*9QbhUKWiae7|;YcpRrHU2uh)A;$@5!0F)_+;D%vCn; zroC)aIhkGf4a9%yAnNitiZ?t5(J4AK9en;}&m#TqQ79kxg~(#_OGy>}aZ+`J#33;7W#n0$Aphxf-t3^2dSlAw7z z_)OG^jKCvizJ-d@$R)hP4!^;4bZRnHXg*4Hgh#3JZg>3QWmspmy~=i+Wfu=R)=dXj z@HIu+1<3)uBISV>={o;nE(rKRanC{e?LFw(9oBaZo(Q#Buqw;v+#5Vw!ze*Q=y*9; zQW=R4nE;&=vz$L;W~MIq>*z*9q%ok!f2}#+eED_=mabS)>%Vx`rmlOsoMKz-4^o9i z(^?w?JR7U@g^cq3Q;XFR?xR?(AVV@^1IQ{$f3xAetFblm29N`5xr(54j^b<~y|w$6 zp5YBK>@`dg6$9w5@9@%%uhrlHUgXO)IqyS}iGiH5MgLp?F8YC!=newN%F?E};^A4u zZnb{rJ8W|pVztw4x}J4*ZZO_8Mxm4eVU>AsLO}1XZt_-7Q7wP@4p^!jE4AbN>8R1s zhi|OvijMBK&2x3v7XSeNNIYBa(4+|D$=C?N@z^DG*jlM{o5t6o(!!y~FC z6PVNvT5&P%R`&$BVP#<+_y4Jn-uzr92!cMO&jvaRP$IWU5?WJ2OO%)#;!|71*4tR6 zZKYzOX;OvUxgTa@VZkUSnLyH2|H3m}^MlK?jH_cqpND$N$MyA0bHXV-=^Re@pj^pM ziTT7@hhIAlOc;!H+^S%^Cgxj=5&=t$?pOAI5V8dBAS~9_d3&w*MWd^`#$3=qGWj4# zQcR9E(nQBeTp6K#zElQ*%vCeiB-fH#@D#kJZ$3)OT7!o8rE%0$vSGofc`sT}+=kB- zuSmketBUL)x}&ePX&lG<4hGVYu0151Z_O>MpBYxSU6XrQrLHyC%9pnk%g00|u5E5| zK#|57BLF)Zg=eu6!!;d`Wi^{O9iM4W`&*lD~81hSDlCapsU&_ zfs!Au+NS+rZzhuV=As*2m!gk_wi*HGiaCT+DV<8LQEf-?6{qCI8kb!f!b8PA=wmZ;Q*C-!O8J+t{HaLsBCh_*Pmail1J|l1J-bJ|XYZFi z7xWh@=AM#EU4~x<@8qouw_#x4Y{l)w@7xfss%ie}qE&r+!}|Uji#&)rijG87>?(jH zs#2ont;;gtpoTq^Y!q{$6{s-tHTvWOKO1oqj5OI5C-s0%_gAF%}&&mZG2R zh8KpD==>0iEB*3Ca6Nv>w35E^+TC4o0=A!*KKOiqH{sXv1tJ=Rri~5hwB+>$q7NzW z&{98T(nmo^RglXy?(N_;^loP?T?6y3EXbt`EC)i*Zbtm73jA^x1idi)#e(-$v8|&O z0a1l}1@Xhrv*R}>o)53dtAKn6X3HN%CO!+KGtfA_ps8|Ru4qkS)jQYlBd6r&<2(OG z*S0Y`-nP5GcC&-9ubP&1gzKb-QBF6=lQJYtRW0>WL-h+U46Ur*dVx0?KBWh>F^B$5 z3jEc}2k!ng5kAJeKyfGSO#5blaZMZL!NGPxzE)C4`1Nf(Pql~s;$;vZY&LD@b@ePM znhI?kpdr?*mdt5Q%P8+>-SyqNGH(knblZ1$*RxFy{R2bLMsJJzgEA&*iqdBPx07T; z6%WJ5<{C&QK=%RLP&)~@qhP+By`UefIuiWg5bQlMqTeq`B2{rAW_oQ%Wo(ooEqycl zm|w#4{=-wo7#Mi^=hl3BcyI(J`f@Y#?TSF(bFJ3!X5><#wLq{qI6iZo6?X${UHtB% zFP7QCtIBmg4ne+~gxxc34otDf?!wxD)AdHqjZ+g}-4Au-n!wbRnu7}CHJ7K?T|%5p zw$^U;BijeGA6T@j?{(w|Jx*sGOa$_ns|d!unU+QFVUDV|rFqG-K;hg0n<^7R`=Q=H zYZiet$h#dO{tAm9;=VAb-4~TndN9;zLbHcz_ghbhG;5L1cmrf=WLeKV(a6t<+cEYn z>?DJ?AwcURF|hV=5>~?!-J2N>xL+PfFbn`^!8moEWZRCaLcgP=%n8RP$_IP-gE~@? z`X{Pim6Zvclnyal_UoBMS0@{yoBO$!NxWpaGKG%o{MrG8q^q7Q_MRUap5{~F+u1{0 zBn%sN$m;7M@Y!HA3fmeFvYraJ)<}}OD>%|srK}XPy)9!3JN;Ixu6@=hjA*x0y%WoH zY##T|%=|Zg5HE-S6W@=!cGrV0Em>AB0``COKuuPQxIGo*mD(^nuWZYBe+jru=1s1r z%=3;rx@Pt5lM?Y6yrLUv*iGw3c|{_`ZpTK#&+Tc^8kShOUe`|MJL9C?l+)3+MTpJF z>a!Vs+01IkJg?W->~~PMeDM}T_hszrd5GxsL0i(K5#bG97U^TmRcni9j6x#x8F_c? zw8Ql$<;+vw9(f)%2qHfD4G`c+Jdi)T(;@Kk=zhA4se}^R9o<5Xavp;5iGKQR+lL_A zR4jfT>iQ?bKQBoj-~^G1f`Q~QzGI+qa$=%~&whs4;d{acu4`8SFr-ZMdMt+Wh3C|7 zvX~dnlR4ApNiSd};C{y=N8+xK>-0 zwb-n4@gX{T?kvxFrJMsVhHr?H!y5!7iZs${tII_dc}J4wtQ)k->XN2JR_fc&o5x?7 zgWf@5iA!6D-wI3LK8S`nS!|uQf|fqFwUGHN7Pj>G-e(LX3$Hh8JYQfrHFb%$Xy84* z$tx*pS4`50j7+T8RJjRzQntC^A*^jRK|J#}YPMt%C3J~uc2&D;UU&5f4M(@-{o;KFU`TCvJv)0Bo2q6}uWp;B3lb~4+ zWaTR9s1_z&foXZ#9G}O=Tpr0=or`apC>Vj}jJytM2K`O_cb1K$6aj~A8~_TBwm6g8 zbn{VgVNNj_tP{-ph>|QwAzwuJ{nOo=ixPM&(@T^YJQ&%#^8YdQ7F=z%P1|;hOL2D! z#T|-!ac_&eyE_ysP~3}akOIZsU4y#^cXxt@eDu1Xcdc*DA4txenPX<(x0z#=7fPcN zS-KUjZ7<7_E@k~d=s_X5u{y~I_IdnN8iKN*xQBO~X5iyjC9`nhedP{IhQqRa8`{4w$Ke((ttO@o;LpU#0th=AM{n!B!Jurl>E< zVoNHbqL{qHgU9_ABr8qil9pBMiVo#J(CE1Dv~YrNwG2HfO~2?U)#aT(yH{54_>otY z4>nu1n`&%qIE!5FD4R9$48L;o-tOpdKabONuh8KT5c)MKnzTMQ-{8OQG{3~bm60h> zyy^7(%t)<){WX5Ooxe{>EMg~mF;R&f?|~!i7R3(g;?tDv`(z4^E!bZ zHRrk`>7gSb_x-bhFEV9`0n1CkLWb*5X&`7~`f~`$>I*C3&=tEXpaW~CvCXH!izV-n z7cO1+x?02M{#zYQ{bkSl=ehJzJ10!;?;pr5(&@O&QGRt(X#-WwvpG=AXc(OysWhbL zOBFM51C_L9EC@hHK~+~uP63+rR7 zh<(LoklNJ74P6>_zS1H+xc^zPwm;c{t8QK6W8$0hCu_|-dRQ|{XaG5tHOsiR z&@U}ZT1V}`OcA>#UwgTmPR3WG7+J4*h^E7c^yF+lx=Kygw$O&WH=d-Ao6grZlZQ)C z1TgwS^aAQ=Jh!!U4o$t0&A86(;ekwHjGQPQ3tj6z`2>hL$t6*;2I_Ju<9ZZy#7;}T~ znlX7}LyV^4J&A8NsaZz;iVOuKWa7;P!&?YF7KB(#<@+=WL;3*&fFtAg08K}*aMKTd zT{2fZeDOjx?FzcUml=BfJ-X$xhJzwb7Y&VJtl|rEad z#L&ZzK8>9}^-5S?D_B!47}hzdiUN2}@!rdEq6>WI9Km(5X?PDznaB1gv+L5+!wNG> zdij3$OixD#UoIOaCTsG5n#+eP4ov{SNV@2HWcfqCB2h4bjYp0po|P_g)T83S1N(*E z5(01+%PvZpLhJ%rPvvtOJp+si3yk4f*Z!fzNo-%#gF>@I3>Pd#7U_;Sex=FI5Ujl& zDX-$z=56qAA(|whn56+eFsS_aGa;t%b<(B&?;*jF=khP;r73;aPs4AFA+yZ8@zj5ugVVrxiszjc?$@ai zVZ}%$sIGE>!bQzOJsCmIV%l)bxu-rkKSVP z#0mnD4Me}FR5YRh#cL`4RjYXeb3+kx65H%=@MNYQ*957{9a{CqksZM+V_4Q!s!0S= zF}FN5?&UiwW_G^O=WZ*U)bZ&c-D4HBBISKK{r(xw0sHvk zKwbdbH^z$)l(FM~Nb)Nrhrl8K)E)znLFxZp<%6u1=)CFAPb6c4xs0hi3^19WVHWj0 z$yiVI@6RRT`24ZZ$5fqV0iHu!6ieqTqm%sBi2^CnDrHELL(xk|5L72sy!GJf3%SMM zcEngnv<$-Ay_EC$8(7&8jKiZh8ATxZyD9G?lHC@@)1Z6FIQPqNm8Aq+?*~<~u6u{{ zMdsg?!q+u8xDxTM7Rob&6~jk&No)L_7=uZ}r z7po;_#Ony7O0zYnukeYRT(V)-%NE7Js!D2Vl7MM(o&P0R(8at`>?|<%Fqn7MN&&+w zVOA^;qkKz>-;ozIS-T`G@kQfy*oqn0_#yQ)WN5MoBj<|}y-Y2FkxBS(@(Vqb7G%!y zC{`~#v*ZY!t1--THZf$)nudc@AGObwOq(;p8Ns8^g!|qd$K8peVg{Ulw&X>K&#wpZ z-s{~Q%==v#K?0xt0x1}R9HzcXn_W(Mj_v&DdQfPm^5;9Qp`h^J`91x*U~Jn{fyq#a zq-X;dj-?g)dm@}fphfEHh7{Ovx7s{~K(24C&K1=ZVz-oBx?urI5Q~$ioPX@GM=?#uiHx3kWzws{V6 zApT{7P6TQ*8O8ZZF5g6sEfdP61g!sk0BN|^W2RRenI*d}iV=(v6msW~okU(E^~3WL z7%cOzt^~bkYWWXq>ZN7TLY0(L)qQR9LXY;^El7tChT84=s2BbomGszVvMgnPr^b!V zC0CJBYA(rUWJRoijqE=NQb+O{8J`I3wu`#6$lRML1|2n#)$mHQHG=6}5TAoLanC}F zrP->rdCB;~dk`E0->IRn?3ntZXG^+vx5gs_qt1UBXTK$5%rG>4z5v{V^K=l!$h7SxtVMWZ;;I9$i?$VO)DUJQ5%?2@bqlxtM%0DGuwbv3{a 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%0AKGP|eD=A+K6e10I%60#%5EsGTHrS&d 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%0Av}tU}%Sk!=nUpGCGLo$y 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 BBzyn> literal 0 HcmV?d00001 diff --git a/deployment/build-s3-dist.sh b/deployment/build-s3-dist.sh new file mode 100755 index 0000000..2f2b7a3 --- /dev/null +++ b/deployment/build-s3-dist.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# +# This assumes all of the OS-level configuration has been completed and git repo has already been cloned +# +# This script should be run from the repo's deployment directory +# cd deployment +# ./build-s3-dist.sh source-bucket-base-name solution-name version-code +# +# Paramenters: +# - source-bucket-base-name: Name for the S3 bucket location where the template will source the Lambda +# code from. The template will append '-[region_name]' to this bucket name. +# For example: ./build-s3-dist.sh solutions v1.0.0 +# The template will then expect the source code to be located in the solutions-[region_name] bucket +# +# - solution-name: name of the solution for consistency +# +# - version-code: version of the package + +# Check to see if input has been provided: +if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then + echo "Please provide the base source bucket name, trademark approved solution name and version where the lambda code will eventually reside." + echo "For example: ./build-s3-dist.sh solutions trademarked-solution-name v1.0.0" + exit 1 +fi + +# Get reference for all important folders +template_dir="$PWD" +template_dist_dir="$template_dir/global-s3-assets" +build_dist_dir="$template_dir/regional-s3-assets" +source_dir="$template_dir/../source" + +echo "------------------------------------------------------------------------------" +echo "[Init] Clean old dist, node_modules and bower_components folders" +echo "------------------------------------------------------------------------------" +echo "rm -rf $template_dist_dir" +rm -rf $template_dist_dir +echo "mkdir -p $template_dist_dir" +mkdir -p $template_dist_dir +echo "rm -rf $build_dist_dir" +rm -rf $build_dist_dir +echo "mkdir -p $build_dist_dir" +mkdir -p $build_dist_dir + +echo "------------------------------------------------------------------------------" +echo "[Packing] Templates" +echo "------------------------------------------------------------------------------" +SUB_BUCKET_NAME="s/BUCKET_NAME_PLACEHOLDER/$1/g" +SUB_SOLUTION_NAME="s/SOLUTION_NAME_PLACEHOLDER/$2/g" +SUB_VERSION="s/VERSION_PLACEHOLDER/$3/g" + +for FULLNAME in ./*.yaml +do + TEMPLATE=`basename $FULLNAME .yaml` + echo "Template: $TEMPLATE" + sed -e $SUB_BUCKET_NAME -e $SUB_SOLUTION_NAME -e $SUB_VERSION $template_dir/$TEMPLATE.yaml > $template_dist_dir/$TEMPLATE.template + cp $template_dist_dir/$TEMPLATE.template $build_dist_dir/ +done + +echo "------------------------------------------------------------------------------" +echo "[Building] Utils" +echo "------------------------------------------------------------------------------" +cd $source_dir/utils +npm run clean +npm ci --production + +declare -a lambda_packages=( + "custom-resources" + "workflow-common" + "workflow-export" + "workflow-import" +) + +for lambda_package in "${lambda_packages[@]}" +do + echo "------------------------------------------------------------------------------" + echo "[Building] Lambda package: $lambda_package" + echo "------------------------------------------------------------------------------" + cd $source_dir/$lambda_package + npm run package + + # Check the result of the build and exit if a failure is identified + if [ $? -eq 0 ] + then + echo "[Building] Package for $lambda_package built successfully" + else + echo "------------------------------------------------------------------------------" + echo "[ERROR] Package build FAILED for $lambda_package" + echo "------------------------------------------------------------------------------" + exit 1 + fi + cp ./dist/package.zip $build_dist_dir/$lambda_package.zip +done diff --git a/deployment/cognito-user-profiles-export-reference-architecture.yaml b/deployment/cognito-user-profiles-export-reference-architecture.yaml new file mode 100644 index 0000000..c89e2a9 --- /dev/null +++ b/deployment/cognito-user-profiles-export-reference-architecture.yaml @@ -0,0 +1,895 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Cognito User Profiles Export Reference Architecture +# +# template for cognito-user-profiles-export-reference-architecture +# **DO NOT DELETE** +# +# author: aws-solutions-builder@ +AWSTemplateFormatVersion: 2010-09-09 + +Description: (SO0126) - Cognito User Profiles Export Reference Architecture. Version VERSION_PLACEHOLDER + +Parameters: + PrimaryUserPoolId: + Type: String + AllowedPattern: ^[\w-]+_[0-9a-zA-Z]+$ + SecondaryRegion: + Type: String + AllowedPattern: ^[\w-]+$ + ExportFrequency: + Type: String + Default: "EVERY_DAY" + AllowedValues: ["EVERY_DAY", "EVERY_7_DAYS", "EVERY_30_DAYS"] + CognitoTPS: + Type: String + Default: "10" + AllowedValues: ["1", "5", "10"] + NotificationEmail: + Type: String + AllowedPattern: "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$" + SnsPreference: + Type: String + Default: "INFO_AND_ERRORS" + AllowedValues: ["INFO_AND_ERRORS", "ERRORS_ONLY"] + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: User Pool Configuration + Parameters: + - PrimaryUserPoolId + - SecondaryRegion + - Label: + default: Backup Process Configuration + Parameters: + - ExportFrequency + - CognitoTPS + - NotificationEmail + - SnsPreference + ParameterLabels: + PrimaryUserPoolId: + default: "PrimaryUserPoolId: The ID of the Cognito User Pool that will be backed up (Required)" + SecondaryRegion: + default: "SecondaryRegion: The region in which the Secondary User Pool was created (Required)" + ExportFrequency: + default: "ExportFrequency: The frequency at which the ExportWorkflow will run (Required)" + CognitoTPS: + default: "CognitoTPS: The amount of times a Cognito API will be called per second (Required)" + NotificationEmail: + default: "NotificationEmail: Email address for SNS notifications. Subscribed users will receive receive notifications if an issue is detected (Required)" + SnsPreference: + default: "SnsPreference: INFO_AND_ERRORS - The solution will publish a message to the SNS topic each time a workflow completes and if there are errors detected. ERRORS_ONLY - The solution will only publish messages if an error is detected (Required)" + +Mappings: + MetricsMap: + Send-Data: + SendAnonymousData: "Yes" # change to 'No' to disable the collection of anonymous Operational Metrics for this solution + + SourceCode: + General: + S3Bucket: BUCKET_NAME_PLACEHOLDER + KeyPrefix: SOLUTION_NAME_PLACEHOLDER/VERSION_PLACEHOLDER + +Resources: + BackupTable: + Type: AWS::DynamoDB::Table + DeletionPolicy: Retain + Properties: + BillingMode: PAY_PER_REQUEST + StreamSpecification: + StreamViewType: NEW_AND_OLD_IMAGES + AttributeDefinitions: + - AttributeName: id + AttributeType: S + - AttributeName: type + AttributeType: S + KeySchema: + - AttributeName: id + KeyType: HASH + - AttributeName: type + KeyType: RANGE + SSESpecification: + SSEEnabled: True + PointInTimeRecoverySpecification: + PointInTimeRecoveryEnabled: True + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + + GlobalTableCreator: + Type: AWS::Lambda::Function + Properties: + Description: Secondary user pool table creator + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "custom-resources.zip"]] + Handler: "custom-resources/global-table-creator.handler" + Role: !GetAtt GlobalTableCreatorRole.Arn + Runtime: nodejs12.x + Timeout: 120 + MemorySize: 128 + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + + GlobalTableCreatorRole: + Type: AWS::IAM::Role + Metadata: + cfn_nag: + rules_to_suppress: + - id: W11 + reason: dynamodb:DescribeLimits cannot have specific resources but requires "*". + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: DynamoDBPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - dynamodb:CreateTable + - dynamodb:CreateTableReplica + - dynamodb:Scan + - dynamodb:Query + - dynamodb:UpdateItem + - dynamodb:PutItem + - dynamodb:GetItem + - dynamodb:DeleteItem + - dynamodb:BatchWriteItem + - dynamodb:UpdateTable + - dynamodb:DescribeTable + Resource: + - !GetAtt BackupTable.Arn + - !Sub arn:${AWS::Partition}:dynamodb:${SecondaryRegion}:${AWS::AccountId}:table/${BackupTable} + - Effect: Allow + Action: dynamodb:DescribeLimits + Resource: "*" + - Effect: Allow + Action: iam:CreateServiceLinkedRole + Resource: + - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/aws-service-role/replication.dynamodb.amazonaws.com/AWSServiceRoleForDynamoDBReplication + - PolicyName: StepFunctionsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - states:StartExecution + Resource: + - !Ref SecondaryUserPoolTableStepFunctions + + GlobalTableChecker: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + Description: Secondary user pool table readiness checker + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "custom-resources.zip"]] + Handler: "custom-resources/global-table-checker.handler" + Role: !GetAtt GlobalTableCheckerRole.Arn + Runtime: nodejs12.x + Timeout: 300 + MemorySize: 128 + Environment: + Variables: + USER_POOL_TABLE: !Ref BackupTable + SECONDARY_REGION: !Ref SecondaryRegion + + GlobalTableCheckerRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: DynamoDBPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - dynamodb:DescribeTable + Resource: + - !Sub arn:${AWS::Partition}:dynamodb:${SecondaryRegion}:${AWS::AccountId}:table/${BackupTable} + + SecondaryUserPoolTable: + Type: Custom::CreateTable + Properties: + ServiceToken: !GetAtt GlobalTableCreator.Arn + UserPoolTable: !Ref BackupTable + SecondaryRegion: !Ref SecondaryRegion + StateMachineArn: !Ref SecondaryUserPoolTableStepFunctions + + SecondaryUserPoolTableStepFunctionsRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - states.amazonaws.com + Action: + - sts:AssumeRole + Path: /service-role/ + Policies: + - PolicyName: StepFunctionPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: lambda:InvokeFunction + Resource: + - !GetAtt GlobalTableChecker.Arn + + SecondaryUserPoolTableStepFunctions: + Type: AWS::StepFunctions::StateMachine + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + RoleArn: !GetAtt SecondaryUserPoolTableStepFunctionsRole.Arn + DefinitionString: !Sub | + { + "Comment": "SOLUTION_NAME_PLACEHOLDER VERSION_PLACEHOLDER: Checks if secondary DynamoDB global table is ready or not", + "StartAt": "GlobalTableChecker", + "States": { + "GlobalTableChecker": { + "Type": "Task", + "Resource": "${GlobalTableChecker.Arn}", + "InputPath": "$", + "OutputPath": "$", + "Next": "Has Stream ARN?" + }, + "Has Stream ARN?": { + "Type": "Choice", + "Choices": [ + { + "Not": { + "Variable": "$.LatestStreamArn", + "StringEquals": "" + }, + "Next": "Yes" + }, + { + "Variable": "$.LatestStreamArn", + "StringEquals": "", + "Next": "No" + } + ], + "Default": "No" + }, + "No": { + "Type": "Pass", + "Next": "Wait 1 sec" + }, + "Wait 1 sec": { + "Comment": "A Wait state delays the state machine from continuing for a specified time.", + "Type": "Wait", + "Seconds": 1, + "Next": "GlobalTableChecker" + }, + "Yes": { + "Type": "Pass", + "End": true + } + } + } + + StackCheckerCustomResourceLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + Description: Checks to see if the current stack update is supported + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "custom-resources.zip"]] + Handler: "custom-resources/stack-checker.handler" + Role: !GetAtt StackCheckerCustomResourceLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 120 + MemorySize: 128 + Environment: + Variables: + FIXED_PARAMETERS: !Join [ ",", [ SecondaryRegion, PrimaryUserPoolId, BackupTableName, AnonymousDataUUID, ParentStackName, PrimaryRegion, ImportNewUsersQueueNamePrefix, SolutionInstanceUUID, UserImportJobMappingFileBucketPrefix, ExportWorkflowQueueNamePrefix ] ] + + StackCheckerCustomResourceLambdaRole: + Type: AWS::IAM::Role + DependsOn: SecondaryUserPoolTable + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: SSMParametersPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - ssm:DeleteParameter + - ssm:GetParameter + - ssm:PutParameter + Resource: + - !Sub arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${AWS::StackName}-${AWS::Region}/fixed-solution-parameters + - PolicyName: CognitoPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + # - cognito-idp:GetUserPoolMfaConfig + - cognito-idp:DescribeUserPool + Resource: + - !Sub arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/${PrimaryUserPoolId} + + StackCheckerCustomResource: + Type: Custom::StackChecker + Properties: + ServiceToken: !GetAtt StackCheckerCustomResourceLambda.Arn + PrimaryUserPoolId: !Ref PrimaryUserPoolId + SecondaryRegion: !Ref SecondaryRegion + BackupTableName: !Ref BackupTable + AnonymousDataUUID: !GetAtt SolutionConstantsCustomResource.AnonymousDataUUID + ParentStackName: !Ref AWS::StackName + PrimaryRegion: !Ref AWS::Region + ExportWorkflowQueueNamePrefix: "export-workflow" + ImportNewUsersQueueNamePrefix: "import-new-users" + SolutionInstanceUUID: !GetAtt SolutionConstantsCustomResource.SolutionInstanceUUID + UserImportJobMappingFileBucketPrefix: !GetAtt SolutionConstantsCustomResource.UserImportJobMappingFileBucketPrefix + + SolutionConstantsCustomResourceLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + Description: Generates values to be used within the solution + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "custom-resources.zip"]] + Handler: "custom-resources/solution-constants.handler" + Role: !GetAtt SolutionConstantsCustomResourceLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 60 + MemorySize: 128 + + SolutionConstantsCustomResourceLambdaRole: + Type: AWS::IAM::Role + DependsOn: SecondaryUserPoolTable + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + + SolutionConstantsCustomResource: + Type: Custom::SolutionConstants + Properties: + ServiceToken: !GetAtt SolutionConstantsCustomResourceLambda.Arn + StackName: !Ref AWS::StackName + + StackSetManagerCustomResourceLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + Description: Custom resource to manage the solution's StackSet + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "custom-resources.zip"]] + Handler: "custom-resources/stackset-manager.handler" + Role: !GetAtt StackSetManagerCustomResourceLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 300 + MemorySize: 128 + Environment: + Variables: + SEND_METRIC: !FindInMap ["MetricsMap", "Send-Data", "SendAnonymousData"] + METRICS_ANONYMOUS_UUID: !GetAtt SolutionConstantsCustomResource.AnonymousDataUUID + SOLUTION_ID: "SO0126" + SOLUTION_VERSION: "VERSION_PLACEHOLDER" + COGNITO_TPS: !Ref CognitoTPS + EXPORT_FREQUENCY: !Ref ExportFrequency + SNS_PREFERENCE: !Ref SnsPreference + STATE_MACHINE_ARN: !Ref StackSetCheckStatusWorkflow + + StackSetManagerCustomResourceLambdaRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: ManageStackSetPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - cloudformation:CreateStackSet + - cloudformation:UpdateStackSet + - cloudformation:CreateStackInstances + - cloudformation:ListStackInstances + - cloudformation:DeleteStackInstances + Resource: + - !Sub "arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stackset/${SolutionConstantsCustomResource.StackSetName}:*" + - Effect: Allow + Action: + - s3:GetObject + Resource: !Sub + - "arn:${AWS::Partition}:s3:::${S3Bucket}-${AWS::Region}/${KeyPrefix}/stack-set-template.template" + - S3Bucket: !FindInMap ["SourceCode", "General", "S3Bucket"] + KeyPrefix: !FindInMap ["SourceCode", "General", "KeyPrefix"] + - Effect: Allow + Action: + - iam:PassRole + Resource: + - !GetAtt StackSetAdminRole.Arn + - Effect: Allow + Action: + - states:StartExecution + Resource: + - !Ref StackSetCheckStatusWorkflow + + StackSetManagerCustomResource: + Type: Custom::StackSet + Properties: + TemplateURL: !Sub + - "https://${S3Bucket}-${AWS::Region}.s3.amazonaws.com/${KeyPrefix}/stack-set-template.template" + - S3Bucket: !FindInMap ["SourceCode", "General", "S3Bucket"] + KeyPrefix: !FindInMap ["SourceCode", "General", "KeyPrefix"] + ServiceToken: !GetAtt StackSetManagerCustomResourceLambda.Arn + StackSetName: !GetAtt SolutionConstantsCustomResource.StackSetName + AdministrationRoleARN: !GetAtt StackSetAdminRole.Arn + ExecutionRoleName: !Ref StackSetExecRole + AccountId: !Ref AWS::AccountId + SecondaryRegion: !Ref SecondaryRegion + StackSetParameters: + PrimaryRegion: !Ref AWS::Region + CognitoTPS: !Ref CognitoTPS + SendAnonymousData: !FindInMap ["MetricsMap", "Send-Data", "SendAnonymousData"] + ExportFrequency: !Ref ExportFrequency + NotificationEmail: !Ref NotificationEmail + SnsPreference: !Ref SnsPreference + ParentStackName: !Ref AWS::StackName + + StackSetAdminRole: + # Gives CloudFormation the permission to assume the StackSetExecRole + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - cloudformation.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: StackSetAdminPolicy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - sts:AssumeRole + Resource: + - !GetAtt StackSetExecRole.Arn + + StackSetExecRole: + # Gives CloudFormation the permission to manage the StackSet resources in both regions + Metadata: + cfn_nag: + rules_to_suppress: + - id: W11 + reason: >- + cloudformation:*, sns:* - The StackSetExecRole role will be assumed by CloudFormation as it provisions StackSet resources. Permissions to CloudFormation and SNS are needed to perform actions and report status + lambda:CreateEventSourceMapping, lambda:DeleteEventSourceMapping - As resource would be UUID, we cannot narrow down the permission. + - id: F3 + reason: >- + cloudformation:*, sns:* - The StackSetExecRole role will be assumed by CloudFormation as it provisions StackSet resources. Permissions to CloudFormation and SNS are needed to perform actions and report status + lambda:CreateEventSourceMapping, lambda:DeleteEventSourceMapping, lambda:GetEventSourceMapping - As resource would be UUID, we cannot narrow down the permission. + - id: W76 + reason: SPCM for IAM policy document is higher than 25 - All permissions are required. + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + AWS: + - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:root + Action: + - sts:AssumeRole + Policies: + - PolicyName: StackSetExecPolicy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - sns:* + Resource: + - '*' + - Effect: Allow + Action: + - cloudformation:* + Resource: + - '*' + - Effect: Allow + Action: + - s3:GetObject + Resource: + # Allow the StackSet to get nested templates and lambda packages for this solutions s3 bucket/prefix + - !Join ["", ["arn:aws:s3:::", !FindInMap ["SourceCode", "General", "S3Bucket"], "-", Ref: "AWS::Region", "/", !FindInMap ["SourceCode", "General", "KeyPrefix"], "/*"]] + - !Join ["", ["arn:aws:s3:::", !FindInMap ["SourceCode", "General", "S3Bucket"], "-", Ref: "SecondaryRegion", "/", !FindInMap ["SourceCode", "General", "KeyPrefix"], "/*"]] + - Effect: Allow + Action: + - lambda:CreateFunction + - lambda:DeleteFunction + - lambda:InvokeFunction + - lambda:GetFunction + - lambda:GetFunctionConfiguration + - lambda:UpdateFunctionConfiguration + - lambda:UpdateFunctionCode + - lambda:AddPermission + - lambda:RemovePermission + - lambda:ListTags + - lambda:TagResource + - lambda:UntagResource + Resource: + - !Sub arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:StackSet-${SolutionConstantsCustomResource.FormattedStackName}* + - !Sub arn:${AWS::Partition}:lambda:${SecondaryRegion}:${AWS::AccountId}:function:StackSet-${SolutionConstantsCustomResource.FormattedStackName}* + - Effect: Allow + Action: + - lambda:CreateEventSourceMapping + - lambda:DeleteEventSourceMapping + - lambda:GetEventSourceMapping + Resource: "*" + - Effect: Allow + Action: + - iam:CreateRole + - iam:DeleteRole + - iam:AttachRolePolicy + - iam:DetachRolePolicy + - iam:GetRolePolicy + - iam:PutRolePolicy + - iam:DeleteRolePolicy + - iam:GetRole + - iam:PassRole + Resource: + - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/StackSet-${SolutionConstantsCustomResource.FormattedStackName}* + - !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/service-role/StackSet-${SolutionConstantsCustomResource.FormattedStackName}* + - Effect: Allow + Action: + - sqs:CreateQueue + - sqs:DeleteQueue + - sqs:GetQueueAttributes + - sqs:TagQueue + - sqs:UntagQueue + Resource: + - !Sub arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:import-new-users-${SolutionConstantsCustomResource.SolutionInstanceUUID} + - !Sub arn:${AWS::Partition}:sqs:${SecondaryRegion}:${AWS::AccountId}:import-new-users-${SolutionConstantsCustomResource.SolutionInstanceUUID}-updates + - !Sub arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:import-new-users-${SolutionConstantsCustomResource.SolutionInstanceUUID}-dlq + - !Sub arn:${AWS::Partition}:sqs:${SecondaryRegion}:${AWS::AccountId}:import-new-users-${SolutionConstantsCustomResource.SolutionInstanceUUID} + - !Sub arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:import-new-users-${SolutionConstantsCustomResource.SolutionInstanceUUID}-updates + - !Sub arn:${AWS::Partition}:sqs:${SecondaryRegion}:${AWS::AccountId}:import-new-users-${SolutionConstantsCustomResource.SolutionInstanceUUID}-dlq + - !Sub arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:export-workflow-${SolutionConstantsCustomResource.SolutionInstanceUUID} + - !Sub arn:${AWS::Partition}:sqs:${AWS::Region}:${AWS::AccountId}:export-workflow-${SolutionConstantsCustomResource.SolutionInstanceUUID}-dlq + - Effect: Allow + Action: + - states:CreateStateMachine + - states:DeleteStateMachine + - states:UpdateStateMachine + - states:TagResource + - states:ListTagsForResource + Resource: + - !Sub arn:${AWS::Partition}:states:${AWS::Region}:${AWS::AccountId}:stateMachine:* + - !Sub arn:${AWS::Partition}:states:${SecondaryRegion}:${AWS::AccountId}:stateMachine:* + - Effect: Allow + Action: + - events:PutRule + - events:DescribeRule + - events:DeleteRule + - events:PutTargets + - events:RemoveTargets + Resource: + - !Sub arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/StackSet-${SolutionConstantsCustomResource.FormattedStackName}* + - !Sub arn:${AWS::Partition}:events:${SecondaryRegion}:${AWS::AccountId}:rule/StackSet-${SolutionConstantsCustomResource.FormattedStackName}* + - Effect: Allow + Action: + - sns:CreateTopic + - sns:DeleteTopic + Resource: + - !Sub arn:${AWS::Partition}:sns:${AWS::Region}:${AWS::AccountId}:cognito-user-profiles-export-reference-architecture-${AWS::Region}-${SolutionConstantsCustomResource.SolutionInstanceUUID} + - !Sub arn:${AWS::Partition}:sns:${SecondaryRegion}:${AWS::AccountId}:cognito-user-profiles-export-reference-architecture-${SecondaryRegion}-${SolutionConstantsCustomResource.SolutionInstanceUUID} + - Effect: Allow + Action: + - iam:TagRole + - tag:TagResources + Resource: "*" + - Effect: Allow + Action: + - s3:CreateBucket + - s3:PutEncryptionConfiguration + - s3:PutBucketVersioning + - s3:PutBucketPublicAccessBlock + - s3:PutBucketAcl + - s3:PutBucketLogging + - s3:PutBucketTagging + Resource: + - !Sub arn:${AWS::Partition}:s3:::${SolutionConstantsCustomResource.UserImportJobMappingFileBucketPrefix}-${AWS::Region} + - !Sub arn:${AWS::Partition}:s3:::${SolutionConstantsCustomResource.UserImportJobMappingFileBucketPrefix}-${AWS::Region}-logs + - !Sub arn:${AWS::Partition}:s3:::${SolutionConstantsCustomResource.UserImportJobMappingFileBucketPrefix}-${AWS::Region}/* + - !Sub arn:${AWS::Partition}:s3:::${SolutionConstantsCustomResource.UserImportJobMappingFileBucketPrefix}-${AWS::Region}-logs/* + - !Sub arn:${AWS::Partition}:s3:::${SolutionConstantsCustomResource.UserImportJobMappingFileBucketPrefix}-${SecondaryRegion} + - !Sub arn:${AWS::Partition}:s3:::${SolutionConstantsCustomResource.UserImportJobMappingFileBucketPrefix}-${SecondaryRegion}-logs + - !Sub arn:${AWS::Partition}:s3:::${SolutionConstantsCustomResource.UserImportJobMappingFileBucketPrefix}-${SecondaryRegion}/* + - !Sub arn:${AWS::Partition}:s3:::${SolutionConstantsCustomResource.UserImportJobMappingFileBucketPrefix}-${SecondaryRegion}-logs/* + + StackSetCheckStatusLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + Description: Checks the status of the solution's StackSet and when ready, responds to CloudFormation + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "custom-resources.zip"]] + Handler: "custom-resources/check-stackset-status.handler" + Role: !GetAtt StackSetCheckStatusLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 300 + MemorySize: 128 + + StackSetCheckStatusLambdaRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: CloudFormationPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - cloudformation:DeleteStackSet + - cloudformation:ListStackSetOperationResults + Resource: + - !Sub "arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stackset/${SolutionConstantsCustomResource.StackSetName}:*" + + StackSetCheckStatusWorkflowRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - states.amazonaws.com + Action: + - sts:AssumeRole + Path: /service-role/ + Policies: + - PolicyName: StepFunctionPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: lambda:InvokeFunction + Resource: + - !GetAtt StackSetCheckStatusLambda.Arn + + StackSetCheckStatusWorkflow: + Type: AWS::StepFunctions::StateMachine + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + RoleArn: !GetAtt StackSetCheckStatusWorkflowRole.Arn + DefinitionString: !Sub | + { + "Comment": "SOLUTION_NAME_PLACEHOLDER VERSION_PLACEHOLDER: Checks the status of the solution's StackSet and when ready, responds to CloudFormation", + "StartAt": "StackSetCheckStatusLambda", + "States": { + "StackSetCheckStatusLambda": { + "Type": "Task", + "Resource": "${StackSetCheckStatusLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "Has responded to CloudFormation?" + }, + "Has responded to CloudFormation?": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.HasRespondedToCfn", + "BooleanEquals": true, + "Next": "Yes" + } + ], + "Default": "No" + }, + "No": { + "Type": "Pass", + "Next": "Wait 5 sec" + }, + "Wait 5 sec": { + "Comment": "A Wait state delays the state machine from continuing for a specified time.", + "Type": "Wait", + "Seconds": 5, + "Next": "StackSetCheckStatusLambda" + }, + "Yes": { + "Type": "Pass", + "End": true + } + } + } + +Outputs: + BackupTableName: + Description: Name of the DynamoDB Global Table containing the backed up user pool data + Value: !Ref BackupTable + UserImportJobMappingFileBucketPrefix: + Description: Prefix for the name of the S3 bucket that will contain mapping files for the Cognito user import jobs + Value: !GetAtt SolutionConstantsCustomResource.UserImportJobMappingFileBucketPrefix diff --git a/deployment/run-unit-tests.sh b/deployment/run-unit-tests.sh new file mode 100755 index 0000000..9ce6369 --- /dev/null +++ b/deployment/run-unit-tests.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# +# This assumes all of the OS-level configuration has been completed and git repo has already been cloned +# +# This script should be run from the repo's deployment directory +# cd deployment +# ./run-unit-tests.sh +# + +# Get reference for all important folders +template_dir="$PWD" +source_dir="$template_dir/../source" + +echo "------------------------------------------------------------------------------" +echo "[Test] utils" +echo "------------------------------------------------------------------------------" +cd $source_dir/utils +npm run clean +npm test + +# Check the result of the test and exit if a failure is identified +if [ $? -eq 0 ] +then + echo "Test for utils successful" +else + echo "------------------------------------------------------------------------------" + echo "[Test] FAILED for utils" + echo "------------------------------------------------------------------------------" + exit 1 +fi + +declare -a lambda_packages=( + "custom-resources" + "workflow-common" + "workflow-export" + "workflow-import" +) + +for lambda_package in "${lambda_packages[@]}" +do + echo "------------------------------------------------------------------------------" + echo "[Test] Lambda package: $lambda_package" + echo "------------------------------------------------------------------------------" + cd $source_dir/$lambda_package + npm run clean + npm test + + # Check the result of the test and exit if a failure is identified + if [ $? -eq 0 ] + then + echo "Test for $lambda_package successful" + else + echo "------------------------------------------------------------------------------" + echo "[Test] FAILED for $lambda_package" + echo "------------------------------------------------------------------------------" + exit 1 + fi +done diff --git a/deployment/stack-set-template.yaml b/deployment/stack-set-template.yaml new file mode 100644 index 0000000..58fc722 --- /dev/null +++ b/deployment/stack-set-template.yaml @@ -0,0 +1,2217 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Cognito User Profiles Export Reference Architecture +# +# template for cognito-user-profiles-export-reference-architecture +# **DO NOT DELETE** +# +# author: aws-solutions-builder@ +AWSTemplateFormatVersion: 2010-09-09 + +Description: (SO0126s) - StackSet template for Cognito User Profiles Export Reference Architecture. Version VERSION_PLACEHOLDER + +Parameters: + PrimaryRegion: + Type: String + AllowedPattern: ^[\w-]+$ + CognitoTPS: + Type: String + Default: "10" + AllowedValues: ["1", "5", "10"] + ExportFrequency: + Type: String + Default: "EVERY_DAY" + AllowedValues: ["EVERY_DAY", "EVERY_7_DAYS", "EVERY_30_DAYS"] + NotificationEmail: + Type: String + AllowedPattern: "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$" + SendAnonymousData: + Type: String + ParentStackName: + Type: String + SnsPreference: + Type: String + Default: "INFO_AND_ERRORS" + AllowedValues: ["INFO_AND_ERRORS", "ERRORS_ONLY"] + +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Backup Process Configuration. Please do not change these values here. To update them, please update the solution's main CloudFormation stack + Parameters: + - NotificationEmail + - SnsPreference + - SendAnonymousData + - ExportFrequency + - CognitoTPS + - Label: + default: Fixed Parameters. Please do not change these values. + Parameters: + - ParentStackName + - PrimaryRegion + ParameterLabels: + ExportFrequency: + default: "ExportFrequency: The frequency at which the Export Workflow will run" + CognitoTPS: + default: "CognitoTPS: The amount of times a Cognito API will be called per second" + NotificationEmail: + default: "NotificationEmail: Email address for SNS notifications. Subscribed users will receive receive notifications if an issue is detected" + SnsPreference: + default: "SnsPreference: INFO_AND_ERRORS - The solution will publish a message to the SNS topic each time a workflow completes and if there are errors detected. ERRORS_ONLY - The solution will only publish messages if an error is detected" + PrimaryRegion: + default: "PrimaryRegion: The region in which you launched this solution's main CloudFormation stack" + ParentStackName: + default: "ParentStackName: The name given to this solution's main CloudFormation stack" + SendAnonymousData: + default: "SendAnonymousData: Flag indicating whether or not to send anonymous operational metrics. Value comes from the 'SendAnonymousData' mapping in the solution's main CloudFormation template" + +Mappings: + SourceCode: + General: + S3Bucket: BUCKET_NAME_PLACEHOLDER + KeyPrefix: SOLUTION_NAME_PLACEHOLDER/VERSION_PLACEHOLDER + +Conditions: + IsPrimaryRegion: !Equals [ !Ref "AWS::Region", !Ref PrimaryRegion ] + ExportDaily: !Equals [ !Ref ExportFrequency, "EVERY_DAY" ] + ExportWeekly: !Equals [ !Ref ExportFrequency, "EVERY_7_DAYS" ] + ExportMonthly: !And + - !Not [ Condition: ExportDaily ] + - !Not [ Condition: ExportWeekly ] + +Resources: + ####################################### + # These resources will be created in both the primary and backup regions + ####################################### + StackSetConstantsCustomResourceLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + Description: Retrieves constants generated by the main stack for use in this StackSet + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "custom-resources.zip"]] + Handler: "custom-resources/stackset-constants.handler" + Role: !GetAtt StackSetConstantsCustomResourceLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 60 + MemorySize: 128 + + StackSetConstantsCustomResourceLambdaRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${AWS::StackName}-${AWS::Region} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - Effect: Allow + Action: + - ssm:GetParameter + Resource: + - !Sub arn:${AWS::Partition}:ssm:${PrimaryRegion}:${AWS::AccountId}:parameter/${ParentStackName}-${PrimaryRegion}/fixed-solution-parameters + + StackSetConstantsCustomResource: + Type: Custom::StackSetConstants + Properties: + ServiceToken: !GetAtt StackSetConstantsCustomResourceLambda.Arn + ParentStackName: !Ref ParentStackName + PrimaryRegion: !Ref PrimaryRegion + + ImportWorkflowServiceRole: + Type: AWS::IAM::Role + Metadata: + cfn_nag: + rules_to_suppress: + - id: W76 + reason: SPCM for IAM policy document is higher than 25 - All permissions are required. + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - states.amazonaws.com + Action: + - sts:AssumeRole + Path: /service-role/ + Policies: + - PolicyName: ImportWorkflowServiceRolePolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: lambda:InvokeFunction + Resource: + - !GetAtt ImportCheckNewUserPoolLambda.Arn + - !GetAtt ImportScanTableLambda.Arn + - !GetAtt ImportNewUsersLambda.Arn + - !GetAtt ImportCheckImportJobLambda.Arn + - !GetAtt ImportUpdateNewUsersLambda.Arn + - !GetAtt CheckExecutionsLambda.Arn + - !GetAtt WorkflowMessageBrokerLambda.Arn + - !GetAtt CheckWorkflowQueuesLambda.Arn + + ImportWorkflow: + Type: AWS::StepFunctions::StateMachine + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + RoleArn: !GetAtt ImportWorkflowServiceRole.Arn + DefinitionString: !Sub | + { + "Comment": "SOLUTION_NAME_PLACEHOLDER VERSION_PLACEHOLDER: Restores a new user pool with the state reflected in the backup table", + "StartAt": "CheckExecutionsLambda", + "States": { + "CheckExecutionsLambda": { + "Type": "Task", + "Resource": "${CheckExecutionsLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "Only this execution running for this state machine?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "Only this execution running for this state machine?": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.OnlyThisStateMachineExecution", + "BooleanEquals": true, + "Next": "Yes - only this execution is running" + } + ], + "Default": "No - at least one other execution is running" + }, + "Yes - only this execution is running": { + "Type": "Pass", + "Next": "Wait 1 minute" + }, + "No - at least one other execution is running": { + "Type": "Fail", + "Error": "AnotherExecutionRunning", + "Cause": "At least one other execution for this state machine was found to be running. Please check logs for CheckExecutionsLambda for details" + }, + "Wait 1 minute": { + "Comment": "Wait 1 minute to allow queues to achieve consistency", + "Type": "Wait", + "Seconds": 60, + "Next": "CheckWorkflowQueuesLambda" + }, + "CheckWorkflowQueuesLambda": { + "Type": "Task", + "Resource": "${CheckWorkflowQueuesLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "ImportCheckNewUserPoolLambda", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "ImportCheckNewUserPoolLambda": { + "Type": "Task", + "Resource": "${ImportCheckNewUserPoolLambda.Arn}", + "OutputPath": "$.result", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "Next": "Is the new user pool empty?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "Is the new user pool empty?": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.NewUserPoolEmpty", + "BooleanEquals": true, + "Next": "Yes - the new user pool is empty" + } + ], + "Default": "No - the new user pool is not empty" + }, + "No - the new user pool is not empty": { + "Type": "Fail", + "Error": "NewUserPoolNotEmpty", + "Cause": "Please check logs for ImportCheckNewUserPoolLambda for details" + }, + "Yes - the new user pool is empty": { + "Type": "Pass", + "Next": "Parallel: Scan table and import users" + }, + "Parallel: Scan table and import users":{ + "Type": "Parallel", + "Branches": [ + { + "StartAt": "ImportScanTableLambda", + "States": { + "ImportScanTableLambda": { + "Type": "Task", + "Resource": "${ImportScanTableLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "Finished Scanning Table?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "Parallel: WorkflowErrorHandlerLambda (Scan Table)" + } + ] + }, + "Finished Scanning Table?": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.AllGroupsProcessed", + "StringEquals": "Yes", + "Next": "Yes" + }, + { + "Variable": "$.AllGroupsProcessed", + "StringEquals": "No", + "Next": "No" + } + ], + "Default": "Yes" + }, + "Yes": { + "Type": "Pass", + "End": true + }, + "No": { + "Type": "Pass", + "Next": "ImportScanTableLambda" + }, + "Parallel: WorkflowErrorHandlerLambda (Scan Table)": { + "Type": "Task", + "Resource": "${WorkflowMessageBrokerLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "Next": "Parallel: Unexpected workflow error (Scan Table)" + }, + "Parallel: Unexpected workflow error (Scan Table)": { + "Type": "Fail", + "Error": "UnexpectedErrorInWorkflow", + "Cause": "An unexpected error occured while executing this workflow. Please check logs for the State Machine task that generated this error for details" + } + } + }, + { + "StartAt": "Parallel: Wait 60 seconds", + "States": { + "Parallel: Wait 60 seconds": { + "Comment": "Wait 60 seconds to allow messages to be queued", + "Type": "Wait", + "Seconds": 60, + "Next": "Parallel: ImportNewUsers" + }, + "Parallel: ImportNewUsers": { + "Type": "Task", + "Resource": "${ImportNewUsersLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "Parallel: Is User Import Job Running?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "Parallel: WorkflowErrorHandlerLambda" + } + ] + }, + "Parallel: Is User Import Job Running?": { + "Type": "Choice", + "Choices": [ + { + "Or": [ + { + "Variable": "$.ImportJobStatus", + "StringEquals": "Pending" + }, + { + "Variable": "$.ImportJobStatus", + "StringEquals": "InProgress" + } + ], + "Next": "Parallel: Yes - CSV is being imported" + }, + { + "Or": [ + { + "Variable": "$.ImportJobStatus", + "StringEquals": "Succeeded" + }, + { + "Variable": "$.ImportJobStatus", + "StringEquals": "" + } + ], + "Next": "Parallel: No import job running" + } + ] + }, + "Parallel: Yes - CSV is being imported": { + "Type": "Pass", + "Next": "Parallel: Wait 30 seconds" + }, + "Parallel: Wait 30 seconds": { + "Comment": "Wait 30 seconds before checking the import job again", + "Type": "Wait", + "Seconds": 30, + "Next": "Parallel: CheckUserImportJob" + }, + "Parallel: CheckUserImportJob": { + "Type": "Task", + "Resource": "${ImportCheckImportJobLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "Parallel: Is User Import Job Running?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "Parallel: WorkflowErrorHandlerLambda" + } + ] + }, + "Parallel: No import job running": { + "Type": "Pass", + "Next": "Parallel: Is New Users Queue Empty?" + }, + "Parallel: Is New Users Queue Empty?": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.QueueEmpty", + "BooleanEquals": true, + "Next": "Parallel: Yes - New Users Queue has been drained" + }, + { + "Variable": "$.QueueEmpty", + "BooleanEquals": false, + "Next": "Parallel: No - New Users Queue is not empty" + } + ] + }, + "Parallel: No - New Users Queue is not empty": { + "Type": "Pass", + "Next": "Parallel: ImportNewUsers" + }, + "Parallel: Yes - New Users Queue has been drained": { + "Type": "Pass", + "End": true + }, + "Parallel: WorkflowErrorHandlerLambda": { + "Type": "Task", + "Resource": "${WorkflowMessageBrokerLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "Next": "Parallel: Unexpected workflow error" + }, + "Parallel: Unexpected workflow error": { + "Type": "Fail", + "Error": "UnexpectedErrorInWorkflow", + "Cause": "An unexpected error occured while executing this workflow. Please check logs for the State Machine task that generated this error for details" + } + } + } + ], + "Next": "Wait 60 seconds" + }, + "Wait 60 seconds": { + "Comment": "Wait 60 seconds to allow users to be queued", + "Type": "Wait", + "Seconds": 60, + "Next": "ImportNewUsers" + }, + "ImportNewUsers": { + "Type": "Task", + "Resource": "${ImportNewUsersLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "Is User Import Job Running?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "Is User Import Job Running?": { + "Type": "Choice", + "Choices": [ + { + "Or": [ + { + "Variable": "$.ImportJobStatus", + "StringEquals": "Pending" + }, + { + "Variable": "$.ImportJobStatus", + "StringEquals": "InProgress" + } + ], + "Next": "Yes - CSV is being imported" + }, + { + "Or": [ + { + "Variable": "$.ImportJobStatus", + "StringEquals": "Succeeded" + }, + { + "Variable": "$.ImportJobStatus", + "StringEquals": "" + } + ], + "Next": "No import job running" + } + ] + }, + "Yes - CSV is being imported": { + "Type": "Pass", + "Next": "Wait 30 seconds" + }, + "Wait 30 seconds": { + "Comment": "Wait 30 seconds before checking the import job again", + "Type": "Wait", + "Seconds": 30, + "Next": "CheckUserImportJob" + }, + "CheckUserImportJob": { + "Type": "Task", + "Resource": "${ImportCheckImportJobLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "Is User Import Job Running?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "No import job running": { + "Type": "Pass", + "Next": "Is New Users Queue Empty?" + }, + "Is New Users Queue Empty?": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.QueueEmpty", + "BooleanEquals": true, + "Next": "Yes - New Users Queue has been drained" + }, + { + "Variable": "$.QueueEmpty", + "BooleanEquals": false, + "Next": "No - New Users Queue is not empty" + } + ] + }, + "No - New Users Queue is not empty": { + "Type": "Pass", + "Next": "ImportNewUsers" + }, + "Yes - New Users Queue has been drained": { + "Type": "Pass", + "Next": "UpdateNewUsers" + }, + "UpdateNewUsers": { + "Type": "Task", + "Resource": "${ImportUpdateNewUsersLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "Is New Users Updates Queue Empty?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "Is New Users Updates Queue Empty?": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.QueueEmpty", + "BooleanEquals": true, + "Next": "Yes - New Users Updates Queue has been drained" + }, + { + "Variable": "$.QueueEmpty", + "BooleanEquals": false, + "Next": "No - New Users Updates Queue is not empty" + } + ] + }, + "No - New Users Updates Queue is not empty": { + "Type": "Pass", + "Next": "UpdateNewUsers" + }, + "Yes - New Users Updates Queue has been drained": { + "Type": "Pass", + "Next": "WorkflowCleanupLambda" + }, + "WorkflowCleanupLambda": { + "Type": "Task", + "Resource": "${WorkflowMessageBrokerLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "End": true, + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "WorkflowErrorHandlerLambda": { + "Type": "Task", + "Resource": "${WorkflowMessageBrokerLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "Next": "Unexpected workflow error" + }, + "Unexpected workflow error": { + "Type": "Fail", + "Error": "UnexpectedErrorInWorkflow", + "Cause": "An unexpected error occured while executing this workflow. Please check logs for the State Machine task that generated this error for details" + } + } + } + + CheckWorkflowQueuesLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Validates that the Queue(s) used by the workflow are empty + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-common.zip"]] + Handler: "workflow-common/check-workflow-queues.handler" + Role: !GetAtt CheckWorkflowQueuesLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 60 + MemorySize: 128 + Environment: + Variables: + NEW_USERS_QUEUE_URL: !Ref ImportNewUsersQueue + UPDATES_QUEUE_URL: !Ref ImportNewUsersUpdatesQueue + + CheckWorkflowQueuesLambdaRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: CheckWorkflowQueuesLambdaRolePolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - sqs:GetQueueAttributes + Resource: + - !GetAtt ImportNewUsersQueue.Arn + - !GetAtt ImportNewUsersUpdatesQueue.Arn + + ImportCheckNewUserPoolLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Returns true only if the new user pool is empty + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-import.zip"]] + Handler: "workflow-import/check-new-user-pool.handler" + Role: !GetAtt ImportCheckNewUserPoolLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 60 + MemorySize: 128 + + ImportCheckNewUserPoolLambdaRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: ImportCheckNewUserPoolLambdaRolePolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - cognito-idp:ListUsers + - cognito-idp:ListGroups + Resource: + - !Sub arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/* + + ImportScanTableLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Scans the backup table and sorts items into queues for later processing + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-import.zip"]] + Handler: "workflow-import/scan-table.handler" + Role: !GetAtt ImportScanTableLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 300 + MemorySize: 128 + Environment: + Variables: + BACKUP_TABLE_NAME: !GetAtt StackSetConstantsCustomResource.BackupTableName + TYPE_GROUP: !Join ["-", [ "GROUP", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + TYPE_USER: !Join ["-", [ "USER", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + TYPE_TIMESTAMP: !Join ["-", [ "SYNC_TIMESTAMP", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + NEW_USERS_QUEUE_URL: !Ref ImportNewUsersQueue + NEW_USERS_UPDATES_QUEUE_URL: !Ref ImportNewUsersUpdatesQueue + COGNITO_TPS: !Ref CognitoTPS + + ImportScanTableLambdaRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: ImportScanTableLambdaRolePolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - dynamodb:Scan + Resource: + - !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${StackSetConstantsCustomResource.BackupTableName} + - Effect: Allow + Action: + - cognito-idp:CreateGroup + Resource: + - !Sub arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/* + - Effect: Allow + Action: + - sqs:SendMessage + - sqs:SendMessageBatch + Resource: + - !GetAtt ImportNewUsersQueue.Arn + - !GetAtt ImportNewUsersUpdatesQueue.Arn + + ImportNewUsersQueue: + Type: AWS::SQS::Queue + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + QueueName: !Sub "${StackSetConstantsCustomResource.ImportNewUsersQueueNamePrefix}-${StackSetConstantsCustomResource.SolutionInstanceUUID}" + KmsMasterKeyId: alias/aws/sqs + VisibilityTimeout: 30 + RedrivePolicy: + deadLetterTargetArn: !GetAtt ImportNewUsersDeadLetterQueue.Arn + maxReceiveCount: 2 + + ImportNewUsersUpdatesQueue: + Type: AWS::SQS::Queue + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + QueueName: !Sub "${StackSetConstantsCustomResource.ImportNewUsersQueueNamePrefix}-${StackSetConstantsCustomResource.SolutionInstanceUUID}-updates" + KmsMasterKeyId: alias/aws/sqs + VisibilityTimeout: 30 + RedrivePolicy: + deadLetterTargetArn: !GetAtt ImportNewUsersDeadLetterQueue.Arn + maxReceiveCount: 2 + + ImportNewUsersDeadLetterQueue: + Type: AWS::SQS::Queue + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + QueueName: !Sub "${StackSetConstantsCustomResource.ImportNewUsersQueueNamePrefix}-${StackSetConstantsCustomResource.SolutionInstanceUUID}-dlq" + KmsMasterKeyId: alias/aws/sqs + VisibilityTimeout: 30 + + ImportNewUsersLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Imports users to the new user pool + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-import.zip"]] + Handler: "workflow-import/import-users.handler" + Role: !GetAtt ImportNewUsersLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 900 + MemorySize: 1024 # Higher memory size to allow for large CSV files to be uploaded to the Cognito User Import Job + Environment: + Variables: + BACKUP_TABLE_NAME: !GetAtt StackSetConstantsCustomResource.BackupTableName + TYPE_USER: !Join ["-", [ "USER", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + TYPE_GROUP: !Join ["-", [ "GROUP", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + COGNITO_TPS: !Ref CognitoTPS + NEW_USERS_QUEUE_URL: !Ref ImportNewUsersQueue + NEW_USERS_UPDATES_QUEUE_URL: !Ref ImportNewUsersUpdatesQueue + USER_IMPORT_CLOUDWATCH_ROLE_ARN: !GetAtt CognitoUserImportCloudWatchLogsRole.Arn + USER_IMPORT_JOB_MAPPING_FILES_BUCKET: !Ref UserImportJobMappingFiles + + ImportNewUsersLambdaRole: + Type: AWS::IAM::Role + Metadata: + cfn_nag: + rules_to_suppress: + - id: W76 + reason: SPCM for IAM policy document is higher than 25 - All permissions are required. + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: ImportNewUsersLambdaRolePolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - dynamodb:Scan + # - dynamodb:Query + Resource: + - !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${StackSetConstantsCustomResource.BackupTableName} + - Effect: Allow + Action: + - cognito-idp:DescribeUserImportJob + - cognito-idp:StartUserImportJob + - cognito-idp:CreateUserImportJob + - cognito-idp:GetCSVHeader + # - cognito-idp:AdminDisableUser + # - cognito-idp:AdminAddUserToGroup + Resource: + - !Sub arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/* + - Effect: Allow + Action: + - sqs:ReceiveMessage + - sqs:DeleteMessage + - sqs:GetQueueAttributes + Resource: + - !GetAtt ImportNewUsersQueue.Arn + - !GetAtt ImportNewUsersUpdatesQueue.Arn + - Effect: Allow + Action: + - iam:PassRole + Resource: + - !GetAtt CognitoUserImportCloudWatchLogsRole.Arn + - Effect: Allow + Action: + - s3:PutObject + Resource: + - !Sub arn:${AWS::Partition}:s3:::${UserImportJobMappingFiles}/import-*-user-mapping.csv + - Effect: Allow + Action: + - sns:Publish + Resource: + - !Ref NotificationTopic + + ImportCheckImportJobLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Checks the user import job + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-import.zip"]] + Handler: "workflow-import/import-users.handler" + Role: !GetAtt ImportCheckImportJobLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 60 + MemorySize: 128 + Environment: + Variables: + SEND_METRIC: !Ref SendAnonymousData + METRICS_ANONYMOUS_UUID: !GetAtt StackSetConstantsCustomResource.AnonymousDataUUID + SOLUTION_ID: "SO0126" + SOLUTION_VERSION: "VERSION_PLACEHOLDER" + IS_PRIMARY_REGION: !If [ IsPrimaryRegion, "Yes", "No" ] + BACKUP_TABLE_NAME: !GetAtt StackSetConstantsCustomResource.BackupTableName + TYPE_USER: !Join ["-", [ "USER", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + TYPE_GROUP: !Join ["-", [ "GROUP", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + COGNITO_TPS: !Ref CognitoTPS + NEW_USERS_QUEUE_URL: !Ref ImportNewUsersQueue + NEW_USERS_UPDATES_QUEUE_URL: !Ref ImportNewUsersUpdatesQueue + USER_IMPORT_CLOUDWATCH_ROLE_ARN: !GetAtt CognitoUserImportCloudWatchLogsRole.Arn + USER_IMPORT_JOB_MAPPING_FILES_BUCKET: !Ref UserImportJobMappingFiles + + ImportCheckImportJobLambdaRole: + Type: AWS::IAM::Role + Metadata: + cfn_nag: + rules_to_suppress: + - id: W76 + reason: SPCM for IAM policy document is higher than 25 - All permissions are required. + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: ImportCheckImportJobLambdaRolePolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - cognito-idp:DescribeUserImportJob + Resource: + - !Sub arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/* + - Effect: Allow + Action: + - sns:Publish + Resource: + - !Ref NotificationTopic + + ImportUpdateNewUsersLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Updates users that were recently imported to the new user pool + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-import.zip"]] + Handler: "workflow-import/update-new-users.handler" + Role: !GetAtt ImportUpdateNewUsersLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 900 + MemorySize: 128 + Environment: + Variables: + BACKUP_TABLE_NAME: !GetAtt StackSetConstantsCustomResource.BackupTableName + TYPE_USER: !Join ["-", [ "USER", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + TYPE_GROUP: !Join ["-", [ "GROUP", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + COGNITO_TPS: !Ref CognitoTPS + NEW_USERS_QUEUE_URL: !Ref ImportNewUsersQueue + NEW_USERS_UPDATES_QUEUE_URL: !Ref ImportNewUsersUpdatesQueue + USER_IMPORT_CLOUDWATCH_ROLE_ARN: !GetAtt CognitoUserImportCloudWatchLogsRole.Arn + USER_IMPORT_JOB_MAPPING_FILES_BUCKET: !Ref UserImportJobMappingFiles + + ImportUpdateNewUsersLambdaRole: + Type: AWS::IAM::Role + Metadata: + cfn_nag: + rules_to_suppress: + - id: W76 + reason: SPCM for IAM policy document is higher than 25 - All permissions are required. + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: ImportUpdateNewUsersLambdaRolePolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - cognito-idp:AdminDisableUser + - cognito-idp:AdminAddUserToGroup + Resource: + - !Sub arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/* + - Effect: Allow + Action: + - sqs:ReceiveMessage + - sqs:DeleteMessage + - sqs:GetQueueAttributes + Resource: + - !GetAtt ImportNewUsersUpdatesQueue.Arn + - Effect: Allow + Action: + - iam:PassRole + Resource: + - !GetAtt CognitoUserImportCloudWatchLogsRole.Arn + - Effect: Allow + Action: + - sns:Publish + Resource: + - !Ref NotificationTopic + + NotificationTopic: + Type: AWS::SNS::Topic + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + DisplayName: !Sub "Cognito User Profiles Export Reference Architecture: ${AWS::Region} (${StackSetConstantsCustomResource.ParentStackName})" + TopicName: !Sub "cognito-user-profiles-export-reference-architecture-${AWS::Region}-${StackSetConstantsCustomResource.SolutionInstanceUUID}" + KmsMasterKeyId: alias/aws/sns + Subscription: + - Endpoint: !Ref NotificationEmail + Protocol: email + + WorkflowMessageBrokerLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Handles unexpected errors thrown by lambda tasks in the solution's step functions workflows + Handler: "workflow-common/message-broker.handler" + Role: !GetAtt WorkflowMessageBrokerLambdaRole.Arn + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], Ref: "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-common.zip"]] + Runtime: nodejs12.x + Timeout: 300 + Environment: + Variables: + SEND_METRIC: !Ref SendAnonymousData + METRICS_ANONYMOUS_UUID: !GetAtt StackSetConstantsCustomResource.AnonymousDataUUID + SOLUTION_ID: "SO0126" + SOLUTION_VERSION: "VERSION_PLACEHOLDER" + IS_PRIMARY_REGION: !If [ IsPrimaryRegion, "Yes", "No" ] + NOTIFICATION_TOPIC: !Ref NotificationTopic + SNS_MESSAGE_PREFERENCE: !Ref SnsPreference + BACKUP_TABLE_NAME: !GetAtt StackSetConstantsCustomResource.BackupTableName + TYPE_TIMESTAMP: !Join ["-", [ "SYNC_TIMESTAMP", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + + WorkflowMessageBrokerLambdaRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: workflow-message-broker-policy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/* + - Effect: Allow + Action: + - sns:Publish + Resource: + - !Ref NotificationTopic + - Effect: Allow + Action: + - dynamodb:PutItem + Resource: + - !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${StackSetConstantsCustomResource.BackupTableName} + + CognitoUserImportCloudWatchLogsRole: + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - cognito-idp.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: cognito-user-import-cw-logs-policy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:DescribeLogStreams + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/cognito/* + + UserImportJobMappingFiles: + Type: AWS::S3::Bucket + DeletionPolicy: Retain + UpdateReplacePolicy: Retain + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + BucketName: !Sub ${StackSetConstantsCustomResource.UserImportJobMappingFileBucketPrefix}-${AWS::Region} + PublicAccessBlockConfiguration: + BlockPublicAcls: True + BlockPublicPolicy: True + IgnorePublicAcls: True + RestrictPublicBuckets: True + LoggingConfiguration: + DestinationBucketName: !Ref UserImportJobMappingFilesLogsBucket + LogFilePrefix: user-import-job-mapping-files/ + BucketEncryption: + ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + SSEAlgorithm: aws:kms + Metadata: + cfn_nag: + rules_to_suppress: + - id: W51 + reason: Policy not required for this bucket. + + UserImportJobMappingFilesLogsBucket: + Type: AWS::S3::Bucket + Metadata: + cfn_nag: + rules_to_suppress: + - id: W35 + reason: Logging not enabled, as this is the logging destination for the other s3 buckets in this template. + - id: W51 + reason: Policy not required for this bucket. + DeletionPolicy: Retain + UpdateReplacePolicy: Retain + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + BucketName: !Sub ${StackSetConstantsCustomResource.UserImportJobMappingFileBucketPrefix}-${AWS::Region}-logs + AccessControl: LogDeliveryWrite + PublicAccessBlockConfiguration: + BlockPublicAcls: True + BlockPublicPolicy: True + IgnorePublicAcls: True + RestrictPublicBuckets: True + BucketEncryption: + ServerSideEncryptionConfiguration: + - ServerSideEncryptionByDefault: + SSEAlgorithm: aws:kms + + CheckExecutionsLambda: + Type: AWS::Lambda::Function + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Returns whether a state machine has multiple executions running + Handler: "workflow-common/check-state-machine-executions.handler" + Role: !GetAtt CheckExecutionsLambdaRole.Arn + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], Ref: "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-common.zip"]] + Runtime: nodejs12.x + Timeout: 300 + + CheckExecutionsLambdaRole: + Metadata: + cfn_nag: + rules_to_suppress: + - id: W11 + reason: states:ListExecutions cannot have specific resources and requires "*". + Type: AWS::IAM::Role + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: check-state-machine-executions-policy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/* + - Effect: Allow + Action: + - states:ListExecutions + Resource: "*" + + ####################################### + # These resources will be created in the primary region only + ####################################### + ExportWorkflowServiceRole: + Type: AWS::IAM::Role + Condition: IsPrimaryRegion + Metadata: + cfn_nag: + rules_to_suppress: + - id: W76 + reason: SPCM for IAM policy document is higher than 25 - All permissions are required. + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - states.amazonaws.com + Action: + - sts:AssumeRole + Path: /service-role/ + Policies: + - PolicyName: StepFunctionPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: lambda:InvokeFunction + Resource: + - !GetAtt ExportUsersLambda.Arn + - !GetAtt ListGroupsLambda.Arn + - !GetAtt ExportGroupLambda.Arn + - !GetAtt ExportUsersInGroupLambda.Arn + - !GetAtt CheckExecutionsLambda.Arn + - !GetAtt CheckUserPoolConfigLambda.Arn + - !GetAtt BackupTableCleanupLambda.Arn + - !GetAtt WorkflowMessageBrokerLambda.Arn + + ExportWorkflow: + Type: AWS::StepFunctions::StateMachine + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + RoleArn: !GetAtt ExportWorkflowServiceRole.Arn + DefinitionString: !Sub | + { + "Comment": "SOLUTION_NAME_PLACEHOLDER VERSION_PLACEHOLDER: Backs up User Profiles, Groups and Group Memberships to a DynamoDB Global Table", + "StartAt": "CheckExecutionsLambda", + "States": { + "CheckExecutionsLambda": { + "Type": "Task", + "Resource": "${CheckExecutionsLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "Only this execution running for this state machine?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "Only this execution running for this state machine?": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.OnlyThisStateMachineExecution", + "BooleanEquals": true, + "Next": "Yes - only this execution is running" + } + ], + "Default": "No - at least one other execution is running" + }, + "Yes - only this execution is running": { + "Type": "Pass", + "Next": "CheckUserPoolConfigLambda" + }, + "No - at least one other execution is running": { + "Type": "Fail", + "Error": "AnotherExecutionRunning", + "Cause": "At least one other execution for this state machine was found to be running. Please check logs for CheckExecutionsLambda for details" + }, + "CheckUserPoolConfigLambda": { + "Type": "Task", + "Resource": "${CheckUserPoolConfigLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "ExportUsersLambda", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "ExportUsersLambda": { + "Type": "Task", + "Resource": "${ExportUsersLambda.Arn}", + "InputPath": "$", + "OutputPath": "$.result", + "Next": "Has ListUsers Next Token?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "Has ListUsers Next Token?": { + "Type": "Choice", + "Choices": [ + { + "Not": { + "Variable": "$.paginationToken", + "StringEquals": "" + }, + "Next": "Yes - ListUsers" + }, + { + "Variable": "$.paginationToken", + "StringEquals": "", + "Next": "No - ListUsers" + } + ], + "Default": "No - ListUsers" + }, + "Yes - ListUsers": { + "Type": "Pass", + "Next": "Wait 1 sec - ListUsers" + }, + "Wait 1 sec - ListUsers": { + "Comment": "A Wait state delays the state machine from continuing for a specified time.", + "Type": "Wait", + "Seconds": 1, + "Next": "ExportUsersLambda" + }, + "No - ListUsers": { + "Type": "Pass", + "Next": "ListGroupsLambda" + }, + "ListGroupsLambda": { + "Type": "Task", + "Resource": "${ListGroupsLambda.Arn}", + "InputPath": "$", + "Next": "Process Groups Map", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "Process Groups Map": { + "Type": "Map", + "ResultPath": "$.ProcessedGroups", + "ItemsPath": "$.Groups", + "Parameters": { + "groupName.$": "$$.Map.Item.Value.groupName", + "groupDescription.$": "$$.Map.Item.Value.groupDescription", + "groupPrecedence.$": "$$.Map.Item.Value.groupPrecedence", + "groupLastModifiedDate.$": "$$.Map.Item.Value.groupLastModifiedDate", + "UsernameAttributes.$": "$$.Map.Item.Value.UsernameAttributes", + "exportTimestamp.$": "$.ExportTimestamp" + }, + "Iterator": { + "StartAt": "ExportGroupLambda", + "States": { + "ExportGroupLambda": { + "Type": "Task", + "Resource": "${ExportGroupLambda.Arn}", + "InputPath": "$", + "Next": "ExportUsersInGroupLambda", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambdaGroupsMap" + } + ] + }, + "ExportUsersInGroupLambda": { + "Type": "Task", + "Resource": "${ExportUsersInGroupLambda.Arn}", + "InputPath": "$", + "Next": "Processed all users in group?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambdaGroupsMap" + } + ] + }, + "Processed all users in group?": { + "Type": "Choice", + "Choices": [ + { + "Not": { + "Variable": "$.processedAllUsersInGroup", + "StringEquals": "Yes" + }, + "Next": "More users to process in group" + }, + { + "Variable": "$.processedAllUsersInGroup", + "StringEquals": "Yes", + "Next": "All users in group processed" + } + ], + "Default": "More users to process in group" + }, + "More users to process in group": { + "Type": "Pass", + "Next": "Wait 1 second" + }, + "Wait 1 second": { + "Comment": "A Wait state delays the state machine from continuing for a specified time.", + "Type": "Wait", + "Seconds": 1, + "Next": "ExportUsersInGroupLambda" + }, + "All users in group processed": { + "Type": "Pass", + "End": true + }, + "WorkflowErrorHandlerLambdaGroupsMap": { + "Type": "Task", + "Resource": "${WorkflowMessageBrokerLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "Next": "Unexpected workflow error in Groups map" + }, + "Unexpected workflow error in Groups map": { + "Type": "Fail", + "Error": "UnexpectedErrorInWorkflow", + "Cause": "An unexpected error occured while executing this workflow. Please check logs for the State Machine task that generated this error for details" + } + } + }, + "MaxConcurrency": 1, + "Next": "Processed all groups?" + }, + "Processed all groups?": { + "Type": "Choice", + "Choices": [ + { + "Not": { + "Variable": "$.ProcessedAllGroups", + "StringEquals": "Yes" + }, + "Next": "More groups to process" + }, + { + "Variable": "$.ProcessedAllGroups", + "StringEquals": "Yes", + "Next": "All groups processed" + } + ], + "Default": "All groups processed" + }, + "More groups to process": { + "Type": "Pass", + "Next": "Wait 1 sec - List Groups" + }, + "Wait 1 sec - List Groups": { + "Comment": "A Wait state delays the state machine from continuing for a specified time.", + "Type": "Wait", + "Seconds": 1, + "Next": "ListGroupsLambda" + }, + "All groups processed": { + "Type": "Pass", + "Next": "BackupTableCleanup: Find Items" + }, + "BackupTableCleanup: Find Items": { + "Type": "Task", + "Resource": "${BackupTableCleanupLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "BackupTableCleanup: Checked Entire Table?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "BackupTableCleanup: Checked Entire Table?": { + "Type": "Choice", + "Choices": [ + { + "Not": { + "Variable": "$.lastEvaluatedKey", + "StringEquals": "" + }, + "Next": "BackupTableCleanup: No, not finished checking table" + }, + { + "Variable": "$.lastEvaluatedKey", + "StringEquals": "", + "Next": "BackupTableCleanup: Yes, finished checking table" + } + ] + }, + "BackupTableCleanup: No, not finished checking table": { + "Type": "Pass", + "Next": "BackupTableCleanup: Find Items" + }, + "BackupTableCleanup: Yes, finished checking table": { + "Type": "Pass", + "Next": "BackupTableCleanup: Items to remove?" + }, + "BackupTableCleanup: Items to remove?": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.NumItemsAddedToQueue", + "NumericGreaterThan": 0, + "Next": "BackupTableCleanup: Remove Items" + } + ], + "Default": "WorkflowCleanupLambda" + }, + "BackupTableCleanup: Remove Items": { + "Type": "Task", + "Resource": "${BackupTableCleanupLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "OutputPath": "$.result", + "Next": "BackupTableCleanup: All items removed?", + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "BackupTableCleanup: All items removed?": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.IsQueueEmpty", + "BooleanEquals": true, + "Next": "BackupTableCleanup: Yes, all items have been removed" + } + ], + "Default": "BackupTableCleanup: No, not all items have been removed" + }, + "BackupTableCleanup: No, not all items have been removed": { + "Type": "Pass", + "Next": "BackupTableCleanup: Remove Items" + }, + "BackupTableCleanup: Yes, all items have been removed": { + "Type": "Pass", + "Next": "WorkflowCleanupLambda" + }, + "WorkflowCleanupLambda": { + "Type": "Task", + "Resource": "${WorkflowMessageBrokerLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "End": true, + "Catch": [ + { + "ErrorEquals": [ + "States.TaskFailed" + ], + "Next": "WorkflowErrorHandlerLambda" + } + ] + }, + "WorkflowErrorHandlerLambda": { + "Type": "Task", + "Resource": "${WorkflowMessageBrokerLambda.Arn}", + "Parameters": { + "Input.$": "$", + "Context.$": "$$" + }, + "Next": "Unexpected workflow error" + }, + "Unexpected workflow error": { + "Type": "Fail", + "Error": "UnexpectedErrorInWorkflow", + "Cause": "An unexpected error occured while executing this workflow. Please check logs for the State Machine task that generated this error for details" + } + } + } + + ExportWorkflowEventRule: + Type: AWS::Events::Rule + Condition: IsPrimaryRegion + Properties: + Description: Starts a state machine for the Export Workflow of the Cognito User Profiles Export Reference Architecture + ScheduleExpression: !If [ExportDaily, "rate(1 day)", !If [ExportWeekly, "rate(7 days)", "rate(30 days)"]] + State: ENABLED + Targets: + - Id: export-workflow-event-rule-target + RoleArn: !GetAtt ExportWorkflowEventRuleRole.Arn + Arn: !Ref ExportWorkflow + + ExportWorkflowEventRuleRole: + Type: AWS::IAM::Role + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - events.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: export-workflow-event-rule-policy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - states:StartExecution + Resource: + - !Ref ExportWorkflow + + ExportUsersLambda: + Type: AWS::Lambda::Function + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Export user profiles from the Primary User Pool to the Backup Table + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], !Ref "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-export.zip"]] + Handler: "workflow-export/export-users.handler" + Role: !GetAtt ExportUsersLambdaRole.Arn + Runtime: nodejs12.x + Timeout: 900 + MemorySize: 128 + Environment: + Variables: + USER_POOL_ID: !GetAtt StackSetConstantsCustomResource.PrimaryUserPoolId + TABLE_NAME: !GetAtt StackSetConstantsCustomResource.BackupTableName + COGNITO_TPS: !Ref CognitoTPS + TYPE_USER: !Join ["-", [ "USER", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + + ExportUsersLambdaRole: + Type: AWS::IAM::Role + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Path: / + Policies: + - PolicyName: CloudWatchLogsPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + - !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/* + - PolicyName: ExportUsersPolicy + PolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Action: + - cognito-idp:ListUsers + - cognito-idp:AdminGetUser + Resource: + - !Sub "arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/${StackSetConstantsCustomResource.PrimaryUserPoolId}" + - Effect: Allow + Action: + - dynamodb:BatchWriteItem + Resource: + - !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${StackSetConstantsCustomResource.BackupTableName} + + ListGroupsLambda: + Type: AWS::Lambda::Function + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Lists the groups in a Cognito User Pool + Handler: "workflow-export/list-groups.handler" + Role: !GetAtt ListGroupsLambdaRole.Arn + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], Ref: "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-export.zip"]] + Runtime: nodejs12.x + Timeout: 300 + Environment: + Variables: + USER_POOL_ID: !GetAtt StackSetConstantsCustomResource.PrimaryUserPoolId + COGNITO_TPS: !Ref CognitoTPS + + ListGroupsLambdaRole: + Type: AWS::IAM::Role + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: list-groups-policy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/* + - Effect: Allow + Action: + - cognito-idp:ListGroups + Resource: + - !Sub "arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/${StackSetConstantsCustomResource.PrimaryUserPoolId}" + + ExportGroupLambda: + Type: AWS::Lambda::Function + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Exports the supplied group name to the backup table + Handler: "workflow-export/export-group.handler" + Role: !GetAtt ExportGroupLambdaRole.Arn + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], Ref: "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-export.zip"]] + Runtime: nodejs12.x + Timeout: 300 + Environment: + Variables: + BACKUP_TABLE_NAME: !GetAtt StackSetConstantsCustomResource.BackupTableName + SOLUTION_INSTANCE_ID: !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID + TYPE_GROUP: !Join ["-", [ "GROUP", !GetAtt StackSetConstantsCustomResource.SolutionInstanceUUID ] ] + + ExportGroupLambdaRole: + Type: AWS::IAM::Role + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: export-users-in-group-policy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/* + - Effect: Allow + Action: + - dynamodb:PutItem + Resource: + - !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${StackSetConstantsCustomResource.BackupTableName} + + ExportUsersInGroupLambda: + Type: AWS::Lambda::Function + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Exports users in the supplied group name to the backup table + Handler: "workflow-export/export-users-in-group.handler" + Role: !GetAtt ExportUsersInGroupLambdaRole.Arn + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], Ref: "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-export.zip"]] + Runtime: nodejs12.x + Timeout: 300 + Environment: + Variables: + USER_POOL_ID: !GetAtt StackSetConstantsCustomResource.PrimaryUserPoolId + BACKUP_TABLE_NAME: !GetAtt StackSetConstantsCustomResource.BackupTableName + COGNITO_TPS: !Ref CognitoTPS + + ExportUsersInGroupLambdaRole: + Type: AWS::IAM::Role + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: export-users-in-group-policy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/* + - Effect: Allow + Action: + - cognito-idp:ListUsersInGroup + Resource: + - !Sub "arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/${StackSetConstantsCustomResource.PrimaryUserPoolId}" + - Effect: Allow + Action: + - dynamodb:BatchWriteItem + Resource: + - !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${StackSetConstantsCustomResource.BackupTableName} + + CheckUserPoolConfigLambda: + Type: AWS::Lambda::Function + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Returns whether a user pool's configuration is supported by this solution + Handler: "workflow-export/check-user-pool-config.handler" + Role: !GetAtt CheckUserPoolConfigLambdaRole.Arn + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], Ref: "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-export.zip"]] + Runtime: nodejs12.x + Timeout: 300 + Environment: + Variables: + PRIMARY_USER_POOL_ID: !GetAtt StackSetConstantsCustomResource.PrimaryUserPoolId + + CheckUserPoolConfigLambdaRole: + Type: AWS::IAM::Role + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: check-user-pool-config-policy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/* + # - Effect: Allow + # Action: + # - cognito-idp:GetUserPoolMfaConfig + # Resource: + # - !Sub "arn:${AWS::Partition}:cognito-idp:${AWS::Region}:${AWS::AccountId}:userpool/${StackSetConstantsCustomResource.PrimaryUserPoolId}" + - Effect: Allow + Action: + - cognito-idp:DescribeUserPool + Resource: + - !Sub arn:${AWS::Partition}:cognito-idp:${PrimaryRegion}:${AWS::AccountId}:userpool/${StackSetConstantsCustomResource.PrimaryUserPoolId} + + ExportWorkflowQueue: + Type: AWS::SQS::Queue + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + QueueName: !Sub "${StackSetConstantsCustomResource.ExportWorkflowQueueNamePrefix}-${StackSetConstantsCustomResource.SolutionInstanceUUID}" + KmsMasterKeyId: alias/aws/sqs + VisibilityTimeout: 30 + RedrivePolicy: + deadLetterTargetArn: !GetAtt ExportWorkflowDeadLetterQueue.Arn + maxReceiveCount: 2 + + ExportWorkflowDeadLetterQueue: + Type: AWS::SQS::Queue + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + QueueName: !Sub "${StackSetConstantsCustomResource.ExportWorkflowQueueNamePrefix}-${StackSetConstantsCustomResource.SolutionInstanceUUID}-dlq" + KmsMasterKeyId: alias/aws/sqs + VisibilityTimeout: 30 + + BackupTableCleanupLambda: + Type: AWS::Lambda::Function + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + Description: Removes items from the Backup Table that were not updated during the export workflow + Handler: "workflow-export/backup-table-cleanup.handler" + Role: !GetAtt BackupTableCleanupLambdaRole.Arn + Code: + S3Bucket: !Join ["-", [!FindInMap ["SourceCode", "General", "S3Bucket"], Ref: "AWS::Region"]] + S3Key: !Join ["/", [!FindInMap ["SourceCode", "General", "KeyPrefix"], "workflow-export.zip"]] + Runtime: nodejs12.x + Timeout: 300 + Environment: + Variables: + BACKUP_TABLE_NAME: !GetAtt StackSetConstantsCustomResource.BackupTableName + QUEUE_URL: !Ref ExportWorkflowQueue + + BackupTableCleanupLambdaRole: + Type: AWS::IAM::Role + Condition: IsPrimaryRegion + Properties: + Tags: + - Key: solution-id-SO0126 + Value: !Sub ${StackSetConstantsCustomResource.ParentStackName}-${PrimaryRegion} + AssumeRolePolicyDocument: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + Service: + - lambda.amazonaws.com + Action: + - sts:AssumeRole + Policies: + - PolicyName: backup-table-cleanup-policy + PolicyDocument: + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + !Sub arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/* + - Effect: Allow + Action: + - sqs:SendMessage + - sqs:SendMessageBatch + - sqs:ReceiveMessage + - sqs:DeleteMessage + - sqs:GetQueueAttributes + Resource: + - !GetAtt ExportWorkflowQueue.Arn + - Effect: Allow + Action: + - dynamodb:Scan + - dynamodb:BatchWriteItem + Resource: + - !Sub arn:${AWS::Partition}:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${StackSetConstantsCustomResource.BackupTableName} diff --git a/source/custom-resources/check-stackset-status.js b/source/custom-resources/check-stackset-status.js new file mode 100644 index 0000000..3f3ebc5 --- /dev/null +++ b/source/custom-resources/check-stackset-status.js @@ -0,0 +1,123 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const cfn = new AWS.CloudFormation(); +const axios = require('axios'); + +/** + * Checks the status of the solution's StackSets and when ready, responds to CloudFormation + */ +exports.handler = async (event, context) => { + console.log(`Received event: ${JSON.stringify(event)}`); + const { operationId } = event.Context.Execution.Input; + const { RequestType } = event.Context.Execution.Input.customResourceEvent; + const { StackSetName } = event.Context.Execution.Input.customResourceEvent.ResourceProperties; + const result = { HasRespondedToCfn: false }; + try { + if (await areAllInstancesUpdated(StackSetName, operationId)) { + if (RequestType === 'Delete') { + await deleteStackSet(StackSetName); + } + const response = { + status: 'SUCCESS', + data: { Message: `${RequestType} Successful` } + }; + + await sendResponse(event.Context.Execution.Input.customResourceEvent, context.logStreamName, response); + result.HasRespondedToCfn = true; + } + } catch (err) { + console.error(err); + const response = { + status: 'FAILED', + data: { Error: err.message } + }; + + await sendResponse(event.Context.Execution.Input.customResourceEvent, context.logStreamName, response); + result.HasRespondedToCfn = true; + } + + return { result }; +}; + +/** + * Checks the CloudFormation StackSet operation and validates that all instances have been updated + * @param {string} stackSetName The name of the StackSet + * @param {string} operationId The id of the StackSet operation + */ +const areAllInstancesUpdated = async (stackSetName, operationId) => { + let listResponse; + const listParams = { StackSetName: stackSetName, OperationId: operationId }; + const operationSummaries = []; + + do { + console.log(`Listing Operation Results: ${JSON.stringify(listParams)}`); + listResponse = await cfn.listStackSetOperationResults(listParams).promise(); + console.log(`List Operation Results Response: ${JSON.stringify(listResponse)}`); + if (listResponse.Summaries && listResponse.Summaries.length > 0) { + operationSummaries.push(...listResponse.Summaries); + } + + delete listParams.NextToken; + if (listResponse.NextToken) { + listParams.NextToken = listResponse.NextToken; + } + } while (listParams.NextToken); + + // Check if any instances failed to update + if (operationSummaries.some(stackSetInstance => (stackSetInstance.Status && stackSetInstance.Status.toUpperCase() === 'FAILED'))) { + throw new Error('At least one instance in this StackSet failed to update'); + } + + // Check if any instance updates were canceled + if (operationSummaries.some(stackSetInstance => (stackSetInstance.Status && stackSetInstance.Status.toUpperCase() === 'CANCELLED'))) { + throw new Error('At least one instance update was canceled'); + } + + // Return whether all instances are successfully updated + return (operationSummaries.length > 0 && operationSummaries.every(stackSetInstance => (stackSetInstance.Status && stackSetInstance.Status.toUpperCase() === 'SUCCEEDED'))); +}; + +/** + * Deletes the solution's StackSet + * @param {string} StackSetName The name of the StackSet + */ +const deleteStackSet = async function deleteStackSet(StackSetName) { + const params = { StackSetName }; + + console.log(`Deleting StackSet: ${JSON.stringify(params)}`); + const response = await cfn.deleteStackSet(params).promise(); + console.log(`Delete StackSet response: ${JSON.stringify(response)}`); +}; + +/** + * Send custom resource response. + * @param {object} event - Custom resource event + * @param {string} logStreamName - Custom resource log stream name + * @param {object} response - Response object { status: "SUCCESS|FAILED", data: object } + */ +async function sendResponse(event, logStreamName, response) { + const responseBody = JSON.stringify({ + Status: response.status, + Reason: `See the details in CloudWatch Log Stream: ${logStreamName}`, + PhysicalResourceId: event.LogicalResourceId, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + Data: response.data, + }); + + const config = { + headers: { + 'Content-Type': '', + 'Content-Length': responseBody.length + } + }; + + await axios.put(event.ResponseURL, responseBody, config); +} diff --git a/source/custom-resources/global-table-checker.js b/source/custom-resources/global-table-checker.js new file mode 100644 index 0000000..a3e2445 --- /dev/null +++ b/source/custom-resources/global-table-checker.js @@ -0,0 +1,109 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const { USER_POOL_TABLE, SECONDARY_REGION } = process.env; +const ONE_MINUTE = 60 * 1000; + +const AWS = require('aws-sdk'); +const dynamodb = new AWS.DynamoDB({ region: SECONDARY_REGION }); +const axios = require('axios'); + +/** + * Checks the status of the Backup Table replica and when active, response to CloudFormation + * @param {object} event + * @param {object} context + */ +exports.handler = async (event, context) => { + console.log(`Requested event: ${JSON.stringify(event, null, 2)}`); + + const output = { + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + ResponseURL: event.ResponseURL, + LatestStreamArn: '' + }; + + while (output.LatestStreamArn === '' && context.getRemainingTimeInMillis() > ONE_MINUTE) { + try { + output.LatestStreamArn = await getSecondaryLastestStreamArn(); + } catch (error) { + // If the table is not created yet, continue after a sleep. + if (error.code === 'ResourceNotFoundException') { + await sleep(1); + continue; + } else { + console.error(`Error occurred while getting secondary lastest stream ARN.`, error); + + await sendResponse(event, context.logStreamName, { + status: 'FAILED', + data: { Error: error.message } + }); + throw error; + } + } + } + + if (output.LatestStreamArn !== '') { + // Send response + await sendResponse(event, context.logStreamName, { + status: 'SUCCESS', + data: { + LatestStreamArn: output.LatestStreamArn + } + }); + } + + return output; +} + +/** + * Return the latest secondary region's global table stream ARN. + * @return {Promise} - Latest stream ARN or empty string + */ +async function getSecondaryLastestStreamArn() { + const response = await dynamodb.describeTable({ + TableName: USER_POOL_TABLE + }).promise(); + + return response.Table.LatestStreamArn ? response.Table.LatestStreamArn : ''; +} + +/** + * Sleep for the provided second(s). + * @return {Promise} - Sleep promise + */ +async function sleep(second) { + return new Promise(resolve => setTimeout(resolve, second * 1000)); +} + +/** + * Send custom resource response. + * @param {object} event - Custom resource event + * @param {string} logStreamName - Custom resource log stream name + * @param {object} response - Response object { status: "SUCCESS|FAILED", data: object } + */ +async function sendResponse(event, logStreamName, response) { + const responseBody = JSON.stringify({ + Status: response.status, + Reason: `See the details in CloudWatch Log Stream: ${logStreamName}`, + PhysicalResourceId: logStreamName, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + Data: response.data, + }); + + const config = { + headers: { + 'Content-Type': '', + 'Content-Length': responseBody.length + } + }; + + await axios.put(event.ResponseURL, responseBody, config); +} \ No newline at end of file diff --git a/source/custom-resources/global-table-creator.js b/source/custom-resources/global-table-creator.js new file mode 100644 index 0000000..9140829 --- /dev/null +++ b/source/custom-resources/global-table-creator.js @@ -0,0 +1,125 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const dynamodb = new AWS.DynamoDB(); +const stepFunctions = new AWS.StepFunctions(); +const axios = require('axios'); + +/** + * Adds a replica to the Backup Table in the Secondary Region + * @param {object} event + * @param {object} context + * @return {Promise} + */ +exports.handler = async (event, context) => { + console.log(`Received event: ${JSON.stringify(event)}`); + + const properties = event.ResourceProperties; + + try { + if (event.RequestType === 'Create') { + const dynamodbResponse = await createGlobalTable(properties); + console.log(`DynamoDB Update: ${JSON.stringify(dynamodbResponse, null, 2)}`); + + // The step function workflow will respond to CloudFormation after + // the Global Table has fully been created + await startStepFunction( + properties.StateMachineArn, + JSON.stringify({ + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + ResponseURL: event.ResponseURL + }) + ); + console.log(`Step Function Execution: ${JSON.stringify()}`) + } else { + await sendResponse(event, context.logStreamName, { status: 'SUCCESS', data: {} }); + } + } catch (error) { + console.error(error); + const response = { + status: 'FAILED', + data: { Error: error.message } + }; + + await sendResponse(event, context.logStreamName, response); + + return response; + } + + return event; +} + +/** + * Create DynamoDB global table in the secondary region + * @param {object} properties - Custom resource properties { UserPoolTable: string, SecondaryRegion: string } + * @return {Promise} + */ +async function createGlobalTable(properties) { + const { UserPoolTable, SecondaryRegion } = properties; + + try { + return await dynamodb.updateTable({ + TableName: UserPoolTable, + ReplicaUpdates: [ + { + Create: { RegionName: SecondaryRegion } + } + ] + }).promise(); + } catch (error) { + console.error(`Error occurred while creating global table in ${SecondaryRegion}.`); + throw error; + } +} + +/** + * Start Step Function to check the status of global table creation. + * @param {string} stateMachineArn - Step Function state machine ARN + * @param {string} input - Stringified JSON object + * @return {Promise} + */ +async function startStepFunction(stateMachineArn, input) { + try { + return await stepFunctions.startExecution({ + stateMachineArn, + input + }).promise(); + } catch (error) { + console.error('Error occurred while starting step function.'); + throw error; + } +} + +/** + * Send custom resource response. + * @param {object} event - Custom resource event + * @param {string} logStreamName - Custom resource log stream name + * @param {object} response - Response object { status: "SUCCESS|FAILED", data: object } + */ +async function sendResponse(event, logStreamName, response) { + const responseBody = JSON.stringify({ + Status: response.status, + Reason: `See the details in CloudWatch Log Stream: ${logStreamName}`, + PhysicalResourceId: logStreamName, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + Data: response.data, + }); + + const config = { + headers: { + 'Content-Type': '', + 'Content-Length': responseBody.length + } + }; + + await axios.put(event.ResponseURL, responseBody, config); +} \ No newline at end of file diff --git a/source/custom-resources/package-lock.json b/source/custom-resources/package-lock.json new file mode 100644 index 0000000..264dde0 --- /dev/null +++ b/source/custom-resources/package-lock.json @@ -0,0 +1,4919 @@ +{ + "name": "custom-resources", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.0.tgz", + "integrity": "sha512-mkLq8nwaXmDtFmRkQ8ED/eA2CnVw4zr7dCztKalZXBvdK5EeNUAesrrwUqjQEzFgomJssayzB0aqlOsP1vGLqg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-module-transforms": "^7.11.0", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.11.0", + "@babel/types": "^7.11.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + }, + "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/generator": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", + "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "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-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", + "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/types": "^7.11.0", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "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.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "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.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@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/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + } + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "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 + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@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" + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/console": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.2.0.tgz", + "integrity": "sha512-mXQfx3nSLwiHm1i7jbu+uvi+vvpVjNGzIQYLCfsat9rapC+MJkS4zBseNrgJE0vU921b3P67bQzhduphjY3Tig==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.2.0", + "jest-util": "^26.2.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.2.2.tgz", + "integrity": "sha512-UwA8gNI8aeV4FHGfGAUfO/DHjrFVvlBravF1Tm9Kt6qFE+6YHR47kFhgdepOFpADEKstyO+MVdPvkV6/dyt9sA==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/reporters": "^26.2.2", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.2", + "@jest/types": "^26.2.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.2.0", + "jest-config": "^26.2.2", + "jest-haste-map": "^26.2.2", + "jest-message-util": "^26.2.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.2.2", + "jest-resolve-dependencies": "^26.2.2", + "jest-runner": "^26.2.2", + "jest-runtime": "^26.2.2", + "jest-snapshot": "^26.2.2", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "jest-watcher": "^26.2.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.2.0.tgz", + "integrity": "sha512-oCgp9NmEiJ5rbq9VI/v/yYLDpladAAVvFxZgNsnJxOETuzPZ0ZcKKHYjKYwCtPOP1WCrM5nmyuOhMStXFGHn+g==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0" + } + }, + "@jest/fake-timers": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.2.0.tgz", + "integrity": "sha512-45Gfe7YzYTKqTayBrEdAF0qYyAsNRBzfkV0IyVUm3cx7AsCWlnjilBM4T40w7IXT5VspOgMPikQlV0M6gHwy/g==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.2.0", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0" + } + }, + "@jest/globals": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.2.0.tgz", + "integrity": "sha512-Hoc6ScEIPaym7RNytIL2ILSUWIGKlwEv+JNFof9dGYOdvPjb2evEURSslvCMkNuNg1ECEClTE8PH7ULlMJntYA==", + "dev": true, + "requires": { + "@jest/environment": "^26.2.0", + "@jest/types": "^26.2.0", + "expect": "^26.2.0" + } + }, + "@jest/reporters": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.2.2.tgz", + "integrity": "sha512-7854GPbdFTAorWVh+RNHyPO9waRIN6TcvCezKVxI1khvFq9YjINTW7J3WU+tbR038Ynn6WjYred6vtT0YmIWVQ==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.2.0", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.2", + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.2.2", + "jest-resolve": "^26.2.2", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.1", + "node-notifier": "^7.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + } + }, + "@jest/source-map": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.1.0.tgz", + "integrity": "sha512-XYRPYx4eEVX15cMT9mstnO7hkHP3krNtKfxUYd8L7gbtia8JvZZ6bMzSwa6IQJENbudTwKMw5R1BePRD+bkEmA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.2.0.tgz", + "integrity": "sha512-kgPlmcVafpmfyQEu36HClK+CWI6wIaAWDHNxfQtGuKsgoa2uQAYdlxjMDBEa3CvI40+2U3v36gQF6oZBkoKatw==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.2.2.tgz", + "integrity": "sha512-SliZWon5LNqV/lVXkeowSU6L8++FGOu3f43T01L1Gv6wnFDP00ER0utV9jyK9dVNdXqfMNCN66sfcyar/o7BNw==", + "dev": true, + "requires": { + "@jest/test-result": "^26.2.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.2.2", + "jest-runner": "^26.2.2", + "jest-runtime": "^26.2.2" + } + }, + "@jest/transform": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.2.2.tgz", + "integrity": "sha512-c1snhvi5wRVre1XyoO3Eef5SEWpuBCH/cEbntBUd9tI5sNYiBDmO0My/lc5IuuGYKp/HFIHV1eZpSx5yjdkhKw==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.2.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.2.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.2.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", + "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "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.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", + "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "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": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/node": { + "version": "14.0.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz", + "integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/prettier": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.2.tgz", + "integrity": "sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA==", + "dev": true + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "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==", + "dev": true + }, + "ajv": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "dev": true, + "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-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "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=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sdk": { + "version": "2.726.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.726.0.tgz", + "integrity": "sha512-QRQ7MaW5dprdr/T3vCTC+J8TeUfpM45yWsBuATPcCV/oO8afFHVySwygvGLY4oJuo5Mf4mJn3+JYTquo6CqiaA==", + "dev": true, + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "dependencies": { + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + } + } + }, + "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=", + "dev": true + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "axios-mock-adapter": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.18.2.tgz", + "integrity": "sha512-e5aTsPy2Viov22zNpFTlid76W1Scz82pXeEwwCXdtO85LROhHAF8pHF2qDhiyMONLxKyY3lQ+S4UCsKgrlx8Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "is-buffer": "^2.0.3" + } + }, + "babel-jest": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.2.2.tgz", + "integrity": "sha512-JmLuePHgA+DSOdOL8lPxCgD2LhPPm+rdw1vnxR73PpIrnmKCS2/aBhtkAcxQWuUcW2hBrH8MJ3LKXE7aWpNZyA==", + "dev": true, + "requires": { + "@jest/transform": "^26.2.2", + "@jest/types": "^26.2.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "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": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.2.0.tgz", + "integrity": "sha512-B/hVMRv8Nh1sQ1a3EY8I0n4Y1Wty3NrR5ebOyVT302op+DOAau+xNEImGMsUWOC3++ZlMooCytKz+NgN8aKGbA==", + "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": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "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-preset-jest": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.2.0.tgz", + "integrity": "sha512-R1k8kdP3R9phYQugXeNnK/nvCGlBzG4m3EoIIukC80GXb6wCv2XiwPhK6K9MAkQcMszWBYvl2Wm+yigyXFQqXg==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.2.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "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 + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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 + }, + "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 + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.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 + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "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 + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "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=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "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==", + "dev": true + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "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==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "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=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "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-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "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==", + "dev": true + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emittery": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", + "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", + "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==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "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" + } + }, + "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": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expect": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.2.0.tgz", + "integrity": "sha512-8AMBQ9UVcoUXt0B7v+5/U5H6yiUR87L6eKCfjE3spx7Ya5lF+ebUo37MCFBML2OiLfkX1sxmQOZhIDonyVTkcw==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-regex-util": "^26.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "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-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==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "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" + } + }, + "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 + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "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-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "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==", + "dev": true, + "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-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "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==", + "dev": true, + "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==", + "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" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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==", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "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-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-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.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.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.2.2.tgz", + "integrity": "sha512-EkJNyHiAG1+A8pqSz7cXttoVa34hOEzN/MrnJhYnfp5VHxflVcf2pu3oJSrhiy6LfIutLdWo+n6q63tjcoIeig==", + "dev": true, + "requires": { + "@jest/core": "^26.2.2", + "import-local": "^3.0.2", + "jest-cli": "^26.2.2" + }, + "dependencies": { + "jest-cli": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.2.2.tgz", + "integrity": "sha512-vVcly0n/ijZvdy6gPQiQt0YANwX2hLTPQZHtW7Vi3gcFdKTtif7YpI85F8R8JYy5DFSWz4x1OW0arnxlziu5Lw==", + "dev": true, + "requires": { + "@jest/core": "^26.2.2", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.2.2", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "prompts": "^2.0.1", + "yargs": "^15.3.1" + } + } + } + }, + "jest-changed-files": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.2.0.tgz", + "integrity": "sha512-+RyJb+F1K/XBLIYiL449vo5D+CvlHv29QveJUWNPXuUicyZcq+tf1wNxmmFeRvAU1+TzhwqczSjxnCCFt7+8iA==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "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==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-config": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.2.2.tgz", + "integrity": "sha512-2lhxH0y4YFOijMJ65usuf78m7+9/8+hAb1PZQtdRdgnQpAb4zP6KcVDDktpHEkspBKnc2lmFu+RQdHukUUbiTg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.2.2", + "@jest/types": "^26.2.0", + "babel-jest": "^26.2.2", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.2.0", + "jest-environment-node": "^26.2.0", + "jest-get-type": "^26.0.0", + "jest-jasmine2": "^26.2.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.2.2", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "micromatch": "^4.0.2", + "pretty-format": "^26.2.0" + } + }, + "jest-diff": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.2.0.tgz", + "integrity": "sha512-Wu4Aopi2nzCsHWLBlD48TgRy3Z7OsxlwvHNd1YSnHc7q1NJfrmyCPoUXrTIrydQOG5ApaYpsAsdfnMbJqV1/wQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.2.0" + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.2.0.tgz", + "integrity": "sha512-gHPCaho1twWHB5bpcfnozlc6mrMi+VAewVPNgmwf81x2Gzr6XO4dl+eOrwPWxbkYlgjgrYjWK2xgKnixbzH3Ew==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-util": "^26.2.0", + "pretty-format": "^26.2.0" + } + }, + "jest-environment-jsdom": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.2.0.tgz", + "integrity": "sha512-sDG24+5M4NuIGzkI3rJW8XUlrpkvIdE9Zz4jhD8OBnVxAw+Y1jUk9X+lAOD48nlfUTlnt3lbAI3k2Ox+WF3S0g==", + "dev": true, + "requires": { + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0", + "jsdom": "^16.2.2" + } + }, + "jest-environment-node": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.2.0.tgz", + "integrity": "sha512-4M5ExTYkJ19efBzkiXtBi74JqKLDciEk4CEsp5tTjWGYMrlKFQFtwIVG3tW1OGE0AlXhZjuHPwubuRYY4j4uOw==", + "dev": true, + "requires": { + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-haste-map": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.2.2.tgz", + "integrity": "sha512-3sJlMSt+NHnzCB+0KhJ1Ut4zKJBiJOlbrqEYNdRQGlXTv8kqzZWjUKQRY3pkjmlf+7rYjAV++MQ4D6g4DhAyOg==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.2.0", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.1", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.2.2.tgz", + "integrity": "sha512-Q8AAHpbiZMVMy4Hz9j1j1bg2yUmPa1W9StBvcHqRaKa9PHaDUMwds8LwaDyzP/2fkybcTQE4+pTMDOG9826tEw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.2.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.2.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.2.0", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-runtime": "^26.2.2", + "jest-snapshot": "^26.2.2", + "jest-util": "^26.2.0", + "pretty-format": "^26.2.0", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.2.0.tgz", + "integrity": "sha512-aQdzTX1YiufkXA1teXZu5xXOJgy7wZQw6OJ0iH5CtQlOETe6gTSocaYKUNui1SzQ91xmqEUZ/WRavg9FD82rtQ==", + "dev": true, + "requires": { + "jest-get-type": "^26.0.0", + "pretty-format": "^26.2.0" + } + }, + "jest-matcher-utils": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.2.0.tgz", + "integrity": "sha512-2cf/LW2VFb3ayPHrH36ZDjp9+CAeAe/pWBAwsV8t3dKcrINzXPVxq8qMWOxwt5BaeBCx4ZupVGH7VIgB8v66vQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.2.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.2.0" + } + }, + "jest-message-util": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.2.0.tgz", + "integrity": "sha512-g362RhZaJuqeqG108n1sthz5vNpzTNy926eNDszo4ncRbmmcMRIUAZibnd6s5v2XSBCChAxQtCoN25gnzp7JbQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.2.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.2.0.tgz", + "integrity": "sha512-XeC7yWtWmWByoyVOHSsE7NYsbXJLtJNgmhD7z4MKumKm6ET0si81bsSLbQ64L5saK3TgsHo2B/UqG5KNZ1Sp/Q==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@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": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.2.2.tgz", + "integrity": "sha512-ye9Tj/ILn/0OgFPE/3dGpQPUqt4dHwIocxt5qSBkyzxQD8PbL0bVxBogX2FHxsd3zJA7V2H/cHXnBnNyyT9YoQ==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.2.0", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.2.2.tgz", + "integrity": "sha512-S5vufDmVbQXnpP7435gr710xeBGUFcKNpNswke7RmFvDQtmqPjPVU/rCeMlEU0p6vfpnjhwMYeaVjKZAy5QYJA==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.2.2" + } + }, + "jest-runner": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.2.2.tgz", + "integrity": "sha512-/qb6ptgX+KQ+aNMohJf1We695kaAfuu3u3ouh66TWfhTpLd9WbqcF6163d/tMoEY8GqPztXPLuyG0rHRVDLxCA==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/environment": "^26.2.0", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.2.2", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.2.2", + "jest-leak-detector": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-resolve": "^26.2.2", + "jest-runtime": "^26.2.2", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.1", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.2.2.tgz", + "integrity": "sha512-a8VXM3DxCDnCIdl9+QucWFfQ28KdqmyVFqeKLigHdErtsx56O2ZIdQkhFSuP1XtVrG9nTNHbKxjh5XL1UaFDVQ==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/globals": "^26.2.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.2", + "@jest/types": "^26.2.0", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.2.2", + "jest-haste-map": "^26.2.2", + "jest-message-util": "^26.2.0", + "jest-mock": "^26.2.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.2.2", + "jest-snapshot": "^26.2.2", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.2.0.tgz", + "integrity": "sha512-V7snZI9IVmyJEu0Qy0inmuXgnMWDtrsbV2p9CRAcmlmPVwpC2ZM8wXyYpiugDQnwLHx0V4+Pnog9Exb3UO8M6Q==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.2.2.tgz", + "integrity": "sha512-NdjD8aJS7ePu268Wy/n/aR1TUisG0BOY+QOW4f6h46UHEKOgYmmkvJhh2BqdVZQ0BHSxTMt04WpCf9njzx8KtA==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.2.0", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.2.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.2.0", + "jest-get-type": "^26.0.0", + "jest-haste-map": "^26.2.2", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-resolve": "^26.2.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.2.0", + "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "jest-util": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.2.0.tgz", + "integrity": "sha512-YmDwJxLZ1kFxpxPfhSJ0rIkiZOM0PQbRcfH0TzJOhqCisCAsI1WcmoQqO83My9xeVA2k4n+rzg2UuexVKzPpig==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-validate": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.2.0.tgz", + "integrity": "sha512-8XKn3hM6VIVmLNuyzYLCPsRCT83o8jMZYhbieh4dAyKLc4Ypr36rVKC+c8WMpWkfHHpGnEkvWUjjIAyobEIY/Q==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.2.0" + }, + "dependencies": { + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.2.0.tgz", + "integrity": "sha512-674Boco4Joe0CzgKPL6K4Z9LgyLx+ZvW2GilbpYb8rFEUkmDGgsZdv1Hv5rxsRpb1HLgKUOL/JfbttRCuFdZXQ==", + "dev": true, + "requires": { + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.2.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.2.1.tgz", + "integrity": "sha512-+XcGMMJDTeEGncRb5M5Zq9P7K4sQ1sirhjdOxsN1462h6lFo9w59bl2LVQmdGEEeU3m+maZCkS2Tcc9SfCHO4A==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "dev": true + }, + "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": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.3.0.tgz", + "integrity": "sha512-zggeX5UuEknpdZzv15+MS1dPYG0J/TftiiNunOeNxSl3qr8Z6cIlQpN0IdJa44z9aFxZRIVqRncvEhQ7X5DtZg==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "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.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "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=", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "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.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "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.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "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 + } + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "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 + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.2.tgz", + "integrity": "sha512-ux+n4hPVETuTL8+daJXTOC6uKLgMsl1RYfFv7DKRzyvzBapqco0rZZ9g72ZN8VS6V+gvNYHYa/ofcCY8fkJWsA==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.2.0", + "which": "^2.0.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "optional": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "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" + } + }, + "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 + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.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==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "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" + } + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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-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 + }, + "parse-json": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", + "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "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=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "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" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "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=", + "dev": true + }, + "pretty-format": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", + "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "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" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "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": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "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-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "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 + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", + "dev": true + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "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 + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.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 + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "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.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "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.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "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 + } + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "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==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "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" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "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-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "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": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "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=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "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.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "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" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==" + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "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=", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "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==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "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==", + "dev": true + }, + "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" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "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.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "dev": true + }, + "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==", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "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=", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/source/custom-resources/package.json b/source/custom-resources/package.json new file mode 100644 index 0000000..096dde5 --- /dev/null +++ b/source/custom-resources/package.json @@ -0,0 +1,28 @@ +{ + "name": "custom-resources", + "description": "Custom Resources to support Cognito User Profiles Export Reference Architecture", + "author": { + "name": "aws-solutions-builder" + }, + "license": "Apache-2.0", + "version": "1.0.0", + "private": true, + "dependencies": { + "axios": "~0.19.2", + "uuid": "^8.1.0" + }, + "devDependencies": { + "aws-sdk": "*", + "jest": "*", + "axios-mock-adapter": "*" + }, + "scripts": { + "pretest": "npm ci", + "clean": "rm -rf dist/ node_modules/ coverage/", + "test": "jest test/*.spec.js --coverage --silent", + "package:zip": "cd dist && zip -rq package.zip .", + "package:dist": "mkdir dist && rsync -avr ../utils ./dist/ && rsync -avr --exclude=*test* --exclude=*dist* --exclude=*node_modules* ./ ./dist/$npm_package_name && rsync -avr ./node_modules ./dist/$npm_package_name", + "package": "npm run clean && npm ci --production && npm run package:dist && npm run package:zip", + "build": "npm run clean && rm -rf package-lock.json && npm install" + } +} diff --git a/source/custom-resources/solution-constants.js b/source/custom-resources/solution-constants.js new file mode 100644 index 0000000..2471305 --- /dev/null +++ b/source/custom-resources/solution-constants.js @@ -0,0 +1,45 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const CustomResourceHelperFunctions = require('../utils/custom-resource-helper-functions'); +const { appendToStrWithMaxChar } = require('../utils/helper-functions'); +const uuid = require('uuid'); + +/** + * Generates values to be used within the solution + */ +exports.handler = async (event, context) => { + return await CustomResourceHelperFunctions.handler(event, context, handleCreate); +}; + +/** + * Generates values to be used within the solution + * @param {object} event The incoming event from the Custom Resource invokation + */ +const handleCreate = async function handleCreate(event) { + const { StackName } = event.ResourceProperties; + const solutionInstanceUUID = uuid.v4(); + const formattedStackName = StackName.length < 15 ? StackName : StackName.slice(0, 15); + return { + StackSetName: getStackSetName(StackName), + FormattedStackName: formattedStackName, + UserImportJobMappingFileBucketPrefix: `${formattedStackName.toLowerCase()}-import-jobs-${solutionInstanceUUID.split('-').pop()}`, + SolutionInstanceUUID: solutionInstanceUUID, + AnonymousDataUUID: uuid.v4() + }; +}; + +/** + * Generates a name to be used for the solution's StackSet, making sure to stay within the StackSet name character limit + * @param {string} stackName The name of the CloudFormation Stack + */ +const getStackSetName = function getStackSetNameFromStackName(stackName) { + const stackSetNameMaxChars = 128; + const suffix = '-StackSet'; + + return appendToStrWithMaxChar(stackName, suffix, stackSetNameMaxChars); +}; diff --git a/source/custom-resources/stack-checker.js b/source/custom-resources/stack-checker.js new file mode 100644 index 0000000..0099233 --- /dev/null +++ b/source/custom-resources/stack-checker.js @@ -0,0 +1,117 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const ssm = new AWS.SSM(); +const cognitoISP = new AWS.CognitoIdentityServiceProvider(); +const CustomResourceHelperFunctions = require('../utils/custom-resource-helper-functions'); +const { AWS_REGION, FIXED_PARAMETERS } = process.env; +const fixedParameters = FIXED_PARAMETERS.split(','); + +/** + * Custom Resource that checks to see if the current stack update is supported + */ +exports.handler = async (event, context) => { + return await CustomResourceHelperFunctions.handler(event, context, handleCreate, handleUpdate, handleDelete); +}; + +/** + * Stores the values of the solution's fixed parameters in SSM Parameter Store so they can be referenced later in the event of a stack update + * @param {object} event The incoming event from the Custom Resource invokation + */ +const handleCreate = async function putSSMParameters(event) { + const resourceProperties = event.ResourceProperties; + + // Make sure the secondary region is not the same as the primary region + if (resourceProperties.SecondaryRegion === AWS_REGION) { + throw new Error('The backup region must be different than the primary'); + } + + // Check to make sure the primary user pool has a supported configuration + await checkUserPoolConfig(resourceProperties.PrimaryUserPoolId); + + const ssmParameterName = `/${resourceProperties.ParentStackName}-${AWS_REGION}/fixed-solution-parameters`; + const putParams = { + Type: 'String', + Name: ssmParameterName, + Value: JSON.stringify(fixedParameters.reduce((obj, fixedParam) => { + return { ...obj, [fixedParam]: resourceProperties[fixedParam] }; + }, {})) + }; + + console.log(`Putting parameter: ${JSON.stringify(putParams)}`); + const putResponse = await ssm.putParameter(putParams).promise(); + console.log(`Put response: ${JSON.stringify(putResponse)}`); +}; + +/** + * Retrieves values for each of the solution's fixed parameters from SSM Parameter Store and checks to make sure they have not changed in the stack update + * @param {object} event The incoming event from the Custom Resource invokation + */ +const handleUpdate = async function checkCurrentPropertiesAgainstSSM(event) { + const resourceProperties = event.ResourceProperties; + const ssmParameterName = `/${resourceProperties.ParentStackName}-${AWS_REGION}/fixed-solution-parameters`; + const getParams = { Name: ssmParameterName }; + + console.log(`Getting parameter: ${JSON.stringify(getParams)}`); + const getResponse = await ssm.getParameter(getParams).promise(); + console.log(`Get response: ${JSON.stringify(getResponse)}`); + + const parametersFromSSM = JSON.parse(getResponse.Parameter.Value); + + fixedParameters.forEach(parameterName => { + console.log(`Checking parameter "${parameterName}"`); + if (resourceProperties[parameterName] !== parametersFromSSM[parameterName]) { + throw new Error(`Value for CloudFormation parameter "${parameterName}" cannot be changed. Please relaunch the solution if you need to change this value`); + } + }); + + console.log('All parameters checked OK'); +}; + +/** + * Removes the solution's fixed parameters from SSM Parameter Store when the solution is deleted + * @param {object} event The incoming event from the Custom Resource invokation + */ +const handleDelete = async function deleteSSMParameters(event) { + const resourceProperties = event.ResourceProperties; + const ssmParameterName = `/${resourceProperties.ParentStackName}-${AWS_REGION}/fixed-solution-parameters`; + + try { + const deleteParams = { Name: ssmParameterName }; + console.log(`Deleting parameters: ${JSON.stringify(deleteParams)}`); + const deleteResponse = await ssm.deleteParameter(deleteParams).promise(); + console.log(`Delete response: ${JSON.stringify(deleteResponse)}`); + } catch (err) { + if (err.code === 'ParameterNotFound') { + console.log(`Parameter ${ssmParameterName} is not present in SSM`); + } else { + throw err; + } + } +}; + +/** + * Throws an Error if the supplied Cognito user pool has a configuration that is not supported by this solution + * @param {string} UserPoolId The ID of the user pool that should be evaluated + */ +const checkUserPoolConfig = async (UserPoolId) => { + const describeUserPoolParams = { UserPoolId }; + console.log(`Describing user pool: ${JSON.stringify(describeUserPoolParams)}`); + const describeUserPoolResponse = await cognitoISP.describeUserPool(describeUserPoolParams).promise(); + console.log(`Describe user pool response: ${JSON.stringify(describeUserPoolResponse, null, 2)}`); + + if (describeUserPoolResponse.UserPool.MfaConfiguration && describeUserPoolResponse.UserPool.MfaConfiguration !== 'OFF') { + throw new Error(`User Pools with MFA enabled are not supported. The user pool\'s MFA configuration is set to ${describeUserPoolResponse.UserPool.MfaConfiguration}`); + } + + if (describeUserPoolResponse.UserPool.UsernameAttributes) { + if (describeUserPoolResponse.UserPool.UsernameAttributes.length > 1) { + throw new Error(`This solution does not support user pools for which more than one username attribute is allowed. Configured username attributes: ${JSON.stringify(describeUserPoolResponse.UserPool.UsernameAttributes)}`); + } + } +}; diff --git a/source/custom-resources/stackset-constants.js b/source/custom-resources/stackset-constants.js new file mode 100644 index 0000000..4a0018c --- /dev/null +++ b/source/custom-resources/stackset-constants.js @@ -0,0 +1,35 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const CustomResourceHelperFunctions = require('../utils/custom-resource-helper-functions'); +const AWS = require('aws-sdk'); + +/** + * Retrieves solutions constants from SSM parameter store so they can be used within the StackSet instance + */ +exports.handler = async (event, context) => { + return await CustomResourceHelperFunctions.handler(event, context, handleCreate); +}; + +/** + * Retrieves the Solution Constants from SSM Parameter Store and makes them available to the StackSet + * @param {object} event The incoming event from the Custom Resource invokation + */ +const handleCreate = async function handleCreate(event) { + const { ParentStackName, PrimaryRegion } = event.ResourceProperties; + const ssm = new AWS.SSM({ region: PrimaryRegion }); + const ssmParameterName = `/${ParentStackName}-${PrimaryRegion}/fixed-solution-parameters`; + const getParams = { Name: ssmParameterName }; + + console.log(`Getting parameter: ${JSON.stringify(getParams)}`); + const getResponse = await ssm.getParameter(getParams).promise(); + console.log(`Get response: ${JSON.stringify(getResponse)}`); + + const parametersFromSSM = JSON.parse(getResponse.Parameter.Value); + + return parametersFromSSM; +}; diff --git a/source/custom-resources/stackset-manager.js b/source/custom-resources/stackset-manager.js new file mode 100644 index 0000000..59c6546 --- /dev/null +++ b/source/custom-resources/stackset-manager.js @@ -0,0 +1,198 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const cfn = new AWS.CloudFormation(); +const stepFunctions = new AWS.StepFunctions(); +const axios = require('axios'); +const { AWS_REGION, STATE_MACHINE_ARN } = process.env; + +// Values for sending anonymous metrics +const { SEND_METRIC, METRICS_ANONYMOUS_UUID, SOLUTION_ID, SOLUTION_VERSION, COGNITO_TPS, EXPORT_FREQUENCY, SNS_PREFERENCE } = process.env; +const { sendAnonymousMetric } = require('../utils/metrics'); + +/** + * Manages the solution's StackSet during solution create/update/deletes + * @param {object} event + * @param {object} context + * @return {Promise} + */ +exports.handler = async (event, context) => { + console.log(`Received event: ${JSON.stringify(event)}`); + const customResourceStartTime = new Date().getTime(); + let operationId; + + try { + switch (event.RequestType) { + case 'Create': + await createStackSet(event); + operationId = await createStackInstances(event); + break; + case 'Update': + operationId = await updateStackSet(event); + break; + case 'Delete': + operationId = await deleteStackInstances(event); + break; + } + + // Start the Step Functions state machine that will check the StackSet status and respond to CloudFormation + const startExecutionParams = { + stateMachineArn: STATE_MACHINE_ARN, + input: JSON.stringify({ + customResourceStartTime, + operationId, + customResourceEvent: event + }) + }; + console.log(`Starting State Machine execution: ${JSON.stringify(startExecutionParams)}`); + const startExecutionResponse = await stepFunctions.startExecution(startExecutionParams).promise(); + console.log(`State machine started: ${JSON.stringify(startExecutionResponse)}`); + + // If enabled, send anonymous metric + if (SEND_METRIC === 'Yes') { + try { + const payload = { + EventType: `Solution-${event.RequestType}`, + EventDetails: { + Region: AWS_REGION, + CognitoTPS: COGNITO_TPS, + SnsPreference: SNS_PREFERENCE, + ExportFrequency: EXPORT_FREQUENCY + } + }; + + await sendAnonymousMetric(SOLUTION_ID, SOLUTION_VERSION, METRICS_ANONYMOUS_UUID, payload); + } catch (err) { + console.error(err); + } + } + } catch (error) { + console.error(error); + const response = { + status: 'FAILED', + data: { Error: error.message } + }; + + await sendResponse(event, context.logStreamName, response); + + return response; + } + + return event; +} + +/** + * Creates the solution's StackSet + * @param {object} event The incoming event from the Custom Resource invokation + */ +const createStackSet = async function createStackSet(event) { + const { StackSetName, StackSetParameters, TemplateURL, AdministrationRoleARN, ExecutionRoleName } = event.ResourceProperties; + const params = { + StackSetName: StackSetName, + TemplateURL: TemplateURL, + AdministrationRoleARN: AdministrationRoleARN, + ExecutionRoleName: ExecutionRoleName, + Capabilities: ['CAPABILITY_IAM'], + Parameters: Object.keys(StackSetParameters).map(paramKey => { + return { ParameterKey: paramKey, ParameterValue: StackSetParameters[paramKey] }; + }) + }; + + console.log(`Creating StackSet: ${JSON.stringify(params)}`); + const response = await cfn.createStackSet(params).promise(); + console.log(`Create StackSet Response: ${JSON.stringify(response)}`); +}; + +/** + * Creates instances of the solution's StackSet in both the primary and backup regions + * @param {object} event The incoming event from the Custom Resource invokation + */ +const createStackInstances = async function createStackInstances(event) { + const { StackSetName, AccountId } = event.ResourceProperties; + const { SecondaryRegion } = event.ResourceProperties; + const params = { + StackSetName: StackSetName, + Accounts: [AccountId], + Regions: [SecondaryRegion, AWS_REGION] + } + + console.log(`Creating StackSet Instance: ${JSON.stringify(params)}`); + const response = await cfn.createStackInstances(params).promise(); + console.log(`Create StackSet Instance Response: ${JSON.stringify(response)}`); + return response.OperationId; +}; + +/** + * Deletes the instances from the solution's StackSet + * @param {object} event The incoming event from the Custom Resource invokation + */ +const deleteStackInstances = async function deleteStackInstances(event) { + const { StackSetName, AccountId } = event.ResourceProperties; + const { SecondaryRegion } = event.ResourceProperties; + const params = { + StackSetName: StackSetName, + Accounts: [AccountId], + Regions: [SecondaryRegion, AWS_REGION], + RetainStacks: false + } + + console.log(`Deleting Stack Instances: ${JSON.stringify(params)}`); + const response = await cfn.deleteStackInstances(params).promise(); + console.log(`Delete Stack Instances response: ${JSON.stringify(response)}`); + return response.OperationId; +}; + +/** + * Updates the StackSet with a new TemplateURL or parameters + * @param {object} event The incoming event from the Custom Resource invokation + */ +const updateStackSet = async (event) => { + const { StackSetName, StackSetParameters, TemplateURL, AdministrationRoleARN, ExecutionRoleName } = event.ResourceProperties; + const params = { + StackSetName: StackSetName, + TemplateURL: TemplateURL, + AdministrationRoleARN: AdministrationRoleARN, + ExecutionRoleName: ExecutionRoleName, + Capabilities: ['CAPABILITY_IAM'], + Parameters: Object.keys(StackSetParameters).map(paramKey => { + return { ParameterKey: paramKey, ParameterValue: StackSetParameters[paramKey] }; + }) + }; + + console.log(`Updating StackSet: ${JSON.stringify(params)}`); + const response = await cfn.updateStackSet(params).promise(); + console.log(`Update StackSet response: ${JSON.stringify(response)}`); + return response.OperationId; +}; + +/** + * Send custom resource response. + * @param {object} event - Custom resource event + * @param {string} logStreamName - Custom resource log stream name + * @param {object} response - Response object { status: "SUCCESS|FAILED", data: object } + */ +async function sendResponse(event, logStreamName, response) { + const responseBody = JSON.stringify({ + Status: response.status, + Reason: `See the details in CloudWatch Log Stream: ${logStreamName}`, + PhysicalResourceId: logStreamName, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + Data: response.data, + }); + + const config = { + headers: { + 'Content-Type': '', + 'Content-Length': responseBody.length + } + }; + + await axios.put(event.ResponseURL, responseBody, config); +} diff --git a/source/custom-resources/test/check-stackset-status.spec.js b/source/custom-resources/test/check-stackset-status.spec.js new file mode 100644 index 0000000..fe26282 --- /dev/null +++ b/source/custom-resources/test/check-stackset-status.spec.js @@ -0,0 +1,282 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function () { + return 100000; + } +}; + +// Mock axios +const axios = require('axios'); +const MockAdapter = require('axios-mock-adapter'); +let axiosMock = new MockAdapter(axios); + +// Mock AWS SDK +const mockSSM = { + getParameter: jest.fn() +}; + +const mockCfn = { + listStackSetOperationResults: jest.fn(), + deleteStackSet: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + SSM: jest.fn(() => ({ + getParameter: mockSSM.getParameter + })), + CloudFormation: jest.fn(() => ({ + listStackSetOperationResults: mockCfn.listStackSetOperationResults, + deleteStackSet: mockCfn.deleteStackSet + })) + }; +}); + +describe('check-stackset-status', function () { + beforeEach(() => { + process.env.AWS_REGION = 'us-east-1'; + process.env.STATE_MACHINE_ARN = 'state-machine-arn'; + for (const mockFn in mockSSM) { + mockSSM[mockFn].mockReset(); + } + for (const mockFn in mockCfn) { + mockCfn[mockFn].mockReset(); + } + axiosMock = new MockAdapter(axios); + }); + + afterEach(() => { + axiosMock.restore(); + }); + + it('Should return an error if a stackset instance failed', async function () { + axiosMock.onPut().reply(200); + + // Mock event data + const event = { + Context: { + Execution: { + Input: { + customResourceStartTime: new Date().getTime(), + operationId: 'op-id', + customResourceEvent: { + RequestType: 'Create', + ResourceProperties: { StackSetName: 'stackset-name' } + } + } + } + } + }; + + mockCfn.listStackSetOperationResults.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Summaries:[{ + Status: 'FAILED' + }] + }); + } + }; + }); + + + const lambda = require('../check-stackset-status'); + await lambda.handler(event, context); + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'FAILED', + Reason: 'See the details in CloudWatch Log Stream: log-stream', + Data: { + Error: 'At least one instance in this StackSet failed to update' + } + }) + }); + + it('Should return an error if a stackset instance was canceled', async function () { + axiosMock.onPut().reply(200); + + // Mock event data + const event = { + Context: { + Execution: { + Input: { + customResourceStartTime: new Date().getTime(), + operationId: 'op-id', + customResourceEvent: { + RequestType: 'Create', + ResourceProperties: { StackSetName: 'stackset-name' } + } + } + } + } + }; + + mockCfn.listStackSetOperationResults.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Summaries:[{ + Status: 'CANCELLED' + }] + }); + } + }; + }); + + + const lambda = require('../check-stackset-status'); + await lambda.handler(event, context); + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'FAILED', + Reason: 'See the details in CloudWatch Log Stream: log-stream', + Data: { + Error: 'At least one instance update was canceled' + } + }) + }); + + it('Should return with no errors if an update is pending', async function () { + axiosMock.onPut().reply(200); + + // Mock event data + const event = { + Context: { + Execution: { + Input: { + customResourceStartTime: new Date().getTime(), + operationId: 'op-id', + customResourceEvent: { + RequestType: 'Create', + ResourceProperties: { StackSetName: 'stackset-name' } + } + } + } + } + }; + + mockCfn.listStackSetOperationResults.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Summaries:[{ + Status: 'PENDING' + }] + }); + } + }; + }); + + + const lambda = require('../check-stackset-status'); + await lambda.handler(event, context); + }); + + it('Should return SUCCESS if all instances were successful', async function () { + axiosMock.onPut().reply(200); + + // Mock event data + const event = { + Context: { + Execution: { + Input: { + customResourceStartTime: new Date().getTime(), + operationId: 'op-id', + customResourceEvent: { + RequestType: 'Create', + ResourceProperties: { StackSetName: 'stackset-name' } + } + } + } + } + }; + + mockCfn.listStackSetOperationResults.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Summaries:[{ + Status: 'SUCCEEDED' + }] + }); + } + }; + }); + + + const lambda = require('../check-stackset-status'); + await lambda.handler(event, context); + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'SUCCESS', + Reason: 'See the details in CloudWatch Log Stream: log-stream', + Data: { + Message: 'Create Successful' + } + }) + }); + + it('Should return SUCCESS if all instances were successfully deleted', async function () { + axiosMock.onPut().reply(200); + + // Mock event data + const event = { + Context: { + Execution: { + Input: { + customResourceStartTime: new Date().getTime(), + operationId: 'op-id', + customResourceEvent: { + RequestType: 'Delete', + ResourceProperties: { StackSetName: 'stackset-name' } + } + } + } + } + }; + + mockCfn.listStackSetOperationResults.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Summaries:[{ + Status: 'SUCCEEDED' + }] + }); + } + }; + }); + + mockCfn.deleteStackSet.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const lambda = require('../check-stackset-status'); + await lambda.handler(event, context); + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'SUCCESS', + Reason: 'See the details in CloudWatch Log Stream: log-stream', + Data: { + Message: 'Delete Successful' + } + }) + }); +}); diff --git a/source/custom-resources/test/global-table-checker.spec.js b/source/custom-resources/test/global-table-checker.spec.js new file mode 100644 index 0000000..135f49f --- /dev/null +++ b/source/custom-resources/test/global-table-checker.spec.js @@ -0,0 +1,251 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Import packages +const axios = require('axios'); +const MockAdapter = require('axios-mock-adapter'); +const axiosMock = new MockAdapter(axios); + +// Mock axios +axiosMock.onPut('/cfn-response').reply(200); + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function() { + return 100000; + } +}; + +// Mock AWS SDK +const mockDynamoDB = jest.fn(); +jest.mock('aws-sdk', () => { + return { + DynamoDB: jest.fn(() => ({ + describeTable: mockDynamoDB + })) + }; +}); + +describe('global-table-checker', function() { + // Mock event data + const event = { + "StackId": "CFN_STACK_ID", + "RequestId": "02f6b8db-835e-4a83-b338-520f642e8f97", + "LogicalResourceId": "SecondaryUserPoolTable", + "ResponseURL": "/cfn-response" + }; + const describeTableResponse = { + "Table": { + "AttributeDefinitions": [ + { + "AttributeName": "id", + "AttributeType": "S" + }, + { + "AttributeName": "type", + "AttributeType": "S" + } + ], + "TableName": "global", + "KeySchema": [ + { + "AttributeName": "id", + "KeyType": "HASH" + }, + { + "AttributeName": "type", + "KeyType": "RANGE" + } + ], + "TableStatus": "ACTIVE", + "CreationDateTime": 1592868506.319, + "ProvisionedThroughput": { + "NumberOfDecreasesToday": 0, + "ReadCapacityUnits": 0, + "WriteCapacityUnits": 0 + }, + "TableSizeBytes": 0, + "ItemCount": 0, + "TableArn": "arn:aws:dynamodb:mock-region:accountId:table/mock-table", + "TableId": "069af9bb-691a-4a47-941a-09ba7c174dd4", + "BillingModeSummary": { + "BillingMode": "PAY_PER_REQUEST", + "LastUpdateToPayPerRequestDateTime": 1592868506.319 + }, + "StreamSpecification": { + "StreamEnabled": true, + "StreamViewType": "NEW_AND_OLD_IMAGES" + }, + "LatestStreamLabel": "2020-06-22T23:28:26.319", + "LatestStreamArn": "arn:aws:dynamodb:mock-region:accountId:table/mock-table/stream/2020-06-22T23:28:26.319", + "GlobalTableVersion": "2019.11.21", + "Replicas": [ + { + "RegionName": "primary-region", + "ReplicaStatus": "ACTIVE" + } + ] + } + }; + + beforeEach(() => { + process.env.SECONDARY_REGION = 'mock-region'; + process.env.USER_POOL_TABLE = 'mock-table'; + + mockDynamoDB.mockReset(); + }); + + // No resource, and return + it('should return stream ARN when DynamoDB global table is not ready at first, but ready secondly', async function() { + mockDynamoDB.mockImplementationOnce(() => { + return { + promise() { + // dynamodb.describeTable + return Promise.reject({ + code: 'ResourceNotFoundException', + message: 'Table: mock-table not found' + }); + } + }; + }).mockImplementationOnce(() => { + return { + promise() { + // dynamodb.describeTable + return Promise.resolve(describeTableResponse); + } + }; + }); + + const index = require('../global-table-checker'); + const result = await index.handler(event, context); + + expect(result).toEqual({ + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + ResponseURL: event.ResponseURL, + LatestStreamArn: describeTableResponse.Table.LatestStreamArn + }); + }); + + // Resource, and return + it('should return stream ARN when DynamoDB global table is ready without stream ARN firstly, but ready secondly', async function() { + mockDynamoDB.mockImplementationOnce(() => { + return { + promise() { + // dynamodb.describeTable + return Promise.resolve({ Table: {} }); + } + }; + }).mockImplementationOnce(() => { + return { + promise() { + // dynamodb.describeTable + return Promise.resolve(describeTableResponse); + } + }; + }); + + const index = require('../global-table-checker'); + const result = await index.handler(event, context); + + expect(result).toEqual({ + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + ResponseURL: event.ResponseURL, + LatestStreamArn: describeTableResponse.Table.LatestStreamArn + }); + }); + + // No resource, but timeout + it('should return empty stream ARN when DynamoDB global table is not ready and Lambda times out', async function() { + context.getRemainingTimeInMillis = function() { + return 1000; + }; + + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.describeTable + return Promise.reject({ + code: 'ResourceNotFoundException', + message: 'Table: mock-table not found' + }); + } + }; + }); + + const index = require('../global-table-checker'); + const result = await index.handler(event, context); + + expect(result).toEqual({ + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + ResponseURL: event.ResponseURL, + LatestStreamArn: '' + }); + }); + + // Resource, but timeout + it('should return empty stream ARN when DynamoDB global table is ready without stream ARN and Lambda times out', async function() { + context.getRemainingTimeInMillis = function() { + return 1000; + }; + + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.describeTable + return Promise.resolve({ Table: {} }); + } + }; + }); + + const index = require('../global-table-checker'); + const result = await index.handler(event, context); + + expect(result).toEqual({ + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + ResponseURL: event.ResponseURL, + LatestStreamArn: '' + }); + }); + + // error + it('should throw error when unexpected error occurs', async function() { + context.getRemainingTimeInMillis = function() { + return 100000; + }; + + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.describeTable + return Promise.reject({ + code: 'UnexpectedException', + message: 'Unexpected exception' + }); + } + }; + }); + + const index = require('../global-table-checker'); + try { + await index.handler(event, context); + } catch (error) { + expect(error).toEqual({ + code: 'UnexpectedException', + message: 'Unexpected exception' + }); + } + }); +}); \ No newline at end of file diff --git a/source/custom-resources/test/global-table-creator.spec.js b/source/custom-resources/test/global-table-creator.spec.js new file mode 100644 index 0000000..c9df614 --- /dev/null +++ b/source/custom-resources/test/global-table-creator.spec.js @@ -0,0 +1,197 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Import packages +const axios = require('axios'); +const MockAdapter = require('axios-mock-adapter'); +const axiosMock = new MockAdapter(axios); + +// Mock axios +axiosMock.onPut('/cfn-response').reply(200); + +// Mock context +const context = { + logStreamName: 'log-stream' +}; + +// Mock AWS SDK +const mockDynamoDB = jest.fn(); +const mockStepFucntions = jest.fn(); +jest.mock('aws-sdk', () => { + return { + DynamoDB: jest.fn(() => ({ + updateTable: mockDynamoDB + })), + StepFunctions: jest.fn(() => ({ + startExecution: mockStepFucntions + })) + }; +}); + +describe('global-table-creator', function() { + // Mock event data + const event = { + "RequestType": "Create", + "ServiceToken": "LAMBDA_ARN", + "ResponseURL": "/cfn-response", + "StackId": "CFN_STACK_ID", + "RequestId": "02f6b8db-835e-4a83-b338-520f642e8f97", + "LogicalResourceId": "SecondaryUserPoolTable", + "ResourceType": "Custom::CreateTable", + "ResourceProperties": { + "ServiceToken": "LAMBDA_ARN", + "UserPoolTable": "user-pool-table", + "SecondaryRegion": "mock-secondary-region" + } + }; + const updateTableResponse = { + "TableDescription": { + "AttributeDefinitions": [ + { + "AttributeName": "id", + "AttributeType": "S" + }, + { + "AttributeName": "type", + "AttributeType": "S" + } + ], + "TableName": "user-pool-table", + "KeySchema": [ + { + "AttributeName": "id", + "KeyType": "HASH" + }, + { + "AttributeName": "type", + "KeyType": "RANGE" + } + ], + "TableStatus": "UPDATING", + "CreationDateTime": "2020-06-15T21:51:39.371Z", + "ProvisionedThroughput": { + "NumberOfDecreasesToday": 0, + "ReadCapacityUnits": 0, + "WriteCapacityUnits": 0 + }, + "TableSizeBytes": 0, + "ItemCount": 0, + "TableArn": "arn:of:dynamodb:mock-primary-region:account-id:table/user-pool-table", + "TableId": "3901dd6b-86da-4521-9b8e-564353348ffe", + "BillingModeSummary": { + "BillingMode": "PAY_PER_REQUEST", + "LastUpdateToPayPerRequestDateTime": "2020-06-15T21:51:39.371Z" + }, + "StreamSpecification": { + "StreamEnabled": true, + "StreamViewType": "NEW_AND_OLD_IMAGES" + }, + "LatestStreamLabel": "2020-06-15T21:51:48.977", + "LatestStreamArn": "arn:of:dynamodb:mock-primary-region:account-id:table/user-pool-table/stream/2020-06-15T21:51:48.977", + "GlobalTableVersion": "2019.11.21" + } + }; + + beforeEach(() => { + mockDynamoDB.mockReset(); + }); + + it('should return event when DynamoDB global table creation and Step Function execution succeed', async function() { + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.updateTable + return Promise.resolve(updateTableResponse); + } + }; + }); + mockStepFucntions.mockImplementation(() => { + return { + promise() { + // stepFunctions.startExecution + return Promise.resolve({ + executionArn: 'arn-of-step-function-execution', + startDate: new Date() + }); + } + }; + }); + + const index = require('../global-table-creator'); + const result = await index.handler(event, context); + + expect(result).toEqual(event); + }); + + it('should return failure when DynamoDB global table creation fails', async function() { + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.updateTable + return Promise.reject({ + message: 'ERROR to update the table' + }); + } + }; + }); + + const index = require('../global-table-creator'); + const result = await index.handler(event, context); + + expect(result).toEqual({ + status: 'FAILED', + data: { Error: 'ERROR to update the table' } + }); + }); + + it('should return failure when Step Function start execution fails', async function() { + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.updateTable + return Promise.resolve(updateTableResponse); + } + }; + }); + mockStepFucntions.mockImplementation(() => { + return { + promise() { + // stepFunctions.startExecution + return Promise.reject({ + message: 'ERROR to start execution' + }); + } + }; + }); + + const index = require('../global-table-creator'); + const result = await index.handler(event, context); + + expect(result).toEqual({ + status: 'FAILED', + data: { Error: 'ERROR to start execution' } + }); + }); + + it('should return failure when update event comes in', async function() { + event.RequestType = 'Update'; + + const index = require('../global-table-creator'); + const result = await index.handler(event, context); + + expect(result).toEqual(event); + }); + + it('should return event when delete event comes in', async function() { + event.RequestType = 'Delete'; + + const index = require('../global-table-creator'); + const result = await index.handler(event, context); + + expect(result).toEqual(event); + }); +}); \ No newline at end of file diff --git a/source/custom-resources/test/solution-constants.spec.js b/source/custom-resources/test/solution-constants.spec.js new file mode 100644 index 0000000..d047882 --- /dev/null +++ b/source/custom-resources/test/solution-constants.spec.js @@ -0,0 +1,77 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function () { + return 100000; + } +}; + +const CustomResourceHelperFunctions = require('../../utils/custom-resource-helper-functions'); +jest.mock('../../utils/custom-resource-helper-functions'); + +describe('solution-constants', function () { + beforeEach(() => {}); + + it('Handles Create With Short Stack Name', async function () { + // Mock event data + const event = { + RequestType: 'Create', + StackId: 'CFN_STACK_ID', + RequestId: '02f6b8db-835e-4a83-b338-520f642e8f97', + LogicalResourceId: 'SolutionConstants', + ResponseURL: '/cfn-response', + ResourceProperties:{ + StackName: 'stack-name' + } + }; + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate) => { + return await handleCreate(evt); + }); + + const lambda = require('../solution-constants'); + const result = await lambda.handler(event, context); + + const uuidRegex = /([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}){1}/; + expect(result.StackSetName).toBe(`${event.ResourceProperties.StackName}-StackSet`); + expect(result.FormattedStackName).toBe(event.ResourceProperties.StackName); + expect(result.UserImportJobMappingFileBucketPrefix).toBe(`stack-name-import-jobs-${result.SolutionInstanceUUID.split('-').pop()}`); + expect(result.AnonymousDataUUID).toMatch(uuidRegex); + expect(result.SolutionInstanceUUID).toMatch(uuidRegex); + }); + + it('Handles Create With long Stack Name', async function () { + // Mock event data + const event = { + RequestType: 'Create', + StackId: 'CFN_STACK_ID', + RequestId: '02f6b8db-835e-4a83-b338-520f642e8f97', + LogicalResourceId: 'SolutionConstants', + ResponseURL: '/cfn-response', + ResourceProperties:{ + StackName: 'this-is-a-very-long-stack-name-the-reason-it-is-this-long-is-because-we-need-it-to-be-above-one-hundred-twenty-eight-characters-which-is-pretty-long-when-you-think-about-it' + } + }; + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate) => { + return await handleCreate(evt); + }); + + const lambda = require('../solution-constants'); + const result = await lambda.handler(event, context); + + const uuidRegex = /([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}){1}/; + expect(result.StackSetName).toBe('this-is-a-very-long-stack-name-the-reason-it-is-this-long-is-because-we-need-it-to-be-above-one-hundred-twenty-eight-ch-StackSet'); + expect(result.FormattedStackName).toBe('this-is-a-very-'); + expect(result.UserImportJobMappingFileBucketPrefix).toBe(`this-is-a-very--import-jobs-${result.SolutionInstanceUUID.split('-').pop()}`); + expect(result.AnonymousDataUUID).toMatch(uuidRegex); + expect(result.SolutionInstanceUUID).toMatch(uuidRegex); + }); +}); \ No newline at end of file diff --git a/source/custom-resources/test/stack-checker.spec.js b/source/custom-resources/test/stack-checker.spec.js new file mode 100644 index 0000000..52f0180 --- /dev/null +++ b/source/custom-resources/test/stack-checker.spec.js @@ -0,0 +1,330 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function () { + return 100000; + } +}; + +// Mock AWS SDK +const mockSSM = { + putParameter: jest.fn(), + getParameter: jest.fn(), + deleteParameter: jest.fn() +}; + +const mockCognitoISP = { + describeUserPool: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + CognitoIdentityServiceProvider: jest.fn(() => ({ + describeUserPool: mockCognitoISP.describeUserPool + })), + SSM: jest.fn(() => ({ + putParameter: mockSSM.putParameter, + getParameter: mockSSM.getParameter, + deleteParameter: mockSSM.deleteParameter + })) + }; +}); + +const CustomResourceHelperFunctions = require('../../utils/custom-resource-helper-functions'); +jest.mock('../../utils/custom-resource-helper-functions'); + +describe('stack-checker', function () { + beforeEach(() => { + process.env.AWS_REGION = 'us-east-1'; + process.env.FIXED_PARAMETERS = 'SecondaryRegion,PrimaryUserPoolId,BackupTableName,AnonymousDataUUID,ParentStackName,PrimaryRegion,ImportNewUsersQueueNamePrefix,SolutionInstanceUUID,UserImportJobMappingFileBucketPrefix'; + for (const mockFn in mockCognitoISP) { + mockCognitoISP[mockFn].mockReset(); + } + + for (const mockFn in mockSSM) { + mockSSM[mockFn].mockReset(); + } + }); + + it('Create: Handles supported user pool without errors', async function () { + // Mock event data + const event = { + ResourceProperties: { + StackName: 'stack-name', + PrimaryUserPoolId: 'primary-user-pool-id' + } + }; + + mockCognitoISP.describeUserPool.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + UserPool: { + MfaConfiguration: 'OFF', + UsernameAttributes: ['email'] + } + }); + } + }; + }); + + mockSSM.putParameter.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate) => { + return await handleCreate(evt); + }); + + const lambda = require('../stack-checker'); + await lambda.handler(event, context); + }); + + it('Create: Throws an error if the SecondaryRegion matches the primary', async function () { + // Mock event data + const event = { + ResourceProperties: { + StackName: 'stack-name', + PrimaryUserPoolId: 'user-pool-id', + SecondaryRegion: 'us-east-1' + } + }; + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate) => { + return await handleCreate(evt); + }); + + const lambda = require('../stack-checker'); + try { + await lambda.handler(event, context); + } catch (err) { + expect(err.message).toBe('The backup region must be different than the primary'); + } + }); + + it('Create: Throws an error if MFA is enabled', async function () { + // Mock event data + const event = { + ResourceProperties: { + StackName: 'stack-name', + PrimaryUserPoolId: 'user-pool-id-a' + } + }; + + mockCognitoISP.describeUserPool.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + UserPool: { + MfaConfiguration: 'OPTIONAL', + UsernameAttributes: ['email'] + } + }); + } + }; + }); + + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate) => { + await handleCreate(evt); + }); + + const lambda = require('../stack-checker'); + await expect(async () => { + await lambda.handler(event, context); + }).rejects.toThrow('User Pools with MFA enabled are not supported. The user pool\'s MFA configuration is set to OPTIONAL'); + }); + + it('Create: Throws an error if more than one username attributes are configured', async function () { + // Mock event data + const event = { + ResourceProperties: { + StackName: 'stack-name', + PrimaryUserPoolId: 'user-pool-id-a' + } + }; + + mockCognitoISP.describeUserPool.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + UserPool: { + MfaConfiguration: 'OFF', + UsernameAttributes: ['email', 'phone_number'] + } + }); + } + }; + }); + + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate) => { + await handleCreate(evt); + }); + + const lambda = require('../stack-checker'); + await expect(async () => { + await lambda.handler(event, context); + }).rejects.toThrow('This solution does not support user pools for which more than one username attribute is allowed. Configured username attributes: ["email","phone_number"]'); + }); + + it('Update: Handles without errors if parameters match', async function () { + // Mock event data + const event = { + ResourceProperties: { + StackName: 'stack-name', + PrimaryUserPoolId: 'primary-user-pool-id', + SecondaryRegion: 'us-east-1' + } + }; + + mockSSM.getParameter.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Parameter: { + Value: JSON.stringify({ + PrimaryUserPoolId: 'primary-user-pool-id', + SecondaryRegion: 'us-east-1' + }) + } + }); + } + }; + }); + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate, handleUpdate) => { + return await handleUpdate(evt); + }); + + const lambda = require('../stack-checker'); + await lambda.handler(event, context); + }); + + it('Update: Throws an error if a parameter doesn\'t match', async function () { + const event = { + ResourceProperties: { + StackName: 'stack-name', + PrimaryUserPoolId: 'primary-user-pool-id', + SecondaryRegion: 'us-east-1' + } + }; + + mockSSM.getParameter.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Parameter: { + Value: JSON.stringify({ + PrimaryUserPoolId: 'original-user-pool-id', + SecondaryRegion: 'us-east-1' + }) + } + }); + } + }; + }); + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate, handleUpdate) => { + return await handleUpdate(evt); + }); + + const lambda = require('../stack-checker'); + try { + await lambda.handler(event, context); + } catch (err) { + expect(err.message).toBe('Value for CloudFormation parameter "PrimaryUserPoolId" cannot be changed. Please relaunch the solution if you need to change this value'); + } + }); + + it('Delete: Handles without errors if parameters match', async function () { + // Mock event data + const event = { + ResourceProperties: { + StackName: 'stack-name', + PrimaryUserPoolId: 'primary-user-pool-id', + SecondaryRegion: 'us-east-1' + } + }; + + mockSSM.deleteParameter.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate, handleUpdate, handleDelete) => { + return await handleDelete(evt); + }); + + const lambda = require('../stack-checker'); + await lambda.handler(event, context); + }); + + it('Delete: Handles without errors if ParameterNotFound', async function () { + const event = { + ResourceProperties: { + StackName: 'stack-name', + PrimaryUserPoolId: 'primary-user-pool-id', + SecondaryRegion: 'us-east-1' + } + }; + + mockSSM.deleteParameter.mockImplementationOnce(() => { + return { + promise() { + return Promise.reject({ code: 'ParameterNotFound' }); + } + }; + }); + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate, handleUpdate, handleDelete) => { + return await handleDelete(evt); + }); + + const lambda = require('../stack-checker'); + await lambda.handler(event, context); + }); + + it('Delete: Throws an exception if an unexpected error occurs', async function () { + const event = { + ResourceProperties: { + StackName: 'stack-name', + PrimaryUserPoolId: 'primary-user-pool-id', + SecondaryRegion: 'us-east-1' + } + }; + + mockSSM.deleteParameter.mockImplementationOnce(() => { + return { + promise() { + return Promise.reject({ code: 'UnexpectedError' }); + } + }; + }); + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate, handleUpdate, handleDelete) => { + return await handleDelete(evt); + }); + + const lambda = require('../stack-checker'); + try { + await lambda.handler(event, context); + } catch (err) { + expect(err.code).toBe('UnexpectedError'); + } + }); +}); \ No newline at end of file diff --git a/source/custom-resources/test/stackset-constants.spec.js b/source/custom-resources/test/stackset-constants.spec.js new file mode 100644 index 0000000..3f2b98e --- /dev/null +++ b/source/custom-resources/test/stackset-constants.spec.js @@ -0,0 +1,92 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function () { + return 100000; + } +}; + +// Mock axios +const axios = require('axios'); +const MockAdapter = require('axios-mock-adapter'); +let axiosMock = new MockAdapter(axios); + +// Mock AWS SDK +const mockSSM = { + getParameter: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + SSM: jest.fn(() => ({ + getParameter: mockSSM.getParameter + })) + }; +}); + +const CustomResourceHelperFunctions = require('../../utils/custom-resource-helper-functions'); +jest.mock('../../utils/custom-resource-helper-functions'); + +describe('stackset-manager', function () { + beforeEach(() => { + process.env.AWS_REGION = 'us-east-1'; + process.env.STATE_MACHINE_ARN = 'state-machine-arn'; + for (const mockFn in mockSSM) { + mockSSM[mockFn].mockReset(); + } + axiosMock = new MockAdapter(axios); + }); + + afterEach(() => { + axiosMock.restore(); + }); + + it('Should return the values retrieved from SSM', async function () { + // Mock event data + const event = { + RequestType: 'Create', + StackId: 'CFN_STACK_ID', + RequestId: '02f6b8db-835e-4a83-b338-520f642e8f97', + LogicalResourceId: 'SolutionConstants', + ResponseURL: '/cfn-response', + ResourceProperties: { + ParentStackName: 'parent-stack-name', + PrimaryRegion: 'us-east-1' + } + }; + + mockSSM.getParameter.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Parameter: { + Value: JSON.stringify({ + PrimaryUserPoolId: 'primary-user-pool-id', + SecondaryRegion: 'us-east-1' + }) + } + }); + } + }; + }); + + CustomResourceHelperFunctions.handler.mockImplementationOnce(async (evt, ctx, handleCreate) => { + return await handleCreate(evt); + }); + + const lambda = require('../stackset-constants'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + PrimaryUserPoolId: 'primary-user-pool-id', + SecondaryRegion: 'us-east-1' + }); + }); + +}); diff --git a/source/custom-resources/test/stackset-manager.spec.js b/source/custom-resources/test/stackset-manager.spec.js new file mode 100644 index 0000000..98d6e50 --- /dev/null +++ b/source/custom-resources/test/stackset-manager.spec.js @@ -0,0 +1,226 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock metrics client +const Metrics = require('../../utils/metrics'); +jest.mock('../../utils/metrics'); + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function () { + return 100000; + } +}; + +// Mock axios +const axios = require('axios'); +const MockAdapter = require('axios-mock-adapter'); +let axiosMock = new MockAdapter(axios); + +// Mock AWS SDK +const mockCfn = { + createStackSet: jest.fn(), + createStackInstances: jest.fn(), + listStackInstances: jest.fn(), + deleteStackInstances: jest.fn(), + deleteStackSet: jest.fn(), + updateStackSet: jest.fn() +}; + +const mockStepFunctions = { + startExecution: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + CloudFormation: jest.fn(() => ({ + createStackSet: mockCfn.createStackSet, + createStackInstances: mockCfn.createStackInstances, + listStackInstances: mockCfn.listStackInstances, + deleteStackInstances: mockCfn.deleteStackInstances, + deleteStackSet: mockCfn.deleteStackSet, + updateStackSet: mockCfn.updateStackSet + })), + StepFunctions: jest.fn(() => ({ + startExecution: mockStepFunctions.startExecution + })) + }; +}); + +describe('stackset-manager', function () { + beforeEach(() => { + process.env.AWS_REGION = 'us-east-1'; + process.env.STATE_MACHINE_ARN = 'state-machine-arn'; + process.env.SEND_METRIC = 'Yes'; + for (const mockFn in mockCfn) { + mockCfn[mockFn].mockReset(); + } + + for (const mockFn in mockStepFunctions) { + mockStepFunctions[mockFn].mockReset(); + } + axiosMock = new MockAdapter(axios); + }); + + afterEach(() => { + axiosMock.restore(); + }); + + it('Create: Handled without errors', async function () { + // Mock event data + const event = { + RequestType: 'Create', + ResourceProperties: { + StackSetName: 'stack-name', + StackSetParameters: { Key: 'Value' }, + TemplateURL: 'template-url', + AdministrationRoleARN: 'admin-role-arn', + ExecutionRoleName: 'exec-role-arn' + } + }; + + Metrics.sendAnonymousMetric.mockImplementationOnce(async (x, y, z) => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockCfn.createStackSet.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockCfn.createStackInstances.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockStepFunctions.startExecution.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const lambda = require('../stackset-manager'); + await lambda.handler(event, context); + }, 10000); + + it('Update: Handled without errors', async function () { + // Mock event data + const event = { + RequestType: 'Update', + ResourceProperties: { + StackSetName: 'stack-name', + StackSetParameters: { Key: 'Value' }, + TemplateURL: 'template-url', + AdministrationRoleARN: 'admin-role-arn', + ExecutionRoleName: 'exec-role-arn' + } + }; + + mockCfn.updateStackSet.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockStepFunctions.startExecution.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const lambda = require('../stackset-manager'); + await lambda.handler(event, context); + }, 10000); + + it('Delete: Handled without errors', async function () { + // Mock event data + const event = { + RequestType: 'Delete', + ResourceProperties: { + StackSetName: 'stack-name', + StackSetParameters: {}, + TemplateURL: 'template-url', + AdministrationRoleARN: 'admin-role-arn', + ExecutionRoleName: 'exec-role-arn' + } + }; + + mockCfn.deleteStackInstances.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockStepFunctions.startExecution.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const lambda = require('../stackset-manager'); + await lambda.handler(event, context); + }, 10000); + + it('Error: Handles error without rethrowing', async function () { + axiosMock.onPut().reply(200); + + // Mock event data + const event = { + RequestType: 'Delete', + ResourceProperties: { + StackSetName: 'stack-name', + StackSetParameters: {}, + TemplateURL: 'template-url', + AdministrationRoleARN: 'admin-role-arn', + ExecutionRoleName: 'exec-role-arn', + ResponseURL: '/cfn-response' + } + }; + + mockCfn.deleteStackInstances.mockImplementationOnce(() => { + return { + promise() { + return Promise.reject({ message: 'an error' }); + } + }; + }); + + const lambda = require('../stackset-manager'); + await lambda.handler(event, context); + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'FAILED', + Reason: 'See the details in CloudWatch Log Stream: log-stream', + PhysicalResourceId: 'log-stream', + Data: { + Error: 'an error' + } + }) + }, 10000); +}); diff --git a/source/utils/custom-resource-helper-functions.js b/source/utils/custom-resource-helper-functions.js new file mode 100644 index 0000000..2d59347 --- /dev/null +++ b/source/utils/custom-resource-helper-functions.js @@ -0,0 +1,83 @@ +const axios = require('axios'); + +/** + * Generic handler for CloudFormation Custom Resource events + * @param {object} event Lambda event payload + * @param {object} context Lambda context object + * @param {function} handleCreate Handler for Create events on this Custom Resource + * @param {function} handleUpdate Handler for Update events on this Custom Resource + * @param {function} handleDelete Handler for Delete events on this Custom Resource + */ +exports.handler = async (event, context, handleCreate = null, handleUpdate = null, handleDelete = null) => { + console.log(`Received event: ${JSON.stringify(event)}`); + + let handler; + let response = { + status: 'SUCCESS', + data: {} + }; + + try { + switch (event.RequestType) { + case 'Create': + handler = handleCreate; + break; + case 'Delete': + handler = handleDelete; + break; + case 'Update': + handler = handleUpdate; + break; + default: + break; + } + + if (handler) { + const handlerResult = await handler(event); + if (handlerResult && typeof handlerResult === 'string') { + response.data.Message = handlerResult; + } else if (handlerResult && typeof handlerResult === 'object') { + response.data = handlerResult; + } + } else { + response.data.Message = `No action required for ${event.RequestType}`; + } + } catch (error) { + console.error(error); + response = { + status: 'FAILED', + data: { Error: error.message } + }; + } finally { + await this.sendResponse(event, context.logStreamName, response); + } + + return response; +}; + +/** + * Sends a response back to CloudFormation + * @param {object} event - Custom resource event + * @param {string} logStreamName - Custom resource log stream name + * @param {object} response - Response object { status: "SUCCESS|FAILED", data: object } + */ +exports.sendResponse = async function sendResponseToCfn(event, logStreamName, response) { + const responseBody = JSON.stringify({ + Status: response.status, + Reason: `See the details in CloudWatch Log Stream: ${logStreamName}`, + PhysicalResourceId: event.LogicalResourceId, + StackId: event.StackId, + RequestId: event.RequestId, + LogicalResourceId: event.LogicalResourceId, + Data: response.data, + }); + + const config = { + headers: { + 'Content-Type': '', + 'Content-Length': responseBody.length + } + }; + + return await axios.put(event.ResponseURL, responseBody, config); +}; diff --git a/source/utils/helper-functions.js b/source/utils/helper-functions.js new file mode 100644 index 0000000..c1cd39d --- /dev/null +++ b/source/utils/helper-functions.js @@ -0,0 +1,111 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +/** + * Validates the supplied environment variables and lambda event payload contain the expected parameters and returns an object with them + * @param {string[]} requiredEnvironmentVariables Required lambda environment variables + * @param {string[]} requiredEventProperties Properties required to be in the lambda event payload + * @param {string} optionalEventProperties An array of optional event properties. If any of these properties is not present in the event payload, no Error is thrown + * @param {object} event The lambda event payload to validate + */ +exports.getFunctionData = function validateEventAndEnvironmentVariablesAndReturnFunctionData(requiredEnvironmentVariables, requiredEventProperties, optionalEventProperties, event) { + const output = {}; + + if (this.objHasProperties(process.env, requiredEnvironmentVariables, 'Environment Variables')) { + requiredEnvironmentVariables.forEach(envVar => { + output[envVar] = process.env[envVar]; + }); + } + + if (this.objHasProperties(event, requiredEventProperties, 'Event Payload')) { + requiredEventProperties.forEach(eventProp => { + output[eventProp] = event[eventProp]; + }); + } + + if (optionalEventProperties) { + optionalEventProperties.forEach(optionalEventProp => { + if (event[optionalEventProp]) { + output[optionalEventProp] = event[optionalEventProp]; + } + }); + } + + return output; +}; + +/** + * Returns true if the supplied object has all required properties. Throws Error otherwise + * @param {object} objToValidate The object to validate + * @param {string[]} requiredProperties The array of property names that should be present in the object to validate + * @param {string} objectDescriptor A descriptor for the object being validated. Used in case an Error is thrown + */ +exports.objHasProperties = function objHasProperties(objToValidate, requiredProperties, objectDescriptor) { + if (!Array.isArray(requiredProperties)) { + throw new Error(`Error validating ${objectDescriptor}. Must pass an array as requiredProperties`); + } + + requiredProperties.forEach(prop => { + if (typeof prop !== 'string' || prop.trim() === '') { + throw new Error(`Error validating ${objectDescriptor}. Must only pass non-empty strings in the requiredProperties array`); + } + + if (!objToValidate[prop]) { + throw new Error(`Error validating ${objectDescriptor}. Missing value for ${prop}`); + } + + if (typeof objToValidate[prop] === 'string' && objToValidate[prop].trim() === '') { + throw new Error(`Error validating ${objectDescriptor}. Value for ${prop} must not be only whitespace`); + } + }); + + return true; +}; + +/** + * Appends a suffix string to the supplied prefix string. The prefix string will be trimmed if the combined string's length is above maxChars + * @param {string} prefix The prefix string + * @param {string} suffix The string to be appended to the prefix + * @param {number} maxChars The maximum number of characters the combined string should be + */ +exports.appendToStrWithMaxChar = function appendSuffixToPrefixAndTrimPrefixIfNeeded(prefix, suffix, maxChars) { + let output = `${prefix ? prefix : ''}${suffix ? suffix : ''}`; + + if (maxChars > 0 && output.length > maxChars) { + output = `${prefix.slice(0, (maxChars - suffix.length))}${suffix}`; + } + + return output; +}; + +/** + * Returns a promise to be used as a sleep function. The values for sleepTimeInSeconds will be added to the value for sleepTimeInMS + * @param {number} sleepTimeInSeconds Number of seconds to sleep + * @param {number} sleepTimeInMS Number of milliseconds + * @return {Promise} Sleep promise + */ +exports.sleep = async (sleepTimeInSeconds = 0, sleepTimeInMS = 0) => { + return new Promise(resolve => setTimeout(resolve, sleepTimeInMS + (sleepTimeInSeconds * 1000))); +}; + +/** + * Returns the number of milliseconds to be used in an exponential backoff + * @param {number} base The base number of milliseconds to wait + * @param {number} attempt The number of times the operation has been attempted + * @param {number} max The maximum amount of milliseconds to wait + * @param {boolean} withJitter Set to true to add jitter (randomness) to the exponential backoff time that is returned + * @returns {number} The number of milliseconds to be used in an exponential backoff + */ +exports.getExponentialBackoffTimeInMS = (base, attempt, max, withJitter = false) => { + const backOffTime = Math.min(max, base * 2 ** attempt); + + if (!withJitter) { + return backOffTime; + } + + return 1 + Math.floor(Math.random() * backOffTime); +}; diff --git a/source/utils/metrics.js b/source/utils/metrics.js new file mode 100644 index 0000000..c50081e --- /dev/null +++ b/source/utils/metrics.js @@ -0,0 +1,42 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const axios = require('axios'); +const moment = require('moment'); + +/** + * Client for sending anonymous operational metrics + * @param {string} solutionId The ID for this solution + * @param {string} solutionVersion The version of this solution + * @param {string} solutionUUID The anonymous ID for this instance of the solution, generated at launch + * @param {object} jsonData Anonymous metric payload + */ +exports.sendAnonymousMetric = async (solutionId, solutionVersion, solutionUUID, jsonData) => { + try { + const metricData = { + Solution: solutionId, + Version: solutionVersion, + UUID: solutionUUID, + TimeStamp: moment().utc().toISOString(), + Data: jsonData + }; + + const params = { + method: 'post', + port: 443, + url: 'https://metrics.awssolutionsbuilder.com/generic', + headers: { 'Content-Type': 'application/json' }, + data: metricData + }; + + console.log(`Sending anonymous metric: ${JSON.stringify(metricData)}`); + const response = await axios(params); + console.log(`Anonymous metric send response status: ${response.status}`); + } catch (err) { + console.error(err); + } +}; diff --git a/source/utils/package-lock.json b/source/utils/package-lock.json new file mode 100644 index 0000000..dba0043 --- /dev/null +++ b/source/utils/package-lock.json @@ -0,0 +1,4729 @@ +{ + "name": "utils", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.5.tgz", + "integrity": "sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.5", + "@babel/types": "^7.10.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + }, + "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/generator": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.5.tgz", + "integrity": "sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==", + "dev": true, + "requires": { + "@babel/types": "^7.10.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "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-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.5.tgz", + "integrity": "sha512-HiqJpYD5+WopCXIAbQDG0zye5XYVvcO9w/DHp5GsaGkRUaamLj2bEtu6i8rnGGprAhHM3qidCMgp71HF4endhA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz", + "integrity": "sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "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.10.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", + "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", + "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.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@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/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.5.tgz", + "integrity": "sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/types": "^7.10.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + } + } + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "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 + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@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" + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/console": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.1.0.tgz", + "integrity": "sha512-+0lpTHMd/8pJp+Nd4lyip+/Iyf2dZJvcCqrlkeZQoQid+JlThA4M9vxHtheyrQ99jJTMQam+es4BcvZ5W5cC3A==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "jest-message-util": "^26.1.0", + "jest-util": "^26.1.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.1.0.tgz", + "integrity": "sha512-zyizYmDJOOVke4OO/De//aiv8b07OwZzL2cfsvWF3q9YssfpcKfcnZAwDY8f+A76xXSMMYe8i/f/LPocLlByfw==", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/reporters": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.1.0", + "jest-config": "^26.1.0", + "jest-haste-map": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.1.0", + "jest-resolve-dependencies": "^26.1.0", + "jest-runner": "^26.1.0", + "jest-runtime": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "jest-watcher": "^26.1.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.1.0.tgz", + "integrity": "sha512-86+DNcGongbX7ai/KE/S3/NcUVZfrwvFzOOWX/W+OOTvTds7j07LtC+MgGydH5c8Ri3uIrvdmVgd1xFD5zt/xA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.1.0", + "@jest/types": "^26.1.0", + "jest-mock": "^26.1.0" + } + }, + "@jest/fake-timers": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.1.0.tgz", + "integrity": "sha512-Y5F3kBVWxhau3TJ825iuWy++BAuQzK/xEa+wD9vDH3RytW9f2DbMVodfUQC54rZDX3POqdxCgcKdgcOL0rYUpA==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-util": "^26.1.0" + } + }, + "@jest/globals": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.1.0.tgz", + "integrity": "sha512-MKiHPNaT+ZoG85oMaYUmGHEqu98y3WO2yeIDJrs2sJqHhYOy3Z6F7F/luzFomRQ8SQ1wEkmahFAz2291Iv8EAw==", + "dev": true, + "requires": { + "@jest/environment": "^26.1.0", + "@jest/types": "^26.1.0", + "expect": "^26.1.0" + } + }, + "@jest/reporters": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.1.0.tgz", + "integrity": "sha512-SVAysur9FOIojJbF4wLP0TybmqwDkdnFxHSPzHMMIYyBtldCW9gG+Q5xWjpMFyErDiwlRuPyMSJSU64A67Pazg==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.1.0", + "jest-resolve": "^26.1.0", + "jest-util": "^26.1.0", + "jest-worker": "^26.1.0", + "node-notifier": "^7.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + } + }, + "@jest/source-map": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.1.0.tgz", + "integrity": "sha512-XYRPYx4eEVX15cMT9mstnO7hkHP3krNtKfxUYd8L7gbtia8JvZZ6bMzSwa6IQJENbudTwKMw5R1BePRD+bkEmA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.1.0.tgz", + "integrity": "sha512-Xz44mhXph93EYMA8aYDz+75mFbarTV/d/x0yMdI3tfSRs/vh4CqSxgzVmCps1fPkHDCtn0tU8IH9iCKgGeGpfw==", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/types": "^26.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.1.0.tgz", + "integrity": "sha512-Z/hcK+rTq56E6sBwMoQhSRDVjqrGtj1y14e2bIgcowARaIE1SgOanwx6gvY4Q9gTKMoZQXbXvptji+q5GYxa6Q==", + "dev": true, + "requires": { + "@jest/test-result": "^26.1.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.1.0", + "jest-runner": "^26.1.0", + "jest-runtime": "^26.1.0" + } + }, + "@jest/transform": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.1.0.tgz", + "integrity": "sha512-ICPm6sUXmZJieq45ix28k0s+d/z2E8CHDsq+WwtWI6kW8m7I8kPqarSEcUN86entHQ570ZBRci5OWaKL0wlAWw==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.1.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.1.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.1.0.tgz", + "integrity": "sha512-GXigDDsp6ZlNMhXQDeuy/iYCDsRIHJabWtDzvnn36+aqFfG14JmFV0e/iXxY4SP9vbXSiPNOWdehU5MeqrYHBQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "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.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", + "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "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": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/node": { + "version": "14.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.23.tgz", + "integrity": "sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/prettier": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.2.tgz", + "integrity": "sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA==", + "dev": true + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "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==", + "dev": true + }, + "ajv": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "dev": true, + "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-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "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=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "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=", + "dev": true + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "axios-mock-adapter": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.18.1.tgz", + "integrity": "sha512-kFBZsG1Ma5yxjRGHq5KuuL55mPb7WzFULhypquEhzPg8SH5CXICb+qwC2CCA5u+GQVpiqGPwKSRkd3mBCs6gdw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "is-buffer": "^2.0.3" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true + } + } + }, + "babel-jest": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.1.0.tgz", + "integrity": "sha512-Nkqgtfe7j6PxLO6TnCQQlkMm8wdTdnIF8xrdpooHCuD5hXRzVEPbPneTJKknH5Dsv3L8ip9unHDAp48YQ54Dkg==", + "dev": true, + "requires": { + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.1.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "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": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.1.0.tgz", + "integrity": "sha512-qhqLVkkSlqmC83bdMhM8WW4Z9tB+JkjqAqlbbohS9sJLT5Ha2vfzuKqg5yenXrAjOPG2YC0WiXdH3a9PvB+YYw==", + "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": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "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-preset-jest": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.1.0.tgz", + "integrity": "sha512-na9qCqFksknlEj5iSdw1ehMVR06LCCTkZLGKeEtxDDdhg8xpUF09m29Kvh1pRbZ07h7AQ5ttLYUwpXL4tO6w7w==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.1.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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==", + "dev": true + }, + "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-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "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 + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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 + }, + "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 + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.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 + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "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 + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "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=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "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==", + "dev": true + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "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==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "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=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "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-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "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==", + "dev": true + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "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==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "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" + } + }, + "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": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expect": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.1.0.tgz", + "integrity": "sha512-QbH4LZXDsno9AACrN9eM0zfnby9G+OsdNgZUohjg/P0mLy1O+/bzTAJGT6VSIjVCe8yKM6SzEl/ckEOFBT7Vnw==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-regex-util": "^26.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "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-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==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "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" + } + }, + "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 + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "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-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "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==", + "dev": true, + "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-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "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==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "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" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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==", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "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-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-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.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.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.1.0.tgz", + "integrity": "sha512-LIti8jppw5BcQvmNJe4w2g1N/3V68HUfAv9zDVm7v+VAtQulGhH0LnmmiVkbNE4M4I43Bj2fXPiBGKt26k9tHw==", + "dev": true, + "requires": { + "@jest/core": "^26.1.0", + "import-local": "^3.0.2", + "jest-cli": "^26.1.0" + }, + "dependencies": { + "jest-cli": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.1.0.tgz", + "integrity": "sha512-Imumvjgi3rU7stq6SJ1JUEMaV5aAgJYXIs0jPqdUnF47N/Tk83EXfmtvNKQ+SnFVI6t6mDOvfM3aA9Sg6kQPSw==", + "dev": true, + "requires": { + "@jest/core": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "prompts": "^2.0.1", + "yargs": "^15.3.1" + } + } + } + }, + "jest-changed-files": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.1.0.tgz", + "integrity": "sha512-HS5MIJp3B8t0NRKGMCZkcDUZo36mVRvrDETl81aqljT1S9tqiHRSpyoOvWg9ZilzZG9TDisDNaN1IXm54fLRZw==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "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==", + "dev": true + } + } + }, + "jest-config": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.1.0.tgz", + "integrity": "sha512-ONTGeoMbAwGCdq4WuKkMcdMoyfs5CLzHEkzFOlVvcDXufZSaIWh/OXMLa2fwKXiOaFcqEw8qFr4VOKJQfn4CVw==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.1.0", + "@jest/types": "^26.1.0", + "babel-jest": "^26.1.0", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.1.0", + "jest-environment-node": "^26.1.0", + "jest-get-type": "^26.0.0", + "jest-jasmine2": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "micromatch": "^4.0.2", + "pretty-format": "^26.1.0" + } + }, + "jest-diff": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.1.0.tgz", + "integrity": "sha512-GZpIcom339y0OXznsEKjtkfKxNdg7bVbEofK8Q6MnevTIiR1jNhDWKhRX6X0SDXJlwn3dy59nZ1z55fLkAqPWg==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.1.0" + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.1.0.tgz", + "integrity": "sha512-lYiSo4Igr81q6QRsVQq9LIkJW0hZcKxkIkHzNeTMPENYYDw/W/Raq28iJ0sLlNFYz2qxxeLnc5K2gQoFYlu2bA==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-util": "^26.1.0", + "pretty-format": "^26.1.0" + } + }, + "jest-environment-jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.1.0.tgz", + "integrity": "sha512-dWfiJ+spunVAwzXbdVqPH1LbuJW/kDL+FyqgA5YzquisHqTi0g9hquKif9xKm7c1bKBj6wbmJuDkeMCnxZEpUw==", + "dev": true, + "requires": { + "@jest/environment": "^26.1.0", + "@jest/fake-timers": "^26.1.0", + "@jest/types": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-util": "^26.1.0", + "jsdom": "^16.2.2" + } + }, + "jest-environment-node": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.1.0.tgz", + "integrity": "sha512-DNm5x1aQH0iRAe9UYAkZenuzuJ69VKzDCAYISFHQ5i9e+2Tbeu2ONGY7YStubCLH8a1wdKBgqScYw85+ySxqxg==", + "dev": true, + "requires": { + "@jest/environment": "^26.1.0", + "@jest/fake-timers": "^26.1.0", + "@jest/types": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-util": "^26.1.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-haste-map": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.1.0.tgz", + "integrity": "sha512-WeBS54xCIz9twzkEdm6+vJBXgRBQfdbbXD0dk8lJh7gLihopABlJmIQFdWSDDtuDe4PRiObsjZSUjbJ1uhWEpA==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^26.1.0", + "jest-util": "^26.1.0", + "jest-worker": "^26.1.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + } + }, + "jest-jasmine2": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.1.0.tgz", + "integrity": "sha512-1IPtoDKOAG+MeBrKvvuxxGPJb35MTTRSDglNdWWCndCB3TIVzbLThRBkwH9P081vXLgiJHZY8Bz3yzFS803xqQ==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.1.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.1.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.1.0", + "jest-matcher-utils": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-runtime": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "pretty-format": "^26.1.0", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.1.0.tgz", + "integrity": "sha512-dsMnKF+4BVOZwvQDlgn3MG+Ns4JuLv8jNvXH56bgqrrboyCbI1rQg6EI5rs+8IYagVcfVP2yZFKfWNZy0rK0Hw==", + "dev": true, + "requires": { + "jest-get-type": "^26.0.0", + "pretty-format": "^26.1.0" + } + }, + "jest-matcher-utils": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.1.0.tgz", + "integrity": "sha512-PW9JtItbYvES/xLn5mYxjMd+Rk+/kIt88EfH3N7w9KeOrHWaHrdYPnVHndGbsFGRJ2d5gKtwggCvkqbFDoouQA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.1.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.1.0" + } + }, + "jest-message-util": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.1.0.tgz", + "integrity": "sha512-dY0+UlldiAJwNDJ08SF0HdF32g9PkbF2NRK/+2iMPU40O6q+iSn1lgog/u0UH8ksWoPv0+gNq8cjhYO2MFtT0g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.1.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.1.0.tgz", + "integrity": "sha512-1Rm8EIJ3ZFA8yCIie92UbxZWj9SuVmUGcyhLHyAhY6WI3NIct38nVcfOPWhJteqSn8V8e3xOMha9Ojfazfpovw==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0" + } + }, + "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": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.1.0.tgz", + "integrity": "sha512-KsY1JV9FeVgEmwIISbZZN83RNGJ1CC+XUCikf/ZWJBX/tO4a4NvA21YixokhdR9UnmPKKAC4LafVixJBrwlmfg==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.1.0", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.1.0.tgz", + "integrity": "sha512-fQVEPHHQ1JjHRDxzlLU/buuQ9om+hqW6Vo928aa4b4yvq4ZHBtRSDsLdKQLuCqn5CkTVpYZ7ARh2fbA8WkRE6g==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.1.0" + } + }, + "jest-runner": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.1.0.tgz", + "integrity": "sha512-elvP7y0fVDREnfqit0zAxiXkDRSw6dgCkzPCf1XvIMnSDZ8yogmSKJf192dpOgnUVykmQXwYYJnCx641uLTgcw==", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/environment": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.1.0", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.1.0", + "jest-jasmine2": "^26.1.0", + "jest-leak-detector": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-resolve": "^26.1.0", + "jest-runtime": "^26.1.0", + "jest-util": "^26.1.0", + "jest-worker": "^26.1.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.1.0.tgz", + "integrity": "sha512-1qiYN+EZLmG1QV2wdEBRf+Ci8i3VSfIYLF02U18PiUDrMbhfpN/EAMMkJtT02jgJUoaEOpHAIXG6zS3QRMzRmA==", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/environment": "^26.1.0", + "@jest/fake-timers": "^26.1.0", + "@jest/globals": "^26.1.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.1.0", + "jest-haste-map": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.1.0.tgz", + "integrity": "sha512-eqZOQG/0+MHmr25b2Z86g7+Kzd5dG9dhCiUoyUNJPgiqi38DqbDEOlHcNijyfZoj74soGBohKBZuJFS18YTJ5w==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.1.0.tgz", + "integrity": "sha512-YhSbU7eMTVQO/iRbNs8j0mKRxGp4plo7sJ3GzOQ0IYjvsBiwg0T1o0zGQAYepza7lYHuPTrG5J2yDd0CE2YxSw==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.1.0", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.1.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.1.0", + "jest-get-type": "^26.0.0", + "jest-haste-map": "^26.1.0", + "jest-matcher-utils": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-resolve": "^26.1.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.1.0", + "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "jest-util": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.1.0.tgz", + "integrity": "sha512-rNMOwFQevljfNGvbzNQAxdmXQ+NawW/J72dmddsK0E8vgxXCMtwQ/EH0BiWEIxh0hhMcTsxwAxINt7Lh46Uzbg==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-validate": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.1.0.tgz", + "integrity": "sha512-WPApOOnXsiwhZtmkDsxnpye+XLb/tUISP+H6cHjfUIXvlG+eKwP+isnivsxlHCPaO9Q5wvbhloIBkdF3qUn+Nw==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.1.0.tgz", + "integrity": "sha512-ffEOhJl2EvAIki613oPsSG11usqnGUzIiK7MMX6hE4422aXOcVEG3ySCTDFLn1+LZNXGPE8tuJxhp8OBJ1pgzQ==", + "dev": true, + "requires": { + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.1.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.1.0.tgz", + "integrity": "sha512-Z9P5pZ6UC+kakMbNJn+tA2RdVdNX5WH1x+5UCBZ9MxIK24pjYtFt96fK+UwBTrjLYm232g1xz0L3eTh51OW+yQ==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.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": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.3.0.tgz", + "integrity": "sha512-zggeX5UuEknpdZzv15+MS1dPYG0J/TftiiNunOeNxSl3qr8Z6cIlQpN0IdJa44z9aFxZRIVqRncvEhQ7X5DtZg==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "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.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "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=", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "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.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "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.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "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 + } + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "moment": { + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", + "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "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 + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.1.tgz", + "integrity": "sha512-VkzhierE7DBmQEElhTGJIoiZa1oqRijOtgOlsXg32KrJRXsPy0NXFBqWGW/wTswnJlDCs5viRYaqWguqzsKcmg==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^7.2.1", + "shellwords": "^0.1.1", + "uuid": "^7.0.3", + "which": "^2.0.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "optional": 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" + } + }, + "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 + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.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==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "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" + } + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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-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 + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "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=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "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" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "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=", + "dev": true + }, + "pretty-format": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.1.0.tgz", + "integrity": "sha512-GmeO1PEYdM+non4BKCj+XsPJjFOJIPnsLewqhDVoqY1xo0yNmDas7tC2XwpMrRAHR3MaE2hPo37deX5OisJ2Wg==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "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==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "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" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "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": { + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "dev": true, + "requires": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "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-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "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 + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "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 + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.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 + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "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.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "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.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "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 + } + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "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==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "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" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "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-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "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": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "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=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "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.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "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" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true, + "optional": true + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "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=", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "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==", + "dev": true + } + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "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==", + "dev": true + }, + "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" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "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.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "dev": true + }, + "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==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/source/utils/package.json b/source/utils/package.json new file mode 100644 index 0000000..d02c3bc --- /dev/null +++ b/source/utils/package.json @@ -0,0 +1,22 @@ +{ + "name": "utils", + "version": "1.0.0", + "description": "Custom Resource Helper functions", + "scripts": { + "pretest": "npm ci", + "clean": "rm -rf dist/ node_modules/ coverage/", + "test": "jest test/*.spec.js --coverage --silent" + }, + "author": { + "name": "aws-solutions-builder" + }, + "license": "Apache-2.0", + "dependencies": { + "axios": "^0.19.2", + "moment": "^2.27.0" + }, + "devDependencies": { + "axios-mock-adapter": "*", + "jest": "*" + } +} diff --git a/source/utils/test/custom-resource-helper-functions.spec.js b/source/utils/test/custom-resource-helper-functions.spec.js new file mode 100644 index 0000000..c788ae4 --- /dev/null +++ b/source/utils/test/custom-resource-helper-functions.spec.js @@ -0,0 +1,145 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ +const CustomResourceHelpers = require('../../utils/custom-resource-helper-functions'); +const axios = require('axios'); +const MockAdapter = require('axios-mock-adapter'); + +describe('utils/custom-resource-helper-functions', () => { + let axiosMock; + + beforeEach(() => { + axiosMock = new MockAdapter(axios); + }); + + afterEach(() => { + axiosMock.restore(); + }); + + it('Create', async function () { + // Force the metric POST event to succeed + axiosMock.onPut().reply(200); + + await CustomResourceHelpers.handler({ RequestType: 'Create', LogicalResourceId: 'logical-id' }, { logStreamName: 'log-stream-name' }, (() => { + return 'response-to-cloudformation'; + }), undefined, undefined); + + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'SUCCESS', + Reason: 'See the details in CloudWatch Log Stream: log-stream-name', + LogicalResourceId: 'logical-id', + PhysicalResourceId: 'logical-id', + Data: { + Message: 'response-to-cloudformation' + } + }) + }); + + it('Update', async function () { + // Force the metric POST event to succeed + axiosMock.onPut().reply(200); + + await CustomResourceHelpers.handler({ RequestType: 'Update', LogicalResourceId: 'logical-id' }, { logStreamName: 'log-stream-name' }, undefined, (() => { + return 'response-to-cloudformation'; + }), undefined); + + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'SUCCESS', + Reason: 'See the details in CloudWatch Log Stream: log-stream-name', + LogicalResourceId: 'logical-id', + PhysicalResourceId: 'logical-id', + Data: { + Message: 'response-to-cloudformation' + } + }) + }); + + it('Delete', async function () { + // Force the metric POST event to succeed + axiosMock.onPut().reply(200); + + await CustomResourceHelpers.handler({ RequestType: 'Delete', LogicalResourceId: 'logical-id' }, { logStreamName: 'log-stream-name' }, undefined, undefined, (() => { + return 'response-to-cloudformation'; + })); + + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'SUCCESS', + Reason: 'See the details in CloudWatch Log Stream: log-stream-name', + LogicalResourceId: 'logical-id', + PhysicalResourceId: 'logical-id', + Data: { + Message: 'response-to-cloudformation' + } + }) + }); + + it('Returned object', async function () { + // Force the metric POST event to succeed + axiosMock.onPut().reply(200); + + await CustomResourceHelpers.handler({ RequestType: 'Delete', LogicalResourceId: 'logical-id' }, { logStreamName: 'log-stream-name' }, undefined, undefined, (() => { + return { key: 'value' }; + })); + + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'SUCCESS', + Reason: 'See the details in CloudWatch Log Stream: log-stream-name', + LogicalResourceId: 'logical-id', + PhysicalResourceId: 'logical-id', + Data: { + key: 'value' + } + }) + }); + + it('Unexpected', async function () { + // Force the metric POST event to succeed + axiosMock.onPut().reply(200); + + await CustomResourceHelpers.handler({ RequestType: 'Unexpected', LogicalResourceId: 'logical-id' }, { logStreamName: 'log-stream-name' }, undefined, undefined, undefined); + + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'SUCCESS', + Reason: 'See the details in CloudWatch Log Stream: log-stream-name', + LogicalResourceId: 'logical-id', + PhysicalResourceId: 'logical-id', + Data: { + Message: 'No action required for Unexpected' + } + }) + }); + + it('Failure', async function () { + // Force the metric POST event to succeed + axiosMock.onPut().reply(200); + + await CustomResourceHelpers.handler({ RequestType: 'Create', LogicalResourceId: 'logical-id' }, { logStreamName: 'log-stream-name' }, (() => { + throw new Error('unexpected error while handling create'); + }), undefined, undefined); + + const cfnReq = axiosMock.history.put[0]; + console.log(cfnReq) + expect(JSON.parse(cfnReq.data)).toEqual({ + Status: 'FAILED', + Reason: 'See the details in CloudWatch Log Stream: log-stream-name', + LogicalResourceId: 'logical-id', + PhysicalResourceId: 'logical-id', + Data: { + Error: 'unexpected error while handling create' + } + }) + }); +}); \ No newline at end of file diff --git a/source/utils/test/helper-functions.spec.js b/source/utils/test/helper-functions.spec.js new file mode 100644 index 0000000..aca765c --- /dev/null +++ b/source/utils/test/helper-functions.spec.js @@ -0,0 +1,109 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ +const HelperFunctions = require('../../utils/helper-functions'); + +describe('utils/helper-functions', () => { + beforeEach(() => { + process.env.SOLUTION_ID = 'SOMOCK'; + process.env.SOLUTION_VERSION = 'v1.0.0'; + process.env.AWS_REGION = 'us-east-1'; + process.env.IS_SECONDARY_REGION = 'No'; + }); + + test('getFunctionData', async function () { + expect(() => { + HelperFunctions.getFunctionData(); + }).toThrow('Error validating Environment Variables. Must pass an array as requiredProperties'); + + expect(() => { + HelperFunctions.getFunctionData([]); + }).toThrow('Error validating Event Payload. Must pass an array as requiredProperties'); + + expect(() => { + HelperFunctions.getFunctionData(['UNKNOWN_ENV_VAR'], [], [], {}); + }).toThrow('Error validating Environment Variables. Missing value for UNKNOWN_ENV_VAR'); + + expect(() => { + HelperFunctions.getFunctionData([], ['MISSING_PROPERTY'], [], {}); + }).toThrow('Error validating Event Payload. Missing value for MISSING_PROPERTY'); + + let result = HelperFunctions.getFunctionData( + ['SOLUTION_ID', 'AWS_REGION'], + ['REQUIRED_PROPERTY'], + ['OPTIONAL_PROPERTY'], + { REQUIRED_PROPERTY: 'value' }); + + expect(result).toEqual({ + SOLUTION_ID: 'SOMOCK', + AWS_REGION: 'us-east-1', + REQUIRED_PROPERTY: 'value' + }); + + result = HelperFunctions.getFunctionData( + ['SOLUTION_ID', 'AWS_REGION'], + ['REQUIRED_PROPERTY'], + ['OPTIONAL_PROPERTY'], + { REQUIRED_PROPERTY: 'value', OPTIONAL_PROPERTY: 'value2' }); + + expect(result).toEqual({ + SOLUTION_ID: 'SOMOCK', + AWS_REGION: 'us-east-1', + REQUIRED_PROPERTY: 'value', + OPTIONAL_PROPERTY: 'value2' + }); + }); + + test('objHasProperties', async function () { + expect(() => { + HelperFunctions.objHasProperties({}, 'not-an-array', 'test-object-type'); + }).toThrow('Error validating test-object-type. Must pass an array as requiredProperties'); + + expect(() => { + HelperFunctions.objHasProperties({ propertyName: '' }, ['propertyName'], 'test-object-type'); + }).toThrow('Error validating test-object-type. Missing value for propertyName'); + + expect(() => { + HelperFunctions.objHasProperties({ propertyName: 'value' }, [''], 'test-object-type'); + }).toThrow('Error validating test-object-type. Must only pass non-empty strings in the requiredProperties array'); + + expect(() => { + HelperFunctions.objHasProperties({ propertyName: ' ' }, ['propertyName'], 'test-object-type'); + }).toThrow('Error validating test-object-type. Value for propertyName must not be only whitespace'); + }); + + test('appendToStrWithMaxChar', async function () { + let result = HelperFunctions.appendToStrWithMaxChar(); + expect(result).toBe(''); + + result = HelperFunctions.appendToStrWithMaxChar('a-long-sqs-fifo-queue-name', '.fifo', 10); + expect(result).toBe('a-lon.fifo'); + }); + + test('sleep', async function () { + const start = Date.now(); + await HelperFunctions.sleep(2, 500); + const sleepTime = Date.now() - start; + + expect(sleepTime).toBeGreaterThanOrEqual(2500); + expect(sleepTime).toBeLessThan(2600); + }); + + test('getExponentialBackoffTimeInMS', async function () { + let result = HelperFunctions.getExponentialBackoffTimeInMS(0, 0, 0); + expect(result).toEqual(0); + + result = HelperFunctions.getExponentialBackoffTimeInMS(100, 100, 1000); + expect(result).toEqual(1000); + + result = HelperFunctions.getExponentialBackoffTimeInMS(100, 2, 1000); + expect(result).toEqual(400); + + result = HelperFunctions.getExponentialBackoffTimeInMS(100, 100, 1000, true); + expect(result).toBeLessThanOrEqual(1000); + expect(result).toBeGreaterThanOrEqual(1); + }); +}); \ No newline at end of file diff --git a/source/utils/test/metrics.spec.js b/source/utils/test/metrics.spec.js new file mode 100644 index 0000000..a277b7d --- /dev/null +++ b/source/utils/test/metrics.spec.js @@ -0,0 +1,53 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ +const { sendAnonymousMetric } = require('../../utils/metrics'); +const axios = require('axios'); +const MockAdapter = require('axios-mock-adapter'); + +describe('utils/metrics', () => { + let axiosMock; + + beforeEach(() => { + process.env.SOLUTION_ID = 'SOMOCK'; + process.env.SOLUTION_VERSION = 'v1.0.0'; + process.env.METRICS_ANONYMOUS_UUID = 'uuid'; + process.env.AWS_REGION = 'us-east-1'; + process.env.IS_SECONDARY_REGION = 'No'; + axiosMock = new MockAdapter(axios); + }); + + afterEach(() => { + axiosMock.restore(); + }); + + it('Should run normally', async function () { + // Force the metric POST event to succeed + axiosMock.onPost().reply(200); + + const { + SOLUTION_ID, SOLUTION_VERSION, METRICS_ANONYMOUS_UUID, + AWS_REGION, IS_SECONDARY_REGION } = process.env; + + const metricData = { + EventType: 'unit-test-metric', + EventDetails: `${AWS_REGION} (${IS_SECONDARY_REGION === 'Yes' ? 'Secondary' : 'Primary'} Region)` + }; + + await sendAnonymousMetric(SOLUTION_ID, SOLUTION_VERSION, METRICS_ANONYMOUS_UUID, metricData); + + const metricReq = axiosMock.history.post[0]; + const metricPayload = JSON.parse(metricReq.data); + const timestampRegex = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/; + + expect(metricReq.url).toMatch('https://metrics.awssolutionsbuilder.com/generic'); + expect(metricPayload.TimeStamp).toMatch(timestampRegex); + expect(metricPayload.Solution).toMatch(SOLUTION_ID); + expect(metricPayload.UUID).toMatch(METRICS_ANONYMOUS_UUID); + expect(metricPayload.Version).toMatch(SOLUTION_VERSION); + expect(metricPayload.Data).toMatchObject(metricData); + }); +}); \ No newline at end of file diff --git a/source/workflow-common/check-state-machine-executions.js b/source/workflow-common/check-state-machine-executions.js new file mode 100644 index 0000000..322e9be --- /dev/null +++ b/source/workflow-common/check-state-machine-executions.js @@ -0,0 +1,33 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const stepFunctions = new AWS.StepFunctions(); + +/** + * Returns whether a state machine has multiple executions running + * @param {object} event + */ +exports.handler = async (event) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const stateMachineArn = event.Context.StateMachine.Id; + const stateMachineExecutionId = event.Context.Execution.Id; + const result = {}; + + const listExecutionsParams = { + stateMachineArn: stateMachineArn, + statusFilter: 'RUNNING' + }; + + console.log(`Listing state machine executions: ${JSON.stringify(listExecutionsParams)}`); + const response = await stepFunctions.listExecutions(listExecutionsParams).promise(); + console.log(JSON.stringify(response)); + + result.OnlyThisStateMachineExecution = (response.executions.length === 1 && response.executions[0].executionArn === stateMachineExecutionId); + console.log(`Result: ${JSON.stringify(result)}`); + return { result: result }; +}; diff --git a/source/workflow-common/check-workflow-queues.js b/source/workflow-common/check-workflow-queues.js new file mode 100644 index 0000000..b920434 --- /dev/null +++ b/source/workflow-common/check-workflow-queues.js @@ -0,0 +1,58 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const sqs = new AWS.SQS(); +const { NEW_USERS_QUEUE_URL, UPDATES_QUEUE_URL } = process.env; + +/** + * Validates that the Queue(s) used by the workflow are empty + * @param {object} event + */ +exports.handler = async (event) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const { Context, Input } = event; + const stateMachineName = Context.StateMachine.Name.split('-')[0]; + const result = Input; + + switch (stateMachineName) { + case 'ImportWorkflow': + const newUsersQueueEmpty = await isQueueEmpty(NEW_USERS_QUEUE_URL); + const updatesQueueEmpty = await isQueueEmpty(UPDATES_QUEUE_URL); + result.QueuesStartedOutEmpty = (newUsersQueueEmpty && updatesQueueEmpty); + break; + default: + throw new Error(`Unknown State Machine Name: ${stateMachineName}`); + } + + console.log(`Result: ${JSON.stringify(result)}`); + return {result}; +}; + +/** + * Returns true if the SQS Queue with the supplied URL is empty. Throws an Error otherwise + * @param {string} queueUrl The URL of the SQS Queue to evaluate + */ +const isQueueEmpty = async (queueUrl) => { + const attributesToCheck = ['ApproximateNumberOfMessages', 'ApproximateNumberOfMessagesVisible', 'ApproximateNumberOfMessagesNotVisible', 'ApproximateNumberOfMessagesDelayed']; + const params = { QueueUrl: queueUrl, AttributeNames: ['All'] }; + + console.log(`Getting queue attributes: ${JSON.stringify(params)}`); + const response = await sqs.getQueueAttributes(params).promise(); + console.log('Get queue attributes response', JSON.stringify(response, null, 2)); + + for (let attribute of attributesToCheck) { + if (response.Attributes && response.Attributes.hasOwnProperty(attribute)) { + console.log(`Checking attribute (${attribute})`); + if (response.Attributes[attribute] !== '0') { + throw new Error(`Queue (${queueUrl}) is not empty. Expected a value of "0" for attribute (${attribute}) and found value "${response.Attributes[attribute]}" instead. Please purge this queue prior to running this workflow`); + } + } + } + + return true; +}; diff --git a/source/workflow-common/message-broker.js b/source/workflow-common/message-broker.js new file mode 100644 index 0000000..9ee75e0 --- /dev/null +++ b/source/workflow-common/message-broker.js @@ -0,0 +1,174 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const sns = new AWS.SNS(); +const docClient = new AWS.DynamoDB.DocumentClient(); +const { BACKUP_TABLE_NAME, TYPE_TIMESTAMP, SNS_MESSAGE_PREFERENCE, SEND_METRIC, METRICS_ANONYMOUS_UUID, SOLUTION_ID, SOLUTION_VERSION, AWS_REGION, IS_PRIMARY_REGION, NOTIFICATION_TOPIC } = process.env; +const { sendAnonymousMetric } = require('../utils/metrics'); + +/** + * Publishes info and error messages to the solution's SNS topic and if enabled, sends anonymous operational metrics + * @param {object} event + */ +exports.handler = async (event) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const { Context, Input } = event; + + switch (Context.State.Name) { + case 'WorkflowErrorHandlerLambda': + case 'WorkflowErrorHandlerLambdaGroupsMap': + case 'WorkflowErrorHandlerLambdaDeletedGroupsMap': + case 'Parallel: WorkflowErrorHandlerLambda (Scan Table)': + case 'Parallel: WorkflowErrorHandlerLambda': + await handleError(Context, Input); + break; + case 'WorkflowCleanupLambda': + await handleCleanup(Context, Input); + break; + default: + console.log(`Unknown State Name: ${Context.State.Name}`); + break; + } +}; + +/** + * Publishes a message to the solution's SNS topic to inform of the error. Sends a metric if enabled + * @param {*} Context State Machine context + * @param {*} Input Lambda input + */ +const handleError = async (Context, Input) => { + let shouldSendMetric = (SEND_METRIC === 'Yes'); + let error = 'Unknown'; + const workflowName = Context.StateMachine.Name; + if (Input && Input.Cause) { + try { + error = JSON.parse(Input.Cause); + } catch (err) { + console.error(err); + if (Input.Cause.trim() !== '') { + error = Input.Cause; + } + } + } + + // Publish the message to the solution's Noitification Topic + await publishMessage(`An unexpected error occurred while executing the ${workflowName} for this solution:\n${JSON.stringify(error, null, 2)}\n\nPlease check the state machine's task logs for additional information\n\nExecution details:\n${JSON.stringify(Context, null, 2)}`); + + if (shouldSendMetric) { + try { + let executionTime = getExecutionTime(Context); + + await sendMetric({ + EventType: 'workflow-error', + EventDetails: { + Region: AWS_REGION, + IsPrimaryRegion: IS_PRIMARY_REGION, + ExecutionTimeInSeconds: executionTime, + WorkflowName: workflowName.split('-')[0] + } + }); + } catch (err) { + console.error(err); + } + } +}; + +/** + * Publishes a message to the solution's Notification SNS Topic + * @param {string} msg Message to publish + */ +const publishMessage = async (msg) => { + console.log('Publishing message to notification topic'); + await sns.publish({ TopicArn: NOTIFICATION_TOPIC, Message: msg }).promise(); + console.log('Message published'); +}; + +/** + * Sends anonymous operational metric + * @param {object} payload Metric data + */ +const sendMetric = async (payload) => { + await sendAnonymousMetric(SOLUTION_ID, SOLUTION_VERSION, METRICS_ANONYMOUS_UUID, payload); +}; + +/** + * Publishes a message to the solution's SNS topic to inform of the workflow completion. Sends a metric if enabled + * @param {*} Context State Machine context + * @param {*} Input Lambda input + */ +const handleCleanup = async (Context, Input) => { + const workflowName = Context.StateMachine.Name; + const executionTime = getExecutionTime(Context); + let shouldSendMetric = (SEND_METRIC === 'Yes'); + + switch (workflowName.split('-')[0]) { + case 'ExportWorkflow': + if (Input && Input.ExportTimestamp) { + await updateLatestExportTimestamp(Input.ExportTimestamp); + } + break; + case 'ImportWorkflow': + // Send metric if enabled + break; + default: + shouldSendMetric = false; + break; + } + + if (SNS_MESSAGE_PREFERENCE === 'INFO_AND_ERRORS') { + // Publish the message to the solution's Noitification Topic + await publishMessage(`Workflow (${workflowName}) completed successfully. Execution took ${executionTime} second(s).\n\nExecution details:\n${JSON.stringify(Context, null, 2)}`); + } + + if (shouldSendMetric) { + try { + await sendAnonymousMetric(SOLUTION_ID, SOLUTION_VERSION, METRICS_ANONYMOUS_UUID, { + EventType: 'workflow-finished', + EventDetails: { + Region: AWS_REGION, + IsPrimaryRegion: IS_PRIMARY_REGION, + ExecutionTimeInSeconds: executionTime, + WorkflowName: workflowName.split('-')[0] + } + }); + } catch (err) { + console.error(err); + } + } +}; + +/** + * Updates the Backup Table with the last time the Export Workflow was successfully completed + * @param {number} exportTimestamp + */ +const updateLatestExportTimestamp = async (exportTimestamp) => { + const putParams = { + TableName: BACKUP_TABLE_NAME, + Item: { + id: 'latest-export-timestamp', + type: TYPE_TIMESTAMP, + latestExportTimestamp: exportTimestamp + } + }; + + console.log(`Updating latest export timestamp: ${JSON.stringify(putParams)}`); + await docClient.put(putParams).promise(); + console.log('Latest export timestamp updated'); +}; + +/** + * Returns the state machine execution time in seconds + * @param {object} Context State Machine Context + */ +const getExecutionTime = (Context) => { + let executionTime = -1; + const startTime = new Date(Context.Execution.StartTime).getTime(); + const endTime = new Date(Context.State.EnteredTime).getTime(); + executionTime = (endTime - startTime) / 1000; + return executionTime; +}; diff --git a/source/workflow-common/package-lock.json b/source/workflow-common/package-lock.json new file mode 100644 index 0000000..489bf74 --- /dev/null +++ b/source/workflow-common/package-lock.json @@ -0,0 +1,4781 @@ +{ + "name": "workflow-common", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.5.tgz", + "integrity": "sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.5", + "@babel/types": "^7.10.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "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/generator": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.5.tgz", + "integrity": "sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==", + "dev": true, + "requires": { + "@babel/types": "^7.10.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "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-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.5.tgz", + "integrity": "sha512-HiqJpYD5+WopCXIAbQDG0zye5XYVvcO9w/DHp5GsaGkRUaamLj2bEtu6i8rnGGprAhHM3qidCMgp71HF4endhA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz", + "integrity": "sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "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.10.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", + "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", + "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.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@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/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.5.tgz", + "integrity": "sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/types": "^7.10.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "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 + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@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" + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/console": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.1.0.tgz", + "integrity": "sha512-+0lpTHMd/8pJp+Nd4lyip+/Iyf2dZJvcCqrlkeZQoQid+JlThA4M9vxHtheyrQ99jJTMQam+es4BcvZ5W5cC3A==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "jest-message-util": "^26.1.0", + "jest-util": "^26.1.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.1.0.tgz", + "integrity": "sha512-zyizYmDJOOVke4OO/De//aiv8b07OwZzL2cfsvWF3q9YssfpcKfcnZAwDY8f+A76xXSMMYe8i/f/LPocLlByfw==", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/reporters": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.1.0", + "jest-config": "^26.1.0", + "jest-haste-map": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.1.0", + "jest-resolve-dependencies": "^26.1.0", + "jest-runner": "^26.1.0", + "jest-runtime": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "jest-watcher": "^26.1.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.1.0.tgz", + "integrity": "sha512-86+DNcGongbX7ai/KE/S3/NcUVZfrwvFzOOWX/W+OOTvTds7j07LtC+MgGydH5c8Ri3uIrvdmVgd1xFD5zt/xA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.1.0", + "@jest/types": "^26.1.0", + "jest-mock": "^26.1.0" + } + }, + "@jest/fake-timers": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.1.0.tgz", + "integrity": "sha512-Y5F3kBVWxhau3TJ825iuWy++BAuQzK/xEa+wD9vDH3RytW9f2DbMVodfUQC54rZDX3POqdxCgcKdgcOL0rYUpA==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-util": "^26.1.0" + } + }, + "@jest/globals": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.1.0.tgz", + "integrity": "sha512-MKiHPNaT+ZoG85oMaYUmGHEqu98y3WO2yeIDJrs2sJqHhYOy3Z6F7F/luzFomRQ8SQ1wEkmahFAz2291Iv8EAw==", + "dev": true, + "requires": { + "@jest/environment": "^26.1.0", + "@jest/types": "^26.1.0", + "expect": "^26.1.0" + } + }, + "@jest/reporters": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.1.0.tgz", + "integrity": "sha512-SVAysur9FOIojJbF4wLP0TybmqwDkdnFxHSPzHMMIYyBtldCW9gG+Q5xWjpMFyErDiwlRuPyMSJSU64A67Pazg==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.1.0", + "jest-resolve": "^26.1.0", + "jest-util": "^26.1.0", + "jest-worker": "^26.1.0", + "node-notifier": "^7.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + } + }, + "@jest/source-map": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.1.0.tgz", + "integrity": "sha512-XYRPYx4eEVX15cMT9mstnO7hkHP3krNtKfxUYd8L7gbtia8JvZZ6bMzSwa6IQJENbudTwKMw5R1BePRD+bkEmA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.1.0.tgz", + "integrity": "sha512-Xz44mhXph93EYMA8aYDz+75mFbarTV/d/x0yMdI3tfSRs/vh4CqSxgzVmCps1fPkHDCtn0tU8IH9iCKgGeGpfw==", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/types": "^26.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.1.0.tgz", + "integrity": "sha512-Z/hcK+rTq56E6sBwMoQhSRDVjqrGtj1y14e2bIgcowARaIE1SgOanwx6gvY4Q9gTKMoZQXbXvptji+q5GYxa6Q==", + "dev": true, + "requires": { + "@jest/test-result": "^26.1.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.1.0", + "jest-runner": "^26.1.0", + "jest-runtime": "^26.1.0" + } + }, + "@jest/transform": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.1.0.tgz", + "integrity": "sha512-ICPm6sUXmZJieq45ix28k0s+d/z2E8CHDsq+WwtWI6kW8m7I8kPqarSEcUN86entHQ570ZBRci5OWaKL0wlAWw==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.1.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.1.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.1.0.tgz", + "integrity": "sha512-GXigDDsp6ZlNMhXQDeuy/iYCDsRIHJabWtDzvnn36+aqFfG14JmFV0e/iXxY4SP9vbXSiPNOWdehU5MeqrYHBQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "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.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", + "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "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": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/node": { + "version": "14.0.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz", + "integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/prettier": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.2.tgz", + "integrity": "sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA==", + "dev": true + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "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==", + "dev": true + }, + "ajv": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "dev": true, + "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-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "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=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sdk": { + "version": "2.723.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.723.0.tgz", + "integrity": "sha512-GmyMacu1x1BOA8tYZuZS1DKcdn7QQX+DJFdFgZ3IilMzlX3cdinMXkBc5onEnhbwHx657XHoPigJynTRGGNuWQ==", + "dev": true, + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.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=", + "dev": true + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "babel-jest": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.1.0.tgz", + "integrity": "sha512-Nkqgtfe7j6PxLO6TnCQQlkMm8wdTdnIF8xrdpooHCuD5hXRzVEPbPneTJKknH5Dsv3L8ip9unHDAp48YQ54Dkg==", + "dev": true, + "requires": { + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.1.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "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": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.1.0.tgz", + "integrity": "sha512-qhqLVkkSlqmC83bdMhM8WW4Z9tB+JkjqAqlbbohS9sJLT5Ha2vfzuKqg5yenXrAjOPG2YC0WiXdH3a9PvB+YYw==", + "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": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "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-preset-jest": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.1.0.tgz", + "integrity": "sha512-na9qCqFksknlEj5iSdw1ehMVR06LCCTkZLGKeEtxDDdhg8xpUF09m29Kvh1pRbZ07h7AQ5ttLYUwpXL4tO6w7w==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.1.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "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 + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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 + }, + "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 + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.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 + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "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 + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "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=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "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==", + "dev": true + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "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==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "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=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "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-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "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==", + "dev": true + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "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==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "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" + } + }, + "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": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expect": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.1.0.tgz", + "integrity": "sha512-QbH4LZXDsno9AACrN9eM0zfnby9G+OsdNgZUohjg/P0mLy1O+/bzTAJGT6VSIjVCe8yKM6SzEl/ckEOFBT7Vnw==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-regex-util": "^26.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "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-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==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "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" + } + }, + "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 + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "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-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "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==", + "dev": true, + "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-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "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==", + "dev": true, + "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==", + "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" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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==", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "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-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-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.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.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.1.0.tgz", + "integrity": "sha512-LIti8jppw5BcQvmNJe4w2g1N/3V68HUfAv9zDVm7v+VAtQulGhH0LnmmiVkbNE4M4I43Bj2fXPiBGKt26k9tHw==", + "dev": true, + "requires": { + "@jest/core": "^26.1.0", + "import-local": "^3.0.2", + "jest-cli": "^26.1.0" + }, + "dependencies": { + "jest-cli": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.1.0.tgz", + "integrity": "sha512-Imumvjgi3rU7stq6SJ1JUEMaV5aAgJYXIs0jPqdUnF47N/Tk83EXfmtvNKQ+SnFVI6t6mDOvfM3aA9Sg6kQPSw==", + "dev": true, + "requires": { + "@jest/core": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "prompts": "^2.0.1", + "yargs": "^15.3.1" + } + } + } + }, + "jest-changed-files": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.1.0.tgz", + "integrity": "sha512-HS5MIJp3B8t0NRKGMCZkcDUZo36mVRvrDETl81aqljT1S9tqiHRSpyoOvWg9ZilzZG9TDisDNaN1IXm54fLRZw==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "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==", + "dev": true + } + } + }, + "jest-config": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.1.0.tgz", + "integrity": "sha512-ONTGeoMbAwGCdq4WuKkMcdMoyfs5CLzHEkzFOlVvcDXufZSaIWh/OXMLa2fwKXiOaFcqEw8qFr4VOKJQfn4CVw==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.1.0", + "@jest/types": "^26.1.0", + "babel-jest": "^26.1.0", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.1.0", + "jest-environment-node": "^26.1.0", + "jest-get-type": "^26.0.0", + "jest-jasmine2": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "micromatch": "^4.0.2", + "pretty-format": "^26.1.0" + } + }, + "jest-diff": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.1.0.tgz", + "integrity": "sha512-GZpIcom339y0OXznsEKjtkfKxNdg7bVbEofK8Q6MnevTIiR1jNhDWKhRX6X0SDXJlwn3dy59nZ1z55fLkAqPWg==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.1.0" + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.1.0.tgz", + "integrity": "sha512-lYiSo4Igr81q6QRsVQq9LIkJW0hZcKxkIkHzNeTMPENYYDw/W/Raq28iJ0sLlNFYz2qxxeLnc5K2gQoFYlu2bA==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-util": "^26.1.0", + "pretty-format": "^26.1.0" + } + }, + "jest-environment-jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.1.0.tgz", + "integrity": "sha512-dWfiJ+spunVAwzXbdVqPH1LbuJW/kDL+FyqgA5YzquisHqTi0g9hquKif9xKm7c1bKBj6wbmJuDkeMCnxZEpUw==", + "dev": true, + "requires": { + "@jest/environment": "^26.1.0", + "@jest/fake-timers": "^26.1.0", + "@jest/types": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-util": "^26.1.0", + "jsdom": "^16.2.2" + } + }, + "jest-environment-node": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.1.0.tgz", + "integrity": "sha512-DNm5x1aQH0iRAe9UYAkZenuzuJ69VKzDCAYISFHQ5i9e+2Tbeu2ONGY7YStubCLH8a1wdKBgqScYw85+ySxqxg==", + "dev": true, + "requires": { + "@jest/environment": "^26.1.0", + "@jest/fake-timers": "^26.1.0", + "@jest/types": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-util": "^26.1.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-haste-map": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.1.0.tgz", + "integrity": "sha512-WeBS54xCIz9twzkEdm6+vJBXgRBQfdbbXD0dk8lJh7gLihopABlJmIQFdWSDDtuDe4PRiObsjZSUjbJ1uhWEpA==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^26.1.0", + "jest-util": "^26.1.0", + "jest-worker": "^26.1.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + } + }, + "jest-jasmine2": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.1.0.tgz", + "integrity": "sha512-1IPtoDKOAG+MeBrKvvuxxGPJb35MTTRSDglNdWWCndCB3TIVzbLThRBkwH9P081vXLgiJHZY8Bz3yzFS803xqQ==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.1.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.1.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.1.0", + "jest-matcher-utils": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-runtime": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "pretty-format": "^26.1.0", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.1.0.tgz", + "integrity": "sha512-dsMnKF+4BVOZwvQDlgn3MG+Ns4JuLv8jNvXH56bgqrrboyCbI1rQg6EI5rs+8IYagVcfVP2yZFKfWNZy0rK0Hw==", + "dev": true, + "requires": { + "jest-get-type": "^26.0.0", + "pretty-format": "^26.1.0" + } + }, + "jest-matcher-utils": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.1.0.tgz", + "integrity": "sha512-PW9JtItbYvES/xLn5mYxjMd+Rk+/kIt88EfH3N7w9KeOrHWaHrdYPnVHndGbsFGRJ2d5gKtwggCvkqbFDoouQA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.1.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.1.0" + } + }, + "jest-message-util": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.1.0.tgz", + "integrity": "sha512-dY0+UlldiAJwNDJ08SF0HdF32g9PkbF2NRK/+2iMPU40O6q+iSn1lgog/u0UH8ksWoPv0+gNq8cjhYO2MFtT0g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.1.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.1.0.tgz", + "integrity": "sha512-1Rm8EIJ3ZFA8yCIie92UbxZWj9SuVmUGcyhLHyAhY6WI3NIct38nVcfOPWhJteqSn8V8e3xOMha9Ojfazfpovw==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0" + } + }, + "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": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.1.0.tgz", + "integrity": "sha512-KsY1JV9FeVgEmwIISbZZN83RNGJ1CC+XUCikf/ZWJBX/tO4a4NvA21YixokhdR9UnmPKKAC4LafVixJBrwlmfg==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.1.0", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.1.0.tgz", + "integrity": "sha512-fQVEPHHQ1JjHRDxzlLU/buuQ9om+hqW6Vo928aa4b4yvq4ZHBtRSDsLdKQLuCqn5CkTVpYZ7ARh2fbA8WkRE6g==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.1.0" + } + }, + "jest-runner": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.1.0.tgz", + "integrity": "sha512-elvP7y0fVDREnfqit0zAxiXkDRSw6dgCkzPCf1XvIMnSDZ8yogmSKJf192dpOgnUVykmQXwYYJnCx641uLTgcw==", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/environment": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.1.0", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.1.0", + "jest-jasmine2": "^26.1.0", + "jest-leak-detector": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-resolve": "^26.1.0", + "jest-runtime": "^26.1.0", + "jest-util": "^26.1.0", + "jest-worker": "^26.1.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.1.0.tgz", + "integrity": "sha512-1qiYN+EZLmG1QV2wdEBRf+Ci8i3VSfIYLF02U18PiUDrMbhfpN/EAMMkJtT02jgJUoaEOpHAIXG6zS3QRMzRmA==", + "dev": true, + "requires": { + "@jest/console": "^26.1.0", + "@jest/environment": "^26.1.0", + "@jest/fake-timers": "^26.1.0", + "@jest/globals": "^26.1.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/transform": "^26.1.0", + "@jest/types": "^26.1.0", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.1.0", + "jest-haste-map": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-mock": "^26.1.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "jest-validate": "^26.1.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.1.0.tgz", + "integrity": "sha512-eqZOQG/0+MHmr25b2Z86g7+Kzd5dG9dhCiUoyUNJPgiqi38DqbDEOlHcNijyfZoj74soGBohKBZuJFS18YTJ5w==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.1.0.tgz", + "integrity": "sha512-YhSbU7eMTVQO/iRbNs8j0mKRxGp4plo7sJ3GzOQ0IYjvsBiwg0T1o0zGQAYepza7lYHuPTrG5J2yDd0CE2YxSw==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.1.0", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.1.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.1.0", + "jest-get-type": "^26.0.0", + "jest-haste-map": "^26.1.0", + "jest-matcher-utils": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-resolve": "^26.1.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.1.0", + "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "jest-util": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.1.0.tgz", + "integrity": "sha512-rNMOwFQevljfNGvbzNQAxdmXQ+NawW/J72dmddsK0E8vgxXCMtwQ/EH0BiWEIxh0hhMcTsxwAxINt7Lh46Uzbg==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-validate": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.1.0.tgz", + "integrity": "sha512-WPApOOnXsiwhZtmkDsxnpye+XLb/tUISP+H6cHjfUIXvlG+eKwP+isnivsxlHCPaO9Q5wvbhloIBkdF3qUn+Nw==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.1.0.tgz", + "integrity": "sha512-ffEOhJl2EvAIki613oPsSG11usqnGUzIiK7MMX6hE4422aXOcVEG3ySCTDFLn1+LZNXGPE8tuJxhp8OBJ1pgzQ==", + "dev": true, + "requires": { + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.1.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.1.0.tgz", + "integrity": "sha512-Z9P5pZ6UC+kakMbNJn+tA2RdVdNX5WH1x+5UCBZ9MxIK24pjYtFt96fK+UwBTrjLYm232g1xz0L3eTh51OW+yQ==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "dev": true + }, + "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": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.3.0.tgz", + "integrity": "sha512-zggeX5UuEknpdZzv15+MS1dPYG0J/TftiiNunOeNxSl3qr8Z6cIlQpN0IdJa44z9aFxZRIVqRncvEhQ7X5DtZg==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "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.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "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=", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "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.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "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.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "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 + } + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "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 + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "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 + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.2.tgz", + "integrity": "sha512-ux+n4hPVETuTL8+daJXTOC6uKLgMsl1RYfFv7DKRzyvzBapqco0rZZ9g72ZN8VS6V+gvNYHYa/ofcCY8fkJWsA==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.2.0", + "which": "^2.0.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "optional": true + }, + "uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", + "dev": true, + "optional": 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" + } + }, + "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 + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.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==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "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" + } + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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-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 + }, + "parse-json": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", + "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "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=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "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" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "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=", + "dev": true + }, + "pretty-format": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.1.0.tgz", + "integrity": "sha512-GmeO1PEYdM+non4BKCj+XsPJjFOJIPnsLewqhDVoqY1xo0yNmDas7tC2XwpMrRAHR3MaE2hPo37deX5OisJ2Wg==", + "dev": true, + "requires": { + "@jest/types": "^26.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "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" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "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": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "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-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "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 + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", + "dev": true + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "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 + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "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.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "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.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "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 + } + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "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==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "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" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "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-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "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": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "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=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "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.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "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" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "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=", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "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==", + "dev": true + } + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "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==", + "dev": true + }, + "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" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "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.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "dev": true + }, + "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==", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "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=", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/source/workflow-common/package.json b/source/workflow-common/package.json new file mode 100644 index 0000000..947ec75 --- /dev/null +++ b/source/workflow-common/package.json @@ -0,0 +1,25 @@ +{ + "name": "workflow-common", + "version": "1.0.0", + "description": "Common functionality for all Step Functions Workflows", + "author": { + "name": "aws-solutions-builder" + }, + "license": "Apache-2.0", + "private": true, + "dependencies": {}, + "devDependencies": { + "aws-sdk": "*", + "jest": "*" + }, + "scripts": { + "pretest": "npm ci", + "clean": "rm -rf dist/ node_modules/ coverage/", + "test": "jest test/*.spec.js --coverage --silent", + "package:zip": "cd dist && zip -rq package.zip .", + "package:dist": "mkdir dist && rsync -avr ../utils ./dist/ && rsync -avr --exclude=*test* --exclude=*dist* --exclude=*node_modules* ./ ./dist/$npm_package_name", + "package": "npm run clean && npm ci --production && npm run package:dist && npm run package:zip", + "build": "npm run clean && rm -f package-lock.json && npm install" + }, + "bundledDependencies": [] +} diff --git a/source/workflow-common/test/check-state-machine-executions.spec.js b/source/workflow-common/test/check-state-machine-executions.spec.js new file mode 100644 index 0000000..813993e --- /dev/null +++ b/source/workflow-common/test/check-state-machine-executions.spec.js @@ -0,0 +1,113 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock AWS SDK +const mockStepFunctions = jest.fn(); +const mockAWS = require('aws-sdk'); +mockAWS.StepFunctions = jest.fn(() => ({ + listExecutions: mockStepFunctions +})); + +describe('check-state-machine-executions', function () { + beforeEach(() => { mockStepFunctions.mockReset(); }); + + it('Should return true if there is only one execution running', async function () { + mockStepFunctions.mockImplementationOnce(() => { + return { + promise() { + // stepFunctions.listExecutions + return Promise.resolve({ + executions: [{ executionArn: 'execution-id' }] + }); + } + }; + }); + + const event = { + Context: { + StateMachine: { Id: 'state-machine-id' }, + Execution: { Id: 'execution-id' } + } + }; + + const lambda = require('../check-state-machine-executions'); + const result = await lambda.handler(event); + expect(result).toEqual({ result: { OnlyThisStateMachineExecution: true } }); + }); + + it('Should return false if there is no executions are returned', async function () { + mockStepFunctions.mockImplementationOnce(() => { + return { + promise() { + // stepFunctions.listExecutions + return Promise.resolve({ + executions: [] + }); + } + }; + }); + + const event = { + Context: { + StateMachine: { Id: 'state-machine-id' }, + Execution: { Id: 'execution-id' } + } + }; + + const lambda = require('../check-state-machine-executions'); + const result = await lambda.handler(event); + expect(result).toEqual({ result: { OnlyThisStateMachineExecution: false } }); + }); + + it('Should return false if there are more than one executions returned', async function () { + mockStepFunctions.mockImplementationOnce(() => { + return { + promise() { + // stepFunctions.listExecutions + return Promise.resolve({ + executions: [{ executionArn: 'execution-id' }, { executionArn: 'execution-id-2' }] + }); + } + }; + }); + + const event = { + Context: { + StateMachine: { Id: 'state-machine-id' }, + Execution: { Id: 'execution-id' } + } + }; + + const lambda = require('../check-state-machine-executions'); + const result = await lambda.handler(event); + expect(result).toEqual({ result: { OnlyThisStateMachineExecution: false } }); + }); + + it('Should return false if the execution ID doesn\'t match the event', async function () { + mockStepFunctions.mockImplementationOnce(() => { + return { + promise() { + // stepFunctions.listExecutions + return Promise.resolve({ + executions: [{ executionArn: 'other-execution-id' }] + }); + } + }; + }); + + const event = { + Context: { + StateMachine: { Id: 'state-machine-id' }, + Execution: { Id: 'execution-id' } + } + }; + + const lambda = require('../check-state-machine-executions'); + const result = await lambda.handler(event); + expect(result).toEqual({ result: { OnlyThisStateMachineExecution: false } }); + }); +}); \ No newline at end of file diff --git a/source/workflow-common/test/check-workflow-queues.spec.js b/source/workflow-common/test/check-workflow-queues.spec.js new file mode 100644 index 0000000..5116a2f --- /dev/null +++ b/source/workflow-common/test/check-workflow-queues.spec.js @@ -0,0 +1,135 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock AWS SDK +const mockSqs = { + getQueueAttributes: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + SQS: jest.fn(() => ({ + getQueueAttributes: mockSqs.getQueueAttributes + })) + }; +}); + +beforeAll(() => { + process.env = Object.assign(process.env, { + NEW_USERS_QUEUE_URL: 'new-users-queue-url', + UPDATES_QUEUE_URL: 'updates-queue-url' + }); +}); + +describe('check-workflow-queues', function () { + beforeEach(() => { + jest.resetModules(); + for (const mockFn in mockSqs) { + mockSqs[mockFn].mockReset(); + } + }); + + it('Throws an error if a queue attribute is not zero', async function () { + mockSqs.getQueueAttributes.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + "Attributes": { + "ApproximateNumberOfMessages": "0", + "ApproximateNumberOfMessagesNotVisible": "0", + "ApproximateNumberOfMessagesDelayed": "0" + } + }); + } + }; + }).mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + "Attributes": { + "ApproximateNumberOfMessages": "0", + "ApproximateNumberOfMessagesNotVisible": "0", + "ApproximateNumberOfMessagesDelayed": "1" + } + }); + } + }; + }); + + const event = { + Context: { + Execution: { StartTime: new Date(0).toISOString() }, + StateMachine: { Id: 'id', StartTime: new Date(), Name: 'ImportWorkflow-HASHVALUE' } + }, + Input: { + "OnlyThisStateMachineExecution": true + } + }; + const lambda = require('../check-workflow-queues'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('Queue (updates-queue-url) is not empty. Expected a value of "0" for attribute (ApproximateNumberOfMessagesDelayed) and found value "1" instead. Please purge this queue prior to running this workflow'); + }); + + it('Throws an error for an unexpected state machine name', async function () { + const event = { + Context: { + Execution: { StartTime: new Date(0).toISOString() }, + StateMachine: { Id: 'id', StartTime: new Date(), Name: 'StateMachineName' } + }, + Input: { + "OnlyThisStateMachineExecution": true + } + }; + const lambda = require('../check-workflow-queues'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('Unknown State Machine Name: StateMachineName'); + }); + + it('Returns when all queue attributes are zero', async function () { + mockSqs.getQueueAttributes.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + "Attributes": { + "ApproximateNumberOfMessages": "0", + "ApproximateNumberOfMessagesNotVisible": "0", + "ApproximateNumberOfMessagesDelayed": "0" + } + }); + } + }; + }).mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + "Attributes": { + "ApproximateNumberOfMessages": "0", + "ApproximateNumberOfMessagesNotVisible": "0", + "ApproximateNumberOfMessagesDelayed": "0" + } + }); + } + }; + }); + + const event = { + Context: { + Execution: { StartTime: new Date(0).toISOString() }, + StateMachine: { Id: 'id', StartTime: new Date(), Name: 'ImportWorkflow-HASHVALUE' } + }, + Input: { + "OnlyThisStateMachineExecution": true + } + }; + + const lambda = require('../check-workflow-queues'); + const result = await lambda.handler(event); + expect(result).toEqual({ result: { OnlyThisStateMachineExecution: true, QueuesStartedOutEmpty: true } }); + }); +}); diff --git a/source/workflow-common/test/message-broker.spec.js b/source/workflow-common/test/message-broker.spec.js new file mode 100644 index 0000000..b45b27b --- /dev/null +++ b/source/workflow-common/test/message-broker.spec.js @@ -0,0 +1,227 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock AWS SDK +const mockSns = { + publish: jest.fn() +}; + +const mockDocClient = { + put: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + SNS: jest.fn(() => ({ + publish: mockSns.publish + })), + DynamoDB: { + DocumentClient: jest.fn(() => ({ + put: mockDocClient.put + })) + } + }; +}); + +// Mock metrics client +const Metrics = require('../../utils/metrics'); +jest.mock('../../utils/metrics'); + +beforeAll(() => { + process.env = Object.assign(process.env, { + SEND_METRIC: 'Yes', + METRICS_ANONYMOUS_UUID: 'uuid', + SOLUTION_ID: 'SOMock', + SOLUTION_VERSION: 'v1.0.0', + AWS_REGION: 'us-east-1', + IS_SECONDARY_REGION: 'No', + NOTIFICATION_TOPIC: 'topic-arn', + SNS_MESSAGE_PREFERENCE: 'INFO_AND_ERRORS', + BACKUP_TABLE_NAME: 'table-name', + TYPE_TIMESTAMP: 'timestamp-type' + }); +}); + +describe('workflow-message-broker', function () { + beforeEach(() => { + jest.resetModules(); + for (const mockFn in mockSns) { + mockSns[mockFn].mockReset(); + } + + for (const mockFn in mockDocClient) { + mockDocClient[mockFn].mockReset(); + } + }); + + it('Handles an error and publishes to SNS', async function () { + mockSns.publish.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + Metrics.sendAnonymousMetric.mockImplementationOnce(async (x, y, z) => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const errorCause = { message: 'error-message' }; + const event = { + Context: { + Execution: { StartTime: new Date(0).toISOString() }, + StateMachine: { Id: 'id', StartTime: new Date(), Name: 'StateMachineName' }, + State: { Name: 'WorkflowErrorHandlerLambda' } + }, + Input: { Error: 'Error', Cause: JSON.stringify(errorCause) } + }; + const lambda = require('../message-broker'); + await lambda.handler(event); + + expect(mockSns.publish.mock.calls[0][0]).toEqual({ + TopicArn: 'topic-arn', + Message: `An unexpected error occurred while executing the StateMachineName for this solution:\n${JSON.stringify(errorCause, null, 2)}\n\nPlease check the state machine's task logs for additional information\n\nExecution details:\n${JSON.stringify(event.Context, null, 2)}` + }); + }); + + it('Handles a cleanup request and publishes to SNS', async function () { + mockSns.publish.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockDocClient.put.mockImplementation(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + Metrics.sendAnonymousMetric.mockImplementationOnce(async (x, y, z) => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { StartTime: new Date(0).toISOString() }, + StateMachine: { Id: 'id', StartTime: new Date(), Name: 'ExportWorkflow-HASH' }, + State: { Name: 'WorkflowCleanupLambda', EnteredTime: new Date(1000).toISOString() } + }, + Input: { ExportTimestamp: new Date().getTime() } + }; + const lambda = require('../message-broker'); + await lambda.handler(event); + + expect(mockSns.publish.mock.calls[0][0]).toEqual({ + TopicArn: 'topic-arn', + Message: `Workflow (ExportWorkflow-HASH) completed successfully. Execution took 1 second(s).\n\nExecution details:\n${JSON.stringify(event.Context, null, 2)}` + }); + + expect(mockDocClient.put.mock.calls[0][0]).toEqual({ + TableName: 'table-name', + Item: { + id: 'latest-export-timestamp', + type: 'timestamp-type', + latestExportTimestamp: event.Input.ExportTimestamp + } + }); + }); + + it('NOOP for unknown state name', async function () { + const event = { + Context: { + Execution: { StartTime: new Date(0).toISOString() }, + StateMachine: { Id: 'id', StartTime: new Date(), Name: 'StateMachineName' }, + State: { Name: 'UNKNOWN', EnteredTime: new Date(1000).toISOString() } + }, + Input: {} + }; + const lambda = require('../message-broker'); + await lambda.handler(event); + }); + + it('Handles an error and publishes to SNS when an error object is not passed', async function () { + mockSns.publish.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + Metrics.sendAnonymousMetric.mockImplementationOnce(async (x, y, z) => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { StartTime: new Date(0).toISOString() }, + StateMachine: { Id: 'id', StartTime: new Date(), Name: 'StateMachineName' }, + State: { Name: 'WorkflowErrorHandlerLambda' } + }, + Input: {} + }; + const lambda = require('../message-broker'); + await lambda.handler(event); + + expect(mockSns.publish.mock.calls[0][0]).toEqual({ + TopicArn: 'topic-arn', + Message: `An unexpected error occurred while executing the StateMachineName for this solution:\n"Unknown"\n\nPlease check the state machine's task logs for additional information\n\nExecution details:\n${JSON.stringify(event.Context, null, 2)}` + }); + }); + + it('Handles an error and publishes to SNS when a string is passed as the error cause', async function () { + mockSns.publish.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + Metrics.sendAnonymousMetric.mockImplementationOnce(async (x, y, z) => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { StartTime: new Date(0).toISOString() }, + StateMachine: { Id: 'id', StartTime: new Date(), Name: 'StateMachineName' }, + State: { Name: 'WorkflowErrorHandlerLambda' } + }, + Input: { Error: 'Error', Cause: 'some-error-cause' } + }; + const lambda = require('../message-broker'); + await lambda.handler(event); + + expect(mockSns.publish.mock.calls[0][0]).toEqual({ + TopicArn: 'topic-arn', + Message: `An unexpected error occurred while executing the StateMachineName for this solution:\n"some-error-cause"\n\nPlease check the state machine's task logs for additional information\n\nExecution details:\n${JSON.stringify(event.Context, null, 2)}` + }); + }); +}); \ No newline at end of file diff --git a/source/workflow-export/backup-table-cleanup.js b/source/workflow-export/backup-table-cleanup.js new file mode 100644 index 0000000..afa8f44 --- /dev/null +++ b/source/workflow-export/backup-table-cleanup.js @@ -0,0 +1,197 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const docClient = new AWS.DynamoDB.DocumentClient(); +const sqs = new AWS.SQS(); +const uuid = require('uuid'); +const { BACKUP_TABLE_NAME, QUEUE_URL } = process.env; +const oneMinuteInMS = 60 * 1000; +const { sleep } = require('../utils/helper-functions'); + +/** + * Cleans up the Backup Table by identifying items that were not updated during the most recent export and removing them + * @param {object} event + */ +exports.handler = async (event, lambdaContext) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const { Context, Input } = event; + const result = { ExportTimestamp: Input.ExportTimestamp, NumItemsAddedToQueue: (Input.NumItemsAddedToQueue || 0) }; + + switch (Context.State.Name) { + case 'BackupTableCleanup: Find Items': + const findItemsResult = await findItemsToCleanup(Input, lambdaContext); + if (findItemsResult.lastEvaluatedKey) { + result.lastEvaluatedKey = findItemsResult.lastEvaluatedKey; + } else { + // Empty string will make us exit the loop in the step function workflow + result.lastEvaluatedKey = ''; + } + + result.NumItemsAddedToQueue += findItemsResult.numItemsAddedToQueue; + break; + case 'BackupTableCleanup: Remove Items': + result.IsQueueEmpty = await readMessagesInQueue(lambdaContext); + break; + default: + console.log(`Unknown State Name: ${Context.State.Name}`); + break; + } + + return { result }; +}; + +/** + * Scans the backup table and identifies items for which the 'lastConfirmedInUserPool' was not updated + * @param {object} Input Lambda input + * @param {object} lambdaContext Lambda context object + */ +const findItemsToCleanup = async (Input, lambdaContext) => { + let numItemsAddedToQueue = 0; + const scanParams = { + TableName: BACKUP_TABLE_NAME, + FilterExpression: 'attribute_exists(lastConfirmedInUserPool) and lastConfirmedInUserPool < :ts', + ProjectionExpression: 'id,#type', + ExpressionAttributeValues: { + ':ts': Input.ExportTimestamp + }, + ExpressionAttributeNames: { + '#type': 'type' + } + }; + + if (Input.lastEvaluatedKey) { + scanParams.ExclusiveStartKey = Input.lastEvaluatedKey; + } + + do { + console.log('Scanning table...'); + const scanResponse = await docClient.scan(scanParams).promise(); + console.log(`Retrieved ${scanResponse.Count} item(s). Scanned ${scanResponse.ScannedCount} item(s)`); + + if (scanResponse.Count > 0) { + await sendItemsToQueue(scanResponse.Items); + numItemsAddedToQueue += scanResponse.Count; + } + + // Check if there are additional items in the backup table to scan + delete scanParams.ExclusiveStartKey; + if (scanResponse.LastEvaluatedKey) { + scanParams.ExclusiveStartKey = scanResponse.LastEvaluatedKey; + } + } while (lambdaContext.getRemainingTimeInMillis() > oneMinuteInMS && scanParams.ExclusiveStartKey); + + return { lastEvaluatedKey: scanParams.ExclusiveStartKey, numItemsAddedToQueue }; +}; + +/** + * Adds the array of items to the export workflow queue so they can be removed + * @param {object[]} items Array of items to be removed from the backup table + */ +const sendItemsToQueue = async (items) => { + while (items.length > 0) { + const sendMessageBatchParams = { + QueueUrl: QUEUE_URL, + Entries: items.splice(0, 10).map(item => { + return { + Id: uuid.v4(), + MessageBody: JSON.stringify({ Action: 'DELETE', Key: item }) + }; + }) + }; + + console.log(`Adding batch of ${sendMessageBatchParams.Entries.length} message(s) to the Export Workflow queue`); + await sqs.sendMessageBatch(sendMessageBatchParams).promise(); + console.log('Message(s) added to the Export Workflow queue'); + } +}; + +/** + * Reads messages off the export workflow queue + * @param {object} lambdaContext Lambda context object + */ +const readMessagesInQueue = async (lambdaContext) => { + let queueEmpty = false; + let numEmptyResponses = 0; + const receiveMessageParams = { + QueueUrl: QUEUE_URL, + MaxNumberOfMessages: 10, + WaitTimeSeconds: 5 + }; + + do { + console.log(`Receiving messages from queue: ${JSON.stringify(receiveMessageParams)}`); + const response = await sqs.receiveMessage(receiveMessageParams).promise(); + if (response.Messages && response.Messages.length > 0) { + numEmptyResponses = 0; + console.log(`Received ${response.Messages.length} message(s)`); + await removeItemsFromBackupTable(response.Messages); + } else { + console.log('Received 0 messages'); + numEmptyResponses++; + if (numEmptyResponses >= 5) { + queueEmpty = true; + } else { + await sleep(1); + } + } + } while (lambdaContext.getRemainingTimeInMillis() > oneMinuteInMS && !queueEmpty); + + return queueEmpty; +}; + +/** + * Removes items from the backup table + * @param {object[]} messages An array of messages that were read off the export table queue + */ +const removeItemsFromBackupTable = async (messages) => { + const batchWriteParams = { + RequestItems: { + [BACKUP_TABLE_NAME]: messages.map(msg => { + const msgBody = JSON.parse(msg.Body); + return { + DeleteRequest: { + Key: msgBody.Key + } + }; + }) + } + }; + + let resp; + do { + console.log(`Going to delete ${batchWriteParams.RequestItems[BACKUP_TABLE_NAME].length} records(s) from ${BACKUP_TABLE_NAME}`); + resp = await docClient.batchWrite(batchWriteParams).promise(); + if (resp.UnprocessedItems[BACKUP_TABLE_NAME] !== undefined && resp.UnprocessedItems[BACKUP_TABLE_NAME].length > 0) { + console.log(`Detected ${resp.UnprocessedItems[BACKUP_TABLE_NAME].length} unprocessed item(s). Waiting 100 ms then processing again`); + batchWriteParams.RequestItems[BACKUP_TABLE_NAME] = resp.UnprocessedItems[BACKUP_TABLE_NAME]; + await sleep(0, 100, false); + } + } while (resp.UnprocessedItems[BACKUP_TABLE_NAME] !== undefined && resp.UnprocessedItems[BACKUP_TABLE_NAME].length > 0); + + console.log('Item(s) removed from the backup table'); + + await deleteMessagesFromQueue(messages); +}; + +/** + * Removes messages from the export workflow queue + * @param {object[]} messages An array of messages to remove from the queue + */ +const deleteMessagesFromQueue = async (messages) => { + const deleteMessageBatchParams = { QueueUrl: QUEUE_URL }; + deleteMessageBatchParams.Entries = messages.map(msg => { + return { + Id: msg.MessageId, + ReceiptHandle: msg.ReceiptHandle + }; + }); + + console.log(`Deleting a batch of ${deleteMessageBatchParams.Entries.length} message(s) from the queue`); + await sqs.deleteMessageBatch(deleteMessageBatchParams).promise(); + console.log('Message batch deleted'); +}; diff --git a/source/workflow-export/check-user-pool-config.js b/source/workflow-export/check-user-pool-config.js new file mode 100644 index 0000000..09380bb --- /dev/null +++ b/source/workflow-export/check-user-pool-config.js @@ -0,0 +1,39 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const { PRIMARY_USER_POOL_ID } = process.env; + +const AWS = require('aws-sdk'); +const cognitoISP = new AWS.CognitoIdentityServiceProvider(); + +/** + * Checks the configuration of the primary user pool to ensure it is supported by the solution + * @param {object} event + */ +exports.handler = async (event) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const result = {}; + + const describeUserPoolParams = { UserPoolId: PRIMARY_USER_POOL_ID }; + console.log(`Describing user pool: ${JSON.stringify(describeUserPoolParams)}`); + const describeUserPoolResponse = await cognitoISP.describeUserPool(describeUserPoolParams).promise(); + console.log(`Describe user pool response: ${JSON.stringify(describeUserPoolResponse, null, 2)}`); + + if (describeUserPoolResponse.UserPool.MfaConfiguration && describeUserPoolResponse.UserPool.MfaConfiguration !== 'OFF'){ + throw new Error(`User Pools with MFA enabled are not supported. The user pool\'s MFA configuration is set to ${describeUserPoolResponse.UserPool.MfaConfiguration}`); + } + + if (describeUserPoolResponse.UserPool.UsernameAttributes){ + if (describeUserPoolResponse.UserPool.UsernameAttributes.length > 1){ + throw new Error(`This solution does not support user pools for which more than one username attribute is allowed. Configured username attributes: ${JSON.stringify(describeUserPoolResponse.UserPool.UsernameAttributes)}`); + } + result.UsernameAttributes = JSON.stringify(describeUserPoolResponse.UserPool.UsernameAttributes); + } + + console.log(`Result: ${JSON.stringify(result)}`); + return { result: result }; +}; diff --git a/source/workflow-export/export-group.js b/source/workflow-export/export-group.js new file mode 100644 index 0000000..6c353e7 --- /dev/null +++ b/source/workflow-export/export-group.js @@ -0,0 +1,56 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const { BACKUP_TABLE_NAME, AWS_REGION, TYPE_GROUP } = process.env; + +/** + * Exports the supplied group name to the backup table + * @param {object} event + */ +exports.handler = async (event) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const { groupName, groupDescription, groupPrecedence, groupLastModifiedDate, exportTimestamp } = event; + + await exportGroupName(groupName, groupDescription, groupPrecedence, groupLastModifiedDate, exportTimestamp); + const output = { + exportTimestamp: exportTimestamp, + groupName: groupName, + UsernameAttributes: event.UsernameAttributes + }; + console.log(`Output: ${JSON.stringify(output)}`); + return output; +}; + +/** + * Puts/updates an item in the backup table for the supplied group that was found in the user pool during the latest export + * @param {string} groupName The name of the group + * @param {string} groupDescription The description of the group + * @param {number} groupPrecedence The precedence of the group + * @param {string} groupLastModifiedDate The ISO timestamp for when the group was last modified + * @param {number} exportTimestamp The timestamp for the latest export + */ +const exportGroupName = async function exportGroupNameToBackupTable(groupName, groupDescription, groupPrecedence, groupLastModifiedDate, exportTimestamp) { + const docClient = new AWS.DynamoDB.DocumentClient(); + const putParams = { + TableName: BACKUP_TABLE_NAME, + Item: { + id: `GROUP-${groupName}`, + type: TYPE_GROUP, + groupName, + groupDescription, + groupPrecedence, + groupLastModifiedDate, + lastConfirmedInUserPool: exportTimestamp, + lastUpdatedRegion: AWS_REGION + } + }; + + console.log(`Putting group in table: ${JSON.stringify(putParams)}`); + await docClient.put(putParams).promise(); + console.log('Group put successfully'); +}; diff --git a/source/workflow-export/export-users-in-group.js b/source/workflow-export/export-users-in-group.js new file mode 100644 index 0000000..f3dca7e --- /dev/null +++ b/source/workflow-export/export-users-in-group.js @@ -0,0 +1,175 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const cognitoISP = new AWS.CognitoIdentityServiceProvider(); +const docClient = new AWS.DynamoDB.DocumentClient(); +const ONE_MINUTE = 60000; +const { sleep, getExponentialBackoffTimeInMS } = require('../utils/helper-functions'); +const { COGNITO_TPS, USER_POOL_ID, BACKUP_TABLE_NAME, AWS_REGION } = process.env; +let poolUsernameAttributes = []; + +/** + * Exports users in the supplied group name to the backup table + * @param {object} event + */ +exports.handler = async (event, context) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const cognitoTPS = parseInt(COGNITO_TPS, 10); + if (isNaN(cognitoTPS)) { + throw new Error(`Unable to parse a number from the COGNITO_TPS value (${COGNITO_TPS})`); + } + + const { groupName, exportTimestamp } = event; + let { listUsersInGroupNextToken } = event; + let usersProcessed = 0; + + let listUsersInGroupParams = { + UserPoolId: USER_POOL_ID, + GroupName: groupName + }; + + if (listUsersInGroupNextToken) { + listUsersInGroupParams.NextToken = listUsersInGroupNextToken; + } + + if (event.UsernameAttributes) { + poolUsernameAttributes = JSON.parse(event.UsernameAttributes); + } + + do { + let cognitoApiCallCount = 0; + let currentTime = new Date().getTime(); + const oneSecondFromNow = currentTime + 1000; + + do { + let numAttempts = 1; + + try { + console.log(`Listing users in group: ${JSON.stringify(listUsersInGroupParams)}`); + const response = await cognitoISP.listUsersInGroup(listUsersInGroupParams).promise(); + cognitoApiCallCount++; + + if (response.Users && response.Users.length > 0) { + const nonExternalUsers = response.Users.filter(user => user.UserStatus !== 'EXTERNAL_PROVIDER'); + + if (nonExternalUsers.length > 0) { + const numUsersReturned = nonExternalUsers.length; + console.log(`Number of users returned: ${numUsersReturned}`); + await exportGroupMembers(groupName, nonExternalUsers, exportTimestamp); + usersProcessed += numUsersReturned; + } else { + console.log('No users were returned'); + } + } else { + console.log('No users were returned'); + } + + // Check to see if there are more users to fetch + response.NextToken ? listUsersInGroupParams.NextToken = response.NextToken : delete listUsersInGroupParams.NextToken; + + currentTime = new Date().getTime(); + } catch (err) { + console.error(err); + if (context.getRemainingTimeInMillis() > ONE_MINUTE && err.retryable) { + const sleepTimeInMs = getExponentialBackoffTimeInMS(100, numAttempts, ONE_MINUTE, false); + numAttempts++; + console.log(`Sleeping for ${sleepTimeInMs} milliseconds and will list users again. That will be attempt #${numAttempts}`); + await sleep(0, sleepTimeInMs); + } else { + throw err; + } + } + } while (listUsersInGroupParams.NextToken && (cognitoApiCallCount < cognitoTPS) && (currentTime < oneSecondFromNow) && (context.getRemainingTimeInMillis() > ONE_MINUTE)); + + if (listUsersInGroupParams.NextToken && (cognitoApiCallCount >= cognitoTPS) && (currentTime < oneSecondFromNow)) { + const waitTime = (oneSecondFromNow - currentTime); + console.log(`Cognito transactions per second limit (${cognitoTPS}) reached. Waiting for ${(oneSecondFromNow - currentTime)}ms before proceeding`); + await sleep(0, waitTime); + } + } while (listUsersInGroupParams.NextToken && context.getRemainingTimeInMillis() > ONE_MINUTE); + + const output = { exportTimestamp: exportTimestamp, groupName: groupName, listUsersInGroupNextToken: listUsersInGroupParams.NextToken }; + output.listUsersInGroupNextToken ? output.processedAllUsersInGroup = 'No' : output.processedAllUsersInGroup = 'Yes'; + console.log(`Number of users processed total: ${usersProcessed}`); + console.log(`Output: ${JSON.stringify(output)}`); + return output; +}; + +/** + * Puts/updates group membership records for the users in the supplied array + * @param {string} groupName The name of the group the users are in + * @param {object[]} users An array of user objects that are members of the supplied group + * @param {number} latestTimestamp The timestamp for the latest export + */ +const exportGroupMembers = async function syncUsersToGroupsTable(groupName, users, latestTimestamp) { + const batchWriteMax = 25; + while (users.length > 0) { + const batchWriteParams = { + RequestItems: {} + }; + + batchWriteParams.RequestItems[BACKUP_TABLE_NAME] = users.splice(0, batchWriteMax).map(user => { + let subValue; + const subAttribute = user.Attributes.find(attr => attr.Name === 'sub'); + if (subAttribute) { + subValue = subAttribute.Value; + } + + if (!subValue) { + throw new Error('Unable to determine the sub attribute for user'); + } + + // The pseudoUsername will be used as the username for the user import + // CSV when importing users during the import workflow + let pseudoUsername; + if (poolUsernameAttributes.length === 0) { + pseudoUsername = user.Username; + } else if (poolUsernameAttributes.length === 1) { + const pseudoUsernameAttribute = user.Attributes.find(attr => attr.Name === poolUsernameAttributes[0]); + pseudoUsername = pseudoUsernameAttribute.Value; + } else { + // Narrow down which attribute to use as pseudoUsername + const possibleAttributes = user.Attributes.filter(attr => poolUsernameAttributes.includes(attr.Name) && attr.Value.trim() !== ''); + if (possibleAttributes.length === 1) { + pseudoUsername = possibleAttributes[0].Value; + } + } + + if (!pseudoUsername) { + throw new Error('Unable to determine the pseudoUsername for the user'); + } + + return { + PutRequest: { + Item: { + id: `GROUP_MEMBER-${groupName}`, + type: `GROUP_MEMBER-${subValue}`, + groupUser: user.Username, + groupPseudoUsername: pseudoUsername, + groupName: groupName, + lastConfirmedInUserPool: latestTimestamp, + lastUpdatedRegion: AWS_REGION + } + } + }; + }); + + let response; + do { + console.log(`Writing ${batchWriteParams.RequestItems[BACKUP_TABLE_NAME].length} user(s)`); + response = await docClient.batchWrite(batchWriteParams).promise(); + + if (response.UnprocessedItems[BACKUP_TABLE_NAME] !== undefined && response.UnprocessedItems[BACKUP_TABLE_NAME].length > 0) { + console.log(`Detected ${response.UnprocessedItems[BACKUP_TABLE_NAME].length} unprocessed item(s). Waiting 100 ms then processing again`); + batchWriteParams.RequestItems[BACKUP_TABLE_NAME] = response.UnprocessedItems[BACKUP_TABLE_NAME]; + await sleep(0, 100, false); + } + } while (response.UnprocessedItems[BACKUP_TABLE_NAME] !== undefined && response.UnprocessedItems[BACKUP_TABLE_NAME].length > 0); + console.log('Users written'); + } +}; diff --git a/source/workflow-export/export-users.js b/source/workflow-export/export-users.js new file mode 100644 index 0000000..0cb6757 --- /dev/null +++ b/source/workflow-export/export-users.js @@ -0,0 +1,237 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const DynamoDB = require('aws-sdk/clients/dynamodb'); +const cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider(); +const documentClient = new DynamoDB.DocumentClient(); + +const { AWS_REGION, USER_POOL_ID, TABLE_NAME, COGNITO_TPS, TYPE_USER } = process.env; +const ONE_MINUTE = 60 * 1000; +const { sleep, getExponentialBackoffTimeInMS } = require('../utils/helper-functions'); +let poolUsernameAttributes = []; + +/** + * Exports user profiles to the backup table + * @return {Promise<{ paginationToken: string, ExportTimestamp: number }>} + */ +exports.handler = async (event, context) => { + console.log(`Requested event: ${JSON.stringify(event, null, 2)}`); + const cognitoTPS = parseInt(COGNITO_TPS, 10); + if (isNaN(cognitoTPS)) { + throw new Error(`Unable to parse a number from the COGNITO_TPS value (${COGNITO_TPS})`); + } + + const output = { + paginationToken: '', + UsernameAttributes: event.UsernameAttributes, + ExportTimestamp: -1 + }; + + if (event.paginationToken) { + // This function was invoked a subsequent time within an execution of the ExportWorkflow + // Retrieve the ExportTimestamp from the event instead of creating a new value + output.paginationToken = event.paginationToken; + output.ExportTimestamp = event.ExportTimestamp; + } else { + output.ExportTimestamp = new Date().getTime(); + } + + if (event.UsernameAttributes) { + poolUsernameAttributes = JSON.parse(event.UsernameAttributes); + } + + try { + let totalUserProcessedCount = 0; + let paginationToken = null; + + if (output.paginationToken && output.paginationToken !== '') { + paginationToken = output.paginationToken; + } + + do { + let cognitoApiCallCount = 0; + let currentTime = new Date().getTime(); + let oneSecondFromNow = currentTime + 1000; + + do { + const cognitoResult = await listCognitoUsers(paginationToken, context); + cognitoApiCallCount++; + + if (cognitoResult.users && cognitoResult.users.length > 0) { + console.log(`Retrieved ${cognitoResult.users.length} user(s)`); + totalUserProcessedCount += cognitoResult.users.length; + const batchWriteUsersResponse = await batchWriteUsers(cognitoResult.users, output.ExportTimestamp, cognitoTPS, oneSecondFromNow, cognitoApiCallCount); + cognitoApiCallCount = batchWriteUsersResponse.cognitoApiCallCount; + oneSecondFromNow = batchWriteUsersResponse.oneSecondFromNow; + } else { + console.log('No users returned'); + } + + paginationToken = cognitoResult.paginationToken; + currentTime = new Date().getTime(); + } while (paginationToken && (cognitoApiCallCount < cognitoTPS) && (currentTime < oneSecondFromNow) && (context.getRemainingTimeInMillis() > ONE_MINUTE)); + + if (paginationToken && (cognitoApiCallCount >= cognitoTPS) && (currentTime < oneSecondFromNow)) { + const waitTime = (oneSecondFromNow - currentTime); + console.log(`Cognito transactions per second limit (${cognitoTPS}) reached. Waiting for ${(oneSecondFromNow - currentTime)}ms before proceeding`); + await sleep(0, waitTime); + } + } while (paginationToken && context.getRemainingTimeInMillis() > ONE_MINUTE); + + console.log(`Successfully processed ${totalUserProcessedCount} user(s)`); + output.paginationToken = paginationToken ? paginationToken : ''; + + console.log(`Output: ${JSON.stringify(output, null, 2)}`); + return { + result: output, + totalUserProcessedCount + }; + } catch (error) { + console.error(error); + throw error; + } +}; + +/** + * List Cognito users. + * @param {string} paginationToken - Pagination token to get next users + * @param {object} context - Lambda context + * @return {Promise<{ users: AWS.CognitoIdentityServiceProvider.UsersListType, paginationToken: string }>} - Cognito users and pagination token + */ +async function listCognitoUsers(paginationToken, context) { + let cognitoResponse; + + do { + let numAttempts = 1; + + try { + const listUsersParams = { + UserPoolId: USER_POOL_ID + }; + + if (paginationToken && paginationToken !== '') { + listUsersParams.PaginationToken = paginationToken; + } + + console.log(`Listing users: ${JSON.stringify(listUsersParams)}`); + cognitoResponse = await cognitoIdentityServiceProvider.listUsers(listUsersParams).promise(); + } catch (err) { + console.error(err); + + if (context.getRemainingTimeInMillis() > ONE_MINUTE && err.retryable) { + const sleepTimeInMs = getExponentialBackoffTimeInMS(100, numAttempts, ONE_MINUTE, false); + numAttempts++; + console.log(`Sleeping for ${sleepTimeInMs} milliseconds and will list users again. That will be attempt #${numAttempts}`); + await sleep(0, sleepTimeInMs); + } else { + throw err; + } + } + } while (!cognitoResponse && context.getRemainingTimeInMillis() > ONE_MINUTE); + + if (cognitoResponse.Users && cognitoResponse.Users.length > 0) { + return { + users: cognitoResponse.Users.filter(user => user.UserStatus !== 'EXTERNAL_PROVIDER'), + paginationToken: cognitoResponse.PaginationToken + }; + } + + return { + users: [], + paginationToken: undefined + }; +} + +/** + * Batch write users into DynamoDB table. + * @param {AWS.CognitoIdentityServiceProvider.UsersListType} users - An array of Cognito users + * @param {number} userLastConfirmedInUserPoolDate - User last confirmed in user pool date + * @param {number} cognitoTPS Maximum number of Cognito API calls per second + * @param {number} oneSecondFromNow The end time for when the Cognito API call count should be reset + * @param {number} cognitoApiCallCount The number of Cognito API calls within the current second + * @return {Promise<{number, number}>} The current cognitoApiCallCount and oneSecondFromNow values + */ +async function batchWriteUsers(users, userLastConfirmedInUserPoolDate, cognitoTPS, oneSecondFromNow, cognitoApiCallCount) { + const batchWriteMax = 25; + try { + while (users.length > 0) { + const batchWriteParams = { + RequestItems: { [TABLE_NAME]: [] } + }; + + let usersToWrite = users.splice(0, batchWriteMax); + + for (let i = 0; i < usersToWrite.length; i++) { + let user = usersToWrite[i]; + + let subValue; + const subAttribute = user.Attributes.find(attr => attr.Name === 'sub'); + if (subAttribute) { + subValue = subAttribute.Value; + } + + if (!subValue) { + throw new Error('Unable to determine the sub attribute for user'); + } + + // The pseudoUsername will be used as the username for the user import + // CSV when importing users during the import workflow + let pseudoUsername; + if (poolUsernameAttributes.length === 0) { + pseudoUsername = user.Username; + } else if (poolUsernameAttributes.length === 1) { + const pseudoUsernameAttribute = user.Attributes.find(attr => attr.Name === poolUsernameAttributes[0]); + pseudoUsername = pseudoUsernameAttribute.Value; + } else { + // Narrow down which attribute to use as pseudoUsername + const possibleAttributes = user.Attributes.filter(attr => poolUsernameAttributes.includes(attr.Name) && attr.Value.trim() !== ''); + if (possibleAttributes.length === 1) { + pseudoUsername = possibleAttributes[0].Value; + } + } + + if (!pseudoUsername) { + throw new Error('Unable to determine the pseudoUsername for the user'); + } + + batchWriteParams.RequestItems[TABLE_NAME].push({ + PutRequest: { + Item: { + id: `USER-${subValue}`, + type: TYPE_USER, + username: user.Username, + pseudoUsername: pseudoUsername, + userAttributes: user.Attributes, + userEnabled: user.Enabled, + userStatus: user.UserStatus, + lastConfirmedInUserPool: userLastConfirmedInUserPoolDate, + lastUpdatedRegion: AWS_REGION + } + } + }); + } + + let batchResult; + do { + console.log(`Writing ${batchWriteParams.RequestItems[TABLE_NAME].length} item(s) to ${TABLE_NAME}`); + batchResult = await documentClient.batchWrite(batchWriteParams).promise(); + + if (batchResult.UnprocessedItems[TABLE_NAME] !== undefined && batchResult.UnprocessedItems[TABLE_NAME].length > 0) { + console.log(`Detected ${batchResult.UnprocessedItems[TABLE_NAME].length} unprocessed item(s). Waiting 100 ms then processing again`); + batchWriteParams.RequestItems[TABLE_NAME] = batchResult.UnprocessedItems[TABLE_NAME]; + await sleep(0, 100, false); + } + } while (batchResult.UnprocessedItems[TABLE_NAME] !== undefined && batchResult.UnprocessedItems[TABLE_NAME].length > 0); + } + } catch (error) { + console.error('Error occurred while batch writing items into dynamodb.'); + throw error; + } + + return { cognitoApiCallCount, oneSecondFromNow }; +} diff --git a/source/workflow-export/list-groups.js b/source/workflow-export/list-groups.js new file mode 100644 index 0000000..417825f --- /dev/null +++ b/source/workflow-export/list-groups.js @@ -0,0 +1,59 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const cognitoISP = new AWS.CognitoIdentityServiceProvider(); +const HelperFunctions = require('../utils/helper-functions'); + +/** + * Lists group in a user pool and returns group details so they can be processed by the Export Workflow + * @param {object} event Event request payload + */ +exports.handler = async (event) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const requiredEnvironmentVariables = ['USER_POOL_ID']; + const requiredEventProperties = ['ExportTimestamp']; + const optionalEventProperties = ['ListGroupsNextToken']; + const functionData = HelperFunctions.getFunctionData(requiredEnvironmentVariables, requiredEventProperties, optionalEventProperties, event); + + const groups = []; + const listGroupsParams = { + UserPoolId: functionData.USER_POOL_ID + }; + + if (functionData.ListGroupsNextToken) { + listGroupsParams.NextToken = functionData.ListGroupsNextToken; + } + + console.log(`Listing groups: ${JSON.stringify(listGroupsParams)}`); + const response = await cognitoISP.listGroups(listGroupsParams).promise(); + + if (response.Groups) { + console.log(`Number of groups returned: ${response.Groups.length}`); + groups.push(...response.Groups.map(group => { + const returnGroup = { + groupName: group.GroupName, + groupLastModifiedDate: group.LastModifiedDate, + UsernameAttributes: event.UsernameAttributes || '[]' + }; + returnGroup.groupDescription = group.Description ? group.Description : ''; + returnGroup.groupPrecedence = group.Precedence !== undefined ? group.Precedence : -1; + + return returnGroup; + })); + } else { + console.log('No groups were returned'); + } + + const output = { ExportTimestamp: functionData.ExportTimestamp, NumGroupsToProcess: groups.length, Groups: [...groups], ListGroupsNextToken: response.NextToken }; + + // Check to see if there are more groups to fetch + output.ListGroupsNextToken ? output.ProcessedAllGroups = 'No' : output.ProcessedAllGroups = 'Yes'; + + console.log(`Output: ${JSON.stringify(output)}`); + return output; +}; diff --git a/source/workflow-export/package-lock.json b/source/workflow-export/package-lock.json new file mode 100644 index 0000000..9cad3e4 --- /dev/null +++ b/source/workflow-export/package-lock.json @@ -0,0 +1,4823 @@ +{ + "name": "workflow-sync", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.11.0.tgz", + "integrity": "sha512-mkLq8nwaXmDtFmRkQ8ED/eA2CnVw4zr7dCztKalZXBvdK5EeNUAesrrwUqjQEzFgomJssayzB0aqlOsP1vGLqg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-module-transforms": "^7.11.0", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.11.0", + "@babel/types": "^7.11.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "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/generator": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.11.0.tgz", + "integrity": "sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "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-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz", + "integrity": "sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz", + "integrity": "sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/template": "^7.10.4", + "@babel/types": "^7.11.0", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", + "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "dev": true, + "requires": { + "@babel/types": "^7.11.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "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.11.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.0.tgz", + "integrity": "sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw==", + "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.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@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/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.11.0.tgz", + "integrity": "sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.11.0", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/parser": "^7.11.0", + "@babel/types": "^7.11.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", + "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "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 + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@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" + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/console": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.2.0.tgz", + "integrity": "sha512-mXQfx3nSLwiHm1i7jbu+uvi+vvpVjNGzIQYLCfsat9rapC+MJkS4zBseNrgJE0vU921b3P67bQzhduphjY3Tig==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.2.0", + "jest-util": "^26.2.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.2.2.tgz", + "integrity": "sha512-UwA8gNI8aeV4FHGfGAUfO/DHjrFVvlBravF1Tm9Kt6qFE+6YHR47kFhgdepOFpADEKstyO+MVdPvkV6/dyt9sA==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/reporters": "^26.2.2", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.2", + "@jest/types": "^26.2.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.2.0", + "jest-config": "^26.2.2", + "jest-haste-map": "^26.2.2", + "jest-message-util": "^26.2.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.2.2", + "jest-resolve-dependencies": "^26.2.2", + "jest-runner": "^26.2.2", + "jest-runtime": "^26.2.2", + "jest-snapshot": "^26.2.2", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "jest-watcher": "^26.2.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.2.0.tgz", + "integrity": "sha512-oCgp9NmEiJ5rbq9VI/v/yYLDpladAAVvFxZgNsnJxOETuzPZ0ZcKKHYjKYwCtPOP1WCrM5nmyuOhMStXFGHn+g==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0" + } + }, + "@jest/fake-timers": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.2.0.tgz", + "integrity": "sha512-45Gfe7YzYTKqTayBrEdAF0qYyAsNRBzfkV0IyVUm3cx7AsCWlnjilBM4T40w7IXT5VspOgMPikQlV0M6gHwy/g==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.2.0", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0" + } + }, + "@jest/globals": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.2.0.tgz", + "integrity": "sha512-Hoc6ScEIPaym7RNytIL2ILSUWIGKlwEv+JNFof9dGYOdvPjb2evEURSslvCMkNuNg1ECEClTE8PH7ULlMJntYA==", + "dev": true, + "requires": { + "@jest/environment": "^26.2.0", + "@jest/types": "^26.2.0", + "expect": "^26.2.0" + } + }, + "@jest/reporters": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.2.2.tgz", + "integrity": "sha512-7854GPbdFTAorWVh+RNHyPO9waRIN6TcvCezKVxI1khvFq9YjINTW7J3WU+tbR038Ynn6WjYred6vtT0YmIWVQ==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.2.0", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.2", + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.2.2", + "jest-resolve": "^26.2.2", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.1", + "node-notifier": "^7.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + } + }, + "@jest/source-map": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.1.0.tgz", + "integrity": "sha512-XYRPYx4eEVX15cMT9mstnO7hkHP3krNtKfxUYd8L7gbtia8JvZZ6bMzSwa6IQJENbudTwKMw5R1BePRD+bkEmA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.2.0.tgz", + "integrity": "sha512-kgPlmcVafpmfyQEu36HClK+CWI6wIaAWDHNxfQtGuKsgoa2uQAYdlxjMDBEa3CvI40+2U3v36gQF6oZBkoKatw==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.2.2.tgz", + "integrity": "sha512-SliZWon5LNqV/lVXkeowSU6L8++FGOu3f43T01L1Gv6wnFDP00ER0utV9jyK9dVNdXqfMNCN66sfcyar/o7BNw==", + "dev": true, + "requires": { + "@jest/test-result": "^26.2.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.2.2", + "jest-runner": "^26.2.2", + "jest-runtime": "^26.2.2" + } + }, + "@jest/transform": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.2.2.tgz", + "integrity": "sha512-c1snhvi5wRVre1XyoO3Eef5SEWpuBCH/cEbntBUd9tI5sNYiBDmO0My/lc5IuuGYKp/HFIHV1eZpSx5yjdkhKw==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.2.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.2.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.2.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", + "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "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.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", + "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "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": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/node": { + "version": "14.0.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz", + "integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/prettier": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.2.tgz", + "integrity": "sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA==", + "dev": true + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "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==", + "dev": true + }, + "ajv": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "dev": true, + "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-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "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=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sdk": { + "version": "2.725.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.725.0.tgz", + "integrity": "sha512-Qd/MlxfQC9NpTxFUQ7u2BdsjiwNtbn5oVp04NPfXEc0xyT216TtcIs+jNyiJ9WaH7AgkHouU1BbBcReO8byYzg==", + "dev": true, + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "dependencies": { + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + } + } + }, + "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=", + "dev": true + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "babel-jest": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.2.2.tgz", + "integrity": "sha512-JmLuePHgA+DSOdOL8lPxCgD2LhPPm+rdw1vnxR73PpIrnmKCS2/aBhtkAcxQWuUcW2hBrH8MJ3LKXE7aWpNZyA==", + "dev": true, + "requires": { + "@jest/transform": "^26.2.2", + "@jest/types": "^26.2.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "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": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.2.0.tgz", + "integrity": "sha512-B/hVMRv8Nh1sQ1a3EY8I0n4Y1Wty3NrR5ebOyVT302op+DOAau+xNEImGMsUWOC3++ZlMooCytKz+NgN8aKGbA==", + "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": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "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-preset-jest": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.2.0.tgz", + "integrity": "sha512-R1k8kdP3R9phYQugXeNnK/nvCGlBzG4m3EoIIukC80GXb6wCv2XiwPhK6K9MAkQcMszWBYvl2Wm+yigyXFQqXg==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.2.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "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 + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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 + }, + "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 + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.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 + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "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 + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "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=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "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==", + "dev": true + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "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==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "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=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "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-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "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==", + "dev": true + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emittery": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", + "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", + "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==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "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" + } + }, + "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": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expect": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.2.0.tgz", + "integrity": "sha512-8AMBQ9UVcoUXt0B7v+5/U5H6yiUR87L6eKCfjE3spx7Ya5lF+ebUo37MCFBML2OiLfkX1sxmQOZhIDonyVTkcw==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-regex-util": "^26.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "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-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==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "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" + } + }, + "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 + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "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-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "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==", + "dev": true, + "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-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "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==", + "dev": true, + "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==", + "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" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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==", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "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-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-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.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.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.2.2.tgz", + "integrity": "sha512-EkJNyHiAG1+A8pqSz7cXttoVa34hOEzN/MrnJhYnfp5VHxflVcf2pu3oJSrhiy6LfIutLdWo+n6q63tjcoIeig==", + "dev": true, + "requires": { + "@jest/core": "^26.2.2", + "import-local": "^3.0.2", + "jest-cli": "^26.2.2" + }, + "dependencies": { + "jest-cli": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.2.2.tgz", + "integrity": "sha512-vVcly0n/ijZvdy6gPQiQt0YANwX2hLTPQZHtW7Vi3gcFdKTtif7YpI85F8R8JYy5DFSWz4x1OW0arnxlziu5Lw==", + "dev": true, + "requires": { + "@jest/core": "^26.2.2", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.2.2", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "prompts": "^2.0.1", + "yargs": "^15.3.1" + } + } + } + }, + "jest-changed-files": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.2.0.tgz", + "integrity": "sha512-+RyJb+F1K/XBLIYiL449vo5D+CvlHv29QveJUWNPXuUicyZcq+tf1wNxmmFeRvAU1+TzhwqczSjxnCCFt7+8iA==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "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==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-config": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.2.2.tgz", + "integrity": "sha512-2lhxH0y4YFOijMJ65usuf78m7+9/8+hAb1PZQtdRdgnQpAb4zP6KcVDDktpHEkspBKnc2lmFu+RQdHukUUbiTg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.2.2", + "@jest/types": "^26.2.0", + "babel-jest": "^26.2.2", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.2.0", + "jest-environment-node": "^26.2.0", + "jest-get-type": "^26.0.0", + "jest-jasmine2": "^26.2.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.2.2", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "micromatch": "^4.0.2", + "pretty-format": "^26.2.0" + } + }, + "jest-diff": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.2.0.tgz", + "integrity": "sha512-Wu4Aopi2nzCsHWLBlD48TgRy3Z7OsxlwvHNd1YSnHc7q1NJfrmyCPoUXrTIrydQOG5ApaYpsAsdfnMbJqV1/wQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.2.0" + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.2.0.tgz", + "integrity": "sha512-gHPCaho1twWHB5bpcfnozlc6mrMi+VAewVPNgmwf81x2Gzr6XO4dl+eOrwPWxbkYlgjgrYjWK2xgKnixbzH3Ew==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-util": "^26.2.0", + "pretty-format": "^26.2.0" + } + }, + "jest-environment-jsdom": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.2.0.tgz", + "integrity": "sha512-sDG24+5M4NuIGzkI3rJW8XUlrpkvIdE9Zz4jhD8OBnVxAw+Y1jUk9X+lAOD48nlfUTlnt3lbAI3k2Ox+WF3S0g==", + "dev": true, + "requires": { + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0", + "jsdom": "^16.2.2" + } + }, + "jest-environment-node": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.2.0.tgz", + "integrity": "sha512-4M5ExTYkJ19efBzkiXtBi74JqKLDciEk4CEsp5tTjWGYMrlKFQFtwIVG3tW1OGE0AlXhZjuHPwubuRYY4j4uOw==", + "dev": true, + "requires": { + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-haste-map": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.2.2.tgz", + "integrity": "sha512-3sJlMSt+NHnzCB+0KhJ1Ut4zKJBiJOlbrqEYNdRQGlXTv8kqzZWjUKQRY3pkjmlf+7rYjAV++MQ4D6g4DhAyOg==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.2.0", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.1", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.2.2.tgz", + "integrity": "sha512-Q8AAHpbiZMVMy4Hz9j1j1bg2yUmPa1W9StBvcHqRaKa9PHaDUMwds8LwaDyzP/2fkybcTQE4+pTMDOG9826tEw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.2.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.2.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.2.0", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-runtime": "^26.2.2", + "jest-snapshot": "^26.2.2", + "jest-util": "^26.2.0", + "pretty-format": "^26.2.0", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.2.0.tgz", + "integrity": "sha512-aQdzTX1YiufkXA1teXZu5xXOJgy7wZQw6OJ0iH5CtQlOETe6gTSocaYKUNui1SzQ91xmqEUZ/WRavg9FD82rtQ==", + "dev": true, + "requires": { + "jest-get-type": "^26.0.0", + "pretty-format": "^26.2.0" + } + }, + "jest-matcher-utils": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.2.0.tgz", + "integrity": "sha512-2cf/LW2VFb3ayPHrH36ZDjp9+CAeAe/pWBAwsV8t3dKcrINzXPVxq8qMWOxwt5BaeBCx4ZupVGH7VIgB8v66vQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.2.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.2.0" + } + }, + "jest-message-util": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.2.0.tgz", + "integrity": "sha512-g362RhZaJuqeqG108n1sthz5vNpzTNy926eNDszo4ncRbmmcMRIUAZibnd6s5v2XSBCChAxQtCoN25gnzp7JbQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.2.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.2.0.tgz", + "integrity": "sha512-XeC7yWtWmWByoyVOHSsE7NYsbXJLtJNgmhD7z4MKumKm6ET0si81bsSLbQ64L5saK3TgsHo2B/UqG5KNZ1Sp/Q==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@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": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.2.2.tgz", + "integrity": "sha512-ye9Tj/ILn/0OgFPE/3dGpQPUqt4dHwIocxt5qSBkyzxQD8PbL0bVxBogX2FHxsd3zJA7V2H/cHXnBnNyyT9YoQ==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.2.0", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.2.2.tgz", + "integrity": "sha512-S5vufDmVbQXnpP7435gr710xeBGUFcKNpNswke7RmFvDQtmqPjPVU/rCeMlEU0p6vfpnjhwMYeaVjKZAy5QYJA==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.2.2" + } + }, + "jest-runner": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.2.2.tgz", + "integrity": "sha512-/qb6ptgX+KQ+aNMohJf1We695kaAfuu3u3ouh66TWfhTpLd9WbqcF6163d/tMoEY8GqPztXPLuyG0rHRVDLxCA==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/environment": "^26.2.0", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.2.2", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.2.2", + "jest-leak-detector": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-resolve": "^26.2.2", + "jest-runtime": "^26.2.2", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.1", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.2.2.tgz", + "integrity": "sha512-a8VXM3DxCDnCIdl9+QucWFfQ28KdqmyVFqeKLigHdErtsx56O2ZIdQkhFSuP1XtVrG9nTNHbKxjh5XL1UaFDVQ==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/globals": "^26.2.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.2", + "@jest/types": "^26.2.0", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.2.2", + "jest-haste-map": "^26.2.2", + "jest-message-util": "^26.2.0", + "jest-mock": "^26.2.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.2.2", + "jest-snapshot": "^26.2.2", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.2.0.tgz", + "integrity": "sha512-V7snZI9IVmyJEu0Qy0inmuXgnMWDtrsbV2p9CRAcmlmPVwpC2ZM8wXyYpiugDQnwLHx0V4+Pnog9Exb3UO8M6Q==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.2.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.2.2.tgz", + "integrity": "sha512-NdjD8aJS7ePu268Wy/n/aR1TUisG0BOY+QOW4f6h46UHEKOgYmmkvJhh2BqdVZQ0BHSxTMt04WpCf9njzx8KtA==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.2.0", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.2.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.2.0", + "jest-get-type": "^26.0.0", + "jest-haste-map": "^26.2.2", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-resolve": "^26.2.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.2.0", + "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "jest-util": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.2.0.tgz", + "integrity": "sha512-YmDwJxLZ1kFxpxPfhSJ0rIkiZOM0PQbRcfH0TzJOhqCisCAsI1WcmoQqO83My9xeVA2k4n+rzg2UuexVKzPpig==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-validate": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.2.0.tgz", + "integrity": "sha512-8XKn3hM6VIVmLNuyzYLCPsRCT83o8jMZYhbieh4dAyKLc4Ypr36rVKC+c8WMpWkfHHpGnEkvWUjjIAyobEIY/Q==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.2.0" + }, + "dependencies": { + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.2.0.tgz", + "integrity": "sha512-674Boco4Joe0CzgKPL6K4Z9LgyLx+ZvW2GilbpYb8rFEUkmDGgsZdv1Hv5rxsRpb1HLgKUOL/JfbttRCuFdZXQ==", + "dev": true, + "requires": { + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.2.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.2.1.tgz", + "integrity": "sha512-+XcGMMJDTeEGncRb5M5Zq9P7K4sQ1sirhjdOxsN1462h6lFo9w59bl2LVQmdGEEeU3m+maZCkS2Tcc9SfCHO4A==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "dev": true + }, + "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": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.3.0.tgz", + "integrity": "sha512-zggeX5UuEknpdZzv15+MS1dPYG0J/TftiiNunOeNxSl3qr8Z6cIlQpN0IdJa44z9aFxZRIVqRncvEhQ7X5DtZg==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "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.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "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=", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "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.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "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.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "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 + } + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "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 + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "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 + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.2.tgz", + "integrity": "sha512-ux+n4hPVETuTL8+daJXTOC6uKLgMsl1RYfFv7DKRzyvzBapqco0rZZ9g72ZN8VS6V+gvNYHYa/ofcCY8fkJWsA==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.2.0", + "which": "^2.0.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "optional": true + }, + "uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", + "dev": true, + "optional": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "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" + } + }, + "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 + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.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==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "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" + } + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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-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 + }, + "parse-json": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", + "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "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=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "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" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "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=", + "dev": true + }, + "pretty-format": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", + "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "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" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "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": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "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-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "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 + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", + "dev": true + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "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 + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "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.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "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.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "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 + } + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "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==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "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" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "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-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "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": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "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=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "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.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "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" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==" + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "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=", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "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==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "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==", + "dev": true + }, + "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" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "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.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "dev": true + }, + "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==", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "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=", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/source/workflow-export/package.json b/source/workflow-export/package.json new file mode 100644 index 0000000..8c6e14b --- /dev/null +++ b/source/workflow-export/package.json @@ -0,0 +1,26 @@ +{ + "name": "workflow-export", + "description": "Exports Cognito user profiles, group data and group memberships to the solution's Backup Table in DynamoDB", + "author": { + "name": "aws-solutions-builder" + }, + "license": "Apache-2.0", + "version": "1.0.0", + "private": true, + "dependencies": { + "uuid": "^8.3.0" + }, + "devDependencies": { + "aws-sdk": "*", + "jest": "*" + }, + "scripts": { + "pretest": "npm ci", + "clean": "rm -rf dist/ node_modules/ coverage/", + "test": "jest test/*.spec.js --coverage --silent", + "package:zip": "cd dist && zip -rq package.zip .", + "package:dist": "mkdir dist && rsync -avr ../utils ./dist/ && rsync -avr --exclude=*test* --exclude=*dist* --exclude=*node_modules* ./ ./dist/$npm_package_name && rsync -avr ./node_modules ./dist/$npm_package_name", + "package": "npm run clean && npm ci --production && npm run package:dist && npm run package:zip", + "build": "npm run clean && rm -f package-lock.json && npm install" + } +} diff --git a/source/workflow-export/test/backup-table-cleanup.spec.js b/source/workflow-export/test/backup-table-cleanup.spec.js new file mode 100644 index 0000000..03ad9a1 --- /dev/null +++ b/source/workflow-export/test/backup-table-cleanup.spec.js @@ -0,0 +1,265 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const mockSqs = { + sendMessageBatch: jest.fn(), + receiveMessage: jest.fn(), + deleteMessageBatch: jest.fn() +}; + +const mockDocClient = { + scan: jest.fn(), + batchWrite: jest.fn() +}; + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function () { + return 100000; + } +}; + +jest.mock('aws-sdk', () => { + return { + SQS: jest.fn(() => ({ + sendMessageBatch: mockSqs.sendMessageBatch, + receiveMessage: mockSqs.receiveMessage, + deleteMessageBatch: mockSqs.deleteMessageBatch + })), + DynamoDB: { + DocumentClient: jest.fn(() => ({ + scan: mockDocClient.scan, + batchWrite: mockDocClient.batchWrite + })) + } + }; +}); + +beforeAll(() => { + process.env = Object.assign(process.env, { + QUEUE_URL: 'queue-url', + BACKUP_TABLE_NAME: 'table-name' + }); +}); + +describe('find-items', () => { + beforeEach(() => { + jest.resetModules(); + for (const mockFn in mockSqs) { + mockSqs[mockFn].mockReset(); + } + + for (const mockFn in mockDocClient) { + mockDocClient[mockFn].mockReset(); + } + }); + + it('Should return when no items are returned', async function () { + mockDocClient.scan.mockImplementation(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + State: { Name: 'BackupTableCleanup: Find Items' } + }, + Input: { ExportTimestamp: new Date().getTime() } + }; + + const lambda = require('../backup-table-cleanup'); + const resp = await lambda.handler(event, context); + + expect(resp).toEqual({ + result: { + NumItemsAddedToQueue: 0, + ExportTimestamp: event.Input.ExportTimestamp, + lastEvaluatedKey: '' + } + }); + }); + + it('Should return when some items are returned', async function () { + mockDocClient.scan.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Count: 2, + ScannedCount: 100, + Items: [ + { id: 'user-id', type: 'user-type' }, + { id: 'user-id2', type: 'user-type' } + ], + LastEvaluatedKey: { id: 'last-eval-id', type: 'user-type' } + }); + } + }; + }).mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Count: 2, + ScannedCount: 100, + Items: [ + { id: 'user-id', type: 'user-type' }, + { id: 'user-id2', type: 'user-type' } + ] + }); + } + }; + }); + + mockSqs.sendMessageBatch.mockImplementation(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + State: { Name: 'BackupTableCleanup: Find Items' } + }, + Input: { ExportTimestamp: new Date().getTime(), lastEvaluatedKey: { id: 'last-eval-id', type: 'user-type' } } + }; + + const lambda = require('../backup-table-cleanup'); + const resp = await lambda.handler(event, context); + + expect(resp).toEqual({ + result: { + NumItemsAddedToQueue: 4, + ExportTimestamp: event.Input.ExportTimestamp, + lastEvaluatedKey: '' + } + }); + }); +}); + +describe('remove-items', () => { + beforeEach(() => { + jest.resetModules(); + for (const mockFn in mockSqs) { + mockSqs[mockFn].mockReset(); + } + + for (const mockFn in mockDocClient) { + mockDocClient[mockFn].mockReset(); + } + }); + + it('NOOP for unknown state name', async function () { + const event = { + Context: { + State: { Name: 'UNKNOWN' } + }, + Input: { ExportTimestamp: new Date().getTime() } + }; + + const lambda = require('../backup-table-cleanup'); + await lambda.handler(event, context); + }); + + it('Should return when no messages are in the queue', async function () { + mockSqs.receiveMessage.mockImplementation(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + State: { Name: 'BackupTableCleanup: Remove Items' } + }, + Input: { ExportTimestamp: new Date().getTime() } + }; + + const lambda = require('../backup-table-cleanup'); + const resp = await lambda.handler(event, context); + + expect(resp).toEqual({ + result: { + IsQueueEmpty: true, + ExportTimestamp: event.Input.ExportTimestamp, + NumItemsAddedToQueue: 0 + } + }); + }); + + it('Should return when some messages are in the queue', async function () { + mockSqs.receiveMessage.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Messages: [ + { Body: JSON.stringify({ Key: { id: 'id', type: 'type' } }) } + ] + }); + } + }; + }).mockImplementation(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockSqs.deleteMessageBatch.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}) + } + } + }); + + mockDocClient.batchWrite.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + UnprocessedItems: { + 'table-name': [{ id: 'id', type: 'type' }] + } + }) + } + } + }).mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + UnprocessedItems: {} + }) + } + } + }); + + const event = { + Context: { + State: { Name: 'BackupTableCleanup: Remove Items' } + }, + Input: { ExportTimestamp: new Date().getTime(), lastEvaluatedKey: { id: 'last-eval-id', type: 'user-type' } } + }; + + const lambda = require('../backup-table-cleanup'); + const resp = await lambda.handler(event, context); + + expect(resp).toEqual({ + result: { + NumItemsAddedToQueue: 0, + IsQueueEmpty: true, + ExportTimestamp: event.Input.ExportTimestamp + } + }); + }); +}); diff --git a/source/workflow-export/test/check-user-pool-config.spec.js b/source/workflow-export/test/check-user-pool-config.spec.js new file mode 100644 index 0000000..37a212d --- /dev/null +++ b/source/workflow-export/test/check-user-pool-config.spec.js @@ -0,0 +1,117 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock AWS SDK +const mockCognitoISP = { + getUserPoolMfaConfig: jest.fn(), + describeUserPool: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + CognitoIdentityServiceProvider: jest.fn(() => ({ + getUserPoolMfaConfig: mockCognitoISP.getUserPoolMfaConfig, + describeUserPool: mockCognitoISP.describeUserPool + })) + }; +}); + + +describe('check-user-pool-config', function () { + beforeEach(() => { + process.env.NOTIFICATION_TOPIC = 'notification-topic'; + process.env.SOURCE_USER_POOL_ID = 'src-user-pool-id'; + process.env.BACKUP_USER_POOL_ID = 'backup-user-pool-id'; + process.env.AWS_REGION = 'us-east-1'; + process.env.BACKUP_REGION = 'us-east-2'; + + for (const mockFn in mockCognitoISP) { + mockCognitoISP[mockFn].mockReset(); + } + }); + + it('Should return the user pool Username attributes', async function () { + mockCognitoISP.describeUserPool.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + UserPool: { + MfaConfiguration: 'OFF', + UsernameAttributes: ['email'] + } + }); + } + }; + }); + + const event = {}; + const lambda = require('../check-user-pool-config'); + const result = await lambda.handler(event); + expect(result).toEqual({ result: { UsernameAttributes: JSON.stringify(['email']) } }); + }); + + it('Should should handle user pools with no Username attributes', async function () { + mockCognitoISP.describeUserPool.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + UserPool: { + MfaConfiguration: 'OFF' + } + }); + } + }; + }); + + const event = {}; + const lambda = require('../check-user-pool-config'); + const result = await lambda.handler(event); + expect(result).toEqual({ result: {} }); + }); + + it('Should return false if MFA is enabled', async function () { + mockCognitoISP.describeUserPool.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + UserPool: { + MfaConfiguration: 'OPTIONAL', + UsernameAttributes: ['phone', 'email'] + } + }); + } + }; + }); + + const event = {}; + const lambda = require('../check-user-pool-config'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('User Pools with MFA enabled are not supported. The user pool\'s MFA configuration is set to OPTIONAL'); + }); + + it('Should return false if multiple username attributes are allowed', async function () { + mockCognitoISP.describeUserPool.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + UserPool: { + MfaConfiguration: 'OFF', + UsernameAttributes: ['phone', 'email'] + } + }); + } + }; + }); + + const event = {}; + const lambda = require('../check-user-pool-config'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('This solution does not support user pools for which more than one username attribute is allowed. Configured username attributes: ["phone","email"]'); + }); +}); diff --git a/source/workflow-export/test/export-group.spec.js b/source/workflow-export/test/export-group.spec.js new file mode 100644 index 0000000..6d84509 --- /dev/null +++ b/source/workflow-export/test/export-group.spec.js @@ -0,0 +1,57 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock context +const context = { + logStreamName: 'log-stream' +}; + +// Mock AWS SDK +const mockDocClient = { + put: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + DynamoDB: { + DocumentClient: jest.fn(() => ({ + put: mockDocClient.put + })) + } + }; +}); + +describe('export-group', () => { + beforeEach(() => { + for (const mockFn in mockDocClient) { + mockDocClient[mockFn].mockReset(); + } + }); + + it('Should return successfully after adding group to DDB', async function () { + const event = { + groupName: 'group-name', + groupDescription: 'group-desc', + groupPrecedence: 1, + groupLastModifiedDate: new Date().toISOString(), + exportTimestamp: new Date().getTime() + }; + + mockDocClient.put.mockImplementation(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const lambda = require('../export-group'); + const resp = await lambda.handler(event, context); + + expect(resp).toEqual({ exportTimestamp: event.exportTimestamp, groupName: 'group-name' }); + }); +}); \ No newline at end of file diff --git a/source/workflow-export/test/export-users-in-group.spec.js b/source/workflow-export/test/export-users-in-group.spec.js new file mode 100644 index 0000000..0398775 --- /dev/null +++ b/source/workflow-export/test/export-users-in-group.spec.js @@ -0,0 +1,187 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const mockCognitoISP = { + listUsersInGroup: jest.fn() +}; + +const mockDocClient = { + batchWrite: jest.fn() +}; + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function () { + return 100000; + } +}; + +jest.mock('aws-sdk', () => { + return { + CognitoIdentityServiceProvider: jest.fn(() => ({ + listUsersInGroup: mockCognitoISP.listUsersInGroup + })), + DynamoDB: { + DocumentClient: jest.fn(() => ({ + batchWrite: mockDocClient.batchWrite + })) + } + }; +}); + +beforeAll(() => { + process.env = Object.assign(process.env, { + AWS_REGION: 'us-east-1', + COGNITO_TPS: '10', + BACKUP_TABLE_NAME: 'table-name' + }); +}); + +describe('export-users-in-group', () => { + beforeEach(() => { + for (const mockFn in mockCognitoISP) { + mockCognitoISP[mockFn].mockReset(); + } + + for (const mockFn in mockDocClient) { + mockDocClient[mockFn].mockReset(); + } + }); + + it('Should return when no users are returned', async function () { + mockCognitoISP.listUsersInGroup.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + groupName: 'group-name', + listUsersInGroupNextToken: 'next-token', + exportTimestamp: new Date().getTime() + }; + + const lambda = require('../export-users-in-group'); + const resp = await lambda.handler(event, context); + + expect(resp).toEqual({ + exportTimestamp: event.exportTimestamp, + groupName: 'group-name', + processedAllUsersInGroup: 'Yes' + }); + }); + + it('Should return when only external provider users are returned', async function () { + mockCognitoISP.listUsersInGroup + .mockImplementationOnce(()=>{ + return { + promise() { + return Promise.reject({ + retryable: true, + message: 'retryable message' + }); + } + }; + }) + .mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Users: [{ + Username: 'name', + UserStatus: 'EXTERNAL_PROVIDER', + Attributes:[{ + Name: 'sub', + Value: 'uuid' + }] + }] + }); + } + }; + }); + + const event = { + groupName: 'group-name', + listUsersInGroupNextToken: 'next-token', + exportTimestamp: new Date().getTime() + }; + + const lambda = require('../export-users-in-group'); + const resp = await lambda.handler(event, context); + + expect(resp).toEqual({ + exportTimestamp: event.exportTimestamp, + groupName: 'group-name', + processedAllUsersInGroup: 'Yes' + }); + }); + + it('Should return when one user is processed', async function () { + const event = { + groupName: 'group-name', + exportTimestamp: new Date().getTime() + }; + + mockCognitoISP.listUsersInGroup.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Users: [{ + Username: 'user-name', + Attributes:[{ + Name: 'sub', + Value: 'uuid' + }], + Enabled: true, + UserStatus: 'CONFIRMED' + }], + NextToken: 'next-token' + }); + } + }; + }); + + mockDocClient.batchWrite.mockImplementation(() => { + return { + promise() { + return Promise.resolve({UnprocessedItems:{ + 'backup-table': [] + }}); + } + }; + }); + + const lambda = require('../export-users-in-group'); + context.getRemainingTimeInMillis = function(){return 1000;}; + const resp = await lambda.handler(event, context); + + expect(resp).toEqual({ + exportTimestamp: event.exportTimestamp, + groupName: 'group-name', + processedAllUsersInGroup: 'No', + listUsersInGroupNextToken: 'next-token' + }); + }); +}); + +describe('groups-invalid CognitoTPS', function () { + beforeEach(() => { + jest.resetModules(); + process.env = Object.assign(process.env, { COGNITO_TPS: 'invalid' }); + }); + + it('Throws an error if an invalid CognitoTPS value is set', async function () { + const event = { LastEvaluatedKey: 'last-key' }; + const lambda = require('../export-users-in-group'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('Unable to parse a number from the COGNITO_TPS value (invalid)'); + }); +}); diff --git a/source/workflow-export/test/export-users.spec.js b/source/workflow-export/test/export-users.spec.js new file mode 100644 index 0000000..fad5ee0 --- /dev/null +++ b/source/workflow-export/test/export-users.spec.js @@ -0,0 +1,475 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock AWS SDK +const mockCognito = jest.fn(); +const mockDynamoDB = jest.fn(); +jest.mock('aws-sdk', () => { + return { + CognitoIdentityServiceProvider: jest.fn(() => ({ + listUsers: mockCognito + })) + }; +}); +jest.mock('aws-sdk/clients/dynamodb', () => { + return { + DocumentClient: jest.fn(() => ({ + batchWrite: mockDynamoDB + })) + }; +}); + +// Mock Date +const now = new Date(); +global.Date = jest.fn(() => now); +global.Date.getTime = now.getTime(); + +const mockUser = { + Username: 'mock-user', + Attributes: [ + { + Name: 'sub', + Value: 'bd830ed0-bc56-448e-9bd9-d6e597bcd20f' + } + ], + UserCreateDate: 1591893018.766, + UserLastModifiedDate: 1592238002.126, + Enabled: true, + UserStatus: 'CONFIRMED' +}; +const mockUsers = { + Users: [mockUser] +}; +const mockUsersWithToken = { + Users: [mockUser], + PaginationToken: 'nextToken' +}; +const mockDate = new Date().getTime(); + +beforeAll(() => { + process.env = Object.assign(process.env, { + AWS_REGION: 'us-east-1', + USER_POOL_ID: 'user-pool-id', + TABLE_NAME: 'table-name', + COGNITO_TPS: '10' + }); +}); + +describe('export-users', function () { + beforeEach(() => { + mockCognito.mockReset(); + mockDynamoDB.mockReset(); + }); + + describe('step function first try', function () { + const event = {}; + const context = { + getRemainingTimeInMillis: function () { + return 100000; + } + }; + + it('should return empty paginationToken - cognito: no user', async () => { + mockCognito.mockImplementation(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve({ Users: [] }); + } + }; + }); + + const lambda = require('../export-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + paginationToken: '', + ExportTimestamp: now.getTime() + }, + totalUserProcessedCount: 0 + }); + }); + + it('should return empty paginationToken - cognito: no more user', async () => { + mockCognito.mockImplementationOnce(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve(JSON.parse(JSON.stringify(mockUsers))); + } + }; + }); + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.batchWrite + return Promise.resolve({ UnprocessedItems: {} }); + } + }; + }); + + const lambda = require('../export-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + paginationToken: '', + ExportTimestamp: now.getTime() + }, + totalUserProcessedCount: 1 + }); + }); + + it('should return empty paginationToken - cognito: no more user, dynamodb: unprocessed items', async () => { + mockCognito.mockImplementation(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve(JSON.parse(JSON.stringify(mockUsers))); + } + }; + }); + mockDynamoDB + .mockImplementationOnce(() => { + return { + promise() { + // dynamodb.batchWrite + const unprocessedItems = {}; + unprocessedItems[process.env.TABLE_NAME] = [{ PutRequest: {} }]; + + return Promise.resolve({ UnprocessedItems: unprocessedItems }); + } + }; + }) + .mockImplementationOnce(() => { + return { + promise() { + // dynamodb.batchWrite + const unprocessedItems = {}; + unprocessedItems[process.env.TABLE_NAME] = [{ PutRequest: {} }]; + + return Promise.resolve({ UnprocessedItems: { [process.env.TABLE_NAME]: [] } }); + } + }; + }); + + + const lambda = require('../export-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + paginationToken: '', + ExportTimestamp: now.getTime() + }, + totalUserProcessedCount: 1 + }); + }); + + it('should return empty paginationToken - cognito: more users', async () => { + mockCognito.mockImplementationOnce(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve({ + Users: [{ + Username: 'mock-user', + Attributes: [ + { + Name: 'sub', + Value: 'bd830ed0-bc56-448e-9bd9-d6e597bcd20f' + } + ], + UserCreateDate: 1591893018.766, + UserLastModifiedDate: 1592238002.126, + Enabled: true, + UserStatus: 'CONFIRMED' + }], + PaginationToken: 'nextToken' + }); + } + }; + }); + + mockCognito.mockImplementationOnce(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve({ + Users: [{ + Username: 'mock-user', + Attributes: [ + { + Name: 'sub', + Value: 'bd830ed0-bc56-448e-9bd9-d6e597bcd20f' + } + ], + UserCreateDate: 1591893018.766, + UserLastModifiedDate: 1592238002.126, + Enabled: true, + UserStatus: 'CONFIRMED' + }] + }); + } + }; + }); + + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.batchWrite + return Promise.resolve({ UnprocessedItems: {} }); + } + }; + }); + + const lambda = require('../export-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + paginationToken: '', + ExportTimestamp: now.getTime() + }, + totalUserProcessedCount: 2 + }); + }); + + it('should return paginationToken - cognito: more users, timeout', async () => { + context.getRemainingTimeInMillis = function () { + return 1000; + }; + + mockCognito.mockImplementation(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve(JSON.parse(JSON.stringify(mockUsersWithToken))); + } + }; + }); + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.batchWrite + return Promise.resolve({ UnprocessedItems: {} }); + } + }; + }); + + const lambda = require('../export-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + paginationToken: mockUsersWithToken.PaginationToken, + ExportTimestamp: now.getTime() + }, + totalUserProcessedCount: 1 + }); + }); + }); + + describe('step function iteration', function () { + const event = { + paginationToken: mockUsersWithToken.PaginationToken, + ExportTimestamp: mockDate + }; + const context = { + getRemainingTimeInMillis: function () { + return 100000; + } + }; + + it('should return empty paginationToken - cognito: no more user', async () => { + mockCognito.mockImplementationOnce(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve(JSON.parse(JSON.stringify(mockUsers))); + } + }; + }); + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.batchWrite + return Promise.resolve({ UnprocessedItems: {} }); + } + }; + }); + + const lambda = require('../export-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + paginationToken: '', + ExportTimestamp: mockDate + }, + totalUserProcessedCount: 1 + }); + }); + + it('should return empty paginationToken - cognito: more users', async () => { + mockCognito.mockImplementationOnce(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve({ + Users: [{ + Username: 'mock-user', + Attributes: [ + { + Name: 'sub', + Value: 'bd830ed0-bc56-448e-9bd9-d6e597bcd20f' + } + ], + UserCreateDate: 1591893018.766, + UserLastModifiedDate: 1592238002.126, + Enabled: true, + UserStatus: 'CONFIRMED' + }], + PaginationToken: 'nextToken' + }); + } + }; + }); + + mockCognito.mockImplementationOnce(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve({ + Users: [{ + Username: 'mock-user', + Attributes: [ + { + Name: 'sub', + Value: 'bd830ed0-bc56-448e-9bd9-d6e597bcd20f' + } + ], + UserCreateDate: 1591893018.766, + UserLastModifiedDate: 1592238002.126, + Enabled: true, + UserStatus: 'CONFIRMED' + }] + }); + } + }; + }); + + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.batchWrite + return Promise.resolve({ UnprocessedItems: {} }); + } + }; + }); + + const lambda = require('../export-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + paginationToken: '', + ExportTimestamp: mockDate + }, + totalUserProcessedCount: 2 + }); + }); + + it('should return paginationToken - cognito: more users, timeout', async () => { + context.getRemainingTimeInMillis = function () { + return 1000; + }; + + mockCognito.mockImplementation(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve(JSON.parse(JSON.stringify(mockUsersWithToken))); + } + }; + }); + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.batchWrite + return Promise.resolve({ UnprocessedItems: {} }); + } + }; + }); + + const lambda = require('../export-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + paginationToken: mockUsersWithToken.PaginationToken, + ExportTimestamp: mockDate + }, + totalUserProcessedCount: 1 + }); + }); + }); + + describe('error', function () { + const event = {}; + const context = { + getRemainingTimeInMillis: function () { + return 100000; + } + }; + + it('should throw an error - cognito-idp:listUsers failure', async () => { + mockCognito.mockImplementation(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.reject({ + message: 'ERROR - listUsers' + }); + } + }; + }); + + const lambda = require('../export-users'); + try { + await lambda.handler(event, context); + } catch (error) { + expect(error).toEqual({ + message: 'ERROR - listUsers' + }); + } + }); + + it('should throw an error - dynamodb:batchWrite failure', async () => { + mockCognito.mockImplementation(() => { + return { + promise() { + // cognitoIdentityServiceProvider.listUsers + return Promise.resolve(JSON.parse(JSON.stringify(mockUsers))); + } + }; + }); + mockDynamoDB.mockImplementation(() => { + return { + promise() { + // dynamodb.batchWrite + return Promise.reject({ + message: 'ERROR - batchWrite' + }); + } + }; + }); + + const lambda = require('../export-users'); + try { + await lambda.handler(event, context); + } catch (error) { + expect(error).toEqual({ + message: 'ERROR - batchWrite' + }); + } + }); + }); +}); \ No newline at end of file diff --git a/source/workflow-export/test/list-groups.spec.js b/source/workflow-export/test/list-groups.spec.js new file mode 100644 index 0000000..2350436 --- /dev/null +++ b/source/workflow-export/test/list-groups.spec.js @@ -0,0 +1,134 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock context +const context = { + logStreamName: 'log-stream' +}; + +// Mock AWS SDK +const mockCognitoISP = jest.fn(); +jest.mock('aws-sdk', () => { + return { + CognitoIdentityServiceProvider: jest.fn(() => ({ + listGroups: mockCognitoISP + })) + }; +}); + +describe('list-groups', () => { + const OLD_ENV = process.env; + + beforeEach(() => { + mockCognitoISP.mockReset(); + process.env = { ...OLD_ENV }; + delete process.env.NODE_ENV; + process.env.USER_POOL_ID = 'foo-user-pool-id'; + }); + + afterEach(() => { + process.env = OLD_ENV; + }); + + it('should return the same number of groups that Cognito returned', async function () { + const event = { ExportTimestamp: new Date().getTime() }; + const listGroupsResponse = { + Groups: [ + { GroupName: 'group-1' }, + { GroupName: 'group-2' }, + { GroupName: 'group-3' } + ] + }; + + mockCognitoISP.mockImplementation(() => { + return { + promise() { + return Promise.resolve(listGroupsResponse); + } + }; + }); + + const lambda = require('../list-groups'); + const resp = await lambda.handler(event, context); + + expect(resp.ExportTimestamp).toBe(event.ExportTimestamp); + expect(resp.NumGroupsToProcess).toBe(listGroupsResponse.Groups.length); + expect(resp.Groups.length).toBe(listGroupsResponse.Groups.length); + expect(resp.ProcessedAllGroups).toBe('Yes'); + }); + + it('should return the NextToken when it is sent by Cognito', async function () { + const event = { ExportTimestamp: new Date().getTime() }; + const listGroupsResponse = { + Groups: [{ GroupName: 'group-1' }], + NextToken: 'foo-next-token' + }; + + mockCognitoISP.mockImplementation(() => { + return { + promise() { + return Promise.resolve(listGroupsResponse); + } + }; + }); + + const lambda = require('../list-groups'); + const resp = await lambda.handler(event, context); + + expect(resp.ExportTimestamp).toBe(event.ExportTimestamp); + expect(resp.ProcessedAllGroups).toBe('No'); + expect(resp.ListGroupsNextToken).toBe(listGroupsResponse.NextToken); + }); + + it('should return an empty GroupName array when Cognito returns no groups', async function () { + const event = { ExportTimestamp: new Date().getTime() }; + const listGroupsResponse = { + }; + + mockCognitoISP.mockImplementation(() => { + return { + promise() { + return Promise.resolve(listGroupsResponse); + } + }; + }); + + const lambda = require('../list-groups'); + const resp = await lambda.handler(event, context); + + expect(resp.ExportTimestamp).toBe(event.ExportTimestamp); + expect(resp.NumGroupsToProcess).toBe(0); + expect(resp.Groups.length).toBe(0); + expect(resp.ProcessedAllGroups).toBe('Yes'); + }); + + it('should return the same number of groups that Cognito returned when a NextToken is supplied', async function () { + const event = { ExportTimestamp: new Date().getTime(), ListGroupsNextToken: 'foo-next-token' }; + const listGroupsResponse = { + Groups: [ + { GroupName: 'group-1' }, + { GroupName: 'group-2' } + ] + }; + + mockCognitoISP.mockImplementation(() => { + return { + promise() { + return Promise.resolve(listGroupsResponse); + } + }; + }); + + const lambda = require('../list-groups'); + const resp = await lambda.handler(event, context); + + expect(resp.ExportTimestamp).toBe(event.ExportTimestamp); + expect(resp.NumGroupsToProcess).toBe(listGroupsResponse.Groups.length); + expect(resp.Groups.length).toBe(listGroupsResponse.Groups.length); + expect(resp.ProcessedAllGroups).toBe('Yes'); + }); +}); diff --git a/source/workflow-import/check-new-user-pool.js b/source/workflow-import/check-new-user-pool.js new file mode 100644 index 0000000..c1347d6 --- /dev/null +++ b/source/workflow-import/check-new-user-pool.js @@ -0,0 +1,56 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const cognitoISP = new AWS.CognitoIdentityServiceProvider(); +const { sleep } = require('../utils/helper-functions'); + +/** + * Checks the new user pool to ensure it has no users or groups + * @param {object} event + */ +exports.handler = async (event) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const result = { NewUserPoolEmpty: true }; + let newUserPoolId; + try { + const { Context } = event; + newUserPoolId = Context.Execution.Input.NewUserPoolId.trim(); + if (!newUserPoolId) { + throw new Error('Unable to determine the new user pool ID'); + } + } catch (err) { + console.error(err); + throw new Error('Unable to determine the new user pool ID'); + } + + try { + const listUsersParams = { UserPoolId: newUserPoolId }; + console.log(`Listing users in new pool: ${JSON.stringify(listUsersParams)}`); + const listUsersResponse = await cognitoISP.listUsers(listUsersParams).promise(); + + if (listUsersResponse.Users && listUsersResponse.Users.length > 0) { + throw new Error(`Found at least ${listUsersResponse.Users.length} user(s) in the new user pool`); + } + + await sleep(1); + + const listGroupsParams = { UserPoolId: newUserPoolId }; + console.log(`Listing groups in new pool: ${JSON.stringify(listGroupsParams)}`); + const listGroupsResponse = await cognitoISP.listGroups(listGroupsParams).promise(); + + if (listGroupsResponse.Groups && listGroupsResponse.Groups.length > 0) { + throw new Error(`Found at least ${listGroupsResponse.Groups.length} group(s) in the new user pool`); + } + } catch (err) { + console.error(err); + result.NewUserPoolEmpty = false; + } + + console.log(`result: ${JSON.stringify(result)}`); + return { result: result }; +}; diff --git a/source/workflow-import/import-users.js b/source/workflow-import/import-users.js new file mode 100644 index 0000000..79c2ba8 --- /dev/null +++ b/source/workflow-import/import-users.js @@ -0,0 +1,333 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const cognitoISP = new AWS.CognitoIdentityServiceProvider(); +const sqs = new AWS.SQS(); +const s3 = new AWS.S3(); +const { + NEW_USERS_QUEUE_URL, USER_IMPORT_CLOUDWATCH_ROLE_ARN, + USER_IMPORT_JOB_MAPPING_FILES_BUCKET, SEND_METRIC, METRICS_ANONYMOUS_UUID, + SOLUTION_ID, SOLUTION_VERSION, AWS_REGION +} = process.env; +const { sleep, getExponentialBackoffTimeInMS } = require('../utils/helper-functions'); +const oneMinuteInMS = 1000 * 60; +const maxUserImportCSV = 500000; // max 500k users per import job +const maxUploadByteSize = 100000000; // max 100mb file size per import job +const axios = require('axios'); +const os = require('os'); +const shouldSendMetric = (SEND_METRIC === 'Yes'); +const { sendAnonymousMetric } = require('../utils/metrics'); + +/** + * Imports users into the new user pool + * @param {object} event + */ +exports.handler = async (event, context) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const { Context, Input } = event; + let result = { ...Input }; + let StateName = ''; + let newUserPoolId; + try { + newUserPoolId = Context.Execution.Input.NewUserPoolId.trim(); + if (!newUserPoolId) { + throw new Error('Unable to determine the new user pool ID'); + } + } catch (err) { + console.error(err); + throw new Error('Unable to determine the new user pool ID'); + } + + if (Context && Context.State) { + StateName = Context.State.Name; + result.StateName = StateName; + } + + switch (StateName) { + case 'ImportNewUsers': + case 'Parallel: ImportNewUsers': + result = { ...result, ... await importUsers(context, newUserPoolId) }; + break; + case 'CheckUserImportJob': + case 'Parallel: CheckUserImportJob': + result = { ...result, ... await checkUserImportJob(Input.ImportJobId, newUserPoolId) }; + break; + default: + throw new Error(`Unknown StateName: ${StateName}`); + } + + console.log(`Result: ${JSON.stringify(result)}`); + return { result }; +}; + +/** + * Reads messages from the New Users Queue and creates a CSV import job to add them to the primary user pool + * @param {object} context Lambda context + * @param {string} newUserPoolId The ID of the import user pool + */ +const importUsers = async (context, newUserPoolId) => { + const output = { ImportJobStatus: '', QueueEmpty: true }; + let numNewUsersToImport = 0; + let userImportCSVHeaders = []; + let userImportCSV = ''; + let userImportCSVByteSize = 0; + let maxUploadByteSizeReached = (userImportCSVByteSize < maxUploadByteSize); + let userImportMappingFile = 'userImportCsvLineNumber,userSub\n'; + + do { + const receiveMessageParams = { QueueUrl: NEW_USERS_QUEUE_URL, MaxNumberOfMessages: 10, WaitTimeSeconds: 20 }; + console.log(`Getting messages off New Users Queue: ${JSON.stringify(receiveMessageParams)}`); + const receiveMessageResult = await sqs.receiveMessage(receiveMessageParams).promise(); + + if (receiveMessageResult.Messages && receiveMessageResult.Messages.length > 0) { + console.log(`Read ${receiveMessageResult.Messages.length} message(s) off the queue`); + output.QueueEmpty = false; + const deleteMessageBatchParams = { QueueUrl: NEW_USERS_QUEUE_URL, Entries: [] }; + if (!userImportCSVHeaders || userImportCSVHeaders.length === 0) { + userImportCSVHeaders = await getCSVHeader(newUserPoolId); + userImportCSV += formatCsvHeader(userImportCSVHeaders); + userImportCSVByteSize += Buffer.byteLength(userImportCSV); + maxUploadByteSizeReached = (userImportCSVByteSize >= maxUploadByteSize); + } + + for (let i = 0; i < receiveMessageResult.Messages.length; i++) { + const message = receiveMessageResult.Messages[i]; + const userData = JSON.parse(message.Body); + const userCSVLine = formatUserToCsvLine(userImportCSVHeaders, userData); + const lineSize = Buffer.byteLength(userCSVLine); + + //Check if adding the next line will put the upload over the limit + if (!maxUploadByteSizeReached) { + maxUploadByteSizeReached = (lineSize + userImportCSVByteSize) >= maxUploadByteSize; + } + + if ((numNewUsersToImport < maxUserImportCSV) && !maxUploadByteSizeReached) { + userImportCSV += userCSVLine; + userImportCSVByteSize += lineSize; + userImportMappingFile += `${numNewUsersToImport + 1},${getUserSub(userData)}\n`; + numNewUsersToImport++; + deleteMessageBatchParams.Entries.push({ Id: message.MessageId, ReceiptHandle: message.ReceiptHandle }); + } + } + + if (deleteMessageBatchParams.Entries.length > 0) { + console.log(`Deleting a batch of ${deleteMessageBatchParams.Entries.length} message(s) from the New User Queue`); + await sqs.deleteMessageBatch(deleteMessageBatchParams).promise(); + console.log('Message batch deleted'); + } + } else { + console.log('No messages in queue'); + output.QueueEmpty = true; + } + } while (!output.QueueEmpty && !maxUploadByteSizeReached && numNewUsersToImport < maxUserImportCSV && context.getRemainingTimeInMillis() > oneMinuteInMS); + + if (numNewUsersToImport > 0) { + console.log(`Going to create a job to import ${numNewUsersToImport} user(s)`); + const userImportJobDetails = await runUserImportJob(userImportCSV, userImportMappingFile, newUserPoolId); + output.ImportJobId = userImportJobDetails.JobId; + output.ImportJobStatus = userImportJobDetails.Status; + + // Set to false so the queue is checked again after the user import job is complete + output.QueueEmpty = false; + } + + return output; +}; + +/** + * Gets the CSV header for the user import job + */ +const getCSVHeader = async (newUserPoolId) => { + const params = { UserPoolId: newUserPoolId }; + console.log(`Getting CSV Header: ${JSON.stringify(params)}`); + const response = await cognitoISP.getCSVHeader(params).promise(); + console.log(`Got CSV Header: ${JSON.stringify(response)}`); + return response.CSVHeader; +}; + +/** + * Formats the CSV header array into a comma-separated string + * @param {string[]} csvHeaderArray An array of CSV headers returned by the getCSVHeader function + */ +const formatCsvHeader = (csvHeaderArray) => { + const formattedHeader = csvHeaderArray.join(',') + os.EOL; + console.log(`Formatted CSV header: ${formattedHeader}`); + return formattedHeader; +}; + +/** + * Formats user data object into a line for the user import CSV file + * @param {string[]} csvHeaderArray An array of CSV headers returned by the getCSVHeader function + * @param {object} userData The data for the user that will be formatted into the CSV line + */ +const formatUserToCsvLine = (csvHeaderArray, userData) => { + let userLine = ''; + + for (let header of csvHeaderArray) { + let headerValue = ''; + switch (header) { + case 'cognito:username': + headerValue = `${userData.pseudoUsername}`; + break; + case 'cognito:mfa_enabled': + headerValue = `false`; + break; + case 'email_verified': + const emailVerified = userData.userAttributes.find(attr => attr.Name === header); + headerValue = `${emailVerified ? emailVerified.Value : 'false'}`; + break; + case 'phone_number_verified': + const phoneVerified = userData.userAttributes.find(attr => attr.Name === header); + headerValue = `${phoneVerified ? phoneVerified.Value : 'false'}`; + break; + default: + const matchingAttribute = userData.userAttributes.find(attr => attr.Name === header); + headerValue = `${matchingAttribute ? matchingAttribute.Value : ''}`; + break; + } + + // Add a slash before each comma in the header value so the + // user import job is able to parse the CSV correctly + headerValue = headerValue.replace(/,/g, '\\,'); + userLine += `${headerValue},`; + } + + // Replace trailing comma with an EOL character + return userLine.slice(0, -1) + os.EOL; +}; + +/** + * Returns the Cognito-generated unique user identifier (sub) attribute + * @param {object} userData The data for the user that will be formatted into the CSV line + */ +const getUserSub = (userData) => { + let subValue = null; + + let subAttribute = userData.userAttributes.find(attr => attr.Name === 'sub'); + if (subAttribute) { + subValue = subAttribute.Value; + } + + if (!subValue) { + throw new Error('Unable to extract user\'s sub attribute'); + } + + return subValue; +}; + +/** + * Uploads the supplied CSV and starts the user import job + * @param {string} csv The CSV file that will be used with the import job + * @param {string} userImportMappingFile The mapping file that will be used to troubleshoot failed user import jobs + * @param {string} newUserPoolId The ID of the import user pool + */ +const runUserImportJob = async (csv, userImportMappingFile, newUserPoolId) => { + const createUserImportJobParams = { + CloudWatchLogsRoleArn: USER_IMPORT_CLOUDWATCH_ROLE_ARN, + UserPoolId: newUserPoolId, + JobName: 'cognito-user-profiles-export-reference-architecture' + }; + + console.log(`Creating user import job: ${JSON.stringify(createUserImportJobParams)}`); + const createUserImportJobResponse = await cognitoISP.createUserImportJob(createUserImportJobParams).promise(); + console.log(`User import job created`); + + const { JobId, PreSignedUrl } = createUserImportJobResponse.UserImportJob; + + console.log(`Uploading user import job mapping file to S3 bucket (${USER_IMPORT_JOB_MAPPING_FILES_BUCKET})`); + await s3.putObject({ + Bucket: USER_IMPORT_JOB_MAPPING_FILES_BUCKET, + Key: `${JobId}-user-mapping.csv`, + ServerSideEncryption: 'AES256', + Body: userImportMappingFile + }).promise(); + console.log('User import job mapping file uploaded'); + + console.log('Uploading CSV for user import job...'); + const options = { + maxBodyLength: maxUploadByteSize, + maxContentLength: maxUploadByteSize, + headers: { 'x-amz-server-side-encryption': 'aws:kms' } + }; + await axios.put(PreSignedUrl, csv, options); + console.log('CSV uploaded'); + + let numAttempts = 1; + let Status; + const maxAttempts = 5; + let jobStarted = false; + while (!jobStarted && numAttempts < maxAttempts) { + try { + const startUserImportJobParams = { UserPoolId: newUserPoolId, JobId: JobId }; + console.log(`Starting user import job: ${JSON.stringify(startUserImportJobParams)}`); + const startUserImportJobResponse = await cognitoISP.startUserImportJob(startUserImportJobParams).promise(); + Status = startUserImportJobResponse.UserImportJob.Status; + console.log(`User import job started: ${JobId} (${Status})`); + jobStarted = true; + } catch (err) { + console.error(err); + const sleepTimeInMs = getExponentialBackoffTimeInMS(100, numAttempts, 10000, false); + numAttempts++; + console.log(`Sleeping for ${sleepTimeInMs} milliseconds and will attempt to run the user import job again. That will be attempt #${numAttempts}`); + await sleep(0, sleepTimeInMs); + } + } + + return { JobId: JobId, Status: Status }; +}; + +/** + * Returns the status of the Cognito User Import job matching the supplied jobId + * @param {string} jobId The ID of the job to check + * @param {string} newUserPoolId The ID of the import user pool + */ +const checkUserImportJob = async (jobId, newUserPoolId) => { + const output = { ImportJobId: jobId }; + const describeUserImportJobParams = { + UserPoolId: newUserPoolId, + JobId: jobId + }; + + console.log(`Describing user import job: ${JSON.stringify(describeUserImportJobParams)}`); + const response = await cognitoISP.describeUserImportJob(describeUserImportJobParams).promise(); + console.log(JSON.stringify(response)); + + if (response.UserImportJob) { + if (shouldSendMetric) { + if (response.UserImportJob.Status !== 'Pending' && response.UserImportJob.Status !== 'InProgress') { + await sendAnonymousMetric(SOLUTION_ID, SOLUTION_VERSION, METRICS_ANONYMOUS_UUID, { + EventType: 'user-import-job-ended', + EventDetails: { + JobStatus: response.UserImportJob.Status, + CreationDate: response.UserImportJob.CreationDate, + StartDate: response.UserImportJob.StartDate, + CompletionDate: response.UserImportJob.CompletionDate, + CompletionMessage: response.UserImportJob.CompletionMessage, + Region: AWS_REGION + } + }); + } + } + + switch (response.UserImportJob.Status) { + case 'Pending': + case 'InProgress': + console.log('Job has not completed yet'); + break; + case 'Succeeded': + console.log('Job completed successfully'); + break; + default: + throw new Error(`User import job with ID "${response.UserImportJob.JobId}" was detected to have a status of "${response.UserImportJob.Status}" in ${AWS_REGION}.\n\nPlease check the CloudWatch logs for this Cognito user import job and use the mapping file (${response.UserImportJob.JobId}-user-mapping.csv) that has been saved in this the solution's S3 bucket (${USER_IMPORT_JOB_MAPPING_FILES_BUCKET}) to cross-reference the line numbers reported the user import job CloudWatch logs`); + } + } + + output.ImportJobStatus = response.UserImportJob.Status; + return output; +}; + diff --git a/source/workflow-import/package-lock.json b/source/workflow-import/package-lock.json new file mode 100644 index 0000000..b1ebe02 --- /dev/null +++ b/source/workflow-import/package-lock.json @@ -0,0 +1,4926 @@ +{ + "name": "workflow-recovery", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/core": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.5.tgz", + "integrity": "sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.5", + "@babel/types": "^7.10.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + }, + "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/generator": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.5.tgz", + "integrity": "sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==", + "dev": true, + "requires": { + "@babel/types": "^7.10.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "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-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.5.tgz", + "integrity": "sha512-HiqJpYD5+WopCXIAbQDG0zye5XYVvcO9w/DHp5GsaGkRUaamLj2bEtu6i8rnGGprAhHM3qidCMgp71HF4endhA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz", + "integrity": "sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "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.10.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", + "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", + "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.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@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/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.5.tgz", + "integrity": "sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/types": "^7.10.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + } + } + }, + "@babel/types": { + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "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 + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@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" + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/console": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.2.0.tgz", + "integrity": "sha512-mXQfx3nSLwiHm1i7jbu+uvi+vvpVjNGzIQYLCfsat9rapC+MJkS4zBseNrgJE0vU921b3P67bQzhduphjY3Tig==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.2.0", + "jest-util": "^26.2.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.2.1.tgz", + "integrity": "sha512-c4Iw59t59mf6V8uespxjIeGny8GreuDxSjXhqznuAUE1nmKSi4gh43LF8OlEUkNpwcE5fcIB4MRKgljil4RABg==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/reporters": "^26.2.1", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.1", + "@jest/types": "^26.2.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.2.0", + "jest-config": "^26.2.1", + "jest-haste-map": "^26.2.1", + "jest-message-util": "^26.2.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.2.1", + "jest-resolve-dependencies": "^26.2.1", + "jest-runner": "^26.2.1", + "jest-runtime": "^26.2.1", + "jest-snapshot": "^26.2.1", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "jest-watcher": "^26.2.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.2.0.tgz", + "integrity": "sha512-oCgp9NmEiJ5rbq9VI/v/yYLDpladAAVvFxZgNsnJxOETuzPZ0ZcKKHYjKYwCtPOP1WCrM5nmyuOhMStXFGHn+g==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0" + } + }, + "@jest/fake-timers": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.2.0.tgz", + "integrity": "sha512-45Gfe7YzYTKqTayBrEdAF0qYyAsNRBzfkV0IyVUm3cx7AsCWlnjilBM4T40w7IXT5VspOgMPikQlV0M6gHwy/g==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.2.0", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0" + } + }, + "@jest/globals": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.2.0.tgz", + "integrity": "sha512-Hoc6ScEIPaym7RNytIL2ILSUWIGKlwEv+JNFof9dGYOdvPjb2evEURSslvCMkNuNg1ECEClTE8PH7ULlMJntYA==", + "dev": true, + "requires": { + "@jest/environment": "^26.2.0", + "@jest/types": "^26.2.0", + "expect": "^26.2.0" + } + }, + "@jest/reporters": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.2.1.tgz", + "integrity": "sha512-A/wbl99EpS1SW1/BZGKrBl65TKqoimpODzMbvGgFrCqbLPfuR5lXUdCcKoDDF5a1OfSRFJCcNpQerS2in7LfYg==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.2.0", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.1", + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.2.1", + "jest-resolve": "^26.2.1", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.1", + "node-notifier": "^7.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + } + }, + "@jest/source-map": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.1.0.tgz", + "integrity": "sha512-XYRPYx4eEVX15cMT9mstnO7hkHP3krNtKfxUYd8L7gbtia8JvZZ6bMzSwa6IQJENbudTwKMw5R1BePRD+bkEmA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.2.0.tgz", + "integrity": "sha512-kgPlmcVafpmfyQEu36HClK+CWI6wIaAWDHNxfQtGuKsgoa2uQAYdlxjMDBEa3CvI40+2U3v36gQF6oZBkoKatw==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.2.1.tgz", + "integrity": "sha512-H1sl/efQeJC2/agSJWEos2Vi1F1lkVfbO2WYtx7YAEfWD5vOz1jOnBd6AY1ER9nlT1Mh7r5MAKlUx1CdsbS7Pg==", + "dev": true, + "requires": { + "@jest/test-result": "^26.2.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.2.1", + "jest-runner": "^26.2.1", + "jest-runtime": "^26.2.1" + } + }, + "@jest/transform": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.2.1.tgz", + "integrity": "sha512-lwPHjT9tIHB0B66/FEv4lr4+GPIT0/0RPOFEBzk7NsnrAKoemelTVyDI99x1f6Dh3juyQ5kK9z8cAyCstkotOQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.2.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.2.1", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.2.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.2.0.tgz", + "integrity": "sha512-lvm3rJvctxd7+wxKSxxbzpDbr4FXDLaC57WEKdUIZ2cjTYuxYSc0zlyD7Z4Uqr5VdKxRUrtwIkiqBuvgf8uKJA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/babel__core": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", + "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "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.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", + "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "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": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/node": { + "version": "14.0.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz", + "integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/prettier": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.2.tgz", + "integrity": "sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA==", + "dev": true + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "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==", + "dev": true + }, + "ajv": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "dev": true, + "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-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "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=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sdk": { + "version": "2.723.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.723.0.tgz", + "integrity": "sha512-GmyMacu1x1BOA8tYZuZS1DKcdn7QQX+DJFdFgZ3IilMzlX3cdinMXkBc5onEnhbwHx657XHoPigJynTRGGNuWQ==", + "dev": true, + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "dependencies": { + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + } + } + }, + "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=", + "dev": true + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "axios-mock-adapter": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-1.18.2.tgz", + "integrity": "sha512-e5aTsPy2Viov22zNpFTlid76W1Scz82pXeEwwCXdtO85LROhHAF8pHF2qDhiyMONLxKyY3lQ+S4UCsKgrlx8Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "is-buffer": "^2.0.3" + } + }, + "babel-jest": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.2.1.tgz", + "integrity": "sha512-8h5l0hzHTVFwWwu2K81iStzu8RPOPPQqaC5tKYrk4jcnlDYk5pMIwW+Yp515S8pxIJKWM/Z1rzkVOLanbNIn0w==", + "dev": true, + "requires": { + "@jest/transform": "^26.2.1", + "@jest/types": "^26.2.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "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": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.2.0.tgz", + "integrity": "sha512-B/hVMRv8Nh1sQ1a3EY8I0n4Y1Wty3NrR5ebOyVT302op+DOAau+xNEImGMsUWOC3++ZlMooCytKz+NgN8aKGbA==", + "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": "0.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", + "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "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-preset-jest": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.2.0.tgz", + "integrity": "sha512-R1k8kdP3R9phYQugXeNnK/nvCGlBzG4m3EoIIukC80GXb6wCv2XiwPhK6K9MAkQcMszWBYvl2Wm+yigyXFQqXg==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.2.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "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 + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "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 + }, + "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 + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.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 + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "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 + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "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=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "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==", + "dev": true + } + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "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==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "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=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "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-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "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==", + "dev": true + } + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "emittery": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", + "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", + "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==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "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" + } + }, + "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": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expect": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.2.0.tgz", + "integrity": "sha512-8AMBQ9UVcoUXt0B7v+5/U5H6yiUR87L6eKCfjE3spx7Ya5lF+ebUo37MCFBML2OiLfkX1sxmQOZhIDonyVTkcw==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-regex-util": "^26.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "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-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==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "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" + } + }, + "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 + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "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-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "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==", + "dev": true, + "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-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "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==", + "dev": true, + "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==", + "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" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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==", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "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-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-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.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.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.2.1.tgz", + "integrity": "sha512-0uQtQchWwE9xn6ScavTyKpdOqzaDByRhNpqWHVC/WPhikgXL7pkEEZLFFhMhiYcb7l9pdy9jm9wyHfBJYCf9xQ==", + "dev": true, + "requires": { + "@jest/core": "^26.2.1", + "import-local": "^3.0.2", + "jest-cli": "^26.2.1" + }, + "dependencies": { + "jest-cli": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.2.1.tgz", + "integrity": "sha512-5Khbf4zGEi0aMb1DEpAfsiAgEEYnds5NeNA1fB+RIAendUAhBnDKIBsJGjeA8BW/bWD2XmlS9Kdo4ytN9zL7GQ==", + "dev": true, + "requires": { + "@jest/core": "^26.2.1", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.2.1", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "prompts": "^2.0.1", + "yargs": "^15.3.1" + } + } + } + }, + "jest-changed-files": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.2.0.tgz", + "integrity": "sha512-+RyJb+F1K/XBLIYiL449vo5D+CvlHv29QveJUWNPXuUicyZcq+tf1wNxmmFeRvAU1+TzhwqczSjxnCCFt7+8iA==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", + "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "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==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "jest-config": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.2.1.tgz", + "integrity": "sha512-0SzwvRapCZ3DIjKUOzXcgGHbNmGjCayR37U5aF6ecC+97O/r9esT+iHAmIC3fnA04Co61+vQUxYkZp/7hOHgtw==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.2.1", + "@jest/types": "^26.2.0", + "babel-jest": "^26.2.1", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.2.0", + "jest-environment-node": "^26.2.0", + "jest-get-type": "^26.0.0", + "jest-jasmine2": "^26.2.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.2.1", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "micromatch": "^4.0.2", + "pretty-format": "^26.2.0" + } + }, + "jest-diff": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.2.0.tgz", + "integrity": "sha512-Wu4Aopi2nzCsHWLBlD48TgRy3Z7OsxlwvHNd1YSnHc7q1NJfrmyCPoUXrTIrydQOG5ApaYpsAsdfnMbJqV1/wQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.2.0" + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.2.0.tgz", + "integrity": "sha512-gHPCaho1twWHB5bpcfnozlc6mrMi+VAewVPNgmwf81x2Gzr6XO4dl+eOrwPWxbkYlgjgrYjWK2xgKnixbzH3Ew==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-util": "^26.2.0", + "pretty-format": "^26.2.0" + } + }, + "jest-environment-jsdom": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.2.0.tgz", + "integrity": "sha512-sDG24+5M4NuIGzkI3rJW8XUlrpkvIdE9Zz4jhD8OBnVxAw+Y1jUk9X+lAOD48nlfUTlnt3lbAI3k2Ox+WF3S0g==", + "dev": true, + "requires": { + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0", + "jsdom": "^16.2.2" + } + }, + "jest-environment-node": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.2.0.tgz", + "integrity": "sha512-4M5ExTYkJ19efBzkiXtBi74JqKLDciEk4CEsp5tTjWGYMrlKFQFtwIVG3tW1OGE0AlXhZjuHPwubuRYY4j4uOw==", + "dev": true, + "requires": { + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "jest-mock": "^26.2.0", + "jest-util": "^26.2.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-haste-map": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.2.1.tgz", + "integrity": "sha512-3815SlK308fgrbd+5A9I/pzu7kgQ9Ymy7rzgHLIm3lltCHwZ2uNsMxkfmV2fPZBHpcolSE6elYIgYTym7VLtcg==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.2.0", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.1", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.2.1.tgz", + "integrity": "sha512-TgDfzC5MUSleysp14y2by4yuka4TOr3sL1Pjl5hlneT4hilnC5seReuMDTmEXxkzlKdZCxiji2pKty+Iaif7Hw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.2.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.2.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.2.0", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-runtime": "^26.2.1", + "jest-snapshot": "^26.2.1", + "jest-util": "^26.2.0", + "pretty-format": "^26.2.0", + "throat": "^5.0.0" + } + }, + "jest-leak-detector": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.2.0.tgz", + "integrity": "sha512-aQdzTX1YiufkXA1teXZu5xXOJgy7wZQw6OJ0iH5CtQlOETe6gTSocaYKUNui1SzQ91xmqEUZ/WRavg9FD82rtQ==", + "dev": true, + "requires": { + "jest-get-type": "^26.0.0", + "pretty-format": "^26.2.0" + } + }, + "jest-matcher-utils": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.2.0.tgz", + "integrity": "sha512-2cf/LW2VFb3ayPHrH36ZDjp9+CAeAe/pWBAwsV8t3dKcrINzXPVxq8qMWOxwt5BaeBCx4ZupVGH7VIgB8v66vQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.2.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.2.0" + } + }, + "jest-message-util": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.2.0.tgz", + "integrity": "sha512-g362RhZaJuqeqG108n1sthz5vNpzTNy926eNDszo4ncRbmmcMRIUAZibnd6s5v2XSBCChAxQtCoN25gnzp7JbQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.2.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.2.0.tgz", + "integrity": "sha512-XeC7yWtWmWByoyVOHSsE7NYsbXJLtJNgmhD7z4MKumKm6ET0si81bsSLbQ64L5saK3TgsHo2B/UqG5KNZ1Sp/Q==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@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": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.2.1.tgz", + "integrity": "sha512-asFO0Edu5kHCi/umhqf21Qem6XJmYAeOon3DdgvbGZBHXk+rLuOKyNrdPgk8aYZRUvKLhb9tWYK+EOa4uiAmgQ==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.2.0", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.2.1.tgz", + "integrity": "sha512-JGvVD6oiOzXnlCE3RV3IXXZj1+cHjaugwSxqc6SJlBI36gsc5Db6+Rx2r/h6S/mDiHy9YbgVcfBVj4PIKmTbSQ==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.2.1" + } + }, + "jest-runner": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.2.1.tgz", + "integrity": "sha512-mBSmITcwOXC/lIiAIYGXb7WxE2gL9Xxk8at4HDLkQgFFi5GPTZJ7xU+2z/QDHiQQiu6N++4yymN9Bu4kP4N2hw==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/environment": "^26.2.0", + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.2.1", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.2.1", + "jest-leak-detector": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-resolve": "^26.2.1", + "jest-runtime": "^26.2.1", + "jest-util": "^26.2.0", + "jest-worker": "^26.2.1", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.2.1.tgz", + "integrity": "sha512-6Fn8F/+bxLIClajuEcprtpOD9XJmidothOhsn6lrIVm+4LeKlH7ygw9hMsV6ehtzimN+6bAbaseP9yi0iOYXQw==", + "dev": true, + "requires": { + "@jest/console": "^26.2.0", + "@jest/environment": "^26.2.0", + "@jest/fake-timers": "^26.2.0", + "@jest/globals": "^26.2.0", + "@jest/source-map": "^26.1.0", + "@jest/test-result": "^26.2.0", + "@jest/transform": "^26.2.1", + "@jest/types": "^26.2.0", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.2.1", + "jest-haste-map": "^26.2.1", + "jest-message-util": "^26.2.0", + "jest-mock": "^26.2.0", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.2.1", + "jest-snapshot": "^26.2.1", + "jest-util": "^26.2.0", + "jest-validate": "^26.2.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.2.0.tgz", + "integrity": "sha512-V7snZI9IVmyJEu0Qy0inmuXgnMWDtrsbV2p9CRAcmlmPVwpC2ZM8wXyYpiugDQnwLHx0V4+Pnog9Exb3UO8M6Q==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.2.1.tgz", + "integrity": "sha512-z9ks6PDEIgshdwgrPZDS4kv2I6KSuw5x85ctQmAEIquFqO/NRgRdmMcW86UYl8WqAq/V3o64Mh647Pj+JHXWDA==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.2.0", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.2.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.2.0", + "jest-get-type": "^26.0.0", + "jest-haste-map": "^26.2.1", + "jest-matcher-utils": "^26.2.0", + "jest-message-util": "^26.2.0", + "jest-resolve": "^26.2.1", + "natural-compare": "^1.4.0", + "pretty-format": "^26.2.0", + "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "jest-util": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.2.0.tgz", + "integrity": "sha512-YmDwJxLZ1kFxpxPfhSJ0rIkiZOM0PQbRcfH0TzJOhqCisCAsI1WcmoQqO83My9xeVA2k4n+rzg2UuexVKzPpig==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-validate": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.2.0.tgz", + "integrity": "sha512-8XKn3hM6VIVmLNuyzYLCPsRCT83o8jMZYhbieh4dAyKLc4Ypr36rVKC+c8WMpWkfHHpGnEkvWUjjIAyobEIY/Q==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.2.0" + }, + "dependencies": { + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.2.0.tgz", + "integrity": "sha512-674Boco4Joe0CzgKPL6K4Z9LgyLx+ZvW2GilbpYb8rFEUkmDGgsZdv1Hv5rxsRpb1HLgKUOL/JfbttRCuFdZXQ==", + "dev": true, + "requires": { + "@jest/test-result": "^26.2.0", + "@jest/types": "^26.2.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.2.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "26.2.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.2.1.tgz", + "integrity": "sha512-+XcGMMJDTeEGncRb5M5Zq9P7K4sQ1sirhjdOxsN1462h6lFo9w59bl2LVQmdGEEeU3m+maZCkS2Tcc9SfCHO4A==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "dev": true + }, + "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": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.3.0.tgz", + "integrity": "sha512-zggeX5UuEknpdZzv15+MS1dPYG0J/TftiiNunOeNxSl3qr8Z6cIlQpN0IdJa44z9aFxZRIVqRncvEhQ7X5DtZg==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "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.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "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=", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "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.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "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.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "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 + } + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "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 + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.2.tgz", + "integrity": "sha512-ux+n4hPVETuTL8+daJXTOC6uKLgMsl1RYfFv7DKRzyvzBapqco0rZZ9g72ZN8VS6V+gvNYHYa/ofcCY8fkJWsA==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.2.0", + "which": "^2.0.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "optional": true + }, + "uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", + "dev": true, + "optional": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "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" + } + }, + "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 + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.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==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "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" + } + }, + "p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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-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 + }, + "parse-json": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", + "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "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=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "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" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "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=", + "dev": true + }, + "pretty-format": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.2.0.tgz", + "integrity": "sha512-qi/8IuBu2clY9G7qCXgCdD1Bf9w+sXakdHTRToknzMtVy0g7c4MBWaZy7MfB7ndKZovRO6XRwJiAYqq+MC7SDA==", + "dev": true, + "requires": { + "@jest/types": "^26.2.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "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" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "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": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } + } + }, + "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-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "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 + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=", + "dev": true + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "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 + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.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 + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "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.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "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.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "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 + } + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "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==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "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" + } + }, + "throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "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-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "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": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "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=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "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.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "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" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==" + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "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=", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "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==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "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==", + "dev": true + }, + "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" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "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.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "dev": true + }, + "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==", + "dev": true + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dev": true, + "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=", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/source/workflow-import/package.json b/source/workflow-import/package.json new file mode 100644 index 0000000..870305a --- /dev/null +++ b/source/workflow-import/package.json @@ -0,0 +1,27 @@ +{ + "name": "workflow-import", + "version": "1.0.0", + "description": "Populates a new user pool with user profiles, groups and group memberships from the backup table", + "scripts": { + "pretest": "npm ci", + "clean": "rm -rf dist/ node_modules/ coverage/", + "test": "jest test/*.spec.js --coverage --silent", + "package:zip": "cd dist && zip -rq package.zip .", + "package:dist": "mkdir dist && rsync -avr ../utils ./dist/ && rsync -avr --exclude=*test* --exclude=*dist* --exclude=*node_modules* ./ ./dist/$npm_package_name && rsync -avr ./node_modules ./dist/$npm_package_name", + "package": "npm run clean && npm ci --production && npm run package:dist && npm run package:zip", + "build": "npm run clean && rm -f package-lock.json && npm install" + }, + "author": { + "name": "aws-solutions-builder" + }, + "license": "Apache-2.0", + "devDependencies": { + "aws-sdk": "*", + "axios-mock-adapter": "*", + "jest": "*" + }, + "dependencies": { + "axios": "^0.19.2", + "uuid": "^8.3.0" + } +} diff --git a/source/workflow-import/scan-table.js b/source/workflow-import/scan-table.js new file mode 100644 index 0000000..452f361 --- /dev/null +++ b/source/workflow-import/scan-table.js @@ -0,0 +1,165 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +const docClient = new AWS.DynamoDB.DocumentClient(); +const cognitoISP = new AWS.CognitoIdentityServiceProvider(); +const sqs = new AWS.SQS(); +const { sleep } = require('../utils/helper-functions'); +const { BACKUP_TABLE_NAME, TYPE_GROUP, TYPE_USER, COGNITO_TPS, + TYPE_TIMESTAMP, NEW_USERS_QUEUE_URL, NEW_USERS_UPDATES_QUEUE_URL } = process.env; +const uuid = require('uuid'); +const ONE_MINUTE = 1000 * 60; + +/** + * Scans the backup table and queues items for the Import Workflow + * @param {object} event Lambda event payload + * @param {object} context Lambda Context + */ +exports.handler = async (event, context) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const cognitoTPS = parseInt(COGNITO_TPS, 10); + if (isNaN(cognitoTPS)) { + throw new Error(`Unable to parse a number from the COGNITO_TPS value (${COGNITO_TPS})`); + } + + let newUserPoolId; + try { + const { Context } = event; + newUserPoolId = Context.Execution.Input.NewUserPoolId.trim(); + if (!newUserPoolId) { + throw new Error('Unable to determine the new user pool ID'); + } + } catch (err) { + console.error(err); + throw new Error('Unable to determine the new user pool ID'); + } + + const result = {}; + + const scanParams = { + TableName: BACKUP_TABLE_NAME + }; + + if (event.Input.LastEvaluatedKey) { + scanParams.ExclusiveStartKey = event.Input.LastEvaluatedKey; + } + let scanResponse; + + do { + console.log(`Scanning: ${JSON.stringify(scanParams)}`); + scanResponse = await docClient.scan(scanParams).promise(); + if (scanResponse.Items && scanResponse.Items.length > 0) { + console.log(`Found ${scanResponse.Items.length} item(s)`); + + // Send user messages to the New User Queue + await sendMessagesToQueue(scanResponse.Items.filter(msg => msg.type === TYPE_USER), NEW_USERS_QUEUE_URL); + + // Send group membership or deactivated user messages to the New User Updates Queue + await sendMessagesToQueue( + scanResponse.Items.filter(msg => { + if (msg.type === TYPE_TIMESTAMP) { + return false; + } else if (msg.type !== TYPE_USER && msg.type !== TYPE_GROUP) { + // This is a group membership record + return true; + } else if (msg.type === TYPE_USER && !msg.userEnabled) { + // This user is not enabled in the user pool + return true; + } + return false; + }), + NEW_USERS_UPDATES_QUEUE_URL); + + const groupMessages = scanResponse.Items.filter(msg => msg.type === TYPE_GROUP); + + while (groupMessages.length > 0) { + let cognitoApiCallCount = 0; + let currentTime = new Date().getTime(); + const oneSecondFromNow = currentTime + 1000; + + while (groupMessages.length > 0 && (cognitoApiCallCount < cognitoTPS) && (currentTime < oneSecondFromNow)) { + const group = groupMessages.splice(0, 1)[0]; + const { groupName, groupDescription, groupPrecedence } = group; + await addGroup(groupName, groupDescription, groupPrecedence, newUserPoolId); + cognitoApiCallCount++; + + currentTime = new Date().getTime(); + } + + if (groupMessages.length > 0 && (cognitoApiCallCount >= cognitoTPS) && (currentTime < oneSecondFromNow)) { + const waitTime = (oneSecondFromNow - currentTime); + console.log(`Cognito transactions per second limit (${cognitoTPS}) reached. Waiting for ${(oneSecondFromNow - currentTime)}ms before proceeding`); + await sleep(0, waitTime); + } + } + } else { + console.log('No items found'); + } + + // Check if there are more items to read from the Backup Table + delete scanParams.ExclusiveStartKey; + if (scanResponse.LastEvaluatedKey) { + scanParams.ExclusiveStartKey = scanResponse.LastEvaluatedKey; + } + } while (scanParams.ExclusiveStartKey && context.getRemainingTimeInMillis() > ONE_MINUTE); + + if (scanResponse.LastEvaluatedKey) { + result.LastEvaluatedKey = scanResponse.LastEvaluatedKey; + result.AllGroupsProcessed = 'No'; + } else { + result.AllGroupsProcessed = 'Yes'; + } + + console.log(`Result: ${JSON.stringify(result)}`); + return { result: result }; +}; + +/** + * Adds a group to the new user pool + * @param {string} groupName Group Name + * @param {string} groupDescription Group Description + * @param {number} groupPrecedence Group Precedence + * @param {string} newUserPoolId The ID of the import user pool + */ +const addGroup = async (groupName, groupDescription, groupPrecedence, newUserPoolId) => { + const createGroupParams = { UserPoolId: newUserPoolId, GroupName: groupName, Description: groupDescription }; + if (groupPrecedence >= 0) { + createGroupParams.Precedence = groupPrecedence; + } + + console.log(`Creating group: ${JSON.stringify(createGroupParams)}`); + const response = await cognitoISP.createGroup(createGroupParams).promise(); + console.log(`Create group response: ${JSON.stringify(response)}`); +}; + +/** + * Sends messages to the supplied queue so they can be processed by further steps of the Import Workflow + * @param {object[]} messages An array of messages to send to the queue + * @param {string} queueUrl The URL of the queue to which the messages will be sent + */ +const sendMessagesToQueue = async (messages, queueUrl) => { + if (messages.length > 0) { + console.log(`Found ${messages.length} ${queueUrl === NEW_USERS_QUEUE_URL ? 'new user' : 'update (i.e. group membership)'} message(s) to add to the queue`); + + while (messages.length > 0) { + const sendMessageBatchParams = { + QueueUrl: queueUrl, + Entries: messages.splice(0, 10).map(msg => { + return { + Id: uuid.v4(), + MessageBody: JSON.stringify(msg) + }; + }) + }; + + console.log(`Adding batch of ${sendMessageBatchParams.Entries.length} message(s) to the New User queue`); + await sqs.sendMessageBatch(sendMessageBatchParams).promise(); + console.log('Message(s) added to the New User queue'); + } + } +}; diff --git a/source/workflow-import/test/check-new-user-pool.spec.js b/source/workflow-import/test/check-new-user-pool.spec.js new file mode 100644 index 0000000..f470427 --- /dev/null +++ b/source/workflow-import/test/check-new-user-pool.spec.js @@ -0,0 +1,132 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock AWS SDK +const mockCognito = { + listUsers: jest.fn(), + listGroups: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + CognitoIdentityServiceProvider: jest.fn(() => ({ + listUsers: mockCognito.listUsers, + listGroups: mockCognito.listGroups + })) + }; +}); + +describe('check-new-user-pool', function () { + beforeEach(() => { + process.env.NEW_USER_POOL_ID = 'user-pool-id'; + for (const mockFn in mockCognito) { + mockCognito[mockFn].mockReset(); + } + }); + + it('Returns NewUserPoolEmpty=false if the new user pool has users in it', async function () { + mockCognito.listUsers.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Users: [{ + id: 'user-id', + username: 'username' + }] + }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } } + } + }; + const lambda = require('../check-new-user-pool'); + const result = await lambda.handler(event); + expect(result).toEqual({ result: { NewUserPoolEmpty: false } }) + }); + + it('Throws an error if the user pool id is not supplied', async function () { + const event = { + Context: { + Execution: { Input: { NewUserPoolId: '' } } + } + }; + + const lambda = require('../check-new-user-pool'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('Unable to determine the new user pool ID'); + }); + + it('Returns NewUserPoolEmpty=false if the new user pool has groups in it', async function () { + mockCognito.listUsers.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Users: [] + }); + } + }; + }); + + mockCognito.listGroups.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Groups: [{ + groupName: 'name', + groupDescription: 'desc' + }] + }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } } + } + }; + const lambda = require('../check-new-user-pool'); + const result = await lambda.handler(event); + expect(result).toEqual({ result: { NewUserPoolEmpty: false } }) + }); + + it('Returns NewUserPoolEmpty=true if the new user pool has no users or groups in it', async function () { + mockCognito.listUsers.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Users: [] + }); + } + }; + }); + + mockCognito.listGroups.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Groups: [] + }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } } + } + }; + const lambda = require('../check-new-user-pool'); + const result = await lambda.handler(event); + expect(result).toEqual({ result: { NewUserPoolEmpty: true } }) + }); +}); \ No newline at end of file diff --git a/source/workflow-import/test/import-users.spec.js b/source/workflow-import/test/import-users.spec.js new file mode 100644 index 0000000..84c8512 --- /dev/null +++ b/source/workflow-import/test/import-users.spec.js @@ -0,0 +1,447 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock AWS SDK +const mockCognitoISP = { + getCSVHeader: jest.fn(), + createUserImportJob: jest.fn(), + startUserImportJob: jest.fn(), + describeUserImportJob: jest.fn(), + adminAddUserToGroup: jest.fn(), + adminDisableUser: jest.fn() +}; + +const mockDocClient = { + scan: jest.fn() +}; + +const mockSqs = { + sendMessageBatch: jest.fn(), + receiveMessage: jest.fn(), + deleteMessageBatch: jest.fn() +}; + +const mockS3 = { + scan: jest.fn(), + putObject: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + CognitoIdentityServiceProvider: jest.fn(() => ({ + getCSVHeader: mockCognitoISP.getCSVHeader, + createUserImportJob: mockCognitoISP.createUserImportJob, + startUserImportJob: mockCognitoISP.startUserImportJob, + describeUserImportJob: mockCognitoISP.describeUserImportJob, + adminAddUserToGroup: mockCognitoISP.adminAddUserToGroup, + adminDisableUser: mockCognitoISP.adminDisableUser + })), + DynamoDB: { + DocumentClient: jest.fn(() => ({ + scan: mockDocClient.scan + })) + }, + SQS: jest.fn(() => ({ + sendMessageBatch: mockSqs.sendMessageBatch, + receiveMessage: mockSqs.receiveMessage, + deleteMessageBatch: mockSqs.deleteMessageBatch + })), + S3: jest.fn(() => ({ + scan: mockS3.scan, + putObject: mockS3.putObject + })) + }; +}); + +// Mock Axios +const axios = require('axios'); +const MockAdapter = require('axios-mock-adapter'); +const axiosMock = new MockAdapter(axios); +axiosMock.onPut('/pre-signed-url').reply(200); + +// Mock metrics client +const Metrics = require('../../utils/metrics'); +jest.mock('../../utils/metrics'); + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function () { + return 100000; + } +}; + +beforeAll(() => { + process.env = Object.assign(process.env, { + AWS_REGION: 'us-east-2', + USER_IMPORT_JOB_MAPPING_FILES_BUCKET: 'mapping-bucket', + SEND_METRIC: 'Yes', + METRICS_ANONYMOUS_UUID: 'uuid', + SOLUTION_ID: 'SOMock', + SOLUTION_VERSION: 'v1.0.0', + NEW_USERS_QUEUE_URL: 'queue-url', + NEW_USERS_UPDATES_QUEUE_URL: 'another-queue-url', + COGNITO_TPS: '10', + TYPE_USER: 'user-type', + TYPE_GROUP: 'group-type' + }); + + for (const mockFn in mockCognitoISP) { + mockCognitoISP[mockFn].mockReset(); + } + + for (const mockFn in mockDocClient) { + mockDocClient[mockFn].mockReset(); + } + + for (const mockFn in mockSqs) { + mockSqs[mockFn].mockReset(); + } +}); + +describe('import-new-users: Unknown State Name', function () { + it('Throws error for unknown state name', async function () { + mockDocClient.scan.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'Unknown' } + } + }; + const lambda = require('../import-users'); + await expect(async () => { + await lambda.handler(event, context); + }).rejects.toThrow('Unknown StateName: Unknown'); + }); +}); + +describe('import-new-users: ImportNewUsers', function () { + it('Returns when no messages are returned from the Queue', async function () { + mockSqs.receiveMessage.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ Messages: [] }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'ImportNewUsers' } + } + }; + const lambda = require('../import-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + ImportJobStatus: '', + QueueEmpty: true, + StateName: event.Context.State.Name + } + }); + }); + + it('Creates an import job when a new user is added and returns the job id', async function () { + mockSqs.receiveMessage.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Messages: [ + { + Body: JSON.stringify({ + id: 'row-id', + type: 'user : uuid', + username: 'test-user', + userAttributes: [{ + Name: 'sub', + Value: 'uuid' + }], + userEnabled: true + }) + } + ] + }); + } + }; + }).mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Messages: [] + }); + } + }; + }); + + mockCognitoISP.getCSVHeader.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ CSVHeader: ['cognito:username', 'cognito:mfa_enabled', 'custom:foobar', 'email_verified', 'phone_number_verified'] }); + } + }; + }); + + mockSqs.sendMessageBatch.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockSqs.deleteMessageBatch.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockCognitoISP.createUserImportJob.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ UserImportJob: { JobId: 'job-id', Status: 'Pending', PreSignedUrl: '/pre-signed-url' } }); + } + }; + }); + + mockS3.putObject.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockCognitoISP.startUserImportJob.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ UserImportJob: { JobId: 'job-id', Status: 'Pending', PreSignedUrl: '/pre-signed-url' } }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'ImportNewUsers' } + } + }; + const lambda = require('../import-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + ImportJobStatus: 'Pending', + ImportJobId: 'job-id', + QueueEmpty: false, + StateName: event.Context.State.Name + } + }); + }); + + it('Throws an error when the sub can\'t be retrieved', async function () { + mockSqs.receiveMessage.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Messages: [ + { + Body: JSON.stringify({ + id: 'row-id', + type: 'user : uuid', + username: 'test-user', + userAttributes: [{ + Name: 'not-the-sub', + Value: 'uuid' + }], + userEnabled: true + }) + } + ] + }); + } + }; + }); + + mockCognitoISP.getCSVHeader.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ CSVHeader: ['cognito:username', 'cognito:mfa_enabled', 'custom:foobar', 'email_verified', 'phone_number_verified'] }); + } + }; + }); + + mockSqs.sendMessageBatch.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockSqs.deleteMessageBatch.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'ImportNewUsers' } + } + }; + const lambda = require('../import-users'); + await expect(async () => { + await lambda.handler(event, context); + }).rejects.toThrow('Unable to extract user\'s sub attribute'); + }); +}); + +describe('import-new-users: CheckUserImportJob', function () { + it('Throws an error when the job fails', async function () { + mockCognitoISP.describeUserImportJob.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ UserImportJob: { Status: 'Failed', JobId: 'job-id' } }); + } + }; + }); + + Metrics.sendAnonymousMetric.mockImplementationOnce(async (x, y, z) => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'CheckUserImportJob' } + }, + Input: { ImportJobId: 'job-id' } + }; + + const lambda = require('../import-users'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('User import job with ID "job-id" was detected to have a status of "Failed" in us-east-2.\n\nPlease check the CloudWatch logs for this Cognito user import job and use the mapping file (job-id-user-mapping.csv) that has been saved in this the solution\'s S3 bucket (mapping-bucket) to cross-reference the line numbers reported the user import job CloudWatch logs'); + }); + + it('Returns the expected result when the job is still Pending', async function () { + mockCognitoISP.describeUserImportJob.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ UserImportJob: { Status: 'Pending', JobId: 'job-id' } }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'CheckUserImportJob' } + }, + Input: { ImportJobId: 'job-id' } + }; + const lambda = require('../import-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + ImportJobStatus: 'Pending', + ImportJobId: 'job-id', + StateName: event.Context.State.Name + } + }); + }); + + it('Returns the expected result when the job is still InProgress', async function () { + mockCognitoISP.describeUserImportJob.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ UserImportJob: { Status: 'InProgress', JobId: 'job-id' } }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'CheckUserImportJob' } + }, + Input: { ImportJobId: 'job-id' } + }; + const lambda = require('../import-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + ImportJobStatus: 'InProgress', + ImportJobId: 'job-id', + StateName: event.Context.State.Name + } + }); + }); + + it('Returns the expected result when the job Succeeded', async function () { + mockCognitoISP.describeUserImportJob.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ UserImportJob: { Status: 'Succeeded', JobId: 'job-id' } }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'CheckUserImportJob' } + }, + Input: { ImportJobId: 'job-id' } + }; + const lambda = require('../import-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + ImportJobStatus: 'Succeeded', + ImportJobId: 'job-id', + StateName: event.Context.State.Name + } + }); + }); +}); + +describe('import-new-users: Errors', function () { + beforeEach(() => { + jest.resetModules(); + process.env = Object.assign(process.env, { COGNITO_TPS: 'invalid' }); + }); + + it('Throws an error if the user pool id is not supplied', async function () { + const event = { + Context: { + Execution: { Input: { NewUserPoolId: '' } } + } + }; + + const lambda = require('../import-users'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('Unable to determine the new user pool ID'); + }); +}); diff --git a/source/workflow-import/test/scan-table.spec.js b/source/workflow-import/test/scan-table.spec.js new file mode 100644 index 0000000..9e7ddd6 --- /dev/null +++ b/source/workflow-import/test/scan-table.spec.js @@ -0,0 +1,348 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function () { + return 100000; + } +}; + +// Mock AWS SDK +const mockCognitoISP = { + getGroup: jest.fn(), + updateGroup: jest.fn(), + createGroup: jest.fn() +}; + +const mockDocClient = { + scan: jest.fn() +}; + +const mockSqs = { + sendMessageBatch: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + CognitoIdentityServiceProvider: jest.fn(() => ({ + getGroup: mockCognitoISP.getGroup, + updateGroup: mockCognitoISP.updateGroup, + createGroup: mockCognitoISP.createGroup + })), + DynamoDB: { + DocumentClient: jest.fn(() => ({ + scan: mockDocClient.scan + })) + }, + SQS: jest.fn(() => ({ + sendMessageBatch: mockSqs.sendMessageBatch + })) + }; +}); + +beforeAll(() => { + process.env = Object.assign(process.env, { + BACKUP_TABLE_NAME: 'backup-table', + USER_POOL_ID: 'user-pool-id', TYPE_GROUP: 'group-type', + TYPE_USER: 'user-type', COGNITO_TPS: '10', + TYPE_TIMESTAMP: 'timestamp-type', + NEW_USERS_QUEUE_URL: 'new-user-queue', + NEW_USERS_UPDATES_QUEUE_URL: 'new-users-updates-queue' + }); + + for (const mockFn in mockCognitoISP) { + mockCognitoISP[mockFn].mockReset(); + } + + for (const mockFn in mockDocClient) { + mockDocClient[mockFn].mockReset(); + } + + for (const mockFn in mockSqs) { + mockSqs[mockFn].mockReset(); + } + + context.getRemainingTimeInMillis = function () { + return 100000; + } +}); + +describe('groups', function () { + it('Returns Yes if no groups are returned', async function () { + mockDocClient.scan.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } } + }, + Input: { LastEvaluatedKey: 'last-key' } + }; + const lambda = require('../scan-table'); + const result = await lambda.handler(event); + expect(result).toEqual({ + result: { AllGroupsProcessed: 'Yes' } + }); + }); + + it('Returns No if a LastEvaluatedKey is returned and the function is out of time', async function () { + context.getRemainingTimeInMillis = function () { + return 1; + } + + mockDocClient.scan.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ LastEvaluatedKey: 'another-key' }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } } + }, + Input: { LastEvaluatedKey: 'last-key' } + }; + const lambda = require('../scan-table'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { AllGroupsProcessed: 'No', LastEvaluatedKey: 'another-key' } + }); + }); + + it('Returns "No" if only a sync timestamp is returned', async function () { + context.getRemainingTimeInMillis = function () { + return 1; + } + + mockDocClient.scan.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Items: [ + { + latestExportTimestamp: new Date().getTime(), + type: 'timestamp-type' + } + ] + }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } } + }, + Input: { LastEvaluatedKey: 'last-key' } + }; + const lambda = require('../scan-table'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { AllGroupsProcessed: 'Yes' } + }); + }); + + it('Returns "Yes" when one group needs to be added', async function () { + mockDocClient.scan.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Items: [ + { + id: 'GROUP-12345', + type: 'group-type', + groupName: 'group-name-2', + groupDescription: 'desc-2', + groupPrecedence: 1 + } + ] + }); + } + }; + }); + + mockCognitoISP.createGroup.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } } + }, + Input: { LastEvaluatedKey: 'last-key' } + }; + const lambda = require('../scan-table'); + const result = await lambda.handler(event); + expect(result).toEqual({ + result: { AllGroupsProcessed: 'Yes' } + }); + }); + + it('Returns "Yes" a new user needs to be disabled', async function () { + mockDocClient.scan.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Items: [ + { + id: 'USER-12345', + type: 'user-type', + userEnabled: false + } + ] + }); + } + }; + }); + + mockSqs.sendMessageBatch.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }).mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } } + }, + Input: { LastEvaluatedKey: 'last-key' } + }; + const lambda = require('../scan-table'); + const result = await lambda.handler(event); + expect(result).toEqual({ + result: { AllGroupsProcessed: 'Yes' } + }); + }); + + it('Returns "Yes" for a group membership message', async function () { + mockDocClient.scan.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Items: [ + { + id: 'USER-12345', + type: 'group-member:group1', + userEnabled: false + } + ] + }); + } + }; + }); + + mockSqs.sendMessageBatch.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } } + }, + Input: { LastEvaluatedKey: 'last-key' } + }; + const lambda = require('../scan-table'); + const result = await lambda.handler(event); + expect(result).toEqual({ + result: { AllGroupsProcessed: 'Yes' } + }); + }); + + it('Throws an error if Cognito throws an unexpected error', async function () { + mockDocClient.scan.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Items: [ + { + id: 'GROUP-12345', + type: 'group-type', + groupName: 'group-name-2', + groupDescription: 'desc-2', + groupPrecedence: 1 + } + ] + }); + } + }; + }); + + mockCognitoISP.createGroup.mockImplementationOnce(() => { + return { + promise() { + return Promise.reject({ code: 'UnexpectedError' }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } } + }, + Input: { LastEvaluatedKey: 'last-key' } + }; + const lambda = require('../scan-table'); + try { + await lambda.handler(event); + } catch (err) { + expect(err.code).toEqual('UnexpectedError') + } + }); + + it('Throws an error if the user pool id is not supplied', async function () { + const event = { + Context: { + Execution: { Input: { NewUserPoolId: '' } } + } + }; + + const lambda = require('../scan-table'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('Unable to determine the new user pool ID'); + }); +}); + +describe('groups-invalid CognitoTPS', function () { + beforeEach(() => { + jest.resetModules(); + process.env = Object.assign(process.env, { COGNITO_TPS: 'invalid' }); + }); + + it('Throws an error if an invalid CognitoTPS value is set', async function () { + const event = { LastEvaluatedKey: 'last-key' }; + const lambda = require('../scan-table'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('Unable to parse a number from the COGNITO_TPS value (invalid)'); + }); +}); diff --git a/source/workflow-import/test/update-new-users.spec.js b/source/workflow-import/test/update-new-users.spec.js new file mode 100644 index 0000000..eb64197 --- /dev/null +++ b/source/workflow-import/test/update-new-users.spec.js @@ -0,0 +1,373 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +// Mock AWS SDK +const mockCognitoISP = { + getCSVHeader: jest.fn(), + createUserImportJob: jest.fn(), + startUserImportJob: jest.fn(), + describeUserImportJob: jest.fn(), + adminAddUserToGroup: jest.fn(), + adminDisableUser: jest.fn() +}; + +const mockDocClient = { + scan: jest.fn() +}; + +const mockSqs = { + sendMessageBatch: jest.fn(), + receiveMessage: jest.fn(), + deleteMessageBatch: jest.fn() +}; + +const mockS3 = { + scan: jest.fn(), + putObject: jest.fn() +}; + +jest.mock('aws-sdk', () => { + return { + CognitoIdentityServiceProvider: jest.fn(() => ({ + getCSVHeader: mockCognitoISP.getCSVHeader, + createUserImportJob: mockCognitoISP.createUserImportJob, + startUserImportJob: mockCognitoISP.startUserImportJob, + describeUserImportJob: mockCognitoISP.describeUserImportJob, + adminAddUserToGroup: mockCognitoISP.adminAddUserToGroup, + adminDisableUser: mockCognitoISP.adminDisableUser + })), + DynamoDB: { + DocumentClient: jest.fn(() => ({ + scan: mockDocClient.scan + })) + }, + SQS: jest.fn(() => ({ + sendMessageBatch: mockSqs.sendMessageBatch, + receiveMessage: mockSqs.receiveMessage, + deleteMessageBatch: mockSqs.deleteMessageBatch + })), + S3: jest.fn(() => ({ + scan: mockS3.scan, + putObject: mockS3.putObject + })), + config: { + update: jest.fn() + } + }; +}); + +// Mock Axios +const axios = require('axios'); +const MockAdapter = require('axios-mock-adapter'); +const axiosMock = new MockAdapter(axios); +axiosMock.onPut('/pre-signed-url').reply(200); + +// Mock metrics client +const Metrics = require('../../utils/metrics'); +jest.mock('../../utils/metrics'); + +// Mock context +const context = { + logStreamName: 'log-stream', + getRemainingTimeInMillis: function () { + return 100000; + } +}; + +beforeAll(() => { + process.env = Object.assign(process.env, { + AWS_REGION: 'us-east-2', + USER_IMPORT_JOB_MAPPING_FILES_BUCKET: 'mapping-bucket', + SEND_METRIC: 'Yes', + METRICS_ANONYMOUS_UUID: 'uuid', + SOLUTION_ID: 'SOMock', + SOLUTION_VERSION: 'v1.0.0', + NEW_USERS_QUEUE_URL: 'queue-url', + NEW_USERS_UPDATES_QUEUE_URL: 'another-queue-url', + COGNITO_TPS: '10', + TYPE_USER: 'user-type', + TYPE_GROUP: 'group-type' + }); + + for (const mockFn in mockCognitoISP) { + mockCognitoISP[mockFn].mockReset(); + } + + for (const mockFn in mockDocClient) { + mockDocClient[mockFn].mockReset(); + } + + for (const mockFn in mockSqs) { + mockSqs[mockFn].mockReset(); + } +}); + +describe('import-new-users: UpdateNewUsers', function () { + it('Returns when no messages are returned from the Queue', async function () { + mockSqs.receiveMessage.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ Messages: [] }); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'UpdateNewUsers' } + } + }; + const lambda = require('../update-new-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + QueueEmpty: true, + StateName: event.Context.State.Name + } + }); + }); + + it('Returns when a user was added but no groups to add', async function () { + mockSqs.receiveMessage.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Messages: [ + { + Body: JSON.stringify({ + id: 'row-id', + type: 'user : uuid', + username: 'test-user', + userAttributes: [{ + Name: 'sub', + Value: 'uuid' + }], + userEnabled: false + }) + } + ] + }); + } + }; + }).mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Messages: [] + }); + } + }; + }); + + mockCognitoISP.adminAddUserToGroup.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockSqs.deleteMessageBatch.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'UpdateNewUsers' } + } + }; + const lambda = require('../update-new-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + QueueEmpty: true, + StateName: event.Context.State.Name + } + }); + }); + + it('Returns when a user was added and a group needs to be added', async function () { + mockSqs.receiveMessage.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Messages: [ + { + Body: JSON.stringify({ + id: 'row-id', + type: 'user : uuid', + username: 'test-user', + userAttributes: [{ + Name: 'sub', + Value: 'uuid' + }], + userEnabled: true + }) + } + ] + }); + } + }; + }).mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Messages: [] + }); + } + }; + }); + + mockDocClient.scan.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Items: [{ + id: 'group-name:group', + GroupName: 'group-name' + }] + }); + } + }; + }); + + mockSqs.deleteMessageBatch.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockCognitoISP.adminAddUserToGroup.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'UpdateNewUsers' } + } + }; + const lambda = require('../update-new-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + QueueEmpty: true, + StateName: event.Context.State.Name + } + }); + }); + + it('Returns when a user was added and then needs to be disabled', async function () { + mockSqs.receiveMessage.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Messages: [ + { + Body: JSON.stringify({ + id: 'row-id', + type: 'user-type', + username: 'test-user', + userAttributes: [{ + Name: 'sub', + Value: 'uuid' + }], + userEnabled: false + }) + } + ] + }); + } + }; + }).mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({ + Messages: [] + }); + } + }; + }); + + mockSqs.deleteMessageBatch.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + mockCognitoISP.adminDisableUser.mockImplementationOnce(() => { + return { + promise() { + return Promise.resolve({}); + } + }; + }); + + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'UpdateNewUsers' } + } + }; + const lambda = require('../update-new-users'); + const result = await lambda.handler(event, context); + expect(result).toEqual({ + result: { + QueueEmpty: true, + StateName: event.Context.State.Name + } + }); + }); +}); + +describe('import-new-users: Errors', function () { + beforeEach(() => { + jest.resetModules(); + process.env = Object.assign(process.env, { COGNITO_TPS: 'invalid' }); + }); + + it('Throws an error if an invalid CognitoTPS value is set', async function () { + const event = { + Context: { + Execution: { Input: { NewUserPoolId: 'user-pool-id' } }, + State: { Name: 'UpdateNewUsers' } + }, + Input: { LastEvaluatedKey: 'last-key' } + }; + const lambda = require('../update-new-users'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('Unable to parse a number from the COGNITO_TPS value (invalid)'); + }); + + it('Throws an error if the user pool id is not supplied', async function () { + const event = { + Context: { + Execution: { Input: { NewUserPoolId: '' } } + } + }; + + const lambda = require('../update-new-users'); + await expect(async () => { + await lambda.handler(event); + }).rejects.toThrow('Unable to determine the new user pool ID'); + }); +}); diff --git a/source/workflow-import/update-new-users.js b/source/workflow-import/update-new-users.js new file mode 100644 index 0000000..bd9693a --- /dev/null +++ b/source/workflow-import/update-new-users.js @@ -0,0 +1,173 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +/** + * @author Solution Builders + */ + +const AWS = require('aws-sdk'); +// 5-second timeout for API calls +AWS.config.update({ httpOptions: { connectTimeout: 5000, timeout: 5000 } }); +const cognitoISP = new AWS.CognitoIdentityServiceProvider(); +const sqs = new AWS.SQS(); +const { COGNITO_TPS, NEW_USERS_UPDATES_QUEUE_URL, TYPE_USER } = process.env; +const { sleep, getExponentialBackoffTimeInMS } = require('../utils/helper-functions'); +const oneMinuteInMS = 1000 * 60; + +/** + * Updates users that have been imported to the new user pool + * @param {object} event + */ +exports.handler = async (event, context) => { + console.log(`Received event: ${JSON.stringify(event, null, 2)}`); + const { Context, Input } = event; + let result = { ...Input }; + let StateName = ''; + let newUserPoolId; + try { + newUserPoolId = Context.Execution.Input.NewUserPoolId.trim(); + if (!newUserPoolId) { + throw new Error('Unable to determine the new user pool ID'); + } + } catch (err) { + console.error(err); + throw new Error('Unable to determine the new user pool ID'); + } + + if (Context && Context.State) { + StateName = Context.State.Name; + result.StateName = StateName; + } + + result = { ...result, ... await updateNewUsers(context, newUserPoolId) }; + + console.log(`Result: ${JSON.stringify(result)}`); + return { result }; +}; + +/** + * Reads messages off the New Users Updates queue and applies any updates (i.e. add to group or disable the user) + * @param {object} context Lambda context + * @param {string} newUserPoolId The ID of the import user pool + */ +const updateNewUsers = async (context, newUserPoolId) => { + const cognitoTPS = parseInt(COGNITO_TPS, 10); + if (isNaN(cognitoTPS)) { + throw new Error(`Unable to parse a number from the COGNITO_TPS value (${COGNITO_TPS})`); + } + + const output = { QueueEmpty: true }; + let cognitoApiCallCount = 0; + let currentTime = new Date().getTime(); + let oneSecondFromNow = currentTime + 1000; + do { + const receiveMessageParams = { QueueUrl: NEW_USERS_UPDATES_QUEUE_URL, MaxNumberOfMessages: 10, WaitTimeSeconds: 3 }; + console.log(`Getting messages off Update Queue: ${JSON.stringify(receiveMessageParams)}`); + const receiveMessageResult = await sqs.receiveMessage(receiveMessageParams).promise(); + + if (receiveMessageResult.Messages && receiveMessageResult.Messages.length > 0) { + console.log(`Read ${receiveMessageResult.Messages.length} message(s) off the queue`); + output.QueueEmpty = false; + const deleteMessageBatchParams = { QueueUrl: NEW_USERS_UPDATES_QUEUE_URL, Entries: [] }; + + for (let i = 0; i < receiveMessageResult.Messages.length; i++) { + const message = receiveMessageResult.Messages[i]; + const msgBody = JSON.parse(message.Body); + let processed = false; + let numAttempts = 1; + + while (!processed) { + try { + if (cognitoApiCallCount >= cognitoTPS) { + const waitTime = (oneSecondFromNow - currentTime) + 1; + console.log(`Cognito transactions per second limit (${cognitoTPS}) reached. Waiting for ${(oneSecondFromNow - currentTime)}ms before proceeding`); + await sleep(0, waitTime); + } + + currentTime = new Date().getTime(); + if (cognitoApiCallCount >= cognitoTPS || currentTime >= oneSecondFromNow) { + // Reset oneSecondFromNow and cognitoApiCallCount + console.log('Resetting Cognito TPS timer and API call count'); + oneSecondFromNow = currentTime + 1000; + cognitoApiCallCount = 0; + } + + cognitoApiCallCount++; + if (msgBody.type === TYPE_USER && !msgBody.userEnabled) { + await disableUser(msgBody.pseudoUsername, newUserPoolId); + } else { + await addUserToGroup(msgBody.groupPseudoUsername, msgBody.groupName, newUserPoolId); + } + + deleteMessageBatchParams.Entries.push({ Id: message.MessageId, ReceiptHandle: message.ReceiptHandle }); + processed = true; + } catch (err) { + console.error(err); + + if (context.getRemainingTimeInMillis() > oneMinuteInMS && err.retryable) { + const sleepTimeInMs = getExponentialBackoffTimeInMS(100, numAttempts, oneMinuteInMS, true); + numAttempts++; + console.log(`Sleeping for ${sleepTimeInMs} milliseconds and will attempt to process the message again. That will be attempt #${numAttempts}`); + await sleep(0, sleepTimeInMs); + } else { + throw err; + } + } + } + } + + if (deleteMessageBatchParams.Entries.length > 0) { + let batchDeleted = false; + let numAttempts = 1; + while (!batchDeleted) { + try { + console.log(`Deleting a batch of ${deleteMessageBatchParams.Entries.length} message(s) from the Update Queue`); + await sqs.deleteMessageBatch(deleteMessageBatchParams).promise(); + console.log('Message batch deleted'); + batchDeleted = true; + } catch (err) { + console.error(err); + if (err.retryable) { + const sleepTimeInMs = getExponentialBackoffTimeInMS(50, numAttempts, 1000, false); + numAttempts++; + console.log(`Sleeping for ${sleepTimeInMs} milliseconds and will attempt to delete the batch again. That will be attempt #${numAttempts}`); + await sleep(0, sleepTimeInMs); + } else { + throw err; + } + } + } + } + } else { + console.log('No messages in queue'); + output.QueueEmpty = true; + } + } while (!output.QueueEmpty && context.getRemainingTimeInMillis() > oneMinuteInMS); + + return output; +}; + +/** + * Disables a user in the primary user pool + * @param {string} username User name + * @param {string} newUserPoolId The ID of the import user pool + */ +const disableUser = async (username, newUserPoolId) => { + const params = { UserPoolId: newUserPoolId, Username: username }; + console.log('Disabling user...'); + await cognitoISP.adminDisableUser(params).promise(); + console.log('User disabled'); +}; + +/** + * Adds the user to the supplied group + * @param {string} username Username for the user + * @param {string} groupName Name of the group + * @param {string} newUserPoolId The ID of the import user pool + */ +const addUserToGroup = async (username, groupName, newUserPoolId) => { + const addUserToGroupParams = { UserPoolId: newUserPoolId, GroupName: groupName, Username: username }; + console.log(`Adding user to group (${groupName})`); + await cognitoISP.adminAddUserToGroup(addUserToGroupParams).promise(); + console.log('User added to group'); +};