diff --git a/.dockerignore b/.dockerignore index 20691a16..f98de6cc 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,8 +5,18 @@ docs /infrastructure /blueprint test +/tools/deployment-cli-tools .github .git .vscode /deployment -skaffold.yaml \ No newline at end of file +skaffold.yaml +*.egg-info +__pycache__ +.hypothesis +.coverage +.pytest_cache +/application-templates +/deployment-configuration +/cloud-harness +.openapi-generator \ No newline at end of file diff --git a/.github/workflows/trivy-analysis.yml b/.github/workflows/trivy-analysis.yml index a367b926..4b73cabc 100644 --- a/.github/workflows/trivy-analysis.yml +++ b/.github/workflows/trivy-analysis.yml @@ -23,14 +23,14 @@ jobs: contents: read # for actions/checkout to fetch code security-events: write # for github/codeql-action/upload-sarif to upload SARIF results name: Build - runs-on: "ubuntu-18.04" + runs-on: "ubuntu-20.04" steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Build an image from Dockerfile run: | - docker build -t cloudharness-base:${{ github.sha }} . -f ./infrastructure/base-images/cloudharness-base/Dockerfile + DOCKER_BUILDKIT=1 docker build -t cloudharness-base:${{ github.sha }} . -f ./infrastructure/base-images/cloudharness-base/Dockerfile - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@2a2157eb22c08c9a1fac99263430307b8d1bc7a2 diff --git a/.gitignore b/.gitignore index 45798e1b..90f643c0 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ skaffold.yaml .tox .pytest_cache .overrides -deployment.yaml +/deployment.yaml .hypothesis -__pycache__ \ No newline at end of file +__pycache__ +.env \ No newline at end of file diff --git a/application-templates/django-app/Dockerfile b/application-templates/django-app/Dockerfile index fb89e042..f40e9560 100644 --- a/application-templates/django-app/Dockerfile +++ b/application-templates/django-app/Dockerfile @@ -21,7 +21,8 @@ WORKDIR ${APP_DIR} RUN mkdir -p ${APP_DIR}/static/www COPY backend/requirements.txt ${APP_DIR} -RUN pip3 install --no-cache-dir -r requirements.txt +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip3 install --no-cache-dir -r requirements.txt --prefer-binary COPY backend/requirements.txt backend/setup.py ${APP_DIR} RUN python3 -m pip install -e . diff --git a/application-templates/flask-server/backend/Dockerfile b/application-templates/flask-server/backend/Dockerfile index 44ae6bf5..d0bc723c 100644 --- a/application-templates/flask-server/backend/Dockerfile +++ b/application-templates/flask-server/backend/Dockerfile @@ -8,7 +8,8 @@ ENV PORT=8080 COPY requirements.txt /usr/src/app/ -RUN pip3 install --no-cache-dir -r requirements.txt +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip3 install --no-cache-dir -r requirements.txt COPY . /usr/src/app diff --git a/application-templates/webapp/frontend/package-lock.json b/application-templates/webapp/frontend/package-lock.json deleted file mode 100644 index 9f88d053..00000000 --- a/application-templates/webapp/frontend/package-lock.json +++ /dev/null @@ -1,8800 +0,0 @@ -{ - "name": "samples", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/compat-data": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz", - "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==", - "dev": true - }, - "@babel/core": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", - "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.10", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^5.4.1", - "source-map": "^0.5.0" - } - }, - "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.11", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", - "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", - "dev": true, - "requires": { - "@babel/types": "^7.12.10" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", - "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", - "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.12.5", - "@babel/helper-validator-option": "^7.12.1", - "browserslist": "^4.14.5", - "semver": "^5.5.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz", - "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4" - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", - "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "regexpu-core": "^4.7.1" - } - }, - "@babel/helper-define-map": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", - "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/types": "^7.10.5", - "lodash": "^4.17.19" - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz", - "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.1" - } - }, - "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", - "dev": true, - "requires": { - "@babel/types": "^7.12.10" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", - "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", - "dev": true, - "requires": { - "@babel/types": "^7.12.7" - } - }, - "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.5" - } - }, - "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "lodash": "^4.17.19" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", - "dev": true, - "requires": { - "@babel/types": "^7.12.10" - } - }, - "@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-remap-async-to-generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", - "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-wrap-function": "^7.10.4", - "@babel/types": "^7.12.1" - } - }, - "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" - } - }, - "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.1" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", - "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", - "dev": true, - "requires": { - "@babel/types": "^7.12.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", - "dev": true, - "requires": { - "@babel/types": "^7.12.11" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", - "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", - "dev": true - }, - "@babel/helper-wrap-function": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz", - "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, - "@babel/helpers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", - "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", - "dev": true, - "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" - } - }, - "@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" - } - }, - "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz", - "integrity": "sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.12.1", - "@babel/plugin-syntax-async-generators": "^7.8.0" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", - "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", - "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz", - "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz", - "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.0" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz", - "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", - "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz", - "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", - "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz", - "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz", - "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz", - "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", - "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@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-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", - "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@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-jsx": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", - "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", - "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz", - "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz", - "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.12.1" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz", - "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz", - "integrity": "sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", - "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-define-map": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz", - "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", - "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz", - "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz", - "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz", - "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz", - "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz", - "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz", - "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz", - "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz", - "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz", - "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.12.1", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz", - "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-identifier": "^7.10.4", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz", - "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", - "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", - "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz", - "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", - "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz", - "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz", - "integrity": "sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz", - "integrity": "sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.12.10", - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.12.1", - "@babel/types": "^7.12.12" - } - }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.12.tgz", - "integrity": "sha512-i1AxnKxHeMxUaWVXQOSIco4tvVvvCxMSfeBMnMM06mpaJt3g+MpxYQQrDfojUQldP1xxraPSJYSMEljoWM/dCg==", - "dev": true, - "requires": { - "@babel/plugin-transform-react-jsx": "^7.12.12" - } - }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz", - "integrity": "sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", - "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.2" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz", - "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz", - "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz", - "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz", - "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz", - "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz", - "integrity": "sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz", - "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", - "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/preset-env": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.11.tgz", - "integrity": "sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.12.7", - "@babel/helper-compilation-targets": "^7.12.5", - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-option": "^7.12.11", - "@babel/plugin-proposal-async-generator-functions": "^7.12.1", - "@babel/plugin-proposal-class-properties": "^7.12.1", - "@babel/plugin-proposal-dynamic-import": "^7.12.1", - "@babel/plugin-proposal-export-namespace-from": "^7.12.1", - "@babel/plugin-proposal-json-strings": "^7.12.1", - "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", - "@babel/plugin-proposal-numeric-separator": "^7.12.7", - "@babel/plugin-proposal-object-rest-spread": "^7.12.1", - "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.12.7", - "@babel/plugin-proposal-private-methods": "^7.12.1", - "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.12.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.0", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.12.1", - "@babel/plugin-transform-arrow-functions": "^7.12.1", - "@babel/plugin-transform-async-to-generator": "^7.12.1", - "@babel/plugin-transform-block-scoped-functions": "^7.12.1", - "@babel/plugin-transform-block-scoping": "^7.12.11", - "@babel/plugin-transform-classes": "^7.12.1", - "@babel/plugin-transform-computed-properties": "^7.12.1", - "@babel/plugin-transform-destructuring": "^7.12.1", - "@babel/plugin-transform-dotall-regex": "^7.12.1", - "@babel/plugin-transform-duplicate-keys": "^7.12.1", - "@babel/plugin-transform-exponentiation-operator": "^7.12.1", - "@babel/plugin-transform-for-of": "^7.12.1", - "@babel/plugin-transform-function-name": "^7.12.1", - "@babel/plugin-transform-literals": "^7.12.1", - "@babel/plugin-transform-member-expression-literals": "^7.12.1", - "@babel/plugin-transform-modules-amd": "^7.12.1", - "@babel/plugin-transform-modules-commonjs": "^7.12.1", - "@babel/plugin-transform-modules-systemjs": "^7.12.1", - "@babel/plugin-transform-modules-umd": "^7.12.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", - "@babel/plugin-transform-new-target": "^7.12.1", - "@babel/plugin-transform-object-super": "^7.12.1", - "@babel/plugin-transform-parameters": "^7.12.1", - "@babel/plugin-transform-property-literals": "^7.12.1", - "@babel/plugin-transform-regenerator": "^7.12.1", - "@babel/plugin-transform-reserved-words": "^7.12.1", - "@babel/plugin-transform-shorthand-properties": "^7.12.1", - "@babel/plugin-transform-spread": "^7.12.1", - "@babel/plugin-transform-sticky-regex": "^7.12.7", - "@babel/plugin-transform-template-literals": "^7.12.1", - "@babel/plugin-transform-typeof-symbol": "^7.12.10", - "@babel/plugin-transform-unicode-escapes": "^7.12.1", - "@babel/plugin-transform-unicode-regex": "^7.12.1", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.12.11", - "core-js-compat": "^3.8.0", - "semver": "^5.5.0" - } - }, - "@babel/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/preset-react": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.12.10.tgz", - "integrity": "sha512-vtQNjaHRl4DUpp+t+g4wvTHsLQuye+n0H/wsXIZRn69oz/fvNC7gQ4IK73zGJBaxvHoxElDvnYCthMcT7uzFoQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-transform-react-display-name": "^7.12.1", - "@babel/plugin-transform-react-jsx": "^7.12.10", - "@babel/plugin-transform-react-jsx-development": "^7.12.7", - "@babel/plugin-transform-react-pure-annotations": "^7.12.1" - } - }, - "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" - } - }, - "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" - } - }, - "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", - "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==", - "dev": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.4", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.4", - "fastq": "^1.6.0" - } - }, - "@npmcli/move-file": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", - "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", - "dev": true, - "requires": { - "mkdirp": "^1.0.4" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "@types/anymatch": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", - "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", - "dev": true - }, - "@types/eslint": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz", - "integrity": "sha512-I+1sYH+NPQ3/tVqCeUSBwTE/0heyvtXqpIopUUArlBm0Kpocb8FbMa3AZ/ASKIFpN3rnEx932TTXDbt9OXsNDw==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", - "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.45", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.45.tgz", - "integrity": "sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==", - "dev": true - }, - "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/node": { - "version": "14.14.20", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", - "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==", - "dev": true - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/tapable": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz", - "integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==", - "dev": true - }, - "@types/uglify-js": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.11.1.tgz", - "integrity": "sha512-7npvPKV+jINLu1SpSYVWG8KvyJBhBa8tmzMMdDoVc2pWUYHN8KIXlPJhjJ4LT97c4dXJA2SHL/q6ADbDriZN+Q==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "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 - } - } - }, - "@types/webpack": { - "version": "4.41.25", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.25.tgz", - "integrity": "sha512-cr6kZ+4m9lp86ytQc1jPOJXgINQyz3kLLunZ57jznW+WIAL0JqZbGubQk4GlD42MuQL5JGOABrxdpqqWeovlVQ==", - "dev": true, - "requires": { - "@types/anymatch": "*", - "@types/node": "*", - "@types/tapable": "*", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "source-map": "^0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "@types/webpack-sources": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz", - "integrity": "sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "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 - } - } - }, - "@typescript-eslint/experimental-utils": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", - "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.34.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - }, - "dependencies": { - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - } - } - }, - "@typescript-eslint/typescript-estree": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", - "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/info": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.1.tgz", - "integrity": "sha512-fLnDML5HZ5AEKzHul8xLAksoKN2cibu6MgonkUj8R9V7bbeVRkd1XbGEGWrAUNYHbX1jcqCsDEpBviE5StPMzQ==", - "dev": true, - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.2.1.tgz", - "integrity": "sha512-Zj1z6AyS+vqV6Hfi7ngCjFGdHV5EwZNIHo6QfFTNe9PyW+zBU1zJ9BiOW1pmUEq950RC4+Dym6flyA/61/vhyw==", - "dev": true - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "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" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "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" - }, - "dependencies": { - "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" - } - } - } - }, - "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-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "array-includes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz", - "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "get-intrinsic": "^1.0.1", - "is-string": "^1.0.5" - } - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "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 - }, - "array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" - } - }, - "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 - }, - "ast-types": { - "version": "0.9.6", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", - "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "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 - }, - "awesome-typescript-loader": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/awesome-typescript-loader/-/awesome-typescript-loader-5.2.1.tgz", - "integrity": "sha512-slv66OAJB8orL+UUaTI3pKlLorwIvS4ARZzYR9iJJyGsEgOqueMfOMdKySWzZ73vIkEe3fcwFgsKMg4d8zyb1g==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.1.0", - "lodash": "^4.17.5", - "micromatch": "^3.1.9", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.3", - "webpack-log": "^1.2.0" - } - }, - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - } - }, - "babel-helper-evaluate-path": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz", - "integrity": "sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA==", - "dev": true - }, - "babel-helper-flip-expressions": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.4.3.tgz", - "integrity": "sha1-NpZzahKKwYvCUlS19AoizrPB0/0=", - "dev": true - }, - "babel-helper-is-nodes-equiv": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz", - "integrity": "sha1-NOmzALFHnd2Y7HfqC76TQt/jloQ=", - "dev": true - }, - "babel-helper-is-void-0": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-is-void-0/-/babel-helper-is-void-0-0.4.3.tgz", - "integrity": "sha1-fZwBtFYee5Xb2g9u7kj1tg5nMT4=", - "dev": true - }, - "babel-helper-mark-eval-scopes": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz", - "integrity": "sha1-0kSjvvmESHJgP/tG4izorN9VFWI=", - "dev": true - }, - "babel-helper-remove-or-void": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz", - "integrity": "sha1-pPA7QAd6D/6I5F0HAQ3uJB/1rmA=", - "dev": true - }, - "babel-helper-to-multiple-sequence-expressions": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz", - "integrity": "sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA==", - "dev": true - }, - "babel-loader": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz", - "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==", - "dev": true, - "requires": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^1.4.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-minify-builtins": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.5.0.tgz", - "integrity": "sha512-wpqbN7Ov5hsNwGdzuzvFcjgRlzbIeVv1gMIlICbPj0xkexnfoIDe7q+AZHMkQmAE/F9R5jkrB6TLfTegImlXag==", - "dev": true - }, - "babel-plugin-minify-constant-folding": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.5.0.tgz", - "integrity": "sha512-Vj97CTn/lE9hR1D+jKUeHfNy+m1baNiJ1wJvoGyOBUx7F7kJqDZxr9nCHjO/Ad+irbR3HzR6jABpSSA29QsrXQ==", - "dev": true, - "requires": { - "babel-helper-evaluate-path": "^0.5.0" - } - }, - "babel-plugin-minify-dead-code-elimination": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.5.1.tgz", - "integrity": "sha512-x8OJOZIrRmQBcSqxBcLbMIK8uPmTvNWPXH2bh5MDCW1latEqYiRMuUkPImKcfpo59pTUB2FT7HfcgtG8ZlR5Qg==", - "dev": true, - "requires": { - "babel-helper-evaluate-path": "^0.5.0", - "babel-helper-mark-eval-scopes": "^0.4.3", - "babel-helper-remove-or-void": "^0.4.3", - "lodash": "^4.17.11" - } - }, - "babel-plugin-minify-flip-comparisons": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.4.3.tgz", - "integrity": "sha1-AMqHDLjxO0XAOLPB68DyJyk8llo=", - "dev": true, - "requires": { - "babel-helper-is-void-0": "^0.4.3" - } - }, - "babel-plugin-minify-guarded-expressions": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.4.tgz", - "integrity": "sha512-RMv0tM72YuPPfLT9QLr3ix9nwUIq+sHT6z8Iu3sLbqldzC1Dls8DPCywzUIzkTx9Zh1hWX4q/m9BPoPed9GOfA==", - "dev": true, - "requires": { - "babel-helper-evaluate-path": "^0.5.0", - "babel-helper-flip-expressions": "^0.4.3" - } - }, - "babel-plugin-minify-infinity": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.4.3.tgz", - "integrity": "sha1-37h2obCKBldjhO8/kuZTumB7Oco=", - "dev": true - }, - "babel-plugin-minify-mangle-names": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.5.0.tgz", - "integrity": "sha512-3jdNv6hCAw6fsX1p2wBGPfWuK69sfOjfd3zjUXkbq8McbohWy23tpXfy5RnToYWggvqzuMOwlId1PhyHOfgnGw==", - "dev": true, - "requires": { - "babel-helper-mark-eval-scopes": "^0.4.3" - } - }, - "babel-plugin-minify-numeric-literals": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.4.3.tgz", - "integrity": "sha1-jk/VYcefeAEob/YOjF/Z3u6TwLw=", - "dev": true - }, - "babel-plugin-minify-replace": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.5.0.tgz", - "integrity": "sha512-aXZiaqWDNUbyNNNpWs/8NyST+oU7QTpK7J9zFEFSA0eOmtUNMU3fczlTTTlnCxHmq/jYNFEmkkSG3DDBtW3Y4Q==", - "dev": true - }, - "babel-plugin-minify-simplify": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.5.1.tgz", - "integrity": "sha512-OSYDSnoCxP2cYDMk9gxNAed6uJDiDz65zgL6h8d3tm8qXIagWGMLWhqysT6DY3Vs7Fgq7YUDcjOomhVUb+xX6A==", - "dev": true, - "requires": { - "babel-helper-evaluate-path": "^0.5.0", - "babel-helper-flip-expressions": "^0.4.3", - "babel-helper-is-nodes-equiv": "^0.0.1", - "babel-helper-to-multiple-sequence-expressions": "^0.5.0" - } - }, - "babel-plugin-minify-type-constructors": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.4.3.tgz", - "integrity": "sha1-G8bxW4f3qxCF1CszC3F2V6IVZQA=", - "dev": true, - "requires": { - "babel-helper-is-void-0": "^0.4.3" - } - }, - "babel-plugin-module-resolver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz", - "integrity": "sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==", - "dev": true, - "requires": { - "find-babel-config": "^1.2.0", - "glob": "^7.1.6", - "pkg-up": "^3.1.0", - "reselect": "^4.0.0", - "resolve": "^1.13.1" - } - }, - "babel-plugin-transform-inline-consecutive-adds": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz", - "integrity": "sha1-Mj1Ho+pjqDp6w8gRro5pQfrysNE=", - "dev": true - }, - "babel-plugin-transform-member-expression-literals": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz", - "integrity": "sha1-NwOcmgwzE6OUlfqsL/OmtbnQOL8=", - "dev": true - }, - "babel-plugin-transform-merge-sibling-variables": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.4.tgz", - "integrity": "sha1-hbQi/DN3tEnJ0c3kQIcgNTJAHa4=", - "dev": true - }, - "babel-plugin-transform-minify-booleans": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz", - "integrity": "sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg=", - "dev": true - }, - "babel-plugin-transform-property-literals": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz", - "integrity": "sha1-mMHSHiVXNlc/k+zlRFn2ziSYXTk=", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "babel-plugin-transform-regexp-constructors": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.4.3.tgz", - "integrity": "sha1-WLd3W2OvzzMyj66aX4j71PsLSWU=", - "dev": true - }, - "babel-plugin-transform-remove-console": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz", - "integrity": "sha1-uYA2DAZzhOJLNXpYjYB9PINSd4A=", - "dev": true - }, - "babel-plugin-transform-remove-debugger": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz", - "integrity": "sha1-QrcnYxyXl44estGZp67IShgznvI=", - "dev": true - }, - "babel-plugin-transform-remove-undefined": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.5.0.tgz", - "integrity": "sha512-+M7fJYFaEE/M9CXa0/IRkDbiV3wRELzA1kKQFCJ4ifhrzLKn/9VCCgj9OFmYWwBd8IB48YdgPkHYtbYq+4vtHQ==", - "dev": true, - "requires": { - "babel-helper-evaluate-path": "^0.5.0" - } - }, - "babel-plugin-transform-simplify-comparison-operators": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz", - "integrity": "sha1-9ir+CWyrDh9ootdT/fKDiIRxzrk=", - "dev": true - }, - "babel-plugin-transform-undefined-to-void": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz", - "integrity": "sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA=", - "dev": true - }, - "babel-preset-minify": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.5.1.tgz", - "integrity": "sha512-1IajDumYOAPYImkHbrKeiN5AKKP9iOmRoO2IPbIuVp0j2iuCcj0n7P260z38siKMZZ+85d3mJZdtW8IgOv+Tzg==", - "dev": true, - "requires": { - "babel-plugin-minify-builtins": "^0.5.0", - "babel-plugin-minify-constant-folding": "^0.5.0", - "babel-plugin-minify-dead-code-elimination": "^0.5.1", - "babel-plugin-minify-flip-comparisons": "^0.4.3", - "babel-plugin-minify-guarded-expressions": "^0.4.4", - "babel-plugin-minify-infinity": "^0.4.3", - "babel-plugin-minify-mangle-names": "^0.5.0", - "babel-plugin-minify-numeric-literals": "^0.4.3", - "babel-plugin-minify-replace": "^0.5.0", - "babel-plugin-minify-simplify": "^0.5.1", - "babel-plugin-minify-type-constructors": "^0.4.3", - "babel-plugin-transform-inline-consecutive-adds": "^0.4.3", - "babel-plugin-transform-member-expression-literals": "^6.9.4", - "babel-plugin-transform-merge-sibling-variables": "^6.9.4", - "babel-plugin-transform-minify-booleans": "^6.9.4", - "babel-plugin-transform-property-literals": "^6.9.4", - "babel-plugin-transform-regexp-constructors": "^0.4.3", - "babel-plugin-transform-remove-console": "^6.9.4", - "babel-plugin-transform-remove-debugger": "^6.9.4", - "babel-plugin-transform-remove-undefined": "^0.5.0", - "babel-plugin-transform-simplify-comparison-operators": "^6.9.4", - "babel-plugin-transform-undefined-to-void": "^6.9.4", - "lodash": "^4.17.11" - } - }, - "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" - } - } - } - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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" - } - } - } - }, - "browserslist": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", - "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001173", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.634", - "escalade": "^3.1.1", - "node-releases": "^1.1.69" - } - }, - "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 - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "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" - } - }, - "call-bind": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.1.tgz", - "integrity": "sha512-tvAvUwNcRikl3RVF20X9lsYmmepsovzTWeJiXjO0PkJp15uy/6xKFZOQtuiSULwYW+6ToZBprphCgWXC2dSgcQ==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", - "dev": true, - "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001174", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001174.tgz", - "integrity": "sha512-tqClL/4ThQq6cfFXH3oJL4rifFBeM6gTkphjao5kgwMaW9yn0tKgQLAEfKzDwj6HQWCB/aWo8kTFlSvIN8geEA==", - "dev": true - }, - "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" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "dependencies": { - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - } - } - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "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" - } - } - } - }, - "clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "clean-webpack-plugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz", - "integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==", - "dev": true, - "requires": { - "@types/webpack": "^4.4.31", - "del": "^4.1.1" - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true - }, - "clipboard-copy": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-3.2.0.tgz", - "integrity": "sha512-vooFaGFL6ulEP1liiaWFBmmfuPm3cY3y7T9eB83ZTnYc/oFeAKsq3NcDrOkBC8XaauEE8zHQwI7k0+JSYiVQSQ==" - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "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": "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 - }, - "colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", - "dev": true - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "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 - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "compression-webpack-plugin": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-7.1.2.tgz", - "integrity": "sha512-9DKNW6ILLjx+bNBoviHDgLx6swBhWWH9ApClC9sTH2NoFfQM47BapQfovCm9zjD9v1uZwInF5a925FB9ErGQeQ==", - "dev": true, - "requires": { - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1" - }, - "dependencies": { - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "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 - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "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" - } - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-anything": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.1.tgz", - "integrity": "sha512-lA57e7viQHOdPQcrytv5jFeudZZOXuyk47lZym279FiDQ8jeZomXiGuVf6ffMKkJ+3TIai3J1J3yi6M+/4U35g==", - "dev": true, - "requires": { - "is-what": "^3.7.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 - }, - "copy-webpack-plugin": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz", - "integrity": "sha512-MXyPCjdPVx5iiWyl40Va3JGh27bKzOTNY3NjUTrosD2q7dR/cLD0013uqJ3BpFbUjyONINjb6qI7nDIJujrMbA==", - "dev": true, - "requires": { - "cacache": "^15.0.5", - "fast-glob": "^3.2.4", - "find-cache-dir": "^3.3.1", - "glob-parent": "^5.1.1", - "globby": "^11.0.1", - "loader-utils": "^2.0.0", - "normalize-path": "^3.0.0", - "p-limit": "^3.0.2", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "webpack-sources": "^1.4.3" - }, - "dependencies": { - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "cacache": { - "version": "15.0.5", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz", - "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==", - "dev": true, - "requires": { - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.0", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "globby": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", - "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "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" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "ssri": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", - "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", - "dev": true, - "requires": { - "minipass": "^3.1.1" - } - } - } - }, - "core-js-compat": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.2.tgz", - "integrity": "sha512-LO8uL9lOIyRRrQmZxHZFl1RV+ZbcsAkFWTktn5SmH40WgLtSNYN4m4W2v9ONT147PxBY/XrRhrWq8TlvObyUjQ==", - "dev": true, - "requires": { - "browserslist": "^4.16.0", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "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" - } - }, - "css-loader": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", - "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^1.2.3", - "normalize-path": "^3.0.0", - "postcss": "^7.0.32", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.2", - "postcss-modules-scope": "^2.2.0", - "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^2.7.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 - } - } - }, - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", - "dev": true - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "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-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "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 - }, - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "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" - } - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", - "dev": true, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "requires": { - "utila": "~0.4" - } - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz", - "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==", - "dev": true - } - } - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - }, - "dependencies": { - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "requires": { - "tslib": "^2.0.3" - } - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", - "dev": true - } - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.635", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.635.tgz", - "integrity": "sha512-RRriZOLs9CpW6KTLmgBqyUdnY0QNqqWs0HOtuQGGEMizOTNNn1P7sGRBxARnUeLejOsgwjDyRqT3E/CSst02ZQ==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "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" - } - }, - "enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - } - } - }, - "entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "dev": true - }, - "envinfo": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.3.tgz", - "integrity": "sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA==", - "dev": true - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "es6-templates": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz", - "integrity": "sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ=", - "dev": true, - "requires": { - "recast": "~0.11.12", - "through": "~2.3.6" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - } - } - }, - "eslint-plugin-jest": { - "version": "23.20.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", - "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "^2.5.0" - } - }, - "eslint-plugin-react": { - "version": "7.22.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz", - "integrity": "sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==", - "dev": true, - "requires": { - "array-includes": "^3.1.1", - "array.prototype.flatmap": "^1.2.3", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "object.entries": "^1.1.2", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", - "prop-types": "^15.7.2", - "resolve": "^1.18.1", - "string.prototype.matchall": "^4.0.2" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - } - } - }, - "eslint-plugin-react-hooks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-3.0.0.tgz", - "integrity": "sha512-EjxTHxjLKIBWFgDJdhKKzLh5q+vjTFrqNZX36uIxWS4OfyXe5DawqPj3U5qeJ1ngLwatjzQnmR0Lz0J0YH3kxw==", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - }, - "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "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 - }, - "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "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 - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", - "dev": true - }, - "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", - "dev": true, - "requires": { - "original": "^1.0.0" - } - }, - "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" - } - }, - "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 - } - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - } - } - }, - "ext": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", - "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dev": true, - "requires": { - "type": "^2.0.0" - }, - "dependencies": { - "type": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.1.0.tgz", - "integrity": "sha512-G9absDWvhAWCV2gmF1zKud3OyC61nZDwWvBL2DApaVFogI07CprggiQAOOjvp2NRjYWFzPyu7vwtDrQFq8jeSA==", - "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" - } - } - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "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" - } - } - } - }, - "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-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" - }, - "dependencies": { - "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" - } - }, - "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" - } - }, - "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 - }, - "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" - } - }, - "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" - } - } - } - }, - "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 - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true - }, - "fastparse": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", - "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", - "dev": true - }, - "fastq": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", - "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "file-loader": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-5.1.0.tgz", - "integrity": "sha512-u/VkLGskw3Ue59nyOwUwXI/6nuBCo7KBkniB/l7ICwr/7cPNGsL1WCXUp3GB0qgOOKU1TiP49bv4DZF/LJqprg==", - "dev": true, - "requires": { - "loader-utils": "^1.4.0", - "schema-utils": "^2.5.0" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "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" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.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" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "find-babel-config": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", - "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", - "dev": true, - "requires": { - "json5": "^0.5.1", - "path-exists": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "follow-redirects": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", - "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==" - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "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" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "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 - }, - "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" - } - }, - "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "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 - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "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": { - "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" - } - } - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - } - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "html-entities": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", - "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", - "dev": true - }, - "html-loader": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-0.5.5.tgz", - "integrity": "sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog==", - "dev": true, - "requires": { - "es6-templates": "^0.2.3", - "fastparse": "^1.1.1", - "html-minifier": "^3.5.8", - "loader-utils": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "html-minifier": { - "version": "3.5.21", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", - "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", - "dev": true, - "requires": { - "camel-case": "3.0.x", - "clean-css": "4.2.x", - "commander": "2.17.x", - "he": "1.2.x", - "param-case": "2.1.x", - "relateurl": "0.2.x", - "uglify-js": "3.4.x" - } - }, - "html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", - "dev": true, - "requires": { - "camel-case": "^4.1.1", - "clean-css": "^4.2.3", - "commander": "^4.1.1", - "he": "^1.2.0", - "param-case": "^3.0.3", - "relateurl": "^0.2.7", - "terser": "^4.6.3" - }, - "dependencies": { - "camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true - }, - "param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "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 - }, - "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", - "dev": true - } - } - }, - "html-webpack-plugin": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.1.tgz", - "integrity": "sha512-yzK7RQZwv9xB+pcdHNTjcqbaaDZ+5L0zJHXfi89iWIZmb/FtzxhLk0635rmJihcQbs3ZUF27Xp4oWGx6EK56zg==", - "dev": true, - "requires": { - "@types/html-minifier-terser": "^5.0.0", - "@types/tapable": "^1.0.5", - "@types/webpack": "^4.41.8", - "html-minifier-terser": "^5.0.1", - "loader-utils": "^1.2.3", - "lodash": "^4.17.20", - "pretty-error": "^2.1.1", - "tapable": "^1.1.3", - "util.promisify": "1.0.0" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "http-parser-js": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", - "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", - "dev": true - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "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" - } - }, - "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "dev": true, - "requires": { - "postcss": "^7.0.14" - } - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", - "dev": true, - "optional": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^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 - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "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 - }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - } - }, - "internal-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", - "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", - "dev": true, - "requires": { - "es-abstract": "^1.17.0-next.1", - "has": "^1.0.3", - "side-channel": "^1.0.2" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } - } - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "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 - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "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-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.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-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", - "dev": true - }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "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-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true - }, - "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-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-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "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" - } - } - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "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-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "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-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-what": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.12.0.tgz", - "integrity": "sha512-2ilQz5/f/o9V7WRWJQmpFYNmQFZ9iM+OXRonZKcYgTkCzjb949Vi4h282PD1UfmgHk666rcWonbRJ++KI41VGw==", - "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": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "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 - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "dependencies": { - "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 - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "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-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-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", - "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" - } - }, - "jsx-ast-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", - "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", - "dev": true, - "requires": { - "array-includes": "^3.1.2", - "object.assign": "^4.1.2" - } - }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", - "dev": true - }, - "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 - }, - "less": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/less/-/less-3.13.1.tgz", - "integrity": "sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw==", - "dev": true, - "requires": { - "copy-anything": "^2.0.1", - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "native-request": "^1.0.5", - "source-map": "~0.6.0", - "tslib": "^1.10.0" - }, - "dependencies": { - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "optional": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "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, - "optional": true - } - } - }, - "less-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-5.0.0.tgz", - "integrity": "sha512-bquCU89mO/yWLaUq0Clk7qCsKhsF/TZpJUzETRvJa9KSVEL9SO3ovCvdEHISBhrC81OwC8QSVX7E0bzElZj9cg==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "loader-utils": "^1.1.0", - "pify": "^4.0.1" - } - }, - "less-vars-to-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/less-vars-to-js/-/less-vars-to-js-1.3.0.tgz", - "integrity": "sha512-xeiLLn/IMCGtdyCkYQnW8UuzoW2oYMCKg9boZRaGI58fLz5r90bNJDlqGzmVt/1Uqk75/DxIVtQSNCMkE5fRZQ==", - "dev": true, - "requires": { - "strip-json-comments": "^2.0.1" - } - }, - "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" - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "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.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "loglevel": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", - "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", - "dev": true - }, - "loglevelnext": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", - "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==", - "dev": true, - "requires": { - "es6-symbol": "^3.1.1", - "object.assign": "^4.1.0" - } - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "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 - } - } - }, - "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" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "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 - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "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" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", - "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", - "dev": true - }, - "mime-types": { - "version": "2.1.28", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", - "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", - "dev": true, - "requires": { - "mime-db": "1.45.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "mini-create-react-context": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", - "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", - "requires": { - "@babel/runtime": "^7.12.1", - "tiny-warning": "^1.0.3" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "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 - }, - "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "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" - } - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "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 - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } - }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", - "dev": true, - "optional": 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" - } - }, - "native-request": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.0.8.tgz", - "integrity": "sha512-vU2JojJVelUGp6jRcLwToPoWGxSx23z/0iX+I77J3Ht17rf2INGjrhOoQnjVo60nQd8wVsgzKkPfRXBiVdD2ag==", - "dev": true, - "optional": true - }, - "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 - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "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 - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "requires": { - "lower-case": "^1.1.1" - } - }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "dev": true - }, - "node-releases": { - "version": "1.1.69", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.69.tgz", - "integrity": "sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "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" - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "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-inspect": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", - "dev": true - }, - "object-is": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.4.tgz", - "integrity": "sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-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.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", - "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" - } - }, - "object.fromentries": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz", - "integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz", - "integrity": "sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "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" - } - }, - "object.values": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz", - "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "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": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, - "requires": { - "is-wsl": "^1.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" - } - }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "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-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "dev": true, - "requires": { - "retry": "^0.12.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 - }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", - "dev": true, - "requires": { - "no-case": "^2.2.0" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - }, - "dependencies": { - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "requires": { - "tslib": "^2.0.3" - } - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", - "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-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "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-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "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 - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "requires": { - "isarray": "0.0.1" - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.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" - } - }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "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 - }, - "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "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 - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dev": true, - "requires": { - "postcss": "^7.0.5" - } - }, - "postcss-modules-local-by-default": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", - "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", - "dev": true, - "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.32", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", - "dev": true, - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - } - }, - "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", - "dev": true, - "requires": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" - } - }, - "postcss-selector-parser": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz", - "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1", - "util-deprecate": "^1.0.2" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "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-error": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", - "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", - "dev": true, - "requires": { - "lodash": "^4.17.20", - "renderkid": "^2.0.4" - } - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "dev": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "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.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - } - } - }, - "raw-loader": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", - "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" - } - }, - "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==" - }, - "react-router": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", - "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", - "requires": { - "@babel/runtime": "^7.1.2", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "mini-create-react-context": "^0.4.0", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "react-router-dom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", - "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", - "requires": { - "@babel/runtime": "^7.1.2", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.2.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "recast": { - "version": "0.11.23", - "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", - "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", - "dev": true, - "requires": { - "ast-types": "0.9.6", - "esprima": "~3.1.0", - "private": "~0.1.5", - "source-map": "~0.5.0" - }, - "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - } - } - }, - "rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", - "dev": true, - "requires": { - "regenerate": "^1.4.0" - } - }, - "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" - }, - "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "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" - } - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } - } - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "regexpu-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", - "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", - "dev": true, - "requires": { - "regenerate": "^1.4.0", - "regenerate-unicode-properties": "^8.2.0", - "regjsgen": "^0.5.1", - "regjsparser": "^0.6.4", - "unicode-match-property-ecmascript": "^1.0.4", - "unicode-match-property-value-ecmascript": "^1.2.0" - } - }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "regjsparser": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.6.tgz", - "integrity": "sha512-jjyuCp+IEMIm3N1H1LLTJW1EISEJV9+5oHdEyrt43Pg9cDSb6rrLZei2cVWpl0xTjmmlpec/lEQGYgM7xfpGCQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "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 - }, - "renderkid": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz", - "integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==", - "dev": true, - "requires": { - "css-select": "^2.0.2", - "dom-converter": "^0.2", - "htmlparser2": "^3.10.1", - "lodash": "^4.17.20", - "strip-ansi": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "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 - }, - "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 - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "reselect": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz", - "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==", - "dev": true - }, - "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "dev": true, - "requires": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - } - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, - "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 - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "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 - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true - }, - "run-parallel": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", - "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", - "dev": true - }, - "rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "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 - }, - "scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz", - "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==", - "dev": true, - "requires": { - "node-forge": "^0.10.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.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" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "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" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "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" - } - } - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "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 - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "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 - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "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 - } - } - }, - "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" - } - } - } - }, - "sockjs": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", - "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", - "dev": true, - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^3.4.0", - "websocket-driver": "^0.7.4" - } - }, - "sockjs-client": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.0.tgz", - "integrity": "sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==", - "dev": true, - "requires": { - "debug": "^3.2.6", - "eventsource": "^1.0.7", - "faye-websocket": "^0.11.3", - "inherits": "^2.0.4", - "json3": "^3.3.3", - "url-parse": "^1.4.7" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "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 - }, - "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" - }, - "dependencies": { - "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-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 - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "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 - }, - "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" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string.prototype.matchall": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz", - "integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has-symbols": "^1.0.1", - "internal-slot": "^1.0.2", - "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.3" - } - }, - "string.prototype.trimend": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", - "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", - "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "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 - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "style-loader": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz", - "integrity": "sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^2.7.0" - }, - "dependencies": { - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } - } - }, - "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" - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "terser": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.5.1.tgz", - "integrity": "sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "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 - } - } - }, - "terser-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", - "dev": true, - "requires": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.5.1" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "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 - } - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "tiny-invariant": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", - "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "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": "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" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsutils": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.19.1.tgz", - "integrity": "sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "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-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typescript": { - "version": "3.9.7", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", - "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", - "dev": true - }, - "uglify-js": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", - "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", - "dev": true, - "requires": { - "commander": "~2.19.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", - "dev": true - }, - "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 - } - } - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^1.0.4", - "unicode-property-aliases-ecmascript": "^1.0.4" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", - "dev": true - }, - "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" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "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 - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "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 - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.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 - }, - "use-clipboard-copy": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/use-clipboard-copy/-/use-clipboard-copy-0.1.2.tgz", - "integrity": "sha512-EkauxqyX+us4+Mfif/f61ew89EAOWIArqFpHR0jSG4SwwuDZzDAOeqO7gkK0vi+DQVADeB1RB3xqU3U0oOO3NQ==", - "requires": { - "clipboard-copy": "^3.0.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" - } - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, - "v8-compile-cache": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", - "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", - "dev": true - }, - "value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "watchpack": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.0.tgz", - "integrity": "sha512-UjgD1mqjkG99+3lgG36at4wPnUXNvis2v1utwTgQ43C22c4LD71LsYMExdWXh4HZ+RmW+B0t1Vrg2GpXAkTOQw==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webpack": { - "version": "5.12.3", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.12.3.tgz", - "integrity": "sha512-7tiQmcTnKhZwbf7X7sEfXe0pgkGjUZjT6JfYkZHvvIb4/ZsXl1rJu5PxsJoN7W3v5sNSP/8TgBoiOdDqVdvK5w==", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.45", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.0.4", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.3.1", - "eslint-scope": "^5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "pkg-dir": "^5.0.0", - "schema-utils": "^3.0.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" - }, - "dependencies": { - "acorn": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", - "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", - "dev": true - }, - "enhanced-resolve": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.5.0.tgz", - "integrity": "sha512-b4a6BasBCoLzri4MdaeOlDMpls2oioI28CF17csMiav9dq46yvQaKPFNUrCHB6VqQokBDG2VIEEL81jMiQ6Wtw==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "requires": { - "find-up": "^5.0.0" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "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 - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "dev": true - }, - "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", - "dev": true, - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - } - } - }, - "webpack-cli": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.3.1.tgz", - "integrity": "sha512-/F4+9QNZM/qKzzL9/06Am8NXIkGV+/NqQ62Dx7DSqudxxpAgBqYn6V7+zp+0Y7JuWksKUbczRY3wMTd+7Uj6OA==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/info": "^1.2.1", - "@webpack-cli/serve": "^1.2.1", - "colorette": "^1.2.1", - "commander": "^6.2.0", - "enquirer": "^2.3.6", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", - "webpack-merge": "^4.2.2" - }, - "dependencies": { - "commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true - }, - "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": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", - "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", - "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" - } - }, - "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 - }, - "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 - }, - "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" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.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 - }, - "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 - }, - "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 - }, - "webpack-merge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", - "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "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" - } - } - } - }, - "webpack-dev-middleware": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", - "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", - "dev": true, - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "mime": { - "version": "2.4.7", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.7.tgz", - "integrity": "sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA==", - "dev": true - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - } - } - } - }, - "webpack-dev-server": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz", - "integrity": "sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.3.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.8", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.26", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.8", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "^0.3.21", - "sockjs-client": "^1.5.0", - "spdy": "^4.0.2", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "^13.3.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - } - } - } - }, - "webpack-log": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", - "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "log-symbols": "^2.1.0", - "loglevelnext": "^1.0.1", - "uuid": "^3.1.0" - } - }, - "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "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 - } - } - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "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 - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "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": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.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": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/applications/argo/deploy/charts/templates/controller/workflow-controller-cluster-roles.yaml b/applications/argo/deploy/charts/templates/controller/workflow-controller-cluster-roles.yaml index 72e97f45..7e36aa83 100644 --- a/applications/argo/deploy/charts/templates/controller/workflow-controller-cluster-roles.yaml +++ b/applications/argo/deploy/charts/templates/controller/workflow-controller-cluster-roles.yaml @@ -35,6 +35,8 @@ rules: resources: - persistentvolumeclaims verbs: + - get + - list - create - delete - apiGroups: diff --git a/applications/common/server/requirements.txt b/applications/common/server/requirements.txt index 70e1f0c5..c4293e26 100644 --- a/applications/common/server/requirements.txt +++ b/applications/common/server/requirements.txt @@ -9,3 +9,5 @@ swagger-ui-bundle >= 0.0.2 python_dateutil >= 2.6.0 setuptools >= 21.0.0 Flask == 1.1.2 +flask_sqlalchemy==2.4.4 +sqlalchemy<2.0.0 \ No newline at end of file diff --git a/applications/common/server/setup.py b/applications/common/server/setup.py index 31e9ded2..29d7afcd 100644 --- a/applications/common/server/setup.py +++ b/applications/common/server/setup.py @@ -17,7 +17,8 @@ "connexion>=2.0.2", "swagger-ui-bundle>=0.0.2", "python_dateutil>=2.6.0", - "psycopg2" + "psycopg2", + "flask_sqlalchemy", ] setup( diff --git a/applications/events/Dockerfile b/applications/events/Dockerfile deleted file mode 100644 index 14d4e987..00000000 --- a/applications/events/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -FROM solsson/kafka-manager diff --git a/applications/events/deploy/charts/.helmignore b/applications/events/deploy/charts/.helmignore new file mode 100644 index 00000000..7a93969f --- /dev/null +++ b/applications/events/deploy/charts/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +example/ +README.md diff --git a/applications/events/deploy/charts/Chart.yaml b/applications/events/deploy/charts/Chart.yaml new file mode 100644 index 00000000..2ae296b4 --- /dev/null +++ b/applications/events/deploy/charts/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: kafka-ui +description: A Helm chart for kafka-UI +type: application +version: 0.4.6 +appVersion: v0.4.0 +icon: https://github.com/provectus/kafka-ui/raw/master/documentation/images/kafka-ui-logo.png diff --git a/applications/events/deploy/charts/README.md b/applications/events/deploy/charts/README.md new file mode 100644 index 00000000..5d08629d --- /dev/null +++ b/applications/events/deploy/charts/README.md @@ -0,0 +1,34 @@ +# Kafka-UI Helm Chart + +## Configuration + +Most of the Helm charts parameters are common, follow table describe unique parameters related to application configuration. + +### Kafka-UI parameters + +| Parameter | Description | Default | +| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `existingConfigMap` | Name of the existing ConfigMap with Kafka-UI environment variables | `nil` | +| `existingSecret` | Name of the existing Secret with Kafka-UI environment variables | `nil` | +| `envs.secret` | Set of the sensitive environment variables to pass to Kafka-UI | `{}` | +| `envs.config` | Set of the environment variables to pass to Kafka-UI | `{}` | +| `yamlApplicationConfigConfigMap` | Map with name and keyName keys, name refers to the existing ConfigMap, keyName refers to the ConfigMap key with Kafka-UI config in Yaml format | `{}` | +| `yamlApplicationConfig` | Kafka-UI config in Yaml format | `{}` | +| `networkPolicy.enabled` | Enable network policies | `false` | +| `networkPolicy.egressRules.customRules` | Custom network egress policy rules | `[]` | +| `networkPolicy.ingressRules.customRules` | Custom network ingress policy rules | `[]` | +| `podLabels` | Extra labels for Kafka-UI pod | `{}` | + + +## Example + +To install Kafka-UI need to execute follow: +``` bash +helm repo add kafka-ui https://provectus.github.io/kafka-ui +helm install kafka-ui kafka-ui/kafka-ui --set envs.config.KAFKA_CLUSTERS_0_NAME=local --set envs.config.KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka:9092 +``` +To connect to Kafka-UI web application need to execute: +``` bash +kubectl port-forward svc/kafka-ui 8080:80 +``` +Open the `http://127.0.0.1:8080` on the browser to access Kafka-UI. diff --git a/applications/events/deploy/charts/index.yaml b/applications/events/deploy/charts/index.yaml new file mode 100644 index 00000000..87280719 --- /dev/null +++ b/applications/events/deploy/charts/index.yaml @@ -0,0 +1,3 @@ +apiVersion: v1 +entries: {} +generated: "2021-11-11T12:26:08.479581+03:00" diff --git a/applications/events/deploy/charts/templates/NOTES.txt b/applications/events/deploy/charts/templates/NOTES.txt new file mode 100644 index 00000000..94e8d394 --- /dev/null +++ b/applications/events/deploy/charts/templates/NOTES.txt @@ -0,0 +1,21 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "kafka-ui.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "kafka-ui.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "kafka-ui.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "kafka-ui.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:8080 +{{- end }} diff --git a/applications/events/deploy/charts/templates/_helpers.tpl b/applications/events/deploy/charts/templates/_helpers.tpl new file mode 100644 index 00000000..510452d4 --- /dev/null +++ b/applications/events/deploy/charts/templates/_helpers.tpl @@ -0,0 +1,79 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "kafka-ui.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kafka-ui.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kafka-ui.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "kafka-ui.labels" -}} +helm.sh/chart: {{ include "kafka-ui.chart" . }} +{{ include "kafka-ui.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kafka-ui.selectorLabels" -}} +app.kubernetes.io/name: {{ include "kafka-ui.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "kafka-ui.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "kafka-ui.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + + +{{/* +This allows us to check if the registry of the image is specified or not. +*/}} +{{- define "kafka-ui.imageName" -}} +{{- $registryName := .Values.image.registry -}} +{{- $repository := .Values.image.repository -}} +{{- $tag := .Values.image.tag | default .Chart.AppVersion -}} +{{- if $registryName }} +{{- printf "%s/%s:%s" $registryName $repository $tag -}} +{{- else }} +{{- printf "%s:%s" $repository $tag -}} +{{- end }} +{{- end -}} + diff --git a/applications/events/deploy/charts/templates/configmap.yaml b/applications/events/deploy/charts/templates/configmap.yaml new file mode 100644 index 00000000..22d2a699 --- /dev/null +++ b/applications/events/deploy/charts/templates/configmap.yaml @@ -0,0 +1,10 @@ +{{- if .Values.envs.config -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "kafka-ui.fullname" . }} + labels: + {{- include "kafka-ui.labels" . | nindent 4 }} +data: + {{- toYaml .Values.envs.config | nindent 2 }} +{{- end -}} \ No newline at end of file diff --git a/applications/events/deploy/charts/templates/configmap_fromValues.yaml b/applications/events/deploy/charts/templates/configmap_fromValues.yaml new file mode 100644 index 00000000..ae8b7695 --- /dev/null +++ b/applications/events/deploy/charts/templates/configmap_fromValues.yaml @@ -0,0 +1,11 @@ +{{- if .Values.yamlApplicationConfig -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "kafka-ui.fullname" . }}-fromvalues + labels: + {{- include "kafka-ui.labels" . | nindent 4 }} +data: + config.yml: |- + {{- toYaml .Values.yamlApplicationConfig | nindent 4}} +{{ end }} \ No newline at end of file diff --git a/applications/events/deploy/charts/templates/deployment.yaml b/applications/events/deploy/charts/templates/deployment.yaml new file mode 100644 index 00000000..219e9b44 --- /dev/null +++ b/applications/events/deploy/charts/templates/deployment.yaml @@ -0,0 +1,150 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "kafka-ui.fullname" . }} + labels: + {{- include "kafka-ui.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} +{{- end }} + selector: + matchLabels: + {{- include "kafka-ui.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/configFromValues: {{ include (print $.Template.BasePath "/configmap_fromValues.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + labels: + {{- include "kafka-ui.selectorLabels" . | nindent 8 }} + {{- if .Values.podLabels }} + {{- toYaml .Values.podLabels | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "kafka-ui.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: {{ include "kafka-ui.imageName" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if or .Values.env .Values.yamlApplicationConfig .Values.yamlApplicationConfigConfigMap}} + env: + {{- with .Values.env }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if or .Values.yamlApplicationConfig .Values.yamlApplicationConfigConfigMap}} + - name: SPRING_CONFIG_LOCATION + {{- if .Values.yamlApplicationConfig }} + value: /kafka-ui/config.yml + {{- else if .Values.yamlApplicationConfigConfigMap }} + value: /kafka-ui/{{ .Values.yamlApplicationConfigConfigMap.keyName | default "config.yml" }} + {{- end }} + {{- end }} + {{- end }} + envFrom: + {{- if .Values.existingConfigMap }} + - configMapRef: + name: {{ .Values.existingConfigMap }} + {{- end }} + {{- if .Values.envs.config }} + - configMapRef: + name: {{ include "kafka-ui.fullname" . }} + {{- end }} + {{- if .Values.existingSecret }} + - secretRef: + name: {{ .Values.existingSecret }} + {{- end }} + {{- if .Values.envs.secret}} + - secretRef: + name: {{ include "kafka-ui.fullname" . }} + {{- end}} + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + {{- $contextPath := .Values.envs.config.SERVER_SERVLET_CONTEXT_PATH | default "" | printf "%s/actuator/health" | urlParse }} + path: {{ get $contextPath "path" }} + port: http + {{- if .Values.probes.useHttpsScheme }} + scheme: HTTPS + {{- end }} + initialDelaySeconds: 60 + periodSeconds: 30 + timeoutSeconds: 10 + readinessProbe: + httpGet: + {{- $contextPath := .Values.envs.config.SERVER_SERVLET_CONTEXT_PATH | default "" | printf "%s/actuator/health" | urlParse }} + path: {{ get $contextPath "path" }} + port: http + {{- if .Values.probes.useHttpsScheme }} + scheme: HTTPS + {{- end }} + initialDelaySeconds: 60 + periodSeconds: 30 + timeoutSeconds: 10 + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.yamlApplicationConfig .Values.volumeMounts .Values.yamlApplicationConfigConfigMap}} + volumeMounts: + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.yamlApplicationConfig }} + - name: kafka-ui-yaml-conf + mountPath: /kafka-ui/ + {{- end }} + {{- if .Values.yamlApplicationConfigConfigMap}} + - name: kafka-ui-yaml-conf-configmap + mountPath: /kafka-ui/ + {{- end }} + {{- end }} + {{- if or .Values.yamlApplicationConfig .Values.volumes .Values.yamlApplicationConfigConfigMap}} + volumes: + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.yamlApplicationConfig }} + - name: kafka-ui-yaml-conf + configMap: + name: {{ include "kafka-ui.fullname" . }}-fromvalues + {{- end }} + {{- if .Values.yamlApplicationConfigConfigMap}} + - name: kafka-ui-yaml-conf-configmap + configMap: + name: {{ .Values.yamlApplicationConfigConfigMap.name }} + {{- end }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/applications/events/deploy/charts/templates/hpa.yaml b/applications/events/deploy/charts/templates/hpa.yaml new file mode 100644 index 00000000..1cc131c9 --- /dev/null +++ b/applications/events/deploy/charts/templates/hpa.yaml @@ -0,0 +1,46 @@ +{{- if .Values.autoscaling.enabled }} +{{- $kubeCapabilityVersion := semver .Capabilities.KubeVersion.Version -}} +{{- $isHigher1p25 := ge (semver "1.25" | $kubeCapabilityVersion.Compare) 0 -}} +{{- if and ($.Capabilities.APIVersions.Has "autoscaling/v2") $isHigher1p25 -}} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta1 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "kafka-ui.fullname" . }} + labels: + {{- include "kafka-ui.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "kafka-ui.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if $isHigher1p25 }} + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- else }} + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if $isHigher1p25 }} + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- else }} + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} + {{- end }} +{{- end }} diff --git a/applications/events/deploy/charts/templates/ingress.yaml b/applications/events/deploy/charts/templates/ingress.yaml new file mode 100644 index 00000000..e4b33439 --- /dev/null +++ b/applications/events/deploy/charts/templates/ingress.yaml @@ -0,0 +1,89 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "kafka-ui.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- $kubeCapabilityVersion := semver .Capabilities.KubeVersion.Version -}} +{{- $isHigher1p19 := ge (semver "1.19" | $kubeCapabilityVersion.Compare) 0 -}} +{{- if and ($.Capabilities.APIVersions.Has "networking.k8s.io/v1") $isHigher1p19 -}} +apiVersion: networking.k8s.io/v1 +{{- else if $.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +apiVersion: networking.k8s.io/v1beta1 +{{- else }} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "kafka-ui.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.tls.enabled }} + tls: + - hosts: + - {{ tpl .Values.ingress.host . }} + secretName: {{ .Values.ingress.tls.secretName }} + {{- end }} + {{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end }} + rules: + - http: + paths: +{{- if and ($.Capabilities.APIVersions.Has "networking.k8s.io/v1") $isHigher1p19 -}} + {{- range .Values.ingress.precedingPaths }} + - path: {{ .path }} + pathType: Prefix + backend: + service: + name: {{ .serviceName }} + port: + number: {{ .servicePort }} + {{- end }} + - backend: + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + pathType: Prefix +{{- if .Values.ingress.path }} + path: {{ .Values.ingress.path }} +{{- end }} + {{- range .Values.ingress.succeedingPaths }} + - path: {{ .path }} + pathType: Prefix + backend: + service: + name: {{ .serviceName }} + port: + number: {{ .servicePort }} + {{- end }} +{{- if tpl .Values.ingress.host . }} + host: {{tpl .Values.ingress.host . }} +{{- end }} +{{- else -}} + {{- range .Values.ingress.precedingPaths }} + - path: {{ .path }} + backend: + serviceName: {{ .serviceName }} + servicePort: {{ .servicePort }} + {{- end }} + - backend: + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} +{{- if .Values.ingress.path }} + path: {{ .Values.ingress.path }} +{{- end }} + {{- range .Values.ingress.succeedingPaths }} + - path: {{ .path }} + backend: + serviceName: {{ .serviceName }} + servicePort: {{ .servicePort }} + {{- end }} +{{- if tpl .Values.ingress.host . }} + host: {{ tpl .Values.ingress.host . }} +{{- end }} +{{- end }} +{{- end }} diff --git a/applications/events/deploy/charts/templates/networkpolicy-egress.yaml b/applications/events/deploy/charts/templates/networkpolicy-egress.yaml new file mode 100644 index 00000000..4f582802 --- /dev/null +++ b/applications/events/deploy/charts/templates/networkpolicy-egress.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.networkPolicy.enabled .Values.networkPolicy.egressRules.customRules }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ printf "%s-egress" (include "kafka-ui.fullname" .) }} + labels: + {{- include "kafka-ui.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "kafka-ui.selectorLabels" . | nindent 6 }} + policyTypes: + - Egress + egress: + {{- if .Values.networkPolicy.egressRules.customRules }} + {{- toYaml .Values.networkPolicy.egressRules.customRules | nindent 4 }} + {{- end }} +{{- end }} diff --git a/applications/events/deploy/charts/templates/networkpolicy-ingress.yaml b/applications/events/deploy/charts/templates/networkpolicy-ingress.yaml new file mode 100644 index 00000000..74988676 --- /dev/null +++ b/applications/events/deploy/charts/templates/networkpolicy-ingress.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.networkPolicy.enabled .Values.networkPolicy.ingressRules.customRules }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ printf "%s-ingress" (include "kafka-ui.fullname" .) }} + labels: + {{- include "kafka-ui.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "kafka-ui.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + ingress: + {{- if .Values.networkPolicy.ingressRules.customRules }} + {{- toYaml .Values.networkPolicy.ingressRules.customRules | nindent 4 }} + {{- end }} +{{- end }} diff --git a/applications/events/deploy/charts/templates/secret.yaml b/applications/events/deploy/charts/templates/secret.yaml new file mode 100644 index 00000000..a2d1f25f --- /dev/null +++ b/applications/events/deploy/charts/templates/secret.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "kafka-ui.fullname" . }} + labels: + {{- include "kafka-ui.labels" . | nindent 4 }} +type: Opaque +data: + {{- range $key, $val := .Values.envs.secret }} + {{ $key }}: {{ $val | b64enc | quote }} + {{- end -}} diff --git a/applications/events/deploy/charts/templates/service.yaml b/applications/events/deploy/charts/templates/service.yaml new file mode 100644 index 00000000..5801135c --- /dev/null +++ b/applications/events/deploy/charts/templates/service.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "kafka-ui.fullname" . }} + labels: + {{- include "kafka-ui.labels" . | nindent 4 }} +{{- if .Values.service.annotations }} + annotations: +{{ toYaml .Values.service.annotations | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + {{- if (and (eq .Values.service.type "NodePort") .Values.service.nodePort) }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + selector: + {{- include "kafka-ui.selectorLabels" . | nindent 4 }} diff --git a/applications/events/deploy/charts/templates/serviceaccount.yaml b/applications/events/deploy/charts/templates/serviceaccount.yaml new file mode 100644 index 00000000..b89551c8 --- /dev/null +++ b/applications/events/deploy/charts/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "kafka-ui.serviceAccountName" . }} + labels: + {{- include "kafka-ui.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/applications/events/deploy/charts/values.yaml b/applications/events/deploy/charts/values.yaml new file mode 100644 index 00000000..570f1cb4 --- /dev/null +++ b/applications/events/deploy/charts/values.yaml @@ -0,0 +1,157 @@ +replicaCount: 1 + +image: + registry: docker.io + repository: provectuslabs/kafka-ui + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "events-ui" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +existingConfigMap: "" +yamlApplicationConfig: + {} + # kafka: + # clusters: + # - name: yaml + # bootstrapServers: kafka-service:9092 + # spring: + # security: + # oauth2: + # auth: + # type: disabled + # management: + # health: + # ldap: + # enabled: false +yamlApplicationConfigConfigMap: + keyName: config.yml + name: kafka-ui-configmap +existingSecret: "" +envs: + secret: {} + config: {} + +networkPolicy: + enabled: false + egressRules: + ## Additional custom egress rules + ## e.g: + ## customRules: + ## - to: + ## - namespaceSelector: + ## matchLabels: + ## label: example + customRules: [] + ingressRules: + ## Additional custom ingress rules + ## e.g: + ## customRules: + ## - from: + ## - namespaceSelector: + ## matchLabels: + ## label: example + customRules: [] + +podAnnotations: {} +podLabels: {} + +## Annotations to be added to kafka-ui Deployment +## +annotations: {} + +## Set field schema as HTTPS for readines and liveness probe +## +probes: + useHttpsScheme: false + +podSecurityContext: + {} + # fsGroup: 2000 + +securityContext: + {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + # if you want to force a specific nodePort. Must be use with service.type=NodePort + # nodePort: + +# Ingress configuration +ingress: + # Enable ingress resource + enabled: false + + # Annotations for the Ingress + annotations: {} + + # ingressClassName for the Ingress + ingressClassName: "" + + # The path for the Ingress + path: "/" + + # The hostname for the Ingress + host: "" + + # configs for Ingress TLS + tls: + # Enable TLS termination for the Ingress + enabled: false + # the name of a pre-created Secret containing a TLS private key and certificate + secretName: "" + + # HTTP paths to add to the Ingress before the default path + precedingPaths: [] + + # Http paths to add to the Ingress after the default path + succeedingPaths: [] + +resources: + {} + # limits: + # cpu: 200m + # memory: 512Mi + # requests: + # cpu: 200m + # memory: 256Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +env: {} + +initContainers: {} + +volumeMounts: {} + +volumes: {} diff --git a/applications/events/deploy/resources/broker/init.sh b/applications/events/deploy/resources/broker/init.sh index 5caef07e..18e88f3f 100644 --- a/applications/events/deploy/resources/broker/init.sh +++ b/applications/events/deploy/resources/broker/init.sh @@ -36,12 +36,12 @@ printf '%s\n' "${SEDS[@]}" | sed -f - /etc/kafka-configmap/server.properties > / # wait for events to be up & running # install curl first -apt update && apt install -y curl -for i in {1..100} -do - sleep 5 - if curl events; then - curl events:80/clusters --data 'name=cluster-'${POD_NAMESPACE}'&zkHosts=zookeeper.'${POD_NAMESPACE}':2181&kafkaVersion=2.2.0&jmxEnabled=true&jmxUser=&jmxPass=&logkafkaEnabled=true&pollConsumers=true&activeOffsetCacheEnabled=true&tuning.brokerViewUpdatePeriodSeconds=30&tuning.clusterManagerThreadPoolSize=2&tuning.clusterManagerThreadPoolQueueSize=100&tuning.kafkaCommandThreadPoolSize=2&tuning.kafkaCommandThreadPoolQueueSize=100&tuning.logkafkaCommandThreadPoolSize=2&tuning.logkafkaCommandThreadPoolQueueSize=100&tuning.logkafkaUpdatePeriodSeconds=30&tuning.partitionOffsetCacheTimeoutSecs=5&tuning.brokerViewThreadPoolSize=2&tuning.brokerViewThreadPoolQueueSize=1000&tuning.offsetCacheThreadPoolSize=2&tuning.offsetCacheThreadPoolQueueSize=1000&tuning.kafkaAdminClientThreadPoolSize=2&tuning.kafkaAdminClientThreadPoolQueueSize=1000&tuning.kafkaManagedOffsetMetadataCheckMillis=30000&tuning.kafkaManagedOffsetGroupCacheSize=1000000&tuning.kafkaManagedOffsetGroupExpireDays=7&securityProtocol=PLAINTEXT&saslMechanism=DEFAULT&jaasConfig=' -X POST - exit 0 - fi -done +# apt update && apt install -y curl +# for i in {1..100} +# do +# sleep 5 +# if curl events; then +# curl events:80/clusters --data 'name=cluster-'${POD_NAMESPACE}'&zkHosts=zookeeper.'${POD_NAMESPACE}':2181&kafkaVersion=2.2.0&jmxEnabled=true&jmxUser=&jmxPass=&logkafkaEnabled=true&pollConsumers=true&activeOffsetCacheEnabled=true&tuning.brokerViewUpdatePeriodSeconds=30&tuning.clusterManagerThreadPoolSize=2&tuning.clusterManagerThreadPoolQueueSize=100&tuning.kafkaCommandThreadPoolSize=2&tuning.kafkaCommandThreadPoolQueueSize=100&tuning.logkafkaCommandThreadPoolSize=2&tuning.logkafkaCommandThreadPoolQueueSize=100&tuning.logkafkaUpdatePeriodSeconds=30&tuning.partitionOffsetCacheTimeoutSecs=5&tuning.brokerViewThreadPoolSize=2&tuning.brokerViewThreadPoolQueueSize=1000&tuning.offsetCacheThreadPoolSize=2&tuning.offsetCacheThreadPoolQueueSize=1000&tuning.kafkaAdminClientThreadPoolSize=2&tuning.kafkaAdminClientThreadPoolQueueSize=1000&tuning.kafkaManagedOffsetMetadataCheckMillis=30000&tuning.kafkaManagedOffsetGroupCacheSize=1000000&tuning.kafkaManagedOffsetGroupExpireDays=7&securityProtocol=PLAINTEXT&saslMechanism=DEFAULT&jaasConfig=' -X POST +# exit 0 +# fi +# done diff --git a/applications/events/deploy/resources/broker/server.properties b/applications/events/deploy/resources/broker/server.properties index 90900940..584136d9 100644 --- a/applications/events/deploy/resources/broker/server.properties +++ b/applications/events/deploy/resources/broker/server.properties @@ -121,8 +121,8 @@ log.retention.hours=-1 zookeeper.connect=zookeeper:2181 # Timeout in ms for connecting to zookeeper -#zookeeper.connection.timeout.ms=6000 - +zookeeper.connection.timeout.ms=600000 +atlas.kafka.zookeeper.session.timeout.ms=600000 ############################# Group Coordinator Settings ############################# diff --git a/applications/events/deploy/templates/configmap.yaml b/applications/events/deploy/templates/configmap.yaml new file mode 100644 index 00000000..95ffb56f --- /dev/null +++ b/applications/events/deploy/templates/configmap.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: kafka-ui-configmap +data: + config.yml: |- + kafka: + clusters: + - name: "cluster-{{ .Values.namespace }}" + bootstrapServers: "{{ .Values.apps.events.kafka.name }}:9092" + auth: + type: disabled + management: + health: + ldap: + enabled: false \ No newline at end of file diff --git a/applications/events/deploy/values-dev.yaml b/applications/events/deploy/values-dev.yaml new file mode 100644 index 00000000..2694d233 --- /dev/null +++ b/applications/events/deploy/values-dev.yaml @@ -0,0 +1,2 @@ +kafka: + storage: 100Mi \ No newline at end of file diff --git a/applications/events/deploy/values-test.yaml b/applications/events/deploy/values-test.yaml new file mode 100644 index 00000000..5b00a374 --- /dev/null +++ b/applications/events/deploy/values-test.yaml @@ -0,0 +1,4 @@ +harness: + secured: false +kafka: + storage: 100Mi \ No newline at end of file diff --git a/applications/events/deploy/values.yaml b/applications/events/deploy/values.yaml index 79e2c410..071e423c 100644 --- a/applications/events/deploy/values.yaml +++ b/applications/events/deploy/values.yaml @@ -2,12 +2,13 @@ harness: subdomain: events secured: true service: - auto: true - port: 80 + auto: false + name: events-ui deployment: - auto: true - port: 9000 - name: events + auto: false + test: + e2e: + enabled: true env: - name: ZK_HOSTS value: zookeeper:2181 @@ -37,4 +38,4 @@ zoo: memory: 500Mi requests: cpu: 10m - memory: 100Mi \ No newline at end of file + memory: 100Mi diff --git a/applications/jupyterhub/README.md b/applications/jupyterhub/README.md index 192c8607..d961d034 100755 --- a/applications/jupyterhub/README.md +++ b/applications/jupyterhub/README.md @@ -23,3 +23,11 @@ harness: values: pool-highcpu # k8s highcpu instance pool matchPurpose: require # require | prefer | ignore ``` + +## Customizations + +CloudHarness pre puller of tasks images support +To support the pre pulling of task images see (https://github.com/MetaCell/cloud-harness/issues/657) +the template `templates/image-puller/_helpers-daemonset.tpl` has been changed (see line 167 and on) + +TODO: remember to implement/revise this code after you have updated/changed the templates of JupyterHub diff --git a/applications/jupyterhub/deploy/resources/hub/jupyterhub_config.py b/applications/jupyterhub/deploy/resources/hub/jupyterhub_config.py index 2ef5d7ce..d4b3cee2 100755 --- a/applications/jupyterhub/deploy/resources/hub/jupyterhub_config.py +++ b/applications/jupyterhub/deploy/resources/hub/jupyterhub_config.py @@ -271,7 +271,7 @@ def camelCaseify(s): pvc_name_template = get_config("singleuser.storage.dynamic.pvcNameTemplate") c.KubeSpawner.pvc_name_template = pvc_name_template volume_name_template = get_config("singleuser.storage.dynamic.volumeNameTemplate") - c.KubeSpawner.storage_pvc_ensure = True + c.KubeSpawner.storage_pvc_ensure = False set_config_if_not_none( c.KubeSpawner, "storage_class", "singleuser.storage.dynamic.storageClass" ) @@ -524,4 +524,5 @@ def camelCaseify(s): c.apps = get_config('apps') c.registry = get_config('registry') -c.domain = get_config('root.domain') \ No newline at end of file +c.domain = get_config('root.domain') +c.namespace = get_config('root.namespace') \ No newline at end of file diff --git a/applications/jupyterhub/deploy/resources/hub/z2jh.py b/applications/jupyterhub/deploy/resources/hub/z2jh.py index b498b2e2..834a6b6c 100755 --- a/applications/jupyterhub/deploy/resources/hub/z2jh.py +++ b/applications/jupyterhub/deploy/resources/hub/z2jh.py @@ -6,6 +6,7 @@ from collections import Mapping from functools import lru_cache import os +import re import yaml @@ -115,6 +116,18 @@ def get_config(key, default=None): return default else: value = value[level] + + + if value and isinstance(value, str): + replace_var = re.search("{{.*?}}", value) + if replace_var: + variable = replace_var.group(0)[2:-2].strip() + + repl = get_config(variable) + + if repl: + print("replace", variable, "in", value, ":", repl) + value = re.sub("{{.*?}}", repl, value) return value @@ -124,5 +137,6 @@ def set_config_if_not_none(cparent, name, key): configuration item if not None """ data = get_config(key) + if data is not None: setattr(cparent, name, data) \ No newline at end of file diff --git a/applications/jupyterhub/deploy/templates/hub/deployment.yaml b/applications/jupyterhub/deploy/templates/hub/deployment.yaml index 008124d6..82132c62 100755 --- a/applications/jupyterhub/deploy/templates/hub/deployment.yaml +++ b/applications/jupyterhub/deploy/templates/hub/deployment.yaml @@ -48,9 +48,11 @@ spec: - name: cloudharness-allvalues configMap: name: cloudharness-allvalues + {{- if .Values.apps.accounts }} - name: cloudharness-kc-accounts secret: secretName: accounts + {{- end }} - name: secret secret: secretName: {{ include "jupyterhub.hub.fullname" . }} @@ -154,9 +156,11 @@ spec: - name: cloudharness-allvalues mountPath: /opt/cloudharness/resources/allvalues.yaml subPath: allvalues.yaml + {{- if .Values.apps.accounts }} - name: cloudharness-kc-accounts mountPath: /opt/cloudharness/resources/auth readOnly: true + {{- end }} {{- if (include "jupyterhub.hub-existing-secret.fullname" .) }} - mountPath: /usr/local/etc/jupyterhub/existing-secret/ name: existing-secret diff --git a/applications/jupyterhub/deploy/templates/image-puller/_helpers-daemonset.tpl b/applications/jupyterhub/deploy/templates/image-puller/_helpers-daemonset.tpl index d71e971f..e16fd1a9 100644 --- a/applications/jupyterhub/deploy/templates/image-puller/_helpers-daemonset.tpl +++ b/applications/jupyterhub/deploy/templates/image-puller/_helpers-daemonset.tpl @@ -165,6 +165,24 @@ spec: {{- . | toYaml | nindent 12 }} {{- end }} {{- end }} + + {{- /* --- Pull CloudHarness tasks images --- */}} + {{- range $k, $v := ( index .Values "task-images" ) }} + - name: image-pull-{{ $k | replace "-" "" }} + image: {{ $v }} + command: + - /bin/sh + - -c + - echo "Pulling complete" + {{- with $.Values.apps.jupyterhub.prePuller.resources }} + resources: + {{- . | toYaml | nindent 12 }} + {{- end }} + {{- with $.Values.apps.jupyterhub.prePuller.containerSecurityContext }} + securityContext: + {{- . | toYaml | nindent 12 }} + {{- end }} + {{- end }} containers: - name: pause image: {{ .Values.apps.jupyterhub.prePuller.pause.image.name }}:{{ .Values.apps.jupyterhub.prePuller.pause.image.tag }} diff --git a/applications/jupyterhub/deploy/values.yaml b/applications/jupyterhub/deploy/values.yaml index 521a038c..2f5cbca3 100755 --- a/applications/jupyterhub/deploy/values.yaml +++ b/applications/jupyterhub/deploy/values.yaml @@ -12,6 +12,19 @@ harness: - accounts build: - cloudharness-base + quotas: + # sets the maximum number of (included named) servers open concurrently (int) + quota-ws-open: 3 + # sets the cpu guaranteed on a single workspace in CPU units (float) + quota-ws-guaranteecpu: 0.05 + # sets the cpu limit on a single workspace in CPU units (float) + quota-ws-maxcpu: 0.4 + # sets the memory guaranteed on a single workspace in Gb units (float) + quota-ws-guaranteemem: 0.1 + # sets the memory limit on a single workspace in Gb units (float) + quota-ws-maxmem: 0.5 + # sets the storage dedicated to the user data in Gb units (float) + quota-storage-max: 1.25 # fullnameOverride and nameOverride distinguishes blank strings, null values, # and non-blank strings. For more details, see the configuration reference. diff --git a/applications/jupyterhub/src/chauthenticator/chauthenticator/auth.py b/applications/jupyterhub/src/chauthenticator/chauthenticator/auth.py index 9520117a..e7b4cb0d 100644 --- a/applications/jupyterhub/src/chauthenticator/chauthenticator/auth.py +++ b/applications/jupyterhub/src/chauthenticator/chauthenticator/auth.py @@ -25,17 +25,12 @@ def initialize(self, force_new_server, process_user): @gen.coroutine def get(self): - raw_user = yield self.get_current_user() - if raw_user: - if self.force_new_server and user.running: - # Stop user's current server if it is running - # so we get a new one. - status = yield raw_user.spawner.poll_and_notify() - if status is None: - yield self.stop_single_user(raw_user) - else: - try: - accessToken = self.request.cookies.get('accessToken', None) + self.clear_login_cookie() + + try: + + accessToken = self.request.cookies.get( + 'kc-access', None) or self.request.cookies.get('accessToken', None) print("Token", accessToken) if accessToken == '-1' or not accessToken: self.redirect('/hub/logout') @@ -43,10 +38,13 @@ def get(self): accessToken = accessToken.value user_data = AuthClient.decode_token(accessToken) username = user_data['sub'] + print("Username", username, "-",user_data['preferred_username']) raw_user = self.user_from_username(username) + print("JH user: ", raw_user.__dict__) self.set_login_cookie(raw_user) - except Exception as e: + except Exception as e: logging.error("Error getting user from session", exc_info=True) + raise user = yield gen.maybe_future(self.process_user(raw_user, self)) self.redirect(self.get_next_url(user)) diff --git a/applications/jupyterhub/src/harness_jupyter/harness_jupyter/jupyterhub.py b/applications/jupyterhub/src/harness_jupyter/harness_jupyter/jupyterhub.py old mode 100755 new mode 100644 index 159185d5..220883a8 --- a/applications/jupyterhub/src/harness_jupyter/harness_jupyter/jupyterhub.py +++ b/applications/jupyterhub/src/harness_jupyter/harness_jupyter/jupyterhub.py @@ -1,24 +1,55 @@ -import imp -import logging import sys import urllib.parse +import asyncio +from functools import partial from kubespawner.spawner import KubeSpawner -handler = logging.StreamHandler(sys.stdout) -handler.setLevel(logging.DEBUG) -logging.getLogger().addHandler(handler) +from jupyterhub.utils import exponential_backoff + + +from cloudharness.applications import get_configuration +from cloudharness.auth.quota import get_user_quotas +from cloudharness.utils.config import CloudharnessConfig as conf +from cloudharness import log as logging, set_debug + +set_debug() + + +def custom_options_form(spawner, abc): + # let's skip the profile selection form for now + # ToDo: for future we can remove this hook + spawner.profile_list = [] + # ref: https://github.com/jupyterhub/kubespawner/blob/37a80abb0a6c826e5c118a068fa1cf2725738038/kubespawner/spawner.py#L1885-L1935 + return spawner._options_form_default() + + +class PodSpawnException(Exception): + pass + def harness_hub(): """Wraps the method to change spawner configuration""" KubeSpawner.get_pod_manifest_base = KubeSpawner.get_pod_manifest KubeSpawner.get_pod_manifest = spawner_pod_manifest + # let's skip the profile selection form for now + # TODO: for future we can remove this hook + KubeSpawner.options_form = custom_options_form + KubeSpawner.get_pvc_manifest_base = KubeSpawner.get_pvc_manifest + KubeSpawner.get_pvc_manifest = spawner_pvc_manifest + def spawner_pod_manifest(self: KubeSpawner): print("Cloudharness: changing pod manifest") change_pod_manifest(self) - return KubeSpawner.get_pod_manifest_base(self) + +def spawner_pvc_manifest(self: KubeSpawner): + print("Cloudharness: changing pvc manifest") + change_pvc_manifest(self) + return KubeSpawner.get_pvc_manifest_base(self) + + def affinity_spec(key, value): return { @@ -35,10 +66,11 @@ def affinity_spec(key, value): 'topologyKey': 'kubernetes.io/hostname' } + def set_user_volume_affinity(self: KubeSpawner): # Add labels to use for affinity labels = { - 'user': urllib.parse.quote(self.user.name, safe='').replace('%', ''), + 'user': str(self.user.id), } self.common_labels = labels @@ -47,10 +79,58 @@ def set_user_volume_affinity(self: KubeSpawner): for key, value in labels.items(): self.pod_affinity_required.append(affinity_spec(key, value)) + +def set_key_value(self, key, value, unit=None): + if value: + if unit: + print(f"setting key {key} to {value}{unit}") + setattr(self, key, f"{value}{unit}") + else: + print(f"setting key {key} to {value}") + setattr(self, key, value) + + +def change_pvc_manifest(self: KubeSpawner): + try: + # check user quotas + application_config = get_configuration("jupyterhub") + user_quotas = get_user_quotas( + application_config=application_config, + user_id=self.user.name) + set_key_value(self, key="storage_capacity", + value=user_quotas.get("quota-storage-max"), unit="Gi") + except Exception as e: + logging.error("Harness error changing pvc manifest", exc_info=True) + + def change_pod_manifest(self: KubeSpawner): + # check user quotas + application_config = get_configuration("jupyterhub") + + logging.info("Cloudharness: changing pod manifest") + user_quotas = get_user_quotas( + application_config=application_config, + user_id=self.user.name) + + quota_ws_open = user_quotas.get("quota-ws-open") + # Default value, might be overwritten by the app config + self.storage_pvc_ensure = bool(self.pvc_name) + + if quota_ws_open: + # get user number of pods running + servers = [s for s in self.user.all_spawners(include_default=True)] + num_of_pods = len([s for s in servers if s.active]) + if num_of_pods > int(quota_ws_open): + raise PodSpawnException( + "You reached your quota of {} concurrent servers." + " One must be deleted before a new server can be started".format( + quota_ws_open + ), + ) try: - subdomain = self.handler.request.host.split(str(self.config['domain']))[0][0:-1] + subdomain = self.handler.request.host.split( + str(self.config['domain']))[0][0:-1] app_config = self.config['apps'] registry = self.config['registry'] for app in app_config.values(): @@ -58,41 +138,67 @@ def change_pod_manifest(self: KubeSpawner): harness = app['harness'] if 'subdomain' in harness and harness['subdomain'] == subdomain: - if app['name'] != 'jupyterhub': # Would use the hub image in that case, which we don't want. - print('Change image to', harness['deployment']['image']) - self.image = harness['deployment']['image'] + ws_image = getattr(self, "ws_image", None) + logging.info("Subdomain is", subdomain) + if ws_image: + # try getting the image + tag from values.yaml + ch_conf = conf.get_configuration() + task_images = ch_conf['task-images'] + for task_image in task_images: + image_plus_tag = task_images[task_image] + if ws_image in image_plus_tag: + ws_image = image_plus_tag + logging.error( + f'Found tag for image: {ws_image}') + break + else: + # Would use the hub image in that case, which we don't want. + if app['name'] != 'jupyterhub': + ws_image = harness['deployment']['image'] + logging.info(f'Use spacific app image: {ws_image}') + if ws_image: + logging.info(f'Use image: {ws_image}') + self.image = ws_image if registry['name'] in self.image and registry['secret']: self.image_pull_secrets = registry['secret'] if 'jupyterhub' in harness and harness['jupyterhub']: if 'args' in harness['jupyterhub']: + logging.info("Setting custom args") self.args = harness['jupyterhub']['args'] if harness['jupyterhub'].get('mountUserVolume', True): + logging.info("Setting user volume affinity") set_user_volume_affinity(self) else: self.volume_mounts = [] self.volumes = [] # set http timeout higher to give the notebooks time to run their init scripts - self.http_timeout = 60 * 5 # 5 minutes + self.http_timeout = 60 * 5 # 5 minutes if 'spawnerExtraConfig' in harness['jupyterhub']: + logging.info("Setting custom spawner config") try: for k, v in harness['jupyterhub']['spawnerExtraConfig'].items(): if k != 'node_selectors': + logging.info(f"Setting {k} to {v}") setattr(self, k, v) # check if there are node selectors, if so apply them to the pod - node_selectors = harness['jupyterhub']['spawnerExtraConfig'].get('node_selectors') + node_selectors = harness['jupyterhub']['spawnerExtraConfig'].get( + 'node_selectors') if node_selectors: for node_selector in node_selectors: + logging.info( + "Setting node selector", node_selector["key"]) ns = dict( matchExpressions=[ dict( key=node_selector['key'], operator=node_selector['operator'], - values=[node_selector['values']], + values=[ + node_selector['values']], ) ], ) @@ -105,13 +211,28 @@ def change_pod_manifest(self: KubeSpawner): ), ) elif match_node_purpose == 'require': - self.node_affinity_required.append(ns) + self.node_affinity_required.append( + ns) elif match_node_purpose == 'ignore': pass else: - raise ValueError("Unrecognized value for matchNodePurpose: %r" % match_node_purpose) + raise ValueError( + "Unrecognized value for matchNodePurpose: %r" % match_node_purpose) except: - logging.error("Error loading Spawner extra configuration", exc_info=True) + logging.error( + "Error loading Spawner extra configuration", exc_info=True) + + # set user quota cpu/mem usage if value has a "value" else don't change the value + logging.info("Setting user quota cpu/mem usage") + set_key_value(self, key="cpu_guarantee", value=user_quotas.get( + "quota-ws-guaranteecpu")) + set_key_value(self, key="cpu_limit", + value=user_quotas.get("quota-ws-maxcpu")) + set_key_value(self, key="mem_guarantee", value=user_quotas.get( + "quota-ws-guaranteemem"), unit="G") + set_key_value(self, key="mem_limit", value=user_quotas.get( + "quota-ws-maxmem"), unit="G") + # check if there is an applicationHook defined in the values.yaml # if so then execute the applicationHook function with "self" as parameter # @@ -121,11 +242,33 @@ def change_pod_manifest(self: KubeSpawner): # # this will execute jupyter.change_pod_manifest(self=self) if 'applicationHook' in harness['jupyterhub']: - func_name = harness['jupyterhub']['applicationHook'].split('.') + func_name = harness['jupyterhub']['applicationHook'].split( + '.') + logging.info( + f"Executing application hook {func_name}") module = __import__('.'.join(func_name[:-1])) f = getattr(module, func_name[-1]) f(self=self) break + except PodSpawnException as e: + raise e except Exception as e: logging.error("Harness error changing manifest", exc_info=True) + + if self.storage_pvc_ensure and self.volumes: + + pvc = self.get_pvc_manifest() + from pprint import pprint + pprint(self.storage_class) + + + # If there's a timeout, just let it propagate + asyncio.ensure_future(exponential_backoff( + partial( + self._make_create_pvc_request, pvc, self.k8s_api_request_timeout + ), + f'Could not create PVC {self.pvc_name}', + # Each req should be given k8s_api_request_timeout seconds. + timeout=self.k8s_api_request_retry_timeout, + )) diff --git a/applications/nfsserver/.gitignore b/applications/nfsserver/.gitignore new file mode 100644 index 00000000..f66bbe54 --- /dev/null +++ b/applications/nfsserver/.gitignore @@ -0,0 +1,26 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +nfs-client-provisioner diff --git a/applications/nfsserver/Dockerfile b/applications/nfsserver/Dockerfile new file mode 100644 index 00000000..59a07eb6 --- /dev/null +++ b/applications/nfsserver/Dockerfile @@ -0,0 +1,19 @@ +# compile provisioner +FROM golang:1.18.8 as provisioner + +WORKDIR /usr/src/app +COPY nfs-subdir-external-provisioner ./ + +RUN make + +# +FROM k8s.gcr.io/volume-nfs:0.8 + +RUN yum install -y e4fsprogs rpcbind nfs-utils nfs-utils-lib sysvinit-tools + +COPY --from=provisioner /usr/src/app/bin/nfs-subdir-external-provisioner /usr/local/bin/nfs-subdir-external-provisioner + +COPY resources/*.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/*.sh + +RUN echo "/exports *(rw,fsid=0,insecure,no_subtree_check,no_root_squash,crossmnt)" > /etc/exports diff --git a/applications/nfsserver/deploy/templates/_helpers.tpl b/applications/nfsserver/deploy/templates/_helpers.tpl new file mode 100644 index 00000000..30563cc6 --- /dev/null +++ b/applications/nfsserver/deploy/templates/_helpers.tpl @@ -0,0 +1,92 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "nfs-subdir-external-provisioner.name" -}} +{{- default .Chart.Name .Values.apps.nfsserver.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "nfs-subdir-external-provisioner.fullname" -}} +{{- if .Values.apps.nfsserver.fullnameOverride -}} +{{- .Values.apps.nfsserver.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.apps.nfsserver.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "nfs-subdir-external-provisioner.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "nfs-subdir-external-provisioner.provisionerName" -}} +{{- if .Values.apps.nfsserver.storageClass.provisionerName -}} +{{- printf .Values.apps.nfsserver.storageClass.provisionerName -}} +{{- else -}} +{{ template "nfs-subdir-external-provisioner.fullname" . -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "nfs-subdir-external-provisioner.serviceAccountName" -}} +{{- if .Values.apps.nfsserver.serviceAccount.create -}} + {{ default (include "nfs-subdir-external-provisioner.fullname" .) .Values.apps.nfsserver.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.apps.nfsserver.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for podSecurityPolicy. +*/}} +{{- define "podSecurityPolicy.apiVersion" -}} +{{- if semverCompare ">=1.10-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "policy/v1beta1" -}} +{{- else -}} +{{- print "extensions/v1beta1" -}} +{{- end -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "nfs-subdir-external-provisioner.labels" -}} +chart: {{ template "nfs-subdir-external-provisioner.chart" . }} +heritage: {{ .Release.Service }} +{{ include "nfs-subdir-external-provisioner.selectorLabels" . }} +{{- with .Values.apps.nfsserver.labels }} +{{- toYaml . | nindent 0 }} +{{- end }} +{{- end }} + +{{/* +Pod template labels +*/}} +{{- define "nfs-subdir-external-provisioner.podLabels" -}} +{{ include "nfs-subdir-external-provisioner.selectorLabels" . }} +{{- with .Values.apps.nfsserver.labels }} +{{- toYaml . | nindent 0 }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "nfs-subdir-external-provisioner.selectorLabels" -}} +app: {{ template "nfs-subdir-external-provisioner.name" . }} +release: {{ .Release.Name }} +{{- end }} diff --git a/applications/nfsserver/deploy/templates/clusterrole.yaml b/applications/nfsserver/deploy/templates/clusterrole.yaml new file mode 100644 index 00000000..c19a3526 --- /dev/null +++ b/applications/nfsserver/deploy/templates/clusterrole.yaml @@ -0,0 +1,30 @@ +{{- if .Values.apps.nfsserver.rbac.create }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + name: {{ template "nfs-subdir-external-provisioner.fullname" . }}-runner +rules: + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "update", "patch"] +{{- if .Values.apps.nfsserver.podSecurityPolicy.enabled }} + - apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "nfs-subdir-external-provisioner.fullname" . }}] +{{- end }} +{{- end }} diff --git a/applications/nfsserver/deploy/templates/clusterrolebinding.yaml b/applications/nfsserver/deploy/templates/clusterrolebinding.yaml new file mode 100644 index 00000000..38a6c665 --- /dev/null +++ b/applications/nfsserver/deploy/templates/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.apps.nfsserver.rbac.create }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + name: run-{{ template "nfs-subdir-external-provisioner.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "nfs-subdir-external-provisioner.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ template "nfs-subdir-external-provisioner.fullname" . }}-runner + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/applications/nfsserver/deploy/templates/nfs-server.yaml b/applications/nfsserver/deploy/templates/nfs-server.yaml new file mode 100644 index 00000000..32570713 --- /dev/null +++ b/applications/nfsserver/deploy/templates/nfs-server.yaml @@ -0,0 +1,88 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: nfs-exports + labels: + app: nfs-server +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.apps.nfsserver.server.diskSize }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nfs-server + labels: + app: nfs-server + usesvolume: nfs-exports +spec: + selector: + matchLabels: + app: nfs-server + template: + + metadata: + labels: + app: nfs-server + usesvolume: nfs-exports + spec: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: usesvolume + operator: In + values: + - nfs-exports + topologyKey: "kubernetes.io/hostname" + containers: + - name: nfs-server + image: {{ .Values.apps.nfsserver.harness.deployment.image }} + imagePullPolicy: IfNotPresent + env: + # NFS useDNS {{ .Values.apps.nfsserver.nfs.useDNS }} + {{- if .Values.apps.nfsserver.nfs.useDNS }} + - name: NFS_SERVER + value: {{ printf "nfs-server.%s.svc.cluster.local" .Values.namespace }} + {{- end }} + - name: NFS_PATH + value: {{ .Values.apps.nfsserver.nfs.path }} + - name: PROVISIONER_NAME + value: {{ printf "%s-nfs-provisioner" .Values.namespace }} + ports: + - name: nfs + containerPort: 2049 + - name: mountd + containerPort: 20048 + - name: rpcbind + containerPort: 111 + securityContext: + privileged: true + volumeMounts: + - name: storage + mountPath: /exports + volumes: + - name: storage + persistentVolumeClaim: + claimName: nfs-exports +--- +apiVersion: v1 +kind: Service +metadata: + name: nfs-server + labels: + app: nfs-server +spec: + ports: + - name: nfs + port: 2049 + - name: mountd + port: 20048 + - name: rpcbind + port: 111 + selector: + app: nfs-server diff --git a/applications/nfsserver/deploy/templates/podsecuritypolicy.yaml b/applications/nfsserver/deploy/templates/podsecuritypolicy.yaml new file mode 100644 index 00000000..b84c7618 --- /dev/null +++ b/applications/nfsserver/deploy/templates/podsecuritypolicy.yaml @@ -0,0 +1,29 @@ +{{- if .Values.apps.nfsserver.podSecurityPolicy.enabled }} +apiVersion: {{ template "podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "nfs-subdir-external-provisioner.fullname" . }} + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + - ALL + volumes: + - 'secret' + - 'nfs' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/applications/nfsserver/deploy/templates/role.yaml b/applications/nfsserver/deploy/templates/role.yaml new file mode 100644 index 00000000..0e89180f --- /dev/null +++ b/applications/nfsserver/deploy/templates/role.yaml @@ -0,0 +1,18 @@ +{{- if .Values.apps.nfsserver.rbac.create }} +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + name: leader-locking-{{ template "nfs-subdir-external-provisioner.fullname" . }} +rules: + - apiGroups: [""] + resources: ["endpoints"] + verbs: ["get", "list", "watch", "create", "update", "patch"] +{{- if .Values.apps.nfsserver.podSecurityPolicy.enabled }} + - apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "nfs-subdir-external-provisioner.fullname" . }}] +{{- end }} +{{- end }} diff --git a/applications/nfsserver/deploy/templates/rolebinding.yaml b/applications/nfsserver/deploy/templates/rolebinding.yaml new file mode 100644 index 00000000..4af1b054 --- /dev/null +++ b/applications/nfsserver/deploy/templates/rolebinding.yaml @@ -0,0 +1,15 @@ +{{- if .Values.apps.nfsserver.rbac.create }} +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + name: leader-locking-{{ template "nfs-subdir-external-provisioner.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "nfs-subdir-external-provisioner.serviceAccountName" . }} +roleRef: + kind: Role + name: leader-locking-{{ template "nfs-subdir-external-provisioner.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/applications/nfsserver/deploy/templates/serviceaccount.yaml b/applications/nfsserver/deploy/templates/serviceaccount.yaml new file mode 100644 index 00000000..fd12848d --- /dev/null +++ b/applications/nfsserver/deploy/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{ if .Values.apps.nfsserver.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + {{- with .Values.apps.nfsserver.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "nfs-subdir-external-provisioner.serviceAccountName" . }} +{{- end -}} diff --git a/applications/nfsserver/deploy/templates/storageclass.yaml b/applications/nfsserver/deploy/templates/storageclass.yaml new file mode 100644 index 00000000..55df932f --- /dev/null +++ b/applications/nfsserver/deploy/templates/storageclass.yaml @@ -0,0 +1,33 @@ +{{ if .Values.apps.nfsserver.storageClass.create -}} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + name: {{ printf "%s-%s" .Values.namespace .Values.apps.nfsserver.storageClass.name }} + annotations: + {{- if .Values.apps.nfsserver.storageClass.defaultClass }} + storageclass.kubernetes.io/is-default-class: "true" + {{- end }} + {{- with .Values.apps.nfsserver.storageClass.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +provisioner: {{ template "nfs-subdir-external-provisioner.provisionerName" . }} +allowVolumeExpansion: {{ .Values.apps.nfsserver.storageClass.allowVolumeExpansion }} +reclaimPolicy: {{ .Values.apps.nfsserver.storageClass.reclaimPolicy }} +volumeBindingMode: {{ .Values.apps.nfsserver.storageClass.volumeBindingMode }} +parameters: + archiveOnDelete: "{{ .Values.apps.nfsserver.storageClass.archiveOnDelete }}" + {{- if .Values.apps.nfsserver.storageClass.pathPattern }} + pathPattern: "{{ .Values.apps.nfsserver.storageClass.pathPattern }}" + {{- end }} + {{- if .Values.apps.nfsserver.storageClass.onDelete }} + onDelete: "{{ .Values.apps.nfsserver.storageClass.onDelete }}" + {{- end }} +{{- if .Values.apps.nfsserver.nfs.mountOptions }} +mountOptions: + {{- range .Values.apps.nfsserver.nfs.mountOptions }} + - {{ . }} + {{- end }} +{{- end }} +{{ end -}} diff --git a/applications/nfsserver/deploy/values-dev.yaml b/applications/nfsserver/deploy/values-dev.yaml new file mode 100644 index 00000000..ba3d5f6a --- /dev/null +++ b/applications/nfsserver/deploy/values-dev.yaml @@ -0,0 +1,2 @@ +nfs: + useDNS: false \ No newline at end of file diff --git a/applications/nfsserver/deploy/values-local.yaml b/applications/nfsserver/deploy/values-local.yaml new file mode 100644 index 00000000..c96b04b7 --- /dev/null +++ b/applications/nfsserver/deploy/values-local.yaml @@ -0,0 +1,145 @@ +harness: + subdomain: nfsserver + service: + auto: false + deployment: + auto: false + + +# nfs server pvc disk size (/exports) +server: + diskSize: 10Gi + +# nfs-subdir-external-provisioner +# https://github.com/MetaCell/nfs-subdir-external-provisioner +#fullnameOverride: nfs-provisioner +nameOverride: nfs-provisioner + +replicaCount: 1 +strategyType: Recreate + +# provisionerImage: +# repository: gcr.io/metacellllc/nfs-subdir-external-provisioner +# tag: "1.0" +# pullPolicy: IfNotPresent +# imagePullSecrets: [] + +# buildMode: true + +nfs: + server: # auto set via nfs service ip address + useDNS: false + path: /exports # /exports + mountOptions: + - nolock + - nfsvers=3 + - local_lock=all + volumeName: nfs-subdir-external-provisioner-root + # Reclaim policy for the main nfs volume + reclaimPolicy: Retain + +# For creating the StorageClass automatically: +storageClass: + create: true + + # Set a provisioner name. If unset, a name will be generated. + # provisionerName: + + # Set StorageClass as the default StorageClass + # Ignored if storageClass.create is false + defaultClass: false + + # Set a StorageClass base name (will be concatenated with namespace) + # Ignored if storageClass.create is false + name: nfs-client + + # Allow volume to be expanded dynamically + allowVolumeExpansion: true + + # Method used to reclaim an obsoleted volume + reclaimPolicy: Delete + + # When set to false your PVs will not be archived by the provisioner upon deletion of the PVC. + archiveOnDelete: true + + # If it exists and has 'delete' value, delete the directory. If it exists and has 'retain' value, save the directory. + # Overrides archiveOnDelete. + # Ignored if value not set. + onDelete: + + # Specifies a template for creating a directory path via PVC metadata's such as labels, annotations, name or namespace. + # Ignored if value not set. + pathPattern: + + # Set access mode - ReadWriteOnce, ReadOnlyMany or ReadWriteMany + accessModes: ReadWriteOnce + + # Set volume bindinng mode - Immediate or WaitForFirstConsumer + volumeBindingMode: Immediate + + # Storage class annotations + annotations: {} + +leaderElection: + # When set to false leader election will be disabled + enabled: true + +## For RBAC support: +rbac: + # Specifies whether RBAC resources should be created + create: true + +# If true, create & use Pod Security Policy resources +# https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +podSecurityPolicy: + enabled: false + +# Deployment pod annotations +podAnnotations: {} + +## Set pod priorityClassName +# priorityClassName: "" + +podSecurityContext: {} + +securityContext: {} + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + + # Annotations to add to the service account + annotations: {} + + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 10m + memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: { + podAffinity: { + requiredDuringSchedulingIgnoredDuringExecution: [{ + labelSelector: { + matchExpressions: [{ + key: 'app', + operator: 'In', + values: ['nfs-server',] + }] + }, + topologyKey: kubernetes.io/hostname + },]} +} + +# Additional labels for any resource created +labels: {} diff --git a/applications/nfsserver/deploy/values.yaml b/applications/nfsserver/deploy/values.yaml new file mode 100644 index 00000000..8bf13056 --- /dev/null +++ b/applications/nfsserver/deploy/values.yaml @@ -0,0 +1,144 @@ +harness: + subdomain: nfsserver + service: + auto: false + deployment: + auto: false + + +# nfs server pvc disk size (/exports) +server: + diskSize: 10Gi + +# nfs-subdir-external-provisioner +# https://github.com/MetaCell/nfs-subdir-external-provisioner +#fullnameOverride: nfs-provisioner +nameOverride: nfs-provisioner + +replicaCount: 1 +strategyType: Recreate + +# provisionerImage: +# repository: gcr.io/metacellllc/nfs-subdir-external-provisioner +# tag: "1.0" +# pullPolicy: IfNotPresent +# imagePullSecrets: [] + +# buildMode: true + +nfs: + server: # auto set via nfs service ip address + useDNS: true + path: /exports # /exports + mountOptions: + - nolock + - local_lock=all + volumeName: nfs-subdir-external-provisioner-root + # Reclaim policy for the main nfs volume + reclaimPolicy: Retain + +# For creating the StorageClass automatically: +storageClass: + create: true + + # Set a provisioner name. If unset, a name will be generated. + # provisionerName: + + # Set StorageClass as the default StorageClass + # Ignored if storageClass.create is false + defaultClass: false + + # Set a StorageClass base name (will be concatenated with namespace) + # Ignored if storageClass.create is false + name: nfs-client + + # Allow volume to be expanded dynamically + allowVolumeExpansion: true + + # Method used to reclaim an obsoleted volume + reclaimPolicy: Delete + + # When set to false your PVs will not be archived by the provisioner upon deletion of the PVC. + archiveOnDelete: true + + # If it exists and has 'delete' value, delete the directory. If it exists and has 'retain' value, save the directory. + # Overrides archiveOnDelete. + # Ignored if value not set. + onDelete: + + # Specifies a template for creating a directory path via PVC metadata's such as labels, annotations, name or namespace. + # Ignored if value not set. + pathPattern: + + # Set access mode - ReadWriteOnce, ReadOnlyMany or ReadWriteMany + accessModes: ReadWriteOnce + + # Set volume bindinng mode - Immediate or WaitForFirstConsumer + volumeBindingMode: Immediate + + # Storage class annotations + annotations: {} + +leaderElection: + # When set to false leader election will be disabled + enabled: true + +## For RBAC support: +rbac: + # Specifies whether RBAC resources should be created + create: true + +# If true, create & use Pod Security Policy resources +# https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +podSecurityPolicy: + enabled: false + +# Deployment pod annotations +podAnnotations: {} + +## Set pod priorityClassName +# priorityClassName: "" + +podSecurityContext: {} + +securityContext: {} + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + + # Annotations to add to the service account + annotations: {} + + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 10m + memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: { + podAffinity: { + requiredDuringSchedulingIgnoredDuringExecution: [{ + labelSelector: { + matchExpressions: [{ + key: 'app', + operator: 'In', + values: ['nfs-server',] + }] + }, + topologyKey: kubernetes.io/hostname + },]} +} + +# Additional labels for any resource created +labels: {} diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/CHANGELOG.md b/applications/nfsserver/nfs-subdir-external-provisioner/CHANGELOG.md new file mode 100644 index 00000000..10d5b7d5 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/CHANGELOG.md @@ -0,0 +1,51 @@ +# v4.0.2 +- Add arm7 (32bit) support (https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/pull/58) + +# v4.0.1 +- Preserve name of the PV directory name during archiving (https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/pull/59) + +# v4.0.0 +- Remove redundant field in the rbac.yaml (https://github.com/kubernetes-retired/external-storage/pull/970) +- Use `kubernetes-sigs/sig-storage-lib-external-provisioner` instead of `incubator/external-storage/lib` (https://github.com/kubernetes-retired/external-storage/pull/1026) +- Fill in rbac.yaml with ServiceAccount manifest (https://github.com/kubernetes-retired/external-storage/pull/1060, https://github.com/kubernetes-retired/external-storage/pull/1179) +- Make ARM deployment consistent with regular deployment (https://github.com/kubernetes-retired/external-storage/pull/1090) +- Update Deployment apiVersion (from `extensions/v1beta1` to `apps/v1`) and added selector field (https://github.com/kubernetes-retired/external-storage/pull/1230/, https://github.com/kubernetes-retired/external-storage/pull/1231/, https://github.com/kubernetes-retired/external-storage/pull/1283/, https://github.com/kubernetes-retired/external-storage/pull/1294/) +- Fix namespace in deployments (https://github.com/kubernetes-retired/external-storage/pull/1087, https://github.com/kubernetes-retired/external-storage/pull/1279) +- Update path creation and implemented possibility save data after removing PV (https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/pull/7/) +- Support for running controller outside of cluster (https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/pull/9) +- Add a flag to disable leader election (https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/pull/22) +- Switched to kubernetes `v1.18.0` to be compatible with `>=1.20` selfLink removal (https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/pull/26/) +- Enable mountOptions from StorageClass to PersistentVolume (https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/pull/28) + +# v3.1.0 +- Make leader-election configurable: default endpoints object namespace to controller's instead of kube-system (https://github.com/kubernetes-retired/external-storage/pull/957) + +# v3.0.1 +- Fix archiveOnDelete parsing (https://github.com/kubernetes-retired/external-storage/pull/929) + +# v3.0.0 +- Adds archiveOnDelete parameter to provisioner (https://github.com/kubernetes-retired/external-storage/pull/905) +- Change all clusterroles to have endpoints permissions and reduced events permissions, consolidate where possible (https://github.com/kubernetes-retired/external-storage/pull/892) + +# v2.1.2 +- Propagate StorageClass MountOptions to PVs (https://github.com/kubernetes-retired/external-storage/pull/835) +- Skip deletion if the corresponding directory is not found (https://github.com/kubernetes-retired/external-storage/pull/859) + +# v2.1.1 +- Revert "Add namespace extended attributes to directory" (https://github.com/kubernetes-retired/external-storage/pull/816) + +# v2.1.0 +- Change the storage apiVersion from `storage.k8s.io/v1beta1` to `storage.k8s.io/v1` (https://github.com/kubernetes-retired/external-storage/pull/599) +- Fix Makefile to build on OSX (https://github.com/kubernetes-retired/external-storage/pull/661) +- Change the RBAC apiVersion from `rbac.authorization.k8s.io/v1alpha1` to `rbac.authorization.k8s.io/v1` (https://github.com/kubernetes-retired/external-storage/pull/656) +- Add serviceAccount to deployment (https://github.com/kubernetes-retired/external-storage/pull/653) +- Add namespace extended attributes to directory (https://github.com/kubernetes-retired/external-storage/pull/672) + +# v2.0.1 +- Add support for ARM (Raspberry PI). Image at `quay.io/external_storage/nfs-client-provisioner-arm`. (https://github.com/kubernetes-incubator/external-storage/pull/275) + +# v2.0.0 +- Fix issue 149 - nfs-client-provisioner create folder with 755, not 777 (https://github.com/kubernetes-incubator/external-storage/pull/150) + +# v1 +- Initial release diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/CONTRIBUTING.md b/applications/nfsserver/nfs-subdir-external-provisioner/CONTRIBUTING.md new file mode 100644 index 00000000..38ec4ebc --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/CONTRIBUTING.md @@ -0,0 +1,26 @@ +# Contributing Guidelines + +Welcome to Kubernetes. We are excited about the prospect of you joining our [community](https://git.k8s.io/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt: + +_As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._ + +## Getting Started + +We have full documentation on how to get started contributing here: + + + +- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests +- [Kubernetes Contributor Guide](https://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](https://git.k8s.io/community/contributors/guide#contributing) +- [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet) - Common resources for existing developers + +## Mentorship + +- [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers! + +## Contact Information + +- [Slack](https://kubernetes.slack.com/messages/sig-storage) +- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-storage) diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/Makefile b/applications/nfsserver/nfs-subdir-external-provisioner/Makefile new file mode 100644 index 00000000..3bb28220 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/Makefile @@ -0,0 +1,21 @@ +# Copyright 2016 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CMDS=nfs-subdir-external-provisioner +all: build + +include release-tools/build.make + +# BUILD_PLATFORMS=linux amd64 amd64; linux arm arm -arm; linux arm64 arm64 -arm64; linux ppc64le ppc64le -ppc64le; linux s390x s390x -s390x + BUILD_PLATFORMS=linux amd64 amd64 diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/OWNERS b/applications/nfsserver/nfs-subdir-external-provisioner/OWNERS new file mode 100644 index 00000000..db880eaa --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +approvers: + - ashishranjan738 + - humblec + - jackielii + - jsafrane + - kmova + - yonatankahana + - wongma7 diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/OWNERS_ALIASES b/applications/nfsserver/nfs-subdir-external-provisioner/OWNERS_ALIASES new file mode 120000 index 00000000..5dc795a6 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/OWNERS_ALIASES @@ -0,0 +1 @@ +release-tools/OWNERS_ALIASES \ No newline at end of file diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/README-METACELL.md b/applications/nfsserver/nfs-subdir-external-provisioner/README-METACELL.md new file mode 100644 index 00000000..55366b8d --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/README-METACELL.md @@ -0,0 +1,15 @@ +# Kubernetes NFS Subdir External Provisioner - MetaCell Build + +See also the CloudHarness NFS server implementation + +## Build, tag and push + +```bash +make + +docker build . -t nfs-subdir-external-provisioner:latest + +docker tag nfs-subdir-external-provisioner:latest us.gcr.io/metacellllc/nfs-subdir-external-provisioner:latest + +docker push us.gcr.io/metacellllc/nfs-subdir-external-provisioner:latest +``` diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/README.md b/applications/nfsserver/nfs-subdir-external-provisioner/README.md new file mode 100644 index 00000000..2a874a9a --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/README.md @@ -0,0 +1,331 @@ +# Kubernetes NFS Subdir External Provisioner + +**NFS subdir external provisioner** is an automatic provisioner that use your _existing and already configured_ NFS server to support dynamic provisioning of Kubernetes Persistent Volumes via Persistent Volume Claims. Persistent volumes are provisioned as `${namespace}-${pvcName}-${pvName}`. + +Note: This repository is migrated from https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client. As part of the migration: +- The container image name and repository has changed to `k8s.gcr.io/sig-storage` and `nfs-subdir-external-provisioner` respectively. +- To maintain backward compatibility with earlier deployment files, the naming of NFS Client Provisioner is retained as `nfs-client-provisioner` in the deployment YAMLs. +- One of the pending areas for development on this repository is to add automated e2e tests. If you would like to contribute, please raise an issue or reach us on the Kubernetes slack #sig-storage channel. + +## How to deploy NFS Subdir External Provisioner to your cluster + +To note again, you must _already_ have an NFS Server. + +### With Helm + +Follow the instructions from the helm chart [README](charts/nfs-subdir-external-provisioner/README.md). + +The tl;dr is + +```console +$ helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ +$ helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ + --set nfs.server=x.x.x.x \ + --set nfs.path=/exported/path +``` + +### With Kustomize + +**Step 1: Get connection information for your NFS server** + +Make sure your NFS server is accessible from your Kubernetes cluster and get the information you need to connect to it. At a minimum you will need its hostname and exported share path. + +**Step 2: Add the base resource** + +Create a `kustomization.yaml` file in a directory of your choice, and add the [deploy](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/tree/master/deploy) directory as a base. This will use the kustomization file within that directory as our base. + +```yaml +namespace: nfs-provisioner +bases: + - github.com/kubernetes-sigs/nfs-subdir-external-provisioner//deploy +``` + +**Step 3: Create namespace resource** + +Create a file with your namespace resource. The name can be anything as it will get overwritten by the namespace in your kustomization file. + +```yaml +# namespace.yaml +apiVersion: v1 +kind: Namespace +metadata: + name: nfs-provisioner +``` + +**Step 4: Configure deployment** + +To configure the deployment, you will need to patch it's container variables with the connection information for your NFS Server. + +```yaml +# patch_nfs_details.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: nfs-client-provisioner + name: nfs-client-provisioner +spec: + template: + spec: + containers: + - name: nfs-client-provisioner + env: + - name: NFS_SERVER + value: + - name: NFS_PATH + value: + volumes: + - name: nfs-client-root + nfs: + server: + path: +``` + +Replace occurrences of `` and `` with your connection information. + +**Step 5: Add resources and deploy** + +Add the namespace resource and patch you created in earlier steps. + +```yaml +namespace: nfs-provisioner +bases: + - github.com/kubernetes-sigs/nfs-subdir-external-provisioner//deploy +resources: + - namespace.yaml +patchesStrategicMerge: + - patch_nfs_details.yaml +``` + +Deploy (run inside directory with your kustomization file): + +```sh +kubectl apply -k . +``` + +**Step 6: Finally, test your environment!** + +Now we'll test your NFS subdir external provisioner by creating a persistent volume claim and a pod that writes a test file to the volume. This will make sure that the provisioner is provisioning and that the NFS server is reachable and writable. + +Deploy the test resources: + +```sh +$ kubectl create -f https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/test-claim.yaml -f https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/test-pod.yaml +``` + +Now check your NFS Server for the `SUCCESS` inside the PVC's directory. + +Delete the test resources: + +```sh +$ kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/test-claim.yaml -f https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/test-pod.yaml +``` + +Now check the PVC's directory has been deleted. + +**Step 7: Deploying your own PersistentVolumeClaims** + +To deploy your own PVC, make sure that you have the correct `storageClassName` (by default `nfs-client`). You can also patch the StorageClass resource to change it, like so: + +```yaml +# kustomization.yaml +namespace: nfs-provisioner +resources: + - github.com/kubernetes-sigs/nfs-subdir-external-provisioner//deploy + - namespace.yaml +patches: +- target: + kind: StorageClass + name: nfs-client + patch: |- + - op: replace + path: /metadata/name + value: +``` + +### Manually + +**Step 1: Get connection information for your NFS server** + +Make sure your NFS server is accessible from your Kubernetes cluster and get the information you need to connect to it. At a minimum you will need its hostname. + +**Step 2: Get the NFS Subdir External Provisioner files** + +To setup the provisioner you will download a set of YAML files, edit them to add your NFS server's connection information and then apply each with the `kubectl` / `oc` command. + +Get all of the files in the [deploy](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/tree/master/deploy) directory of this repository. These instructions assume that you have cloned the [kubernetes-sigs/nfs-subdir-external-provisioner](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/) repository and have a bash-shell open in the root directory. + +**Step 3: Setup authorization** + +If your cluster has RBAC enabled or you are running OpenShift you must authorize the provisioner. If you are in a namespace/project other than "default" edit `deploy/rbac.yaml`. + +**Kubernetes:** + +```sh +# Set the subject of the RBAC objects to the current namespace where the provisioner is being deployed +$ NS=$(kubectl config get-contexts|grep -e "^\*" |awk '{print $5}') +$ NAMESPACE=${NS:-default} +$ sed -i'' "s/namespace:.*/namespace: $NAMESPACE/g" ./deploy/rbac.yaml ./deploy/deployment.yaml +$ kubectl create -f deploy/rbac.yaml +``` + +**OpenShift:** + +On some installations of OpenShift the default admin user does not have cluster-admin permissions. If these commands fail refer to the OpenShift documentation for **User and Role Management** or contact your OpenShift provider to help you grant the right permissions to your admin user. +On OpenShift the service account used to bind volumes does not have the necessary permissions required to use the `hostmount-anyuid` SCC. See also [Role based access to SCC](https://docs.openshift.com/container-platform/4.4/authentication/managing-security-context-constraints.html#role-based-access-to-ssc_configuring-internal-oauth) for more information. If these commands fail refer to the OpenShift documentation for **User and Role Management** or contact your OpenShift provider to help you grant the right permissions to your admin user. + +```sh +# Set the subject of the RBAC objects to the current namespace where the provisioner is being deployed +$ NAMESPACE=`oc project -q` +$ sed -i'' "s/namespace:.*/namespace: $NAMESPACE/g" ./deploy/rbac.yaml ./deploy/deployment.yaml +$ oc create -f deploy/rbac.yaml +$ oc adm policy add-scc-to-user hostmount-anyuid system:serviceaccount:$NAMESPACE:nfs-client-provisioner +``` + +**Step 4: Configure the NFS subdir external provisioner** + +If you would like to use a custom built nfs-subdir-external-provisioner image, you must edit the provisioner's deployment file to specify the correct location of your `nfs-client-provisioner` container image. + +Next you must edit the provisioner's deployment file to add connection information for your NFS server. Edit `deploy/deployment.yaml` and replace the two occurences of with your server's hostname. + +```yaml +kind: Deployment +apiVersion: apps/v1 +metadata: + name: nfs-client-provisioner +spec: + replicas: 1 + selector: + matchLabels: + app: nfs-client-provisioner + strategy: + type: Recreate + template: + metadata: + labels: + app: nfs-client-provisioner + spec: + serviceAccountName: nfs-client-provisioner + containers: + - name: nfs-client-provisioner + image: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 + volumeMounts: + - name: nfs-client-root + mountPath: /persistentvolumes + env: + - name: PROVISIONER_NAME + value: k8s-sigs.io/nfs-subdir-external-provisioner + - name: NFS_SERVER + value: + - name: NFS_PATH + value: /var/nfs + volumes: + - name: nfs-client-root + nfs: + server: + path: /var/nfs +``` + +Note: If you want to change the PROVISIONER_NAME above from `k8s-sigs.io/nfs-subdir-external-provisioner` to something else like `myorg/nfs-storage`, remember to also change the PROVISIONER_NAME in the storage class definition below. + +To disable leader election, define an env variable named ENABLE_LEADER_ELECTION and set its value to false. + +**Step 5: Deploying your storage class** + +**_Parameters:_** + +| Name | Description | Default | +| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------: | +| onDelete | If it exists and has a delete value, delete the directory, if it exists and has a retain value, save the directory. | will be archived with name on the share: `archived-` | +| archiveOnDelete | If it exists and has a false value, delete the directory. if `onDelete` exists, `archiveOnDelete` will be ignored. | will be archived with name on the share: `archived-` | +| pathPattern | Specifies a template for creating a directory path via PVC metadata's such as labels, annotations, name or namespace. To specify metadata use `${.PVC.}`. Example: If folder should be named like `-`, use `${.PVC.namespace}-${.PVC.name}` as pathPattern. | n/a | + +This is `deploy/class.yaml` which defines the NFS subdir external provisioner's Kubernetes Storage Class: + +```yaml +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: nfs-client +provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME' +parameters: + pathPattern: "${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}" # waits for nfs.io/storage-path annotation, if not specified will accept as empty string. + onDelete: delete +``` + +**Step 6: Finally, test your environment!** + +Now we'll test your NFS subdir external provisioner. + +Deploy: + +```sh +$ kubectl create -f deploy/test-claim.yaml -f deploy/test-pod.yaml +``` + +Now check your NFS Server for the file `SUCCESS`. + +```sh +kubectl delete -f deploy/test-pod.yaml -f deploy/test-claim.yaml +``` + +Now check the folder has been deleted. + +**Step 7: Deploying your own PersistentVolumeClaims** + +To deploy your own PVC, make sure that you have the correct `storageClassName` as indicated by your `deploy/class.yaml` file. + +For example: + +```yaml +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: test-claim + annotations: + nfs.io/storage-path: "test-path" # not required, depending on whether this annotation was shown in the storage class description +spec: + storageClassName: nfs-client + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Mi +``` + +# Build and publish your own container image + +To build your own custom container image from this repository, you will have to build and push the nfs-subdir-external-provisioner image using the following instructions. + +```sh +make build +make container +# `nfs-subdir-external-provisioner:latest` will be created. +# Note: This will build a single-arch image that matches the machine on which container is built. +# To upload this to your custom registry, say `quay.io/myorg` and arch as amd64, you can use +# docker tag nfs-subdir-external-provisioner:latest quay.io/myorg/nfs-subdir-external-provisioner-amd64:latest +# docker push quay.io/myorg/nfs-subdir-external-provisioner-amd64:latest +``` + +# Build and publish with GitHub Actions + +In a forked repository you can use GitHub Actions pipeline defined in [.github/workflows/release.yml](.github/workflows/release.yml). The pipeline builds Docker images for `linux/amd64`, `linux/arm64`, and `linux/arm/v7` platforms and publishes them using a multi-arch manifest. The pipeline is triggered when you add a tag like `gh-v{major}.{minor}.{patch}` to your commit and push it to GitHub. The tag is used for generating Docker image tags: `latest`, `{major}`, `{major}:{minor}`, `{major}:{minor}:{patch}`. + +The pipeline adds several labels: +* `org.opencontainers.image.title=${{ github.event.repository.name }}` +* `org.opencontainers.image.description=${{ github.event.repository.description }}` +* `org.opencontainers.image.url=${{ github.event.repository.html_url }}` +* `org.opencontainers.image.source=${{ github.event.repository.clone_url }}` +* `org.opencontainers.image.created=${{ steps.prep.outputs.created }}` +* `org.opencontainers.image.revision=${{ github.sha }}` +* `org.opencontainers.image.licenses=${{ github.event.repository.license.spdx_id }}` + +**Important:** +* The pipeline performs the docker login command using `REGISTRY_USERNAME` and `REGISTRY_TOKEN` secrets, which have to be provided. +* You also need to provide the `DOCKER_IMAGE` secret specifying your Docker image name, e.g., `quay.io/[username]/nfs-subdir-external-provisioner`. + + +## NFS provisioner limitations/pitfalls +* The provisioned storage is not guaranteed. You may allocate more than the NFS share's total size. The share may also not have enough storage space left to actually accommodate the request. +* The provisioned storage limit is not enforced. The application can expand to use all the available storage regardless of the provisioned size. +* Storage resize/expansion operations are not presently supported in any form. You will end up in an error state: `Ignoring the PVC: didn't find a plugin capable of expanding the volume; waiting for an external controller to process this PVC.` diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/RELEASE.md b/applications/nfsserver/nfs-subdir-external-provisioner/RELEASE.md new file mode 100644 index 00000000..7274b344 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/RELEASE.md @@ -0,0 +1,9 @@ +# Release Process + +The Kubernetes Template Project is released on an as-needed basis. The process is as follows: + +1. An issue is proposing a new release with a changelog since the last release +1. All [OWNERS](OWNERS) must LGTM this release +1. An OWNER runs `git tag -s $VERSION` and inserts the changelog and pushes the tag with `git push $VERSION` +1. The release issue is closed +1. An announcement email is sent to `kubernetes-dev@googlegroups.com` with the subject `[ANNOUNCE] kubernetes-template-project $VERSION is released` diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/SECURITY_CONTACTS b/applications/nfsserver/nfs-subdir-external-provisioner/SECURITY_CONTACTS new file mode 100644 index 00000000..8a7b91d5 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/SECURITY_CONTACTS @@ -0,0 +1,16 @@ +# Defined below are the security contacts for this repo. +# +# They are the contact point for the Product Security Committee to reach out +# to for triaging and handling of incoming issues. +# +# The below names agree to abide by the +# [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy) +# and will be removed and replaced if they violate that agreement. +# +# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE +# INSTRUCTIONS AT https://kubernetes.io/security/ + +jsafrane +msau42 +saad-ali +xing-yang diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/cmd/nfs-subdir-external-provisioner/provisioner.go b/applications/nfsserver/nfs-subdir-external-provisioner/cmd/nfs-subdir-external-provisioner/provisioner.go new file mode 100644 index 00000000..09e1df08 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/cmd/nfs-subdir-external-provisioner/provisioner.go @@ -0,0 +1,301 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "errors" + "flag" + "fmt" + "os" + "os/exec" + "path/filepath" + "regexp" + "strconv" + "strings" + + "github.com/golang/glog" + v1 "k8s.io/api/core/v1" + + storage "k8s.io/api/storage/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + storagehelpers "k8s.io/component-helpers/storage/volume" + "sigs.k8s.io/sig-storage-lib-external-provisioner/v6/controller" +) + +const ( + provisionerNameKey = "PROVISIONER_NAME" +) + +type nfsProvisioner struct { + client kubernetes.Interface + server string + path string +} + +type pvcMetadata struct { + data map[string]string + labels map[string]string + annotations map[string]string +} + +var pattern = regexp.MustCompile(`\${\.PVC\.((labels|annotations)\.(.*?)|.*?)}`) + +func (meta *pvcMetadata) stringParser(str string) string { + result := pattern.FindAllStringSubmatch(str, -1) + for _, r := range result { + switch r[2] { + case "labels": + str = strings.ReplaceAll(str, r[0], meta.labels[r[3]]) + case "annotations": + str = strings.ReplaceAll(str, r[0], meta.annotations[r[3]]) + default: + str = strings.ReplaceAll(str, r[0], meta.data[r[1]]) + } + } + + return str +} + +const ( + mountPath = "/exports" +) + +var _ controller.Provisioner = &nfsProvisioner{} + +func (p *nfsProvisioner) Provision(ctx context.Context, options controller.ProvisionOptions) (*v1.PersistentVolume, controller.ProvisioningState, error) { + if options.PVC.Spec.Selector != nil { + return nil, controller.ProvisioningFinished, fmt.Errorf("claim Selector is not supported") + } + glog.V(4).Infof("nfs provisioner: VolumeOptions %v", options) + capacity := options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] + requestBytes := capacity.Value() + + pvcNamespace := options.PVC.Namespace + pvcName := options.PVC.Name + + pvName := strings.Join([]string{pvcNamespace, pvcName, options.PVName}, "-") + + metadata := &pvcMetadata{ + data: map[string]string{ + "name": pvcName, + "namespace": pvcNamespace, + }, + labels: options.PVC.Labels, + annotations: options.PVC.Annotations, + } + + fullPath := filepath.Join(mountPath, pvName) + path := filepath.Join(p.path, pvName) + + pathPattern, exists := options.StorageClass.Parameters["pathPattern"] + if exists { + customPath := metadata.stringParser(pathPattern) + if customPath != "" { + path = filepath.Join(p.path, customPath) + fullPath = filepath.Join(mountPath, customPath) + } + } + + + // glog.V(4).Infof("creating path %s", fullPath) + // if err := os.MkdirAll(fullPath, 0o777); err != nil { + // return nil, controller.ProvisioningFinished, errors.New("unable to create directory to provision new pv: " + err.Error()) + // } + + // if err := os.Chmod(fullPath, 0o777); err != nil { + // return nil, "", err + // } + + cmd := exec.Command("/usr/local/bin/mklimdir.sh", "-m", fullPath, "-s", strconv.FormatInt(requestBytes, 10)) + if err := cmd.Run(); err != nil { + return nil, controller.ProvisioningFinished, errors.New("unable to create directory to provision new pv: " + err.Error()) + } + + pv := &v1.PersistentVolume{ + ObjectMeta: metav1.ObjectMeta{ + Name: options.PVName, + }, + Spec: v1.PersistentVolumeSpec{ + PersistentVolumeReclaimPolicy: *options.StorageClass.ReclaimPolicy, + AccessModes: options.PVC.Spec.AccessModes, + MountOptions: options.StorageClass.MountOptions, + Capacity: v1.ResourceList{ + v1.ResourceName(v1.ResourceStorage): options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)], + }, + PersistentVolumeSource: v1.PersistentVolumeSource{ + NFS: &v1.NFSVolumeSource{ + Server: p.server, + Path: path, + ReadOnly: false, + }, + }, + }, + } + return pv, controller.ProvisioningFinished, nil +} + +func (p *nfsProvisioner) Delete(ctx context.Context, volume *v1.PersistentVolume) error { + path := volume.Spec.PersistentVolumeSource.NFS.Path + basePath := filepath.Base(path) + oldPath := filepath.Join(mountPath, basePath) + + if _, err := os.Stat(oldPath); os.IsNotExist(err) { + glog.Warningf("path %s does not exist, deletion skipped", oldPath) + return nil + } + // Get the storage class for this volume. + storageClass, err := p.getClassForVolume(ctx, volume) + if err != nil { + return err + } + + // delete the loop back device + cmd := exec.Command("/usr/local/bin/rmlimdir.sh", "-m", oldPath) + if err := cmd.Run(); err != nil { + return err + } + + // Determine if the "onDelete" parameter exists. + // If it exists and has a `delete` value, delete the directory. + // If it exists and has a `retain` value, safe the directory. + onDelete := storageClass.Parameters["onDelete"] + switch onDelete { + case "delete": + return os.RemoveAll(oldPath) + case "retain": + return nil + } + + // Determine if the "archiveOnDelete" parameter exists. + // If it exists and has a false value, delete the directory. + // Otherwise, archive it. + archiveOnDelete, exists := storageClass.Parameters["archiveOnDelete"] + if exists { + archiveBool, err := strconv.ParseBool(archiveOnDelete) + if err != nil { + return err + } + if !archiveBool { + return os.RemoveAll(oldPath) + } + } + + archivePath := filepath.Join(mountPath, "archived-"+basePath) + glog.V(4).Infof("archiving path %s to %s", oldPath, archivePath) + return os.Rename(oldPath, archivePath) +} + +// getClassForVolume returns StorageClass. +func (p *nfsProvisioner) getClassForVolume(ctx context.Context, pv *v1.PersistentVolume) (*storage.StorageClass, error) { + if p.client == nil { + return nil, fmt.Errorf("cannot get kube client") + } + className := storagehelpers.GetPersistentVolumeClass(pv) + if className == "" { + return nil, fmt.Errorf("volume has no storage class") + } + class, err := p.client.StorageV1().StorageClasses().Get(ctx, className, metav1.GetOptions{}) + if err != nil { + return nil, err + } + + return class, nil +} + +func main() { + flag.Parse() + flag.Set("logtostderr", "true") + + server := os.Getenv("NFS_SERVER") + if server == "" { + // 2022-11-04 ZS: use the internal K8s service host env variable + // for getting the ip address of the nfs server + server = os.Getenv("NFS_SERVER_SERVICE_HOST") + if server == "" { + glog.Fatal("NFS_SERVER and NFS_SERVER_SERVICE_HOST are both not set") + } else { + glog.Infof("Using NFS Server: %s", server) + } + } + path := os.Getenv("NFS_PATH") + if path == "" { + glog.Fatal("NFS_PATH not set") + } + provisionerName := os.Getenv(provisionerNameKey) + if provisionerName == "" { + glog.Fatalf("environment variable %s is not set! Please set it.", provisionerNameKey) + } + kubeconfig := os.Getenv("KUBECONFIG") + var config *rest.Config + if kubeconfig != "" { + // Create an OutOfClusterConfig and use it to create a client for the controller + // to use to communicate with Kubernetes + var err error + config, err = clientcmd.BuildConfigFromFlags("", kubeconfig) + if err != nil { + glog.Fatalf("Failed to create kubeconfig: %v", err) + } + } else { + // Create an InClusterConfig and use it to create a client for the controller + // to use to communicate with Kubernetes + var err error + config, err = rest.InClusterConfig() + if err != nil { + glog.Fatalf("Failed to create config: %v", err) + } + } + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + glog.Fatalf("Failed to create client: %v", err) + } + + // The controller needs to know what the server version is because out-of-tree + // provisioners aren't officially supported until 1.5 + serverVersion, err := clientset.Discovery().ServerVersion() + if err != nil { + glog.Fatalf("Error getting server version: %v", err) + } + + leaderElection := true + leaderElectionEnv := os.Getenv("ENABLE_LEADER_ELECTION") + if leaderElectionEnv != "" { + leaderElection, err = strconv.ParseBool(leaderElectionEnv) + if err != nil { + glog.Fatalf("Unable to parse ENABLE_LEADER_ELECTION env var: %v", err) + } + } + + clientNFSProvisioner := &nfsProvisioner{ + client: clientset, + server: server, + path: path, + } + // Start the provision controller which will dynamically provision efs NFS + // PVs + pc := controller.NewProvisionController(clientset, + provisionerName, + clientNFSProvisioner, + serverVersion.GitVersion, + controller.LeaderElection(leaderElection), + ) + // Never stops. + pc.Run(context.Background()) +} diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/go.mod b/applications/nfsserver/nfs-subdir-external-provisioner/go.mod new file mode 100644 index 00000000..fd3cefc0 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/go.mod @@ -0,0 +1,43 @@ +module github.com/kubernetes-sigs/nfs-subdir-external-provisioner + +go 1.14 + +require ( + github.com/golang/glog v1.0.0 + k8s.io/api v0.23.4 + k8s.io/apimachinery v0.23.4 + k8s.io/client-go v0.23.4 + k8s.io/component-helpers v0.23.4 + sigs.k8s.io/sig-storage-lib-external-provisioner/v6 v6.0.0 +) + +replace ( + golang.org/x/crypto => golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd + k8s.io/api => k8s.io/api v0.23.4 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.23.4 + k8s.io/apimachinery => k8s.io/apimachinery v0.23.4 + k8s.io/apiserver => k8s.io/apiserver v0.23.4 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.23.4 + k8s.io/client-go => k8s.io/client-go v0.23.4 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.23.4 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.23.4 + k8s.io/code-generator => k8s.io/code-generator v0.23.4 + k8s.io/component-base => k8s.io/component-base v0.23.4 + k8s.io/component-helpers => k8s.io/component-helpers v0.23.4 + k8s.io/controller-manager => k8s.io/controller-manager v0.23.4 + k8s.io/cri-api => k8s.io/cri-api v0.23.4 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.23.4 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.23.4 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.23.4 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.23.4 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.23.4 + k8s.io/kubectl => k8s.io/kubectl v0.23.4 + k8s.io/kubelet => k8s.io/kubelet v0.23.4 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.23.4 + k8s.io/metrics => k8s.io/metrics v0.23.4 + k8s.io/mount-utils => k8s.io/mount-utils v0.23.4 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.23.4 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.23.4 + k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.23.4 + k8s.io/sample-controller => k8s.io/sample-controller v0.23.4 +) diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/go.sum b/applications/nfsserver/nfs-subdir-external-provisioner/go.sum new file mode 100644 index 00000000..5e6677a2 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/go.sum @@ -0,0 +1,688 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw= +github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg= +github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.5.1 h1:bdHYieyGlH+6OLEk2YQha8THib30KP0/yD0YH9m6xcA= +github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8 h1:+fpWZdT24pJBiqJdAwYBjPSk+5YmQzYNPYzQsdzLkt8= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38= +golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= +golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e h1:XMgFehsDnnLGtjvjOfqWSUzt0alpTR1RSEuznObga2c= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b h1:9zKuko04nR4gjZ4+DNjHqRlAJqbJETHwiNKDqTfOjfE= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.23.4 h1:85gnfXQOWbJa1SiWGpE9EEtHs0UVvDyIsSMpEtl2D4E= +k8s.io/api v0.23.4/go.mod h1:i77F4JfyNNrhOjZF7OwwNJS5Y1S9dpwvb9iYRYRczfI= +k8s.io/apimachinery v0.23.4 h1:fhnuMd/xUL3Cjfl64j5ULKZ1/J9n8NuQEgNL+WXWfdM= +k8s.io/apimachinery v0.23.4/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= +k8s.io/client-go v0.23.4 h1:YVWvPeerA2gpUudLelvsolzH7c2sFoXXR5wM/sWqNFU= +k8s.io/client-go v0.23.4/go.mod h1:PKnIL4pqLuvYUK1WU7RLTMYKPiIh7MYShLshtRY9cj0= +k8s.io/component-helpers v0.23.4 h1:zCLeBuo3Qs0BqtJu767RXJgs5S9ruFJZcbM1aD+cMmc= +k8s.io/component-helpers v0.23.4/go.mod h1:1Pl7L4zukZ054ElzRbvmZ1FJIU8roBXFOeRFu8zipa4= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.30.0 h1:bUO6drIvCIsvZ/XFgfxoGFQU/a4Qkh0iAlvUR7vlHJw= +k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= +k8s.io/utils v0.0.0-20200327001022-6496210b90e8/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20211116205334-6203023598ed h1:ck1fRPWPJWsMd8ZRFsWc6mh/zHp5fZ/shhbrgPUxDAE= +k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s= +sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= +sigs.k8s.io/sig-storage-lib-external-provisioner/v6 v6.0.0 h1:0TUypniRylQye1IqOQLxaLPa+TNuO5MQ2dycNgLK/ko= +sigs.k8s.io/sig-storage-lib-external-provisioner/v6 v6.0.0/go.mod h1:e30PD56mVu/vIRIkP+V1oqwY1EpnIhJ10VdBuHAJ/jk= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y= +sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/.prow.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/.prow.sh new file mode 100755 index 00000000..b9267829 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/.prow.sh @@ -0,0 +1,23 @@ +#! /bin/bash -e + +# Copyright 2021 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This is for testing csi-release-tools itself in Prow. All other +# repos use prow.sh for that, but as csi-release-tools isn't a normal +# repo with some Go code in it, it has a custom Prow test script. + +./verify-shellcheck.sh "$(pwd)" +./verify-spelling.sh "$(pwd)" +./verify-boilerplate.sh "$(pwd)" diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/CONTRIBUTING.md b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/CONTRIBUTING.md new file mode 100644 index 00000000..de471151 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing Guidelines + +Welcome to Kubernetes. We are excited about the prospect of you joining our [community](https://github.com/kubernetes/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt: + +_As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._ + +## Getting Started + +We have full documentation on how to get started contributing here: + + + +- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests +- [Kubernetes Contributor Guide](http://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](http://git.k8s.io/community/contributors/guide#contributing) +- [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet.md) - Common resources for existing developers + +## Mentorship + +- [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers! + + diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/KUBERNETES_CSI_OWNERS_ALIASES b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/KUBERNETES_CSI_OWNERS_ALIASES new file mode 100644 index 00000000..2f3e2dfc --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/KUBERNETES_CSI_OWNERS_ALIASES @@ -0,0 +1,37 @@ +# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md + +aliases: + + # SIG-Storage chairs and leads should always have approval rights in all repos. + # Others may be added as needed here or in each repo. + kubernetes-csi-approvers: + - jsafrane + - msau42 + - saad-ali + - xing-yang + + # Reviewers are automatically assigned to new PRs. The following + # reviewers will be active in all repos. Other reviewers can be + # added in each repo. + # + # Reviewers are encouraged to set the "Busy" flag in their GitHub status + # when they are temporarily unable to review PRs. + kubernetes-csi-reviewers: + - andyzhangx + - chrishenzie + - ggriffiths + - gnufied + - humblec + - j-griffith + - Jiawei0227 + - jingxu97 + - jsafrane + - pohly + - xing-yang + +# This documents who previously contributed to Kubernetes-CSI +# as approver. +emeritus_approvers: +- lpabon +- sbezverk +- vladimirvivien diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/LICENSE b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/LICENSE new file mode 100644 index 00000000..8dada3ed --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + 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. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/OWNERS b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/OWNERS new file mode 100644 index 00000000..1fb74587 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/OWNERS @@ -0,0 +1,8 @@ +# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md + +approvers: +- kubernetes-csi-approvers +- pohly + +reviewers: +- kubernetes-csi-reviewers diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/OWNERS_ALIASES b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/OWNERS_ALIASES new file mode 120000 index 00000000..7ec6c034 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/OWNERS_ALIASES @@ -0,0 +1 @@ +KUBERNETES_CSI_OWNERS_ALIASES \ No newline at end of file diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/README.md b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/README.md new file mode 100644 index 00000000..4a4e5689 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/README.md @@ -0,0 +1,177 @@ +# [csi-release-tools](https://github.com/kubernetes-csi/csi-release-tools) + +These build and test rules can be shared between different Go projects +without modifications. Customization for the different projects happen +in the top-level Makefile. + +The rules include support for building and pushing Docker images, with +the following features: + - one or more command and image per project + - push canary and/or tagged release images + - automatically derive the image tag(s) from repo tags + - the source code revision is stored in a "revision" image label + - never overwrites an existing release image + +Usage +----- + +The expected repository layout is: + - `cmd/*/*.go` - source code for each command + - `cmd/*/Dockerfile` - docker file for each command or + Dockerfile in the root when only building a single command + - `Makefile` - includes `release-tools/build.make` and sets + configuration variables + - `.prow.sh` script which imports `release-tools/prow.sh` + and may contain further customization + - `.cloudbuild.sh` and `cloudbuild.yaml` as symlinks to + the corresponding files in `release-tools` or (if necessary) + as custom files + +To create a release, tag a certain revision with a name that +starts with `v`, for example `v1.0.0`, then `make push` +while that commit is checked out. + +It does not matter on which branch that revision exists, i.e. it is +possible to create releases directly from master. A release branch can +still be created for maintenance releases later if needed. + +Release branches are expected to be named `release-x.y` for releases +`x.y.z`. Building from such a branch creates `x.y-canary` +images. Building from master creates the main `canary` image. + +Sharing and updating +-------------------- + +[`git subtree`](https://github.com/git/git/blob/HEAD/contrib/subtree/git-subtree.txt) +is the recommended way of maintaining a copy of the rules inside the +`release-tools` directory of a project. This way, it is possible to make +changes also locally, test them and then push them back to the shared +repository at a later time. + +We no longer care about importing the full commit history, so `--squash` should be used +when submitting a `release-tools` update. Also make sure that the PR for that +contains the automatically generated commit message in the PR description. +It contains the list of individual commits that were squashed. The script from +https://github.com/kubernetes-csi/csi-release-tools/issues/7 can create such +PRs automatically. + +Cheat sheet: + +- `git subtree add --squash --prefix=release-tools https://github.com/kubernetes-csi/csi-release-tools.git master` - add release tools to a repo which does not have them yet (only once) +- `git subtree pull --squash --prefix=release-tools https://github.com/kubernetes-csi/csi-release-tools.git master` - update local copy to latest upstream (whenever upstream changes) +- edit, `git commit`, `git subtree push --prefix=release-tools git@github.com:/csi-release-tools.git ` - push to a new branch before submitting a PR + +verify-shellcheck.sh +-------------------- + +The [verify-shellcheck.sh](./verify-shellcheck.sh) script in this repo +is a stripped down copy of the [corresponding +script](https://github.com/kubernetes/kubernetes/blob/release-1.14/hack/verify-shellcheck.sh) +in the Kubernetes repository. It can be used to check for certain +errors shell scripts, like missing quotation marks. The default +`test-shellcheck` target in [build.make](./build.make) only checks the +scripts in this directory. Components can add more directories to +`TEST_SHELLCHECK_DIRS` to check also other scripts. + +End-to-end testing +------------------ + +A repo that wants to opt into testing via Prow must set up a top-level +`.prow.sh`. Typically that will source `prow.sh` and then transfer +control to it: + +``` bash +#! /bin/bash -e + +. release-tools/prow.sh +main +``` + +All Kubernetes-CSI repos are expected to switch to Prow. For details +on what is enabled in Prow, see +https://github.com/kubernetes/test-infra/tree/HEAD/config/jobs/kubernetes-csi + +Test results for periodic jobs are visible in +https://testgrid.k8s.io/sig-storage-csi-ci + +It is possible to reproduce the Prow testing locally on a suitable machine: +- Linux host +- Docker installed +- code to be tested checkout out in `$GOPATH/src/` +- `cd $GOPATH/src/ && ./.prow.sh` + +Beware that the script intentionally doesn't clean up after itself and +modifies the content of `$GOPATH`, in particular the `kubernetes` and +`kind` repositories there. Better run it in an empty, disposable +`$GOPATH`. + +When it terminates, the following command can be used to get access to +the Kubernetes cluster that was brought up for testing (assuming that +this step succeeded): + + export KUBECONFIG="$(kind get kubeconfig-path --name="csi-prow")" + +It is possible to control the execution via environment variables. See +`prow.sh` for details. Particularly useful is testing against different +Kubernetes releases: + + CSI_PROW_KUBERNETES_VERSION=1.13.3 ./.prow.sh + CSI_PROW_KUBERNETES_VERSION=latest ./.prow.sh + +Dependencies and vendoring +-------------------------- + +Most projects will (eventually) use `go mod` to manage +dependencies. `dep` is also still supported by `csi-release-tools`, +but not documented here because it's not recommended anymore. + +The usual instructions for using [go +modules](https://github.com/golang/go/wiki/Modules) apply. Here's a cheat sheet +for some of the relevant commands: +- list available updates: `GO111MODULE=on go list -u -m all` +- update or add a single dependency: `GO111MODULE=on go get ` +- update all dependencies to their next minor or patch release: + `GO111MODULE=on go get ./...` (add `-u=patch` to limit to patch + releases) +- lock onto a specific version: `GO111MODULE=on go get @` +- clean up `go.mod`: `GO111MODULE=on go mod tidy` +- update vendor directory: `GO111MODULE=on go mod vendor` + +`GO111MODULE=on` can be left out when using Go >= 1.13 or when the +source is checked out outside of `$GOPATH`. + +`go mod tidy` must be used to ensure that the listed dependencies are +really still needed. Changing import statements or a tentative `go +get` can result in stale dependencies. + +The `test-vendor` verifies that it was used when run locally or in a +pre-merge CI job. If a `vendor` directory is present, it will also +verify that it's content is up-to-date. + +The `vendor` directory is optional. It is still present in projects +because it avoids downloading sources during CI builds. If this is no +longer deemed necessary, then a project can also remove the directory. + +Conversion of a repository that uses `dep` to `go mod` can be done with: + + GO111MODULE=on go mod init + release-tools/go-get-kubernetes.sh + GO111MODULE=on go mod tidy + GO111MODULE=on go mod vendor + git rm -f Gopkg.toml Gopkg.lock + git add go.mod go.sum vendor + +### Updating Kubernetes dependencies + +When using packages that are part of the Kubernetes source code, the +commands above are not enough because the [lack of semantic +versioning](https://github.com/kubernetes/kubernetes/issues/72638) +prevents `go mod` from finding newer releases. Importing directly from +`kubernetes/kubernetes` also needs `replace` statements to override +the fake `v0.0.0` versions +(https://github.com/kubernetes/kubernetes/issues/79384). The +`go-get-kubernetes.sh` script can be used to update all packages in +lockstep to a different Kubernetes version. Example usage: +``` +$ ./release-tools/go-get-kubernetes.sh 1.16.4 +``` diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/RELEASE.md b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/RELEASE.md new file mode 100644 index 00000000..a0fd815b --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/RELEASE.md @@ -0,0 +1,5 @@ +# Release Process + +No tagged releases are planned at this point. The intention is to keep +the master branch in a state such that it can be used for all +supported branches in downstream repos which use these files. diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/SECURITY_CONTACTS b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/SECURITY_CONTACTS new file mode 100644 index 00000000..d34984eb --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/SECURITY_CONTACTS @@ -0,0 +1,14 @@ +# Defined below are the security contacts for this repo. +# +# They are the contact point for the Product Security Team to reach out +# to for triaging and handling of incoming issues. +# +# The below names agree to abide by the +# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/HEAD/security-release-process-documentation/security-release-process.md#embargo-policy) +# and will be removed and replaced if they violate that agreement. +# +# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE +# INSTRUCTIONS AT https://kubernetes.io/security/ + +saad-ali +msau42 diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/SIDECAR_RELEASE_PROCESS.md b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/SIDECAR_RELEASE_PROCESS.md new file mode 100644 index 00000000..8977fbe6 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/SIDECAR_RELEASE_PROCESS.md @@ -0,0 +1,180 @@ +# Sidecar Release Process + +This page describes the process for releasing a kubernetes-csi sidecar. + +## Prerequisites + +The release manager must: + +* Be a member of the kubernetes-csi organization. Open an + [issue](https://github.com/kubernetes/org/issues/new?assignees=&labels=area%2Fgithub-membership&template=membership.md&title=REQUEST%3A+New+membership+for+%3Cyour-GH-handle%3E) in + kubernetes/org to request membership +* Be part of the maintainers group for the repository. + Membership can be requested by submitting a PR to kubernetes/org. + [Example](https://github.com/kubernetes/org/pull/1467) + +## Updating CI Jobs +Whenever a new Kubernetes minor version is released, our kubernetes-csi CI jobs +must be updated. + +[Our CI jobs](https://k8s-testgrid.appspot.com/sig-storage-csi-ci) have the +naming convention `-on-`. + +1. Jobs should be actively monitored to find and fix failures in sidecars and + infrastructure changes early in the development cycle. Test failures are sent + to kubernetes-sig-storage-test-failures@googlegroups.com. +1. "-on-master" jobs are the closest reflection to the new Kubernetes version. +1. Fixes to our prow.sh CI script can be tested in the [CSI hostpath + repo](https://github.com/kubernetes-csi/csi-driver-host-path) by modifying + [prow.sh](https://github.com/kubernetes-csi/csi-driver-host-path/blob/HEAD/release-tools/prow.sh) + along with any overrides in + [.prow.sh](https://github.com/kubernetes-csi/csi-driver-host-path/blob/HEAD/.prow.sh) + to mirror the failing environment. Once e2e tests are passing (verify-unit tests + will fail), then the prow.sh changes can be submitted to [csi-release-tools](https://github.com/kubernetes-csi/csi-release-tools). +1. Changes can then be updated in all the sidecar repos and hostpath driver repo + by following the [update + instructions](https://github.com/kubernetes-csi/csi-release-tools/blob/HEAD/README.md#sharing-and-updating). +1. New pull and CI jobs are configured by adding new K8s versions to the top of + [gen-jobs.sh](https://github.com/kubernetes/test-infra/blob/HEAD/config/jobs/kubernetes-csi/gen-jobs.sh). + New pull jobs that have been unverified should be initially made optional by + setting the new K8s version as + [experimental](https://github.com/kubernetes/test-infra/blob/a1858f46d6014480b130789df58b230a49203a64/config/jobs/kubernetes-csi/gen-jobs.sh#L40). +1. Once new pull and CI jobs have been verified, and the new Kubernetes version + is released, we can make the optional jobs required, and also remove the + Kubernetes versions that are no longer supported. + +## Release Process +1. Identify all issues and ongoing PRs that should go into the release, and + drive them to resolution. +1. Download the latest version of the + [K8s release notes generator](https://github.com/kubernetes/release/tree/HEAD/cmd/release-notes) +1. Create a + [Github personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) + with `repo:public_repo` access +1. Generate release notes for the release. Replace arguments with the relevant + information. + * Clean up old cached information (also needed if you are generating release + notes for multiple repos) + ```bash + rm -rf /tmp/k8s-repo + ``` + * For new minor releases on master: + ```bash + GITHUB_TOKEN= release-notes \ + --discover=mergebase-to-latest \ + --org=kubernetes-csi \ + --repo=external-provisioner \ + --required-author="" \ + --markdown-links \ + --output out.md + ``` + * For new patch releases on a release branch: + ```bash + GITHUB_TOKEN= release-notes \ + --discover=patch-to-latest \ + --branch=release-1.1 \ + --org=kubernetes-csi \ + --repo=external-provisioner \ + --required-author="" \ + --markdown-links \ + --output out.md + ``` +1. Compare the generated output to the new commits for the release to check if + any notable change missed a release note. +1. Reword release notes as needed. Make sure to check notes for breaking + changes and deprecations. +1. If release is a new major/minor version, create a new `CHANGELOG-..md` + file. Otherwise, add the release notes to the top of the existing CHANGELOG + file for that minor version. +1. Submit a PR for the CHANGELOG changes. +1. Submit a PR for README changes, in particular, Compatibility, Feature status, + and any other sections that may need updating. +1. Check that all [canary CI + jobs](https://k8s-testgrid.appspot.com/sig-storage-csi-ci) are passing, + and that test coverage is adequate for the changes that are going into the release. +1. Make sure that no new PRs have merged in the meantime, and no PRs are in + flight and soon to be merged. +1. Create a new release following a previous release as a template. Be sure to select the correct + branch. This requires Github release permissions as required by the prerequisites. + [external-provisioner example](https://github.com/kubernetes-csi/external-provisioner/releases/new) +1. If release was a new major/minor version, create a new `release-` + branch at that commit. +1. Check [image build status](https://k8s-testgrid.appspot.com/sig-storage-image-build). +1. Promote images from k8s-staging-sig-storage to k8s.gcr.io/sig-storage. From + the [k8s image + repo](https://github.com/kubernetes/k8s.io/tree/HEAD/k8s.gcr.io/images/k8s-staging-sig-storage), + run `./generate.sh > images.yaml`, and send a PR with the updated images. + Once merged, the image promoter will copy the images from staging to prod. +1. Update [kubernetes-csi/docs](https://github.com/kubernetes-csi/docs) sidecar + and feature pages with the new released version. +1. After all the sidecars have been released, update + CSI hostpath driver with the new sidecars in the [CSI repo](https://github.com/kubernetes-csi/csi-driver-host-path/tree/HEAD/deploy) + and [k/k + in-tree](https://github.com/kubernetes/kubernetes/tree/HEAD/test/e2e/testing-manifests/storage-csi/hostpath/hostpath) + +### Troubleshooting + +#### Image build jobs + +The following jobs are triggered after tagging to produce the corresponding +image(s): +https://k8s-testgrid.appspot.com/sig-storage-image-build + +Clicking on a failed build job opens that job in https://prow.k8s.io. Next to +the job title is a rerun icon (circle with arrow). Clicking it opens a popup +with a "rerun" button that maintainers with enough permissions can use. If in +doubt, ask someone on #sig-release to rerun the job. + +Another way to rerun a job is to search for it in https://prow.k8s.io and click +the rerun icon in the resulting job list: +https://prow.k8s.io/?job=canary-csi-test-push-images + +#### Verify images + +Canary and staged images can be viewed at https://console.cloud.google.com/gcr/images/k8s-staging-sig-storage + +Promoted images can be viewed at https://console.cloud.google.com/gcr/images/k8s-artifacts-prod/us/sig-storage + +## Adding support for a new Kubernetes release + +1. Add the new release to `k8s_versions` in + https://github.com/kubernetes/test-infra/blob/090dec5dd535d5f61b7ba52e671a810f5fc13dfd/config/jobs/kubernetes-csi/gen-jobs.sh#L25 + to enable generating a job for it. Set `experimental_k8s_version` + in + https://github.com/kubernetes/test-infra/blob/090dec5dd535d5f61b7ba52e671a810f5fc13dfd/config/jobs/kubernetes-csi/gen-jobs.sh#L40 + to ensure that the new jobs aren't run for PRs unless explicitly + requested. Generate and submit the new jobs. +1. Create a test PR to try out the new job in some repo with `/test + pull-kubernetes-csi---on-kubernetes-` where x.y + matches the Kubernetes release. Alternatively, run .prow.sh in that + repo locally with `CSI_PROW_KUBERNETES_VERSION=x.y.z`. +1. Optional: update to a [new + release](https://github.com/kubernetes-sigs/kind/tags) of kind with + pre-built images for the new Kubernetes release. This is optional + if the current version of kind is able to build images for the new + Kubernetes release. However, jobs require less resources when they + don't need to build those images from the Kubernetes source code. + This change needs to be tried out in a PR against a component + first, then get submitted against csi-release-tools. +1. Optional: propagate the updated csi-release-tools to all components + with the script from + https://github.com/kubernetes-csi/csi-release-tools/issues/7#issuecomment-707025402 +1. Once it is likely to work in all components, unset + `experimental_k8s_version` and submit the updated jobs. +1. Once all sidecars for the new Kubernetes release are released, + either bump the version number of the images in the existing + [csi-driver-host-path + deployments](https://github.com/kubernetes-csi/csi-driver-host-path/tree/HEAD/deploy) + and/or create a new deployment, depending on what Kubernetes + release an updated sidecar is compatible with. If no new deployment + is needed, then add a symlink to document that there intentionally + isn't a separate deployment. This symlink is not needed for Prow + testing because that will use "kubernetes-latest" as fallback. + Update that link when creating a new deployment. +1. Create a new csi-driver-host-path release. +1. Bump `CSI_PROW_DRIVER_VERSION` in prow.sh to that new release and + (eventually) roll that change out to all repos by updating + `release-tools` in them. This is used when testing manually. The + Prow jobs override that value, so also update + `hostpath_driver_version` in + https://github.com/kubernetes/test-infra/blob/91b04e6af3a40a9bcff25aa030850a4721e2dd2b/config/jobs/kubernetes-csi/gen-jobs.sh#L46-L47 diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.Dockerfile.txt b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.Dockerfile.txt new file mode 100644 index 00000000..34cb349c --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.Dockerfile.txt @@ -0,0 +1,13 @@ +# Copyright YEAR The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.Makefile.txt b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.Makefile.txt new file mode 100644 index 00000000..d0d52652 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.Makefile.txt @@ -0,0 +1,13 @@ +# Copyright YEAR The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. \ No newline at end of file diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.bzl.txt b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.bzl.txt new file mode 100644 index 00000000..d0d52652 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.bzl.txt @@ -0,0 +1,13 @@ +# Copyright YEAR The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. \ No newline at end of file diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.go.txt b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.go.txt new file mode 100644 index 00000000..3249913b --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright YEAR The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ \ No newline at end of file diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.py b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.py new file mode 100755 index 00000000..5618b9ab --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python + +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import argparse +import difflib +import glob +import os +import re +import sys +from datetime import date + +parser = argparse.ArgumentParser() +parser.add_argument( + "filenames", + help="list of files to check, all files if unspecified", + nargs='*') + +# Rootdir defaults to the directory **above** the repo-infra dir. +rootdir = os.path.dirname(__file__) + "./../../" +rootdir = os.path.abspath(rootdir) +parser.add_argument( + "--rootdir", default=rootdir, help="root directory to examine") + +default_boilerplate_dir = os.path.abspath(os.path.dirname(__file__)) + +parser.add_argument( + "--boilerplate-dir", default=default_boilerplate_dir) + +parser.add_argument( + "-v", "--verbose", + help="give verbose output regarding why a file does not pass", + action="store_true") + +args = parser.parse_args() + +verbose_out = sys.stderr if args.verbose else open("/dev/null", "w") + +def get_refs(): + refs = {} + + for path in glob.glob(os.path.join(args.boilerplate_dir, "boilerplate.*.txt")): + extension = os.path.basename(path).split(".")[1] + + ref_file = open(path, 'r') + ref = ref_file.read().splitlines() + ref_file.close() + refs[extension] = ref + + return refs + +def file_passes(filename, refs, regexs): + try: + f = open(filename, 'r') + except Exception as exc: + print("Unable to open %s: %s" % (filename, exc), file=verbose_out) + return False + + data = f.read() + f.close() + + basename = os.path.basename(filename) + extension = file_extension(filename) + if extension != "": + ref = refs[extension] + else: + ref = refs[basename] + + # remove build tags from the top of Go files + if extension == "go": + p = regexs["go_build_constraints"] + (data, found) = p.subn("", data, 1) + + # remove shebang from the top of shell files + if extension == "sh" or extension == "py": + p = regexs["shebang"] + (data, found) = p.subn("", data, 1) + + data = data.splitlines() + + # if our test file is smaller than the reference it surely fails! + if len(ref) > len(data): + print('File %s smaller than reference (%d < %d)' % + (filename, len(data), len(ref)), + file=verbose_out) + return False + + # trim our file to the same number of lines as the reference file + data = data[:len(ref)] + + p = regexs["year"] + for d in data: + if p.search(d): + print('File %s is missing the year' % filename, file=verbose_out) + return False + + # Replace all occurrences of the regex "CURRENT_YEAR|...|2016|2015|2014" with "YEAR" + p = regexs["date"] + for i, d in enumerate(data): + (data[i], found) = p.subn('YEAR', d) + if found != 0: + break + + # if we don't match the reference at this point, fail + if ref != data: + print("Header in %s does not match reference, diff:" % filename, file=verbose_out) + if args.verbose: + print(file=verbose_out) + for line in difflib.unified_diff(ref, data, 'reference', filename, lineterm=''): + print(line, file=verbose_out) + print(file=verbose_out) + return False + + return True + +def file_extension(filename): + return os.path.splitext(filename)[1].split(".")[-1].lower() + +skipped_dirs = ['Godeps', 'third_party', '_gopath', '_output', '.git', + 'cluster/env.sh', 'vendor', 'test/e2e/generated/bindata.go', + 'repo-infra/verify/boilerplate/test', '.glide'] + +def normalize_files(files): + newfiles = [] + for pathname in files: + if any(x in pathname for x in skipped_dirs): + continue + newfiles.append(pathname) + return newfiles + +def get_files(extensions): + files = [] + if len(args.filenames) > 0: + files = args.filenames + else: + for root, dirs, walkfiles in os.walk(args.rootdir): + # don't visit certain dirs. This is just a performance improvement + # as we would prune these later in normalize_files(). But doing it + # cuts down the amount of filesystem walking we do and cuts down + # the size of the file list + for d in skipped_dirs: + if d in dirs: + dirs.remove(d) + + for name in walkfiles: + pathname = os.path.join(root, name) + files.append(pathname) + + files = normalize_files(files) + + outfiles = [] + for pathname in files: + basename = os.path.basename(pathname) + extension = file_extension(pathname) + if extension in extensions or basename in extensions: + outfiles.append(pathname) + return outfiles + +def get_regexs(): + regexs = {} + # Search for "YEAR" which exists in the boilerplate, but shouldn't in the real thing + regexs["year"] = re.compile( 'YEAR' ) + # dates can be 2014, 2015, 2016, ..., CURRENT_YEAR, company holder names can be anything + years = range(2014, date.today().year + 1) + regexs["date"] = re.compile( '(%s)' % "|".join(map(lambda l: str(l), years)) ) + # strip // +build \n\n build constraints + regexs["go_build_constraints"] = re.compile(r"^(// \+build.*\n)+\n", re.MULTILINE) + # strip #!.* from shell scripts + regexs["shebang"] = re.compile(r"^(#!.*\n)\n*", re.MULTILINE) + return regexs + + + +def main(): + regexs = get_regexs() + refs = get_refs() + filenames = get_files(refs.keys()) + + for filename in filenames: + if not file_passes(filename, refs, regexs): + print(filename, file=sys.stdout) + + return 0 + +if __name__ == "__main__": + sys.exit(main()) diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.py.txt b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.py.txt new file mode 100644 index 00000000..34cb349c --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.py.txt @@ -0,0 +1,13 @@ +# Copyright YEAR The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.sh.txt b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.sh.txt new file mode 100644 index 00000000..d0d52652 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/boilerplate/boilerplate.sh.txt @@ -0,0 +1,13 @@ +# Copyright YEAR The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. \ No newline at end of file diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/build.make b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/build.make new file mode 100644 index 00000000..ff428890 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/build.make @@ -0,0 +1,324 @@ +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# force the usage of /bin/bash instead of /bin/sh +SHELL := /bin/bash + +.PHONY: build-% build container-% container push-% push clean test + +# A space-separated list of all commands in the repository, must be +# set in main Makefile of a repository. +# CMDS= + +# Normally, commands are expected in "cmd". That can be changed for a +# repository to something else by setting CMDS_DIR before including build.make. +CMDS_DIR ?= cmd + +# This is the default. It can be overridden in the main Makefile after +# including build.make. +REGISTRY_NAME?=quay.io/k8scsi + +# Can be set to -mod=vendor to ensure that the "vendor" directory is used. +GOFLAGS_VENDOR= + +# Revision that gets built into each binary via the main.version +# string. Uses the `git describe` output based on the most recent +# version tag with a short revision suffix or, if nothing has been +# tagged yet, just the revision. +# +# Beware that tags may also be missing in shallow clones as done by +# some CI systems (like TravisCI, which pulls only 50 commits). +REV=$(shell git describe --long --tags --match='v*' --dirty 2>/dev/null || git rev-list -n1 HEAD) + +# A space-separated list of image tags under which the current build is to be pushed. +# Determined dynamically. +IMAGE_TAGS= + +# A "canary" image gets built if the current commit is the head of the remote "master" branch. +# That branch does not exist when building some other branch in TravisCI. +IMAGE_TAGS+=$(shell if [ "$$(git rev-list -n1 HEAD)" = "$$(git rev-list -n1 origin/master 2>/dev/null)" ]; then echo "canary"; fi) + +# A "X.Y.Z-canary" image gets built if the current commit is the head of a "origin/release-X.Y.Z" branch. +# The actual suffix does not matter, only the "release-" prefix is checked. +IMAGE_TAGS+=$(shell git branch -r --points-at=HEAD | grep 'origin/release-' | grep -v -e ' -> ' | sed -e 's;.*/release-\(.*\);\1-canary;') + +# A release image "vX.Y.Z" gets built if there is a tag of that format for the current commit. +# --abbrev=0 suppresses long format, only showing the closest tag. +IMAGE_TAGS+=$(shell tagged="$$(git describe --tags --match='v*' --abbrev=0)"; if [ "$$tagged" ] && [ "$$(git rev-list -n1 HEAD)" = "$$(git rev-list -n1 $$tagged)" ]; then echo $$tagged; fi) + +# Images are named after the command contained in them. +IMAGE_NAME=$(REGISTRY_NAME)/$* + +ifdef V +# Adding "-alsologtostderr" assumes that all test binaries contain glog. This is not guaranteed. +TESTARGS = -v -args -alsologtostderr -v 5 +else +TESTARGS = +endif + +# Specific packages can be excluded from each of the tests below by setting the *_FILTER_CMD variables +# to something like "| grep -v 'github.com/kubernetes-csi/project/pkg/foobar'". See usage below. + +# BUILD_PLATFORMS contains a set of tuples [os arch buildx_platform suffix base_image addon_image] +# separated by semicolon. An empty variable or empty entry (= just a +# semicolon) builds for the default platform of the current Go +# toolchain. +BUILD_PLATFORMS = + +# Add go ldflags using LDFLAGS at the time of compilation. +IMPORTPATH_LDFLAGS = -X main.version=$(REV) +EXT_LDFLAGS = -extldflags "-static" +LDFLAGS = +FULL_LDFLAGS = $(LDFLAGS) $(IMPORTPATH_LDFLAGS) $(EXT_LDFLAGS) +# This builds each command (= the sub-directories of ./cmd) for the target platform(s) +# defined by BUILD_PLATFORMS. +$(CMDS:%=build-%): build-%: check-go-version-go + mkdir -p bin + # os_arch_seen captures all of the $$os-$$arch-$$buildx_platform seen for the current binary + # that we want to build, if we've seen an $$os-$$arch-$$buildx_platform before it means that + # we don't need to build it again, this is done to avoid building + # the windows binary multiple times (see the default value of $$BUILD_PLATFORMS) + export os_arch_seen="" && echo '$(BUILD_PLATFORMS)' | tr ';' '\n' | while read -r os arch buildx_platform suffix base_image addon_image; do \ + os_arch_seen_pre=$${os_arch_seen%%$$os-$$arch-$$buildx_platform*}; \ + if ! [ $${#os_arch_seen_pre} = $${#os_arch_seen} ]; then \ + continue; \ + fi; \ + if ! (set -x; cd ./$(CMDS_DIR)/$* && CGO_ENABLED=0 GOOS="$$os" GOARCH="$$arch" go build $(GOFLAGS_VENDOR) -a -ldflags '$(FULL_LDFLAGS)' -o "$(abspath ./bin)/$*$$suffix" .); then \ + echo "Building $* for GOOS=$$os GOARCH=$$arch failed, see error(s) above."; \ + exit 1; \ + fi; \ + os_arch_seen+=";$$os-$$arch-$$buildx_platform"; \ + done + +$(CMDS:%=container-%): container-%: build-% + docker build -t $*:latest -f $(shell if [ -e ./$(CMDS_DIR)/$*/Dockerfile ]; then echo ./$(CMDS_DIR)/$*/Dockerfile; else echo Dockerfile; fi) --label revision=$(REV) . + +$(CMDS:%=push-%): push-%: container-% + set -ex; \ + push_image () { \ + docker tag $*:latest $(IMAGE_NAME):$$tag; \ + docker push $(IMAGE_NAME):$$tag; \ + }; \ + for tag in $(IMAGE_TAGS); do \ + if [ "$$tag" = "canary" ] || echo "$$tag" | grep -q -e '-canary$$'; then \ + : "creating or overwriting canary image"; \ + push_image; \ + elif docker pull $(IMAGE_NAME):$$tag 2>&1 | tee /dev/stderr | grep -q "manifest for $(IMAGE_NAME):$$tag not found"; then \ + : "creating release image"; \ + push_image; \ + else \ + : "release image $(IMAGE_NAME):$$tag already exists, skipping push"; \ + fi; \ + done + +build: $(CMDS:%=build-%) +container: $(CMDS:%=container-%) +push: $(CMDS:%=push-%) + +# Additional parameters are needed when pushing to a local registry, +# see https://github.com/docker/buildx/issues/94. +# However, that then runs into https://github.com/docker/cli/issues/2396. +# +# What works for local testing is: +# make push-multiarch PULL_BASE_REF=master REGISTRY_NAME= BUILD_PLATFORMS="linux amd64; windows amd64 .exe; linux ppc64le -ppc64le; linux s390x -s390x" +DOCKER_BUILDX_CREATE_ARGS ?= + +# This target builds a multiarch image for one command using Moby BuildKit builder toolkit. +# Docker Buildx is included in Docker 19.03. +# +# ./$(CMDS_DIR)//Dockerfile[.Windows] is used if found, otherwise Dockerfile[.Windows]. +# It is currently optional: if no such file exists, Windows images are not included, +# even when Windows is listed in BUILD_PLATFORMS. That way, projects can test that +# Windows binaries can be built before adding a Dockerfile for it. +# +# BUILD_PLATFORMS determines which individual images are included in the multiarch image. +# PULL_BASE_REF must be set to 'master', 'release-x.y', or a tag name, and determines +# the tag for the resulting multiarch image. +$(CMDS:%=push-multiarch-%): push-multiarch-%: check-pull-base-ref build-% + set -ex; \ + export DOCKER_CLI_EXPERIMENTAL=enabled; \ + docker buildx create $(DOCKER_BUILDX_CREATE_ARGS) --use --name multiarchimage-buildertest; \ + trap "docker buildx rm multiarchimage-buildertest" EXIT; \ + dockerfile_linux=$$(if [ -e ./$(CMDS_DIR)/$*/Dockerfile ]; then echo ./$(CMDS_DIR)/$*/Dockerfile; else echo Dockerfile; fi); \ + dockerfile_windows=$$(if [ -e ./$(CMDS_DIR)/$*/Dockerfile.Windows ]; then echo ./$(CMDS_DIR)/$*/Dockerfile.Windows; else echo Dockerfile.Windows; fi); \ + if [ '$(BUILD_PLATFORMS)' ]; then build_platforms='$(BUILD_PLATFORMS)'; else build_platforms="linux amd64"; fi; \ + if ! [ -f "$$dockerfile_windows" ]; then \ + build_platforms="$$(echo "$$build_platforms" | sed -e 's/windows *[^ ]* *[^ ]* *.exe *[^ ]* *[^ ]*//g' -e 's/; *;/;/g' -e 's/;[ ]*$$//')"; \ + fi; \ + pushMultiArch () { \ + tag=$$1; \ + echo "$$build_platforms" | tr ';' '\n' | while read -r os arch buildx_platform suffix base_image addon_image; do \ + escaped_base_image=$${base_image/:/-}; \ + escaped_buildx_platform=$${buildx_platform//\//-}; \ + if ! [ -z $$escaped_base_image ]; then escaped_base_image+="-"; fi; \ + docker buildx build --push \ + --tag $(IMAGE_NAME):$$escaped_buildx_platform-$$os-$$escaped_base_image$$tag \ + --platform=$$os/$$buildx_platform \ + --file $$(eval echo \$${dockerfile_$$os}) \ + --build-arg binary=./bin/$*$$suffix \ + --build-arg ARCH=$$arch \ + --build-arg BASE_IMAGE=$$base_image \ + --build-arg ADDON_IMAGE=$$addon_image \ + --label revision=$(REV) \ + .; \ + done; \ + images=$$(echo "$$build_platforms" | tr ';' '\n' | while read -r os arch buildx_platform suffix base_image addon_image; do \ + escaped_base_image=$${base_image/:/-}; \ + escaped_buildx_platform=$${buildx_platform//\//-}; \ + if ! [ -z $$escaped_base_image ]; then escaped_base_image+="-"; fi; \ + echo $(IMAGE_NAME):$$escaped_buildx_platform-$$os-$$escaped_base_image$$tag; \ + done); \ + docker manifest create --amend $(IMAGE_NAME):$$tag $$images; \ + echo "$$build_platforms" | tr ';' '\n' | while read -r os arch buildx_platform suffix base_image addon_image; do \ + if [ $$os = "windows" ]; then \ + escaped_base_image=$${base_image/:/-}; \ + if ! [ -z $$escaped_base_image ]; then escaped_base_image+="-"; fi; \ + image=$(IMAGE_NAME):$$arch-$$os-$$escaped_base_image$$tag; \ + os_version=$$(docker manifest inspect mcr.microsoft.com/windows/$${base_image} | grep "os.version" | head -n 1 | awk '{print $$2}' | sed -e 's/"//g') || true; \ + docker manifest annotate --os-version $$os_version $(IMAGE_NAME):$$tag $$image; \ + fi; \ + done; \ + docker manifest push -p $(IMAGE_NAME):$$tag; \ + }; \ + if [ $(PULL_BASE_REF) = "master" ]; then \ + : "creating or overwriting canary image"; \ + pushMultiArch canary; \ + elif echo $(PULL_BASE_REF) | grep -q -e 'release-*' ; then \ + : "creating or overwriting canary image for release branch"; \ + release_canary_tag=$$(echo $(PULL_BASE_REF) | cut -f2 -d '-')-canary; \ + pushMultiArch $$release_canary_tag; \ + elif docker pull $(IMAGE_NAME):$(PULL_BASE_REF) 2>&1 | tee /dev/stderr | grep -q "manifest for $(IMAGE_NAME):$(PULL_BASE_REF) not found"; then \ + : "creating release image"; \ + pushMultiArch $(PULL_BASE_REF); \ + else \ + : "ERROR: release image $(IMAGE_NAME):$(PULL_BASE_REF) already exists: a new tag is required!"; \ + exit 1; \ + fi + +.PHONY: check-pull-base-ref +check-pull-base-ref: + if ! [ "$(PULL_BASE_REF)" ]; then \ + echo >&2 "ERROR: PULL_BASE_REF must be set to 'master', 'release-x.y', or a tag name."; \ + exit 1; \ + fi + +.PHONY: push-multiarch +push-multiarch: $(CMDS:%=push-multiarch-%) + +clean: + -rm -rf bin + +test: check-go-version-go + +.PHONY: test-go +test: test-go +test-go: + @ echo; echo "### $@:" + go test $(GOFLAGS_VENDOR) `go list $(GOFLAGS_VENDOR) ./... | grep -v -e 'vendor' -e '/test/e2e$$' $(TEST_GO_FILTER_CMD)` $(TESTARGS) + +.PHONY: test-vet +test: test-vet +test-vet: + @ echo; echo "### $@:" + go vet $(GOFLAGS_VENDOR) `go list $(GOFLAGS_VENDOR) ./... | grep -v vendor $(TEST_VET_FILTER_CMD)` + +.PHONY: test-fmt +test: test-fmt +test-fmt: + @ echo; echo "### $@:" + files=$$(find . -name '*.go' | grep -v './vendor' $(TEST_FMT_FILTER_CMD)); \ + if [ $$(gofmt -d $$files | wc -l) -ne 0 ]; then \ + echo "formatting errors:"; \ + gofmt -d $$files; \ + false; \ + fi + +# This test only runs when dep >= 0.5 is installed, which is the case for the CI setup. +# When using 'go mod', we allow the test to be skipped in the Prow CI under some special +# circumstances, because it depends on accessing all remote repos and thus +# running it all the time would defeat the purpose of vendoring: +# - not handling a PR or +# - the fabricated merge commit leaves go.mod, go.sum and vendor dir unchanged +# - release-tools also didn't change (changing rules or Go version might lead to +# a different result and thus must be tested) +# - import statements not changed (because if they change, go.mod might have to be updated) +# +# "git diff" is intelligent enough to annotate changes inside the "import" block in +# the start of the diff hunk: +# +# diff --git a/rpc/common.go b/rpc/common.go +# index bb4a5c4..5fa4271 100644 +# --- a/rpc/common.go +# +++ b/rpc/common.go +# @@ -21,7 +21,6 @@ import ( +# "fmt" +# "time" +# +# - "google.golang.org/grpc" +# "google.golang.org/grpc/codes" +# "google.golang.org/grpc/status" +# +# We rely on that to find such changes. +# +# Vendoring is optional when using go.mod. +.PHONY: test-vendor +test: test-vendor +test-vendor: + @ echo; echo "### $@:" + @ ./release-tools/verify-vendor.sh + +.PHONY: test-subtree +test: test-subtree +test-subtree: + @ echo; echo "### $@:" + ./release-tools/verify-subtree.sh release-tools + +# Components can extend the set of directories which must pass shellcheck. +# The default is to check only the release-tools directory itself. +TEST_SHELLCHECK_DIRS=release-tools +.PHONY: test-shellcheck +test: test-shellcheck +test-shellcheck: + @ echo; echo "### $@:" + @ ret=0; \ + if ! command -v docker; then \ + echo "skipped, no Docker"; \ + exit 0; \ + fi; \ + for dir in $(abspath $(TEST_SHELLCHECK_DIRS)); do \ + echo; \ + echo "$$dir:"; \ + ./release-tools/verify-shellcheck.sh "$$dir" || ret=1; \ + done; \ + exit $$ret + +# Targets in the makefile can depend on check-go-version- +# to trigger a warning if the x.y version of that binary does not match +# what the project uses. Make ensures that this is only checked once per +# invocation. +.PHONY: check-go-version-% +check-go-version-%: + ./release-tools/verify-go-version.sh "$*" + +# Test for spelling errors. +.PHONY: test-spelling +test-spelling: + @ echo; echo "### $@:" + @ ./release-tools/verify-spelling.sh "$(pwd)" + +# Test the boilerplates of the files. +.PHONY: test-boilerplate +test-boilerplate: + @ echo; echo "### $@:" + @ ./release-tools/verify-boilerplate.sh "$(pwd)" diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/cloudbuild.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/cloudbuild.sh new file mode 100755 index 00000000..1edda4d3 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/cloudbuild.sh @@ -0,0 +1,20 @@ +#! /bin/bash + +# Copyright 2021 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# shellcheck disable=SC1091 +. release-tools/prow.sh + +gcr_cloud_build diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/cloudbuild.yaml b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/cloudbuild.yaml new file mode 100644 index 00000000..4bcffad3 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/cloudbuild.yaml @@ -0,0 +1,47 @@ +# A configuration file for multi-arch image building with the Google cloud build service. +# +# Repos using this file must: +# - import csi-release-tools +# - add a symlink cloudbuild.yaml -> release-tools/cloudbuild.yaml +# - add a .cloudbuild.sh which can be a custom file or a symlink +# to release-tools/cloudbuild.sh +# - accept "binary" as build argument in their Dockerfile(s) (see +# https://github.com/pohly/node-driver-registrar/blob/3018101987b0bb6da2a2657de607174d6e3728f7/Dockerfile#L4-L6) +# because binaries will get built for different architectures and then +# get copied from the built host into the container image +# +# See https://github.com/kubernetes/test-infra/blob/HEAD/config/jobs/image-pushing/README.md +# for more details on image pushing process in Kubernetes. +# +# To promote release images, see https://github.com/kubernetes/k8s.io/tree/HEAD/k8s.gcr.io/images/k8s-staging-sig-storage. + +# This must be specified in seconds. If omitted, defaults to 600s (10 mins). +# Building three images in external-snapshotter takes more than an hour. +timeout: 7200s +# This prevents errors if you don't use both _GIT_TAG and _PULL_BASE_REF, +# or any new substitutions added in the future. +options: + substitution_option: ALLOW_LOOSE +steps: + # The image must contain bash and curl. Ideally it should also contain + # the desired version of Go (currently defined in release-tools/prow.sh), + # but that just speeds up the build and is not required. + - name: 'gcr.io/k8s-staging-test-infra/gcb-docker-gcloud:v20210917-12df099d55' + entrypoint: ./.cloudbuild.sh + env: + - GIT_TAG=${_GIT_TAG} + - PULL_BASE_REF=${_PULL_BASE_REF} + - REGISTRY_NAME=gcr.io/${_STAGING_PROJECT} + - HOME=/root +substitutions: + # _GIT_TAG will be filled with a git-based tag for the image, of the form vYYYYMMDD-hash, and + # can be used as a substitution. + _GIT_TAG: '12345' + # _PULL_BASE_REF will contain the ref that was pushed to trigger this build - + # a branch like 'master' or 'release-0.2', or a tag like 'v0.2'. + _PULL_BASE_REF: 'master' + # The default gcr.io staging project for Kubernetes-CSI + # (=> https://console.cloud.google.com/gcr/images/k8s-staging-sig-storage/GLOBAL). + # Might be overridden in the Prow build job for a repo which wants + # images elsewhere. + _STAGING_PROJECT: 'k8s-staging-sig-storage' diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/code-of-conduct.md b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/code-of-conduct.md new file mode 100644 index 00000000..0d15c00c --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/code-of-conduct.md @@ -0,0 +1,3 @@ +# Kubernetes Community Code of Conduct + +Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md) diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/filter-junit.go b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/filter-junit.go new file mode 100644 index 00000000..5454092b --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/filter-junit.go @@ -0,0 +1,149 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This command filters a JUnit file such that only tests with a name +matching a regular expression are passed through. By concatenating +multiple input files it is possible to merge them into a single file. +*/ +package main + +import ( + "encoding/xml" + "flag" + "io/ioutil" + "os" + "regexp" +) + +var ( + output = flag.String("o", "-", "junit file to write, - for stdout") + tests = flag.String("t", "", "regular expression matching the test names that are to be included in the output") +) + +/* + * TestResults represents a JUnit file. Due to how encoding/xml works, we have + * represent all fields that we want to be passed through. It's therefore + * not a complete solution, but good enough for Ginkgo + Spyglass. + * + * Before Kubernetes 1.25 and ginkgo v2, we directly had in the + * JUnit file. Now we get and inside it the . + */ +type TestResults struct { + XMLName string `xml:"testsuites"` + TestSuite TestSuite `xml:"testsuite"` +} + +type TestSuite struct { + XMLName string `xml:"testsuite"` + TestCases []TestCase `xml:"testcase"` +} + +type TestCase struct { + Name string `xml:"name,attr"` + Time string `xml:"time,attr"` + SystemOut string `xml:"system-out,omitempty"` + Failure string `xml:"failure,omitempty"` + Skipped SkipReason `xml:"skipped,omitempty"` +} + +// SkipReason deals with the special : +// if present, we must re-encode it, even if empty. +type SkipReason string + +func (s *SkipReason) UnmarshalText(text []byte) error { + *s = SkipReason(text) + if *s == "" { + *s = " " + } + return nil +} + +func (s SkipReason) MarshalText() ([]byte, error) { + if s == " " { + return []byte{}, nil + } + return []byte(s), nil +} + +func main() { + var junit TestSuite + var data []byte + + flag.Parse() + + re := regexp.MustCompile(*tests) + + // Read all input files. + for _, input := range flag.Args() { + if input == "-" { + if _, err := os.Stdin.Read(data); err != nil { + panic(err) + } + } else { + var err error + data, err = ioutil.ReadFile(input) + if err != nil { + panic(err) + } + } + if err := xml.Unmarshal(data, &junit); err != nil { + if err.Error() != "expected element type but have " { + panic(err) + } + // Fall back to Ginkgo v2 format. + var junitv2 TestResults + if err := xml.Unmarshal(data, &junitv2); err != nil { + panic(err) + } + junit = junitv2.TestSuite + } + } + + // Keep only matching testcases. Testcases skipped in all test runs are only stored once. + filtered := map[string]TestCase{} + for _, testcase := range junit.TestCases { + if !re.MatchString(testcase.Name) { + continue + } + entry, ok := filtered[testcase.Name] + if !ok || // not present yet + entry.Skipped != "" && testcase.Skipped == "" { // replaced skipped test with real test run + filtered[testcase.Name] = testcase + } + } + junit.TestCases = nil + for _, testcase := range filtered { + junit.TestCases = append(junit.TestCases, testcase) + } + + // Re-encode. + data, err := xml.MarshalIndent(junit, "", " ") + if err != nil { + panic(err) + } + + // Write to output. + if *output == "-" { + if _, err := os.Stdout.Write(data); err != nil { + panic(err) + } + } else { + if err := ioutil.WriteFile(*output, data, 0644); err != nil { + panic(err) + } + } +} diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/go-get-kubernetes.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/go-get-kubernetes.sh new file mode 100755 index 00000000..2b46c187 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/go-get-kubernetes.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash + +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script can be used while converting a repo from "dep" to "go mod" +# by calling it after "go mod init" or to update the Kubernetes packages +# in a repo that has already been converted. Only packages that are +# part of kubernetes/kubernetes and thus part of a Kubernetes release +# are modified. Other k8.io packages (like k8s.io/klog, k8s.io/utils) +# need to be updated separately. + +set -o pipefail + +cmd=$0 + +function help () { + cat < + +Update all components from kubernetes/kubernetes to that version. + +By default, replace statements are added for all Kubernetes packages, +whether they are used or not. This is useful when preparing a +repository for using k8s.io/kubernetes, because those replace +statements are needed to avoid "unknown revision v0.0.0" errors +(https://github.com/kubernetes/kubernetes/issues/79384). + +With the optional -p flag, all unused replace statements are +pruned. This makes go.mod smaller, but isn't required. + +The replace statements are needed for "go get -u ./..." which +otherwise ends up updating Kubernetes packages like client-go to +incompatible versions (in that case, a very old 1.x release which +happens to have a "higher" version number than the current +0.. numbers. +EOF +} + +prune=false + +while getopts "ph" o; do + case "$o" in + h) help; exit 0;; + p) prune=true;; + *) help; exit 1;; + esac +done +shift $((OPTIND-1)) + +if [ $# -ne 1 ]; then + help + exit 1 +fi + +die () { + echo >&2 "$@" + exit 1 +} + +k8s="$1" + +# If the repo imports k8s.io/kubernetes (directly or indirectly), then +# "go mod" will try to find "v0.0.0" versions because +# k8s.io/kubernetes has those in it's go.mod file +# (https://github.com/kubernetes/kubernetes/blob/2bd9643cee5b3b3a5ecbd3af49d09018f0773c77/go.mod#L146-L157). +# (https://github.com/kubernetes/kubernetes/issues/79384). +# +# We need to replicate the replace statements to override those fake +# versions also in our go.mod file (idea and some code from +# https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-521493597). +mods=$( (set -x; curl --silent --show-error --fail "https://raw.githubusercontent.com/kubernetes/kubernetes/v${k8s}/go.mod") | + sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p' + ) || die "failed to determine Kubernetes staging modules" +for mod in $mods; do + if $prune && ! (env GO111MODULE=on go mod graph) | grep "$mod@" > /dev/null; then + echo "Kubernetes module $mod is not used, skipping" + # Remove the module from go.mod "replace" that was added by an older version of this script. + (set -x; env GO111MODULE=on go mod edit "-dropreplace=$mod") || die "'go mod edit' failed" + continue + fi + # The presence of a potentially incomplete go.mod file affects this command, + # so move elsewhere. + modinfo=$(set -x; cd /; env GO111MODULE=on go mod download -json "$mod@kubernetes-${k8s}") || + die "failed to determine version of $mod: $modinfo" + v=$(echo "$modinfo" | sed -n 's|.*"Version": "\(.*\)".*|\1|p') + (set -x; env GO111MODULE=on go mod edit "-replace=$mod=$mod@$v") || die "'go mod edit' failed" +done + +packages= + +# Beware that we have to work with packages, not modules (i.e. no -m +# flag), because some modules trigger a "no Go code except tests" +# error. Getting their packages works. +if ! packages=$( (set -x; env GO111MODULE=on go list all) | grep ^k8s.io/ | sed -e 's; *;;'); then + cat >&2 <&2 <" go.mod; then + deps="$deps $(echo "$package" | sed -e "s;\$;@kubernetes-$k8s;" -e 's;^k8s.io/kubernetes\(/.*\)@kubernetes-;k8s.io/kubernetes\1@v;')" + fi +done + +# shellcheck disable=SC2086 +(set -x; env GO111MODULE=on go get $deps 2>&1) || die "go get failed" +echo "SUCCESS" diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/prow.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/prow.sh new file mode 100755 index 00000000..ba64d719 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/prow.sh @@ -0,0 +1,1389 @@ +#! /bin/bash + +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# This script runs inside a Prow job. It can run unit tests ("make test") +# and E2E testing. This E2E testing covers different scenarios (see +# https://github.com/kubernetes/enhancements/pull/807): +# - running the stable hostpath example against a Kubernetes release +# - running the canary hostpath example against a Kubernetes release +# - building the component in the current repo and running the +# stable hostpath example with that one component replaced against +# a Kubernetes release +# +# The intended usage of this script is that individual repos import +# csi-release-tools, then link their top-level prow.sh to this or +# include it in that file. When including it, several of the variables +# can be overridden in the top-level prow.sh to customize the script +# for the repo. +# +# The expected environment is: +# - $GOPATH/src/ for the repository that is to be tested, +# with PR branch merged (when testing a PR) +# - running on linux-amd64 +# - kind (https://github.com/kubernetes-sigs/kind) installed +# - optional: Go already installed + +RELEASE_TOOLS_ROOT="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" +REPO_DIR="$(pwd)" + +# Sets the default value for a variable if not set already and logs the value. +# Any variable set this way is usually something that a repo's .prow.sh +# or the job can set. +configvar () { + # Ignore: Word is of the form "A"B"C" (B indicated). Did you mean "ABC" or "A\"B\"C"? + # shellcheck disable=SC2140 + eval : \$\{"$1":="\$2"\} + eval echo "\$3:" "$1=\${$1}" +} + +# Prints the value of a variable + version suffix, falling back to variable + "LATEST". +get_versioned_variable () { + local var="$1" + local version="$2" + local value + + eval value="\${${var}_${version}}" + if ! [ "$value" ]; then + eval value="\${${var}_LATEST}" + fi + echo "$value" +} + +# This takes a version string like CSI_PROW_KUBERNETES_VERSION and +# maps it to the corresponding git tag, branch or commit. +version_to_git () { + version="$1" + shift + case "$version" in + latest|master) echo "master";; + release-*) echo "$version";; + *) echo "v$version";; + esac +} + +# the list of windows versions was matched from: +# - https://hub.docker.com/_/microsoft-windows-nanoserver +# - https://hub.docker.com/_/microsoft-windows-servercore +configvar CSI_PROW_BUILD_PLATFORMS "linux amd64 amd64; linux ppc64le ppc64le -ppc64le; linux s390x s390x -s390x; linux arm arm -arm; linux arm64 arm64 -arm64; linux arm arm/v7 -armv7; windows amd64 amd64 .exe nanoserver:1809 servercore:ltsc2019; windows amd64 amd64 .exe nanoserver:20H2 servercore:20H2; windows amd64 amd64 .exe nanoserver:ltsc2022 servercore:ltsc2022" "Go target platforms (= GOOS + GOARCH) and file suffix of the resulting binaries" + +# If we have a vendor directory, then use it. We must be careful to only +# use this for "make" invocations inside the project's repo itself because +# setting it globally can break other go usages (like "go get " +# which is disabled with GOFLAGS=-mod=vendor). +configvar GOFLAGS_VENDOR "$( [ -d vendor ] && echo '-mod=vendor' )" "Go flags for using the vendor directory" + +configvar CSI_PROW_GO_VERSION_BUILD "1.18" "Go version for building the component" # depends on component's source code +configvar CSI_PROW_GO_VERSION_E2E "" "override Go version for building the Kubernetes E2E test suite" # normally doesn't need to be set, see install_e2e +configvar CSI_PROW_GO_VERSION_SANITY "${CSI_PROW_GO_VERSION_BUILD}" "Go version for building the csi-sanity test suite" # depends on CSI_PROW_SANITY settings below +configvar CSI_PROW_GO_VERSION_KIND "${CSI_PROW_GO_VERSION_BUILD}" "Go version for building 'kind'" # depends on CSI_PROW_KIND_VERSION below +configvar CSI_PROW_GO_VERSION_GINKGO "${CSI_PROW_GO_VERSION_BUILD}" "Go version for building ginkgo" # depends on CSI_PROW_GINKGO_VERSION below + +# ginkgo test runner version to use. If the pre-installed version is +# different, the desired version is built from source. For Kubernetes, +# the version built via "make WHAT=vendor/github.com/onsi/ginkgo/ginkgo" is +# used, which is guaranteed to match what the Kubernetes e2e.test binary +# needs. +configvar CSI_PROW_GINKGO_VERSION v1.7.0 "Ginkgo" + +# Ginkgo runs the E2E test in parallel. The default is based on the number +# of CPUs, but typically this can be set to something higher in the job. +configvar CSI_PROW_GINKO_PARALLEL "-p" "Ginko parallelism parameter(s)" + +# Enables building the code in the repository. On by default, can be +# disabled in jobs which only use pre-built components. +configvar CSI_PROW_BUILD_JOB true "building code in repo enabled" + +# Kubernetes version to test against. This must be a version number +# (like 1.13.3), "latest" (builds Kubernetes from the master branch) +# or "release-x.yy" (builds Kubernetes from a release branch). +# +# The patch version is only relevant for picking the E2E test suite +# that is used for testing. The script automatically picks +# the kind images for the major/minor version of Kubernetes +# that the kind release supports. +# +# This can also be a version that was not released yet at the time +# that the settings below were chose. The script will then +# use the same settings as for "latest" Kubernetes. This works +# as long as there are no breaking changes in Kubernetes, like +# deprecating or changing the implementation of an alpha feature. +configvar CSI_PROW_KUBERNETES_VERSION 1.22.0 "Kubernetes" + +# CSI_PROW_KUBERNETES_VERSION reduced to first two version numbers and +# with underscore (1_13 instead of 1.13.3) and in uppercase (LATEST +# instead of latest). +# +# This is used to derive the right defaults for the variables below +# when a Prow job just defines the Kubernetes version. +csi_prow_kubernetes_version_suffix="$(echo "${CSI_PROW_KUBERNETES_VERSION}" | tr . _ | tr '[:lower:]' '[:upper:]' | sed -e 's/^RELEASE-//' -e 's/\([0-9]*\)_\([0-9]*\).*/\1_\2/')" + +# Only the latest KinD is (eventually) guaranteed to work with the +# latest Kubernetes. For example, KinD 0.10.0 failed with Kubernetes +# 1.21.0-beta1. Therefore the default version of KinD is "main" +# for that, otherwise the latest stable release for which we then +# list the officially supported images below. +kind_version_default () { + case "${CSI_PROW_KUBERNETES_VERSION}" in + latest|master) + echo main;; + *) + echo v0.11.1;; + esac +} + +# kind version to use. If the pre-installed version is different, +# the desired version is downloaded from https://github.com/kubernetes-sigs/kind/releases +# (if available), otherwise it is built from source. +configvar CSI_PROW_KIND_VERSION "$(kind_version_default)" "kind" + +# kind images to use. Must match the kind version. +# The release notes of each kind release list the supported images. +configvar CSI_PROW_KIND_IMAGES "kindest/node:v1.23.0@sha256:49824ab1727c04e56a21a5d8372a402fcd32ea51ac96a2706a12af38934f81ac +kindest/node:v1.22.0@sha256:b8bda84bb3a190e6e028b1760d277454a72267a5454b57db34437c34a588d047 +kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6 +kindest/node:v1.20.7@sha256:cbeaf907fc78ac97ce7b625e4bf0de16e3ea725daf6b04f930bd14c67c671ff9 +kindest/node:v1.19.11@sha256:07db187ae84b4b7de440a73886f008cf903fcf5764ba8106a9fd5243d6f32729 +kindest/node:v1.18.19@sha256:7af1492e19b3192a79f606e43c35fb741e520d195f96399284515f077b3b622c +kindest/node:v1.17.17@sha256:66f1d0d91a88b8a001811e2f1054af60eef3b669a9a74f9b6db871f2f1eeed00 +kindest/node:v1.16.15@sha256:83067ed51bf2a3395b24687094e283a7c7c865ccc12a8b1d7aa673ba0c5e8861 +kindest/node:v1.15.12@sha256:b920920e1eda689d9936dfcf7332701e80be12566999152626b2c9d730397a95 +kindest/node:v1.14.10@sha256:f8a66ef82822ab4f7569e91a5bccaf27bceee135c1457c512e54de8c6f7219f8" "kind images" + +# By default, this script tests sidecars with the CSI hostpath driver, +# using the install_csi_driver function. That function depends on +# a deployment script that it searches for in several places: +# +# - The "deploy" directory in the current repository: this is useful +# for the situation that a component becomes incompatible with the +# shared deployment, because then it can (temporarily!) provide its +# own example until the shared one can be updated; it's also how +# csi-driver-host-path itself provides the example. +# +# - CSI_PROW_DRIVER_VERSION of the CSI_PROW_DRIVER_REPO is checked +# out: this allows other repos to reference a version of the example +# that is known to be compatible. +# +# - The /deploy directory can have multiple sub-directories, +# each with different deployments (stable set of images for Kubernetes 1.13, +# stable set of images for Kubernetes 1.14, canary for latest Kubernetes, etc.). +# This is necessary because there may be incompatible changes in the +# "API" of a component (for example, its command line options or RBAC rules) +# or in its support for different Kubernetes versions (CSIDriverInfo as +# CRD in Kubernetes 1.13 vs builtin API in Kubernetes 1.14). +# +# When testing an update for a component in a PR job, the +# CSI_PROW_DEPLOYMENT variable can be set in the +# .prow.sh of each component when there are breaking changes +# that require using a non-default deployment. The default +# is a deployment named "kubernetes-x.yy${CSI_PROW_DEPLOYMENT_SUFFIX}" (if available), +# otherwise "kubernetes-latest${CSI_PROW_DEPLOYMENT_SUFFIX}". +# "none" disables the deployment of the hostpath driver. +# +# When no deploy script is found (nothing in `deploy` directory, +# CSI_PROW_DRIVER_REPO=none), nothing gets deployed. +# +# If the deployment script is called with CSI_PROW_TEST_DRIVER= as +# environment variable, then it must write a suitable test driver configuration +# into that file in addition to installing the driver. +configvar CSI_PROW_DRIVER_VERSION "v1.8.0" "CSI driver version" +configvar CSI_PROW_DRIVER_REPO https://github.com/kubernetes-csi/csi-driver-host-path "CSI driver repo" +configvar CSI_PROW_DEPLOYMENT "" "deployment" +configvar CSI_PROW_DEPLOYMENT_SUFFIX "" "additional suffix in kubernetes-x.yy[suffix].yaml files" + +# The install_csi_driver function may work also for other CSI drivers, +# as long as they follow the conventions of the CSI hostpath driver. +# If they don't, then a different install function can be provided in +# a .prow.sh file and this config variable can be overridden. +configvar CSI_PROW_DRIVER_INSTALL "install_csi_driver" "name of the shell function which installs the CSI driver" + +# If CSI_PROW_DRIVER_CANARY is set (typically to "canary", but also +# version tag. Usually empty. CSI_PROW_HOSTPATH_CANARY is +# accepted as alternative name because some test-infra jobs +# still use that name. +configvar CSI_PROW_DRIVER_CANARY "${CSI_PROW_HOSTPATH_CANARY}" "driver image override for canary images" + +# Image registry to use for canary images. +# Only valid if CSI_PROW_DRIVER_CANARY == "canary". +configvar CSI_PROW_DRIVER_CANARY_REGISTRY "gcr.io/k8s-staging-sig-storage" "registry for canary images" + +# The E2E testing can come from an arbitrary repo. The expectation is that +# the repo supports "go test ./test/e2e -args --storage.testdriver" (https://github.com/kubernetes/kubernetes/pull/72836) +# after setting KUBECONFIG. As a special case, if the repository is Kubernetes, +# then `make WHAT=test/e2e/e2e.test` is called first to ensure that +# all generated files are present. +# +# CSI_PROW_E2E_REPO=none disables E2E testing. +configvar CSI_PROW_E2E_VERSION "$(version_to_git "${CSI_PROW_KUBERNETES_VERSION}")" "E2E version" +configvar CSI_PROW_E2E_REPO "https://github.com/kubernetes/kubernetes" "E2E repo" +configvar CSI_PROW_E2E_IMPORT_PATH "k8s.io/kubernetes" "E2E package" + +# csi-sanity testing from the csi-test repo can be run against the installed +# CSI driver. For this to work, deploying the driver must expose the Unix domain +# csi.sock as a TCP service for use by the csi-sanity command, which runs outside +# of the cluster. The alternative would have been to (cross-)compile csi-sanity +# and install it inside the cluster, which is not necessarily easier. +configvar CSI_PROW_SANITY_REPO https://github.com/kubernetes-csi/csi-test "csi-test repo" +configvar CSI_PROW_SANITY_VERSION v5.0.0 "csi-test version" +configvar CSI_PROW_SANITY_PACKAGE_PATH github.com/kubernetes-csi/csi-test "csi-test package" +configvar CSI_PROW_SANITY_SERVICE "hostpath-service" "Kubernetes TCP service name that exposes csi.sock" +configvar CSI_PROW_SANITY_POD "csi-hostpathplugin-0" "Kubernetes pod with CSI driver" +configvar CSI_PROW_SANITY_CONTAINER "hostpath" "Kubernetes container with CSI driver" + +# The version of dep to use for 'make test-vendor'. Ignored if the project doesn't +# use dep. Only binary releases of dep are supported (https://github.com/golang/dep/releases). +configvar CSI_PROW_DEP_VERSION v0.5.1 "golang dep version to be used for vendor checking" + +# Each job can run one or more of the following tests, identified by +# a single word: +# - unit testing +# - parallel excluding alpha features +# - serial excluding alpha features +# - parallel, only alpha feature +# - serial, only alpha features +# - sanity +# +# Unknown or unsupported entries are ignored. +# +# Testing of alpha features is only supported for CSI_PROW_KUBERNETES_VERSION=latest +# because CSI_PROW_E2E_ALPHA and CSI_PROW_E2E_ALPHA_GATES are not set for +# older Kubernetes releases. The script supports that, it just isn't done because +# it is not needed and would cause additional maintenance effort. +# +# Sanity testing with csi-sanity only covers the CSI driver itself and +# thus only makes sense in repos which provide their own CSI +# driver. Repos can enable sanity testing by setting +# CSI_PROW_TESTS_SANITY=sanity. +configvar CSI_PROW_TESTS "unit parallel serial $(if [ "${CSI_PROW_KUBERNETES_VERSION}" = "latest" ]; then echo parallel-alpha serial-alpha; fi) sanity" "tests to run" +tests_enabled () { + local t1 t2 + # We want word-splitting here, so ignore: Quote to prevent word splitting, or split robustly with mapfile or read -a. + # shellcheck disable=SC2206 + local tests=(${CSI_PROW_TESTS}) + for t1 in "$@"; do + for t2 in "${tests[@]}"; do + if [ "$t1" = "$t2" ]; then + return + fi + done + done + return 1 +} +sanity_enabled () { + [ "${CSI_PROW_TESTS_SANITY}" = "sanity" ] && tests_enabled "sanity" +} +tests_need_kind () { + tests_enabled "parallel" "serial" "serial-alpha" "parallel-alpha" || + sanity_enabled +} +tests_need_non_alpha_cluster () { + tests_enabled "parallel" "serial" || + sanity_enabled +} +tests_need_alpha_cluster () { + tests_enabled "parallel-alpha" "serial-alpha" +} + +# Enabling mock tests adds the "CSI mock volume" tests from https://github.com/kubernetes/kubernetes/blob/HEAD/test/e2e/storage/csi_mock_volume.go +# to the e2e.test invocations (serial, parallel, and the corresponding alpha variants). +# When testing canary images, those get used instead of the images specified +# in the e2e.test's normal YAML files. +# +# The default is to enable this for all jobs which use canary images +# and the latest Kubernetes because those images will be used for mock +# testing once they are released. Using them for mock testing with +# older Kubernetes releases is too risky because the deployment files +# can be very old (for example, still using a removed -provisioner +# parameter in external-provisioner). +configvar CSI_PROW_E2E_MOCK "$(if [ "${CSI_PROW_DRIVER_CANARY}" = "canary" ] && [ "${CSI_PROW_KUBERNETES_VERSION}" = "latest" ]; then echo true; else echo false; fi)" "enable CSI mock volume tests" + +# Regex for non-alpha, feature-tagged tests that should be run. +# +configvar CSI_PROW_E2E_FOCUS_LATEST '\[Feature:VolumeSnapshotDataSource\]' "non-alpha, feature-tagged tests for latest Kubernetes version" +configvar CSI_PROW_E2E_FOCUS "$(get_versioned_variable CSI_PROW_E2E_FOCUS "${csi_prow_kubernetes_version_suffix}")" "non-alpha, feature-tagged tests" + +# Serial vs. parallel is always determined by these regular expressions. +# Individual regular expressions are separated by spaces for readability +# and expected to not contain spaces. Use dots instead. The complete +# regex for Ginkgo will be created by joining the individual terms. +configvar CSI_PROW_E2E_SERIAL '\[Serial\] \[Disruptive\]' "tags for serial E2E tests" +regex_join () { + echo "$@" | sed -e 's/ */|/g' -e 's/^|*//' -e 's/|*$//' -e 's/^$/this-matches-nothing/g' +} + +# Which tests are alpha depends on the Kubernetes version. We could +# use the same E2E test for all Kubernetes version. This would have +# the advantage that new tests can be applied to older versions +# without having to backport tests. +# +# But the feature tag gets removed from E2E tests when the corresponding +# feature becomes beta, so we would have to track which tests were +# alpha in previous Kubernetes releases. This was considered too +# error prone. Therefore we use E2E tests that match the Kubernetes +# version that is getting tested. +configvar CSI_PROW_E2E_ALPHA_LATEST '\[Feature:' "alpha tests for latest Kubernetes version" # there's no need to update this, adding a new case for CSI_PROW_E2E for a new Kubernetes is enough +configvar CSI_PROW_E2E_ALPHA "$(get_versioned_variable CSI_PROW_E2E_ALPHA "${csi_prow_kubernetes_version_suffix}")" "alpha tests" + +# After the parallel E2E test without alpha features, a test cluster +# with alpha features is brought up and tests that were previously +# disabled are run. The alpha gates in each release have to be listed +# explicitly. If none are set (= variable empty), alpha testing +# is skipped. +# +# Testing against "latest" Kubernetes is problematic because some alpha +# feature which used to work might stop working or change their behavior +# such that the current tests no longer pass. If that happens, +# kubernetes-csi components must be updated, either by disabling +# the failing test for "latest" or by updating the test and not running +# it anymore for older releases. +configvar CSI_PROW_E2E_ALPHA_GATES_LATEST '' "alpha feature gates for latest Kubernetes" +configvar CSI_PROW_E2E_ALPHA_GATES "$(get_versioned_variable CSI_PROW_E2E_ALPHA_GATES "${csi_prow_kubernetes_version_suffix}")" "alpha E2E feature gates" + +configvar CSI_PROW_E2E_GATES_LATEST '' "non alpha feature gates for latest Kubernetes" +configvar CSI_PROW_E2E_GATES "$(get_versioned_variable CSI_PROW_E2E_GATES "${csi_prow_kubernetes_version_suffix}")" "non alpha E2E feature gates" + +# Which external-snapshotter tag to use for the snapshotter CRD and snapshot-controller deployment +default_csi_snapshotter_version () { + if [ "${CSI_PROW_KUBERNETES_VERSION}" = "latest" ] || [ "${CSI_PROW_DRIVER_CANARY}" = "canary" ]; then + echo "master" + else + echo "v3.0.2" + fi +} +configvar CSI_SNAPSHOTTER_VERSION "$(default_csi_snapshotter_version)" "external-snapshotter version tag" + +# Some tests are known to be unusable in a KinD cluster. For example, +# stopping kubelet with "ssh systemctl stop kubelet" simply +# doesn't work. Such tests should be written in a way that they verify +# whether they can run with the current cluster provider, but until +# they are, we filter them out by name. Like the other test selection +# variables, this is again a space separated list of regular expressions. +configvar CSI_PROW_E2E_SKIP 'Disruptive' "tests that need to be skipped" + +# This creates directories that are required for testing. +ensure_paths () { + # Work directory. It has to allow running executables, therefore /tmp + # is avoided. Cleaning up after the script is intentionally left to + # the caller. + configvar CSI_PROW_WORK "$(mkdir -p "$GOPATH/pkg" && mktemp -d "$GOPATH/pkg/csiprow.XXXXXXXXXX")" "work directory" + + # This is the directory for additional result files. Usually set by Prow, but + # if not (for example, when invoking manually) it defaults to the work directory. + configvar ARTIFACTS "${CSI_PROW_WORK}/artifacts" "artifacts" + mkdir -p "${ARTIFACTS}" + + # For additional tools. + CSI_PROW_BIN="${CSI_PROW_WORK}/bin" + mkdir -p "${CSI_PROW_BIN}" + PATH="${CSI_PROW_BIN}:$PATH" +} + +run () { + echo "$(date) $(go version | sed -e 's/.*version \(go[^ ]*\).*/\1/') $(if [ "$(pwd)" != "${REPO_DIR}" ]; then pwd; fi)\$" "$@" >&2 + "$@" +} + +info () { + echo >&2 INFO: "$@" +} + +warn () { + echo >&2 WARNING: "$@" +} + +die () { + echo >&2 ERROR: "$@" + exit 1 +} + +# Ensure that PATH has the desired version of the Go tools, then run command given as argument. +# Empty parameter uses the already installed Go. In Prow, that version is kept up-to-date by +# bumping the container image regularly. +run_with_go () { + local version + version="$1" + shift + + if ! [ "$version" ] || go version 2>/dev/null | grep -q "go$version"; then + run "$@" + else + if ! [ -d "${CSI_PROW_WORK}/go-$version" ]; then + run curl --fail --location "https://dl.google.com/go/go$version.linux-amd64.tar.gz" | tar -C "${CSI_PROW_WORK}" -zxf - || die "installation of Go $version failed" + mv "${CSI_PROW_WORK}/go" "${CSI_PROW_WORK}/go-$version" + fi + PATH="${CSI_PROW_WORK}/go-$version/bin:$PATH" run "$@" + fi +} + +# Ensure that we have the desired version of kind. +install_kind () { + if kind --version 2>/dev/null | grep -q " ${CSI_PROW_KIND_VERSION}$"; then + return + fi + if run curl --fail --location -o "${CSI_PROW_WORK}/bin/kind" "https://github.com/kubernetes-sigs/kind/releases/download/${CSI_PROW_KIND_VERSION}/kind-linux-amd64"; then + chmod u+x "${CSI_PROW_WORK}/bin/kind" + else + git_checkout https://github.com/kubernetes-sigs/kind "${GOPATH}/src/sigs.k8s.io/kind" "${CSI_PROW_KIND_VERSION}" --depth=1 && + (cd "${GOPATH}/src/sigs.k8s.io/kind" && run_with_go "$CSI_PROW_GO_VERSION_KIND" make install INSTALL_DIR="${CSI_PROW_WORK}/bin") + fi +} + +# Ensure that we have the desired version of the ginkgo test runner. +install_ginkgo () { + if [ -e "${CSI_PROW_BIN}/ginkgo" ]; then + return + fi + + # CSI_PROW_GINKGO_VERSION contains the tag with v prefix, the command line output does not. + if [ "v$(ginkgo version 2>/dev/null | sed -e 's/.* //')" = "${CSI_PROW_GINKGO_VERSION}" ]; then + return + fi + run_with_go "${CSI_PROW_GO_VERSION_GINKGO}" env GOBIN="${CSI_PROW_BIN}" go install "github.com/onsi/ginkgo/ginkgo@${CSI_PROW_GINKGO_VERSION}" || die "building ginkgo failed" +} + +# Ensure that we have the desired version of dep. +install_dep () { + if dep version 2>/dev/null | grep -q "version:.*${CSI_PROW_DEP_VERSION}$"; then + return + fi + run curl --fail --location -o "${CSI_PROW_WORK}/bin/dep" "https://github.com/golang/dep/releases/download/v0.5.4/dep-linux-amd64" && + chmod u+x "${CSI_PROW_WORK}/bin/dep" +} + +# This checks out a repo ("https://github.com/kubernetes/kubernetes") +# in a certain location ("$GOPATH/src/k8s.io/kubernetes") at +# a certain revision (a hex commit hash, v1.13.1, master). It's okay +# for that directory to exist already. +git_checkout () { + local repo path revision + repo="$1" + shift + path="$1" + shift + revision="$1" + shift + + mkdir -p "$path" + if ! [ -d "$path/.git" ]; then + run git init "$path" + fi + if (cd "$path" && run git fetch "$@" "$repo" "$revision"); then + (cd "$path" && run git checkout FETCH_HEAD) || die "checking out $repo $revision failed" + else + # Might have been because fetching by revision is not + # supported by GitHub (https://github.com/isaacs/github/issues/436). + # Fall back to fetching everything. + (cd "$path" && run git fetch "$repo" '+refs/heads/*:refs/remotes/csiprow/heads/*' '+refs/tags/*:refs/tags/*') || die "fetching $repo failed" + (cd "$path" && run git checkout "$revision") || die "checking out $repo $revision failed" + fi + # This is useful for local testing or when switching between different revisions in the same + # repo. + (cd "$path" && run git clean -fdx) || die "failed to clean $path" +} + +# This clones a repo ("https://github.com/kubernetes/kubernetes") +# in a certain location ("$GOPATH/src/k8s.io/kubernetes") at +# a the head of a specific branch (i.e., release-1.13, master), +# tag (v1.20.0) or commit. +# +# The directory must not exist. +git_clone () { + local repo path name parent + repo="$1" + shift + path="$1" + shift + name="$1" + shift + + parent="$(dirname "$path")" + mkdir -p "$parent" + (cd "$parent" && run git clone --single-branch --branch "$name" "$repo" "$path") || die "cloning $repo" failed + # This is useful for local testing or when switching between different revisions in the same + # repo. + (cd "$path" && run git clean -fdx) || die "failed to clean $path" +} + +list_gates () ( + set -f; IFS=',' + # Ignore: Double quote to prevent globbing and word splitting. + # shellcheck disable=SC2086 + set -- $1 + while [ "$1" ]; do + # Ignore: See if you can use ${variable//search/replace} instead. + # shellcheck disable=SC2001 + echo "$1" | sed -e 's/ *\([^ =]*\) *= *\([^ ]*\) */ \1: \2/' + shift + done +) + +# Turn feature gates in the format foo=true,bar=false into +# a YAML map with the corresponding API groups for use +# with https://kind.sigs.k8s.io/docs/user/configuration/#runtime-config +list_api_groups () ( + set -f; IFS=',' + # Ignore: Double quote to prevent globbing and word splitting. + # shellcheck disable=SC2086 + set -- $1 + while [ "$1" ]; do + if [ "$1" = 'CSIStorageCapacity=true' ]; then + echo ' "storage.k8s.io/v1alpha1": "true"' + fi + shift + done +) + +go_version_for_kubernetes () ( + local path="$1" + local version="$2" + local go_version + + # We use the minimal Go version specified for each K8S release (= minimum_go_version in hack/lib/golang.sh). + # More recent versions might also work, but we don't want to count on that. + go_version="$(grep minimum_go_version= "$path/hack/lib/golang.sh" | sed -e 's/.*=go//')" + if ! [ "$go_version" ]; then + die "Unable to determine Go version for Kubernetes $version from hack/lib/golang.sh." + fi + # Strip the trailing .0. Kubernetes includes it, Go itself doesn't. + # Ignore: See if you can use ${variable//search/replace} instead. + # shellcheck disable=SC2001 + go_version="$(echo "$go_version" | sed -e 's/\.0$//')" + echo "$go_version" +) + +csi_prow_kind_have_kubernetes=false +# Brings up a Kubernetes cluster and sets KUBECONFIG. +# Accepts additional feature gates in the form gate1=true|false,gate2=... +start_cluster () { + local image gates + gates="$1" + + if kind get clusters | grep -q csi-prow; then + run kind delete cluster --name=csi-prow || die "kind delete failed" + fi + + # Try to find a pre-built kind image if asked to use a specific version. + if ! [[ "${CSI_PROW_KUBERNETES_VERSION}" =~ ^release-|^latest$ ]]; then + # Ignore: See if you can use ${variable//search/replace} instead. + # shellcheck disable=SC2001 + major_minor=$(echo "${CSI_PROW_KUBERNETES_VERSION}" | sed -e 's/^\([0-9]*\)\.\([0-9]*\).*/\1.\2/') + for i in ${CSI_PROW_KIND_IMAGES}; do + if echo "$i" | grep -q "kindest/node:v${major_minor}"; then + image="$i" + break + fi + done + fi + + # Need to build from source? + if ! [ "$image" ]; then + if ! ${csi_prow_kind_have_kubernetes}; then + local version="${CSI_PROW_KUBERNETES_VERSION}" + if [ "$version" = "latest" ]; then + version=master + fi + git_clone https://github.com/kubernetes/kubernetes "${CSI_PROW_WORK}/src/kubernetes" "$(version_to_git "$version")" || die "checking out Kubernetes $version failed" + + go_version="$(go_version_for_kubernetes "${CSI_PROW_WORK}/src/kubernetes" "$version")" || die "cannot proceed without knowing Go version for Kubernetes" + # Changing into the Kubernetes source code directory is a workaround for https://github.com/kubernetes-sigs/kind/issues/1910 + # shellcheck disable=SC2046 + (cd "${CSI_PROW_WORK}/src/kubernetes" && run_with_go "$go_version" kind build node-image --image csiprow/node:latest --kube-root "${CSI_PROW_WORK}/src/kubernetes") || die "'kind build node-image' failed" + csi_prow_kind_have_kubernetes=true + fi + image="csiprow/node:latest" + fi + cat >"${CSI_PROW_WORK}/kind-config.yaml" < kubernetes-latest-test. + # Ignore: See if you can use ${variable//search/replace} instead. + # shellcheck disable=SC2001 + file="$dir/$(echo "$deployment" | sed -e 's/[0-9][0-9]*\.[0-9][0-9]*/latest/')/deploy.sh" + if ! [ -e "$file" ]; then + return 1 + fi + fi + echo "$file" +} + +# This installs the CSI driver. It's called with a list of env variables +# that override the default images. CSI_PROW_DRIVER_CANARY overrides all +# image versions with that canary version. +install_csi_driver () { + local images deploy_driver + images="$*" + + if [ "${CSI_PROW_DEPLOYMENT}" = "none" ]; then + return 1 + fi + + if ${CSI_PROW_BUILD_JOB}; then + # Ignore: Double quote to prevent globbing and word splitting. + # Ignore: To read lines rather than words, pipe/redirect to a 'while read' loop. + # shellcheck disable=SC2086 disable=SC2013 + for i in $(grep '^\s*CMDS\s*=' Makefile | sed -e 's/\s*CMDS\s*=//'); do + kind load docker-image --name csi-prow $i:csiprow || die "could not load the $i:latest image into the kind cluster" + done + fi + + if deploy_driver="$(find_deployment "$(pwd)/deploy")"; then + : + elif [ "${CSI_PROW_DRIVER_REPO}" = "none" ]; then + return 1 + else + git_checkout "${CSI_PROW_DRIVER_REPO}" "${CSI_PROW_WORK}/csi-driver" "${CSI_PROW_DRIVER_VERSION}" --depth=1 || die "checking out CSI driver repo failed" + if deploy_driver="$(find_deployment "${CSI_PROW_WORK}/csi-driver/deploy")"; then + : + else + die "deploy.sh not found in ${CSI_PROW_DRIVER_REPO} ${CSI_PROW_DRIVER_VERSION}. To disable E2E testing, set CSI_PROW_DRIVER_REPO=none" + fi + fi + + if [ "${CSI_PROW_DRIVER_CANARY}" != "stable" ]; then + if [ "${CSI_PROW_DRIVER_CANARY}" == "canary" ]; then + images="$images IMAGE_TAG=${CSI_PROW_DRIVER_CANARY} IMAGE_REGISTRY=${CSI_PROW_DRIVER_CANARY_REGISTRY}" + else + images="$images IMAGE_TAG=${CSI_PROW_DRIVER_CANARY}" + fi + fi + # Ignore: Double quote to prevent globbing and word splitting. + # It's intentional here for $images. + # shellcheck disable=SC2086 + if ! run env "CSI_PROW_TEST_DRIVER=${CSI_PROW_WORK}/test-driver.yaml" $images "${deploy_driver}"; then + # Collect information about failed deployment before failing. + collect_cluster_info + (start_loggers >/dev/null; wait) + info "For container output see job artifacts." + die "deploying the CSI driver with ${deploy_driver} failed" + fi +} + +# Installs all necessary snapshotter CRDs +install_snapshot_crds() { + # Wait until volumesnapshot CRDs are in place. + CRD_BASE_DIR="https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/${CSI_SNAPSHOTTER_VERSION}/client/config/crd" + if [[ ${REPO_DIR} == *"external-snapshotter"* ]]; then + CRD_BASE_DIR="${REPO_DIR}/client/config/crd" + fi + echo "Installing snapshot CRDs from ${CRD_BASE_DIR}" + kubectl apply -f "${CRD_BASE_DIR}/snapshot.storage.k8s.io_volumesnapshotclasses.yaml" --validate=false + kubectl apply -f "${CRD_BASE_DIR}/snapshot.storage.k8s.io_volumesnapshots.yaml" --validate=false + kubectl apply -f "${CRD_BASE_DIR}/snapshot.storage.k8s.io_volumesnapshotcontents.yaml" --validate=false + cnt=0 + until kubectl get volumesnapshotclasses.snapshot.storage.k8s.io \ + && kubectl get volumesnapshots.snapshot.storage.k8s.io \ + && kubectl get volumesnapshotcontents.snapshot.storage.k8s.io; do + if [ $cnt -gt 30 ]; then + echo >&2 "ERROR: snapshot CRDs not ready after over 1 min" + exit 1 + fi + echo "$(date +%H:%M:%S)" "waiting for snapshot CRDs, attempt #$cnt" + cnt=$((cnt + 1)) + sleep 2 + done +} + +# Install snapshot controller and associated RBAC, retrying until the pod is running. +install_snapshot_controller() { + CONTROLLER_DIR="https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/${CSI_SNAPSHOTTER_VERSION}" + if [[ ${REPO_DIR} == *"external-snapshotter"* ]]; then + CONTROLLER_DIR="${REPO_DIR}" + fi + SNAPSHOT_RBAC_YAML="${CONTROLLER_DIR}/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml" + echo "kubectl apply -f ${SNAPSHOT_RBAC_YAML}" + # Ignore: Double quote to prevent globbing and word splitting. + # shellcheck disable=SC2086 + kubectl apply -f ${SNAPSHOT_RBAC_YAML} + + cnt=0 + until kubectl get clusterrolebinding snapshot-controller-role; do + if [ $cnt -gt 30 ]; then + echo "Cluster role bindings:" + kubectl describe clusterrolebinding + echo >&2 "ERROR: snapshot controller RBAC not ready after over 5 min" + exit 1 + fi + echo "$(date +%H:%M:%S)" "waiting for snapshot RBAC setup complete, attempt #$cnt" + cnt=$((cnt + 1)) + sleep 10 + done + + SNAPSHOT_CONTROLLER_YAML="${CONTROLLER_DIR}/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml" + if [[ ${REPO_DIR} == *"external-snapshotter"* ]]; then + # snapshot-controller image built from the PR will get a "csiprow" tag. + # Load it into the "kind" cluster so that we can deploy it. + NEW_TAG="csiprow" + NEW_IMG="snapshot-controller:${NEW_TAG}" + echo "kind load docker-image --name csi-prow ${NEW_IMG}" + kind load docker-image --name csi-prow ${NEW_IMG} || die "could not load the snapshot-controller:csiprow image into the kind cluster" + + # deploy snapshot-controller + echo "Deploying snapshot-controller from ${SNAPSHOT_CONTROLLER_YAML} with $NEW_IMG." + # Replace image in SNAPSHOT_CONTROLLER_YAML with snapshot-controller:csiprow and deploy + # NOTE: This logic is similar to the logic here: + # https://github.com/kubernetes-csi/csi-driver-host-path/blob/v1.4.0/deploy/util/deploy-hostpath.sh#L155 + # Ignore: Double quote to prevent globbing and word splitting. + # shellcheck disable=SC2086 + # Ignore: Use find instead of ls to better handle non-alphanumeric filenames. + # shellcheck disable=SC2012 + for i in $(ls ${SNAPSHOT_CONTROLLER_YAML} | sort); do + echo " $i" + # Ignore: Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead. + # shellcheck disable=SC2002 + # Ignore: See if you can use ${variable//search/replace} instead. + # shellcheck disable=SC2001 + modified="$(cat "$i" | while IFS= read -r line; do + nocomments="$(echo "$line" | sed -e 's/ *#.*$//')" + if echo "$nocomments" | grep -q '^[[:space:]]*image:[[:space:]]*'; then + # Split 'image: registry.k8s.io/sig-storage/snapshot-controller:v3.0.0' + # into image (snapshot-controller:v3.0.0), + # name (snapshot-controller), + # tag (v3.0.0). + image=$(echo "$nocomments" | sed -e 's;.*image:[[:space:]]*;;') + name=$(echo "$image" | sed -e 's;.*/\([^:]*\).*;\1;') + tag=$(echo "$image" | sed -e 's;.*:;;') + + # Now replace registry and/or tag + NEW_TAG="csiprow" + line="$(echo "$nocomments" | sed -e "s;$image;${name}:${NEW_TAG};")" + echo " using $line" >&2 + fi + echo "$line" + done)" + if ! echo "$modified" | kubectl apply -f -; then + echo "modified version of $i:" + echo "$modified" + exit 1 + fi + done + elif [ "${CSI_PROW_DRIVER_CANARY}" = "canary" ]; then + echo "Deploying snapshot-controller from ${SNAPSHOT_CONTROLLER_YAML} with canary images." + yaml="$(kubectl apply --dry-run=client -o yaml -f "$SNAPSHOT_CONTROLLER_YAML")" + # Ignore: See if you can use ${variable//search/replace} instead. + # shellcheck disable=SC2001 + modified="$(echo "$yaml" | sed -e "s;image: .*/\([^/:]*\):.*;image: ${CSI_PROW_DRIVER_CANARY_REGISTRY}/\1:canary;")" + diff <(echo "$yaml") <(echo "$modified") + if ! echo "$modified" | kubectl apply -f -; then + echo "modified version of $SNAPSHOT_CONTROLLER_YAML:" + echo "$modified" + exit 1 + fi + else + echo "kubectl apply -f $SNAPSHOT_CONTROLLER_YAML" + kubectl apply -f "$SNAPSHOT_CONTROLLER_YAML" + fi + + cnt=0 + expected_running_pods=$(kubectl apply --dry-run=client -o "jsonpath={.spec.replicas}" -f "$SNAPSHOT_CONTROLLER_YAML") + expected_namespace=$(kubectl apply --dry-run=client -o "jsonpath={.metadata.namespace}" -f "$SNAPSHOT_CONTROLLER_YAML") + while [ "$(kubectl get pods -n "$expected_namespace" -l app=snapshot-controller | grep 'Running' -c)" -lt "$expected_running_pods" ]; do + if [ $cnt -gt 30 ]; then + echo "snapshot-controller pod status:" + kubectl describe pods -n "$expected_namespace" -l app=snapshot-controller + echo >&2 "ERROR: snapshot controller not ready after over 5 min" + exit 1 + fi + echo "$(date +%H:%M:%S)" "waiting for snapshot controller deployment to complete, attempt #$cnt" + cnt=$((cnt + 1)) + sleep 10 + done +} + +# collect logs and cluster status (like the version of all components, Kubernetes version, test version) +collect_cluster_info () { + cat <>"${ARTIFACTS}/$namespace/$pod/$container.log" & + echo "$!" + done + done +} + +# Patches the image versions of test/e2e/testing-manifests/storage-csi/mock in the k/k +# source code, if needed. +patch_kubernetes () { + local source="$1" target="$2" + + if [ "${CSI_PROW_DRIVER_CANARY}" = "canary" ]; then + # We cannot replace registry.k8s.io/sig-storage with gcr.io/k8s-staging-sig-storage because + # e2e.test does not support it (see test/utils/image/manifest.go). Instead we + # invoke the e2e.test binary with KUBE_TEST_REPO_LIST set to a file that + # overrides that registry. + find "$source/test/e2e/testing-manifests/storage-csi/mock" -name '*.yaml' -print0 | xargs -0 sed -i -e 's;registry.k8s.io/sig-storage/\(.*\):v.*;registry.k8s.io/sig-storage/\1:canary;' + cat >"$target/e2e-repo-list" <&2 <&1) + +EOF + fi +} + +# Makes the E2E test suite binary available as "${CSI_PROW_WORK}/e2e.test". +install_e2e () { + if [ -e "${CSI_PROW_WORK}/e2e.test" ]; then + return + fi + + git_checkout "${CSI_PROW_E2E_REPO}" "${GOPATH}/src/${CSI_PROW_E2E_IMPORT_PATH}" "${CSI_PROW_E2E_VERSION}" --depth=1 && + if [ "${CSI_PROW_E2E_IMPORT_PATH}" = "k8s.io/kubernetes" ]; then + patch_kubernetes "${GOPATH}/src/${CSI_PROW_E2E_IMPORT_PATH}" "${CSI_PROW_WORK}" && + go_version="${CSI_PROW_GO_VERSION_E2E:-$(go_version_for_kubernetes "${GOPATH}/src/${CSI_PROW_E2E_IMPORT_PATH}" "${CSI_PROW_E2E_VERSION}")}" && + run_with_go "$go_version" make WHAT=test/e2e/e2e.test "-C${GOPATH}/src/${CSI_PROW_E2E_IMPORT_PATH}" && + ln -s "${GOPATH}/src/${CSI_PROW_E2E_IMPORT_PATH}/_output/bin/e2e.test" "${CSI_PROW_WORK}" && + run_with_go "$go_version" make WHAT=vendor/github.com/onsi/ginkgo/ginkgo "-C${GOPATH}/src/${CSI_PROW_E2E_IMPORT_PATH}" && + ln -s "${GOPATH}/src/${CSI_PROW_E2E_IMPORT_PATH}/_output/bin/ginkgo" "${CSI_PROW_BIN}" + else + run_with_go "${CSI_PROW_GO_VERSION_E2E}" go test -c -o "${CSI_PROW_WORK}/e2e.test" "${CSI_PROW_E2E_IMPORT_PATH}/test/e2e" + fi +} + +# Makes the csi-sanity test suite binary available as +# "${CSI_PROW_WORK}/csi-sanity". +install_sanity () ( + if [ -e "${CSI_PROW_WORK}/csi-sanity" ]; then + return + fi + + git_checkout "${CSI_PROW_SANITY_REPO}" "${GOPATH}/src/${CSI_PROW_SANITY_PACKAGE_PATH}" "${CSI_PROW_SANITY_VERSION}" --depth=1 || die "checking out csi-sanity failed" + ( cd "${GOPATH}/src/${CSI_PROW_SANITY_PACKAGE_PATH}/cmd/csi-sanity" && run_with_go "${CSI_PROW_GO_VERSION_SANITY}" go build -o "${CSI_PROW_WORK}/csi-sanity" ) || die "building csi-sanity failed" +) + +# Captures pod output while running some other command. +run_with_loggers () ( + loggers=$(start_loggers -f) + trap 'kill $loggers' EXIT + + run "$@" +) + +# Invokes the filter-junit.go tool. +run_filter_junit () { + run_with_go "${CSI_PROW_GO_VERSION_BUILD}" go run "${RELEASE_TOOLS_ROOT}/filter-junit.go" "$@" +} + +# Runs the E2E test suite in a sub-shell. +run_e2e () ( + name="$1" + shift + + install_e2e || die "building e2e.test failed" + install_ginkgo || die "installing ginkgo failed" + + # Rename, merge and filter JUnit files. Necessary in case that we run the E2E suite again + # and to avoid the large number of "skipped" tests that we get from using + # the full Kubernetes E2E testsuite while only running a few tests. + move_junit () { + if ls "${ARTIFACTS}"/junit_[0-9]*.xml 2>/dev/null >/dev/null; then + run_filter_junit -t="External.Storage|CSI.mock.volume" -o "${ARTIFACTS}/junit_${name}.xml" "${ARTIFACTS}"/junit_[0-9]*.xml && rm -f "${ARTIFACTS}"/junit_[0-9]*.xml + fi + } + trap move_junit EXIT + + cd "${GOPATH}/src/${CSI_PROW_E2E_IMPORT_PATH}" && + run_with_loggers env KUBECONFIG="$KUBECONFIG" KUBE_TEST_REPO_LIST="$(if [ -e "${CSI_PROW_WORK}/e2e-repo-list" ]; then echo "${CSI_PROW_WORK}/e2e-repo-list"; fi)" ginkgo -v "$@" "${CSI_PROW_WORK}/e2e.test" -- -report-dir "${ARTIFACTS}" -storage.testdriver="${CSI_PROW_WORK}/test-driver.yaml" +) + +# Run csi-sanity against installed CSI driver. +run_sanity () ( + install_sanity || die "installing csi-sanity failed" + + if [[ "${CSI_PROW_SANITY_POD}" =~ " " ]]; then + # Contains spaces, more complex than a simple pod name. + # Evaluate as a shell command. + pod=$(eval "${CSI_PROW_SANITY_POD}") || die "evaluation failed: CSI_PROW_SANITY_POD=${CSI_PROW_SANITY_POD}" + else + pod="${CSI_PROW_SANITY_POD}" + fi + + cat >"${CSI_PROW_WORK}/mkdir_in_pod.sh" <"${CSI_PROW_WORK}/rmdir_in_pod.sh" <"${CSI_PROW_WORK}/checkdir_in_pod.sh" </\>/g' -e 's/\x1B...//g' +} + +# The "make test" output starts each test with "### :" +# and then ends when the next test starts or with "make: *** +# [] Error 1" when there was a failure. Here we read each +# line of that output, split it up into individual tests and generate +# a make-test.xml file in JUnit format. +make_test_to_junit () { + local ret out testname testoutput + ret=0 + # Plain make-test.xml was not delivered as text/xml by the web + # server and ignored by spyglass. It seems that the name has to + # match junit*.xml. + out="${ARTIFACTS}/junit_make_test.xml" + testname= + echo "" >>"$out" + + while IFS= read -r line; do + echo "$line" # pass through + if echo "$line" | grep -q "^### [^ ]*:$"; then + if [ "$testname" ]; then + # previous test successful + echo " " >>"$out" + echo " " >>"$out" + fi + # Ignore: See if you can use ${variable//search/replace} instead. + # shellcheck disable=SC2001 + # + # start new test + testname="$(echo "$line" | sed -e 's/^### \([^ ]*\):$/\1/')" + testoutput= + echo " " >>"$out" + echo " " >>"$out" + elif echo "$line" | grep -q '^make: .*Error [0-9]*$'; then + if [ "$testname" ]; then + # Ignore: Consider using { cmd1; cmd2; } >> file instead of individual redirects. + # shellcheck disable=SC2129 + # + # end test with failure + echo " " >>"$out" + # Include the same text as in also in , + # because then it is easier to view in spyglass (shown directly + # instead of having to click through to stdout). + echo " " >>"$out" + echo -n "$testoutput" | ascii_to_xml >>"$out" + echo " " >>"$out" + echo " " >>"$out" + fi + # remember failure for exit code + ret=1 + # not currently inside a test + testname= + else + if [ "$testname" ]; then + # Test output. + echo "$line" | ascii_to_xml >>"$out" + testoutput="$testoutput$line +" + fi + fi + done + # if still in a test, close it now + if [ "$testname" ]; then + echo " " >>"$out" + echo " " >>"$out" + fi + echo "" >>"$out" + + # this makes the error more visible in spyglass + if [ "$ret" -ne 0 ]; then + echo "ERROR: 'make test' failed" + return 1 + fi +} + +# version_gt returns true if arg1 is greater than arg2. +# +# This function expects versions to be one of the following formats: +# X.Y.Z, release-X.Y.Z, vX.Y.Z +# +# where X,Y, and Z are any number. +# +# Partial versions (1.2, release-1.2) work as well. +# The follow substrings are stripped before version comparison: +# - "v" +# - "release-" +# - "kubernetes-" +# +# Usage: +# version_gt release-1.3 v1.2.0 (returns true) +# version_gt v1.1.1 v1.2.0 (returns false) +# version_gt 1.1.1 v1.2.0 (returns false) +# version_gt 1.3.1 v1.2.0 (returns true) +# version_gt 1.1.1 release-1.2.0 (returns false) +# version_gt 1.2.0 1.2.2 (returns false) +function version_gt() { + versions=$(for ver in "$@"; do ver=${ver#release-}; ver=${ver#kubernetes-}; echo "${ver#v}"; done) + greaterVersion=${1#"release-"}; + greaterVersion=${greaterVersion#"kubernetes-"}; + greaterVersion=${greaterVersion#"v"}; + test "$(printf '%s' "$versions" | sort -V | head -n 1)" != "$greaterVersion" +} + +main () { + local images ret + ret=0 + + # Set up work directory. + ensure_paths + + images= + if ${CSI_PROW_BUILD_JOB}; then + # A successful build is required for testing. + run_with_go "${CSI_PROW_GO_VERSION_BUILD}" make all "GOFLAGS_VENDOR=${GOFLAGS_VENDOR}" "BUILD_PLATFORMS=${CSI_PROW_BUILD_PLATFORMS}" || die "'make all' failed" + # We don't want test failures to prevent E2E testing below, because the failure + # might have been minor or unavoidable, for example when experimenting with + # changes in "release-tools" in a PR (that fails the "is release-tools unmodified" + # test). + if tests_enabled "unit"; then + if [ -f Gopkg.toml ] && ! install_dep; then + warn "installing 'dep' failed, cannot test vendoring" + ret=1 + fi + if ! run_with_go "${CSI_PROW_GO_VERSION_BUILD}" make -k test "GOFLAGS_VENDOR=${GOFLAGS_VENDOR}" 2>&1 | make_test_to_junit; then + warn "'make test' failed, proceeding anyway" + ret=1 + fi + fi + # Required for E2E testing. + run_with_go "${CSI_PROW_GO_VERSION_BUILD}" make container "GOFLAGS_VENDOR=${GOFLAGS_VENDOR}" || die "'make container' failed" + fi + + if tests_need_kind; then + install_kind || die "installing kind failed" + + if ${CSI_PROW_BUILD_JOB}; then + cmds="$(grep '^\s*CMDS\s*=' Makefile | sed -e 's/\s*CMDS\s*=//')" + # Get the image that was just built (if any) from the + # top-level Makefile CMDS variable and set the + # deploy.sh env variables for it. We also need to + # side-load those images into the cluster. + for i in $cmds; do + e=$(echo "$i" | tr '[:lower:]' '[:upper:]' | tr - _) + images="$images ${e}_REGISTRY=none ${e}_TAG=csiprow" + + # We must avoid the tag "latest" because that implies + # always pulling the image + # (https://github.com/kubernetes-sigs/kind/issues/328). + docker tag "$i:latest" "$i:csiprow" || die "tagging the locally built container image for $i failed" + + # For components with multiple cmds, the RBAC file should be in the following format: + # rbac-$cmd.yaml + # If this file cannot be found, we can default to the standard location: + # deploy/kubernetes/rbac.yaml + rbac_file_path=$(find . -type f -name "rbac-$i.yaml") + if [ "$rbac_file_path" == "" ]; then + rbac_file_path="$(pwd)/deploy/kubernetes/rbac.yaml" + fi + + if [ -e "$rbac_file_path" ]; then + # This is one of those components which has its own RBAC rules (like external-provisioner). + # We are testing a locally built image and also want to test with the the current, + # potentially modified RBAC rules. + e=$(echo "$i" | tr '[:lower:]' '[:upper:]' | tr - _) + images="$images ${e}_RBAC=$rbac_file_path" + fi + done + fi + + # Run the external driver tests and optionally also mock tests. + local focus="External.Storage" + if "$CSI_PROW_E2E_MOCK"; then + focus="($focus|CSI.mock.volume)" + fi + + if tests_need_non_alpha_cluster; then + # Need to (re)create the cluster. + start_cluster "${CSI_PROW_E2E_GATES}" || die "starting the non-alpha cluster failed" + + # Install necessary snapshot CRDs and snapshot controller + install_snapshot_crds + install_snapshot_controller + + + # Installing the driver might be disabled. + if ${CSI_PROW_DRIVER_INSTALL} "$images"; then + collect_cluster_info + + if sanity_enabled; then + if ! run_sanity; then + ret=1 + fi + fi + + if tests_enabled "parallel"; then + # Ignore: Double quote to prevent globbing and word splitting. + # shellcheck disable=SC2086 + if ! run_e2e parallel ${CSI_PROW_GINKO_PARALLEL} \ + -focus="$focus" \ + -skip="$(regex_join "${CSI_PROW_E2E_SERIAL}" "${CSI_PROW_E2E_ALPHA}" "${CSI_PROW_E2E_SKIP}")"; then + warn "E2E parallel failed" + ret=1 + fi + + # Run tests that are feature tagged, but non-alpha + # Ignore: Double quote to prevent globbing and word splitting. + # shellcheck disable=SC2086 + if ! run_e2e parallel-features ${CSI_PROW_GINKO_PARALLEL} \ + -focus="$focus.*($(regex_join "${CSI_PROW_E2E_FOCUS}"))" \ + -skip="$(regex_join "${CSI_PROW_E2E_SERIAL}")"; then + warn "E2E parallel features failed" + ret=1 + fi + fi + + if tests_enabled "serial"; then + if ! run_e2e serial \ + -focus="$focus.*($(regex_join "${CSI_PROW_E2E_SERIAL}"))" \ + -skip="$(regex_join "${CSI_PROW_E2E_ALPHA}" "${CSI_PROW_E2E_SKIP}")"; then + warn "E2E serial failed" + ret=1 + fi + fi + fi + delete_cluster_inside_prow_job non-alpha + fi + + # If the cluster for alpha tests doesn't need any feature gates, then we + # could reuse the same cluster as for the other tests. But that would make + # the flow in this script harder and wouldn't help in practice because + # we have separate Prow jobs for alpha and non-alpha tests. + if tests_need_alpha_cluster; then + # Need to (re)create the cluster. + start_cluster "${CSI_PROW_E2E_ALPHA_GATES}" || die "starting alpha cluster failed" + + # Install necessary snapshot CRDs and snapshot controller + install_snapshot_crds + install_snapshot_controller + + # Installing the driver might be disabled. + if ${CSI_PROW_DRIVER_INSTALL} "$images"; then + collect_cluster_info + + if tests_enabled "parallel-alpha"; then + # Ignore: Double quote to prevent globbing and word splitting. + # shellcheck disable=SC2086 + if ! run_e2e parallel-alpha ${CSI_PROW_GINKO_PARALLEL} \ + -focus="$focus.*($(regex_join "${CSI_PROW_E2E_ALPHA}"))" \ + -skip="$(regex_join "${CSI_PROW_E2E_SERIAL}" "${CSI_PROW_E2E_SKIP}")"; then + warn "E2E parallel alpha failed" + ret=1 + fi + fi + + if tests_enabled "serial-alpha"; then + if ! run_e2e serial-alpha \ + -focus="$focus.*(($(regex_join "${CSI_PROW_E2E_SERIAL}")).*($(regex_join "${CSI_PROW_E2E_ALPHA}"))|($(regex_join "${CSI_PROW_E2E_ALPHA}")).*($(regex_join "${CSI_PROW_E2E_SERIAL}")))" \ + -skip="$(regex_join "${CSI_PROW_E2E_SKIP}")"; then + warn "E2E serial alpha failed" + ret=1 + fi + fi + fi + delete_cluster_inside_prow_job alpha + fi + fi + + # Merge all junit files into one. This gets rid of duplicated "skipped" tests. + if ls "${ARTIFACTS}"/junit_*.xml 2>/dev/null >&2; then + run_filter_junit -o "${CSI_PROW_WORK}/junit_final.xml" "${ARTIFACTS}"/junit_*.xml && rm "${ARTIFACTS}"/junit_*.xml && mv "${CSI_PROW_WORK}/junit_final.xml" "${ARTIFACTS}" + fi + + return "$ret" +} + +# This function can be called by a repo's top-level cloudbuild.sh: +# it handles environment set up in the GCR cloud build and then +# invokes "make push-multiarch" to do the actual image building. +gcr_cloud_build () { + # Register gcloud as a Docker credential helper. + # Required for "docker buildx build --push". + gcloud auth configure-docker + + # Might not be needed here, but call it just in case. + ensure_paths + + if find . -name Dockerfile | grep -v ^./vendor | xargs --no-run-if-empty cat | grep -q ^RUN; then + # Needed for "RUN" steps on non-linux/amd64 platforms. + # See https://github.com/multiarch/qemu-user-static#getting-started + (set -x; docker run --rm --privileged multiarch/qemu-user-static --reset -p yes) + fi + + # Extract tag-n-hash value from GIT_TAG (form vYYYYMMDD-tag-n-hash) for REV value. + REV=v$(echo "$GIT_TAG" | cut -f3- -d 'v') + + run_with_go "${CSI_PROW_GO_VERSION_BUILD}" make push-multiarch REV="${REV}" REGISTRY_NAME="${REGISTRY_NAME}" BUILD_PLATFORMS="${CSI_PROW_BUILD_PLATFORMS}" +} diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/pull-test.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/pull-test.sh new file mode 100755 index 00000000..b019c177 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/pull-test.sh @@ -0,0 +1,32 @@ +#! /bin/sh + +# Copyright 2021 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script is called by pull Prow jobs for the csi-release-tools +# repo to ensure that the changes in the PR work when imported into +# some other repo. + +set -ex + +# It must be called inside the updated csi-release-tools repo. +CSI_RELEASE_TOOLS_DIR="$(pwd)" + +# Update the other repo. +cd "$PULL_TEST_REPO_DIR" +git subtree pull --squash --prefix=release-tools "$CSI_RELEASE_TOOLS_DIR" master +git log -n2 + +# Now fall through to testing. +exec ./.prow.sh diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/update-vendor.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/update-vendor.sh new file mode 100755 index 00000000..6f4c27ae --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/update-vendor.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if [ -f Gopkg.toml ]; then + echo "Repo uses 'dep' for vendoring." + (set -x; dep ensure) +elif [ -f go.mod ]; then + release-tools/verify-go-version.sh "go" + (set -x; env GO111MODULE=on go mod tidy && env GO111MODULE=on go mod vendor) +fi diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/util.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/util.sh new file mode 100755 index 00000000..abeb1b2e --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/util.sh @@ -0,0 +1,148 @@ +#!/usr/bin/env bash + +# Copyright 2014 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +function kube::util::sourced_variable { + # Call this function to tell shellcheck that a variable is supposed to + # be used from other calling context. This helps quiet an "unused + # variable" warning from shellcheck and also document your code. + true +} + +kube::util::sortable_date() { + date "+%Y%m%d-%H%M%S" +} + +# arguments: target, item1, item2, item3, ... +# returns 0 if target is in the given items, 1 otherwise. +kube::util::array_contains() { + local search="$1" + local element + shift + for element; do + if [[ "${element}" == "${search}" ]]; then + return 0 + fi + done + return 1 +} + +# Example: kube::util::trap_add 'echo "in trap DEBUG"' DEBUG +# See: http://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal +kube::util::trap_add() { + local trap_add_cmd + trap_add_cmd=$1 + shift + + for trap_add_name in "$@"; do + local existing_cmd + local new_cmd + + # Grab the currently defined trap commands for this trap + existing_cmd=$(trap -p "${trap_add_name}" | awk -F"'" '{print $2}') + + if [[ -z "${existing_cmd}" ]]; then + new_cmd="${trap_add_cmd}" + else + new_cmd="${trap_add_cmd};${existing_cmd}" + fi + + # Assign the test. Disable the shellcheck warning telling that trap + # commands should be single quoted to avoid evaluating them at this + # point instead evaluating them at run time. The logic of adding new + # commands to a single trap requires them to be evaluated right away. + # shellcheck disable=SC2064 + trap "${new_cmd}" "${trap_add_name}" + done +} + +kube::util::download_file() { + local -r url=$1 + local -r destination_file=$2 + + rm "${destination_file}" 2&> /dev/null || true + + for i in $(seq 5) + do + if ! curl -fsSL --retry 3 --keepalive-time 2 "${url}" -o "${destination_file}"; then + echo "Downloading ${url} failed. $((5-i)) retries left." + sleep 1 + else + echo "Downloading ${url} succeed" + return 0 + fi + done + return 1 +} + +# Wait for background jobs to finish. Return with +# an error status if any of the jobs failed. +kube::util::wait-for-jobs() { + local fail=0 + local job + for job in $(jobs -p); do + wait "${job}" || fail=$((fail + 1)) + done + return ${fail} +} + +# kube::util::join +# Concatenates the list elements with the delimiter passed as first parameter +# +# Ex: kube::util::join , a b c +# -> a,b,c +function kube::util::join { + local IFS="$1" + shift + echo "$*" +} + +# kube::util::check-file-in-alphabetical-order +# Check that the file is in alphabetical order +# +function kube::util::check-file-in-alphabetical-order { + local failure_file="$1" + if ! diff -u "${failure_file}" <(LC_ALL=C sort "${failure_file}"); then + { + echo + echo "${failure_file} is not in alphabetical order. Please sort it:" + echo + echo " LC_ALL=C sort -o ${failure_file} ${failure_file}" + echo + } >&2 + false + fi +} + +# Some useful colors. +if [[ -z "${color_start-}" ]]; then + declare -r color_start="\033[" + declare -r color_red="${color_start}0;31m" + declare -r color_yellow="${color_start}0;33m" + declare -r color_green="${color_start}0;32m" + declare -r color_blue="${color_start}1;34m" + declare -r color_cyan="${color_start}1;36m" + declare -r color_norm="${color_start}0m" + + kube::util::sourced_variable "${color_start}" + kube::util::sourced_variable "${color_red}" + kube::util::sourced_variable "${color_yellow}" + kube::util::sourced_variable "${color_green}" + kube::util::sourced_variable "${color_blue}" + kube::util::sourced_variable "${color_cyan}" + kube::util::sourced_variable "${color_norm}" +fi + +# ex: ts=2 sw=2 et filetype=sh diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-boilerplate.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-boilerplate.sh new file mode 100755 index 00000000..81593957 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-boilerplate.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# Copyright 2014 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +echo "Verifying boilerplate" + +if [[ -z "$(command -v python)" ]]; then + echo "Cannot find python. Make link to python3..." + update-alternatives --install /usr/bin/python python /usr/bin/python3 1 +fi + +# The csi-release-tools directory (absolute path). +TOOLS="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" + +# Directory to check. Default is the parent of the tools themselves. +ROOT="${1:-${TOOLS}/..}" + +boiler="${TOOLS}/boilerplate/boilerplate.py" + +mapfile -t files_need_boilerplate < <("${boiler}" --rootdir="${ROOT}" --verbose) + +# Run boilerplate.py unit tests +unitTestOut="$(mktemp)" +trap cleanup EXIT +cleanup() { + rm "${unitTestOut}" +} + +# Run boilerplate check +if [[ ${#files_need_boilerplate[@]} -gt 0 ]]; then + for file in "${files_need_boilerplate[@]}"; do + echo "Boilerplate header is wrong for: ${file}" + done + + exit 1 +fi + +echo "Done" diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-go-version.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-go-version.sh new file mode 100755 index 00000000..c235e74f --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-go-version.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +GO="$1" + +if [ ! "$GO" ]; then + echo >&2 "usage: $0 " + exit 1 +fi + +die () { + echo "ERROR: $*" + exit 1 +} + +version=$("$GO" version) || die "determining version of $GO failed" +# shellcheck disable=SC2001 +majorminor=$(echo "$version" | sed -e 's/.*go\([0-9]*\)\.\([0-9]*\).*/\1.\2/') +# SC1091: Not following: release-tools/prow.sh was not specified as input (see shellcheck -x). +# shellcheck disable=SC1091 +expected=$(. release-tools/prow.sh >/dev/null && echo "$CSI_PROW_GO_VERSION_BUILD") + +if [ "$majorminor" != "$expected" ]; then + cat >&2 < /dev/null || true +} + +# ensure we're linting the source tree +cd "${ROOT}" + +# find all shell scripts excluding ./_*, ./.git/*, ./vendor*, +# and anything git-ignored +all_shell_scripts=() +while IFS=$'\n' read -r script; + do git check-ignore -q "$script" || all_shell_scripts+=("$script"); +done < <(find . -name "*.sh" \ + -not \( \ + -path ./_\* -o \ + -path ./.git\* -o \ + -path ./vendor\* \ + \)) + +# detect if the host machine has the required shellcheck version installed +# if so, we will use that instead. +HAVE_SHELLCHECK=false +if command -v shellcheck &>/dev/null; then + detected_version="$(shellcheck --version | grep 'version: .*')" + if [[ "${detected_version}" = "version: ${SHELLCHECK_VERSION}" ]]; then + HAVE_SHELLCHECK=true + fi +fi + +# tell the user which we've selected and possibly set up the container +if ${HAVE_SHELLCHECK}; then + echo "Using host shellcheck ${SHELLCHECK_VERSION} binary." +else + echo "Using shellcheck ${SHELLCHECK_VERSION} docker image." + # remove any previous container, ensure we will attempt to cleanup on exit, + # and create the container + remove_container + kube::util::trap_add 'remove_container' EXIT + if ! output="$(create_container 2>&1)"; then + { + echo "Failed to create shellcheck container with output: " + echo "" + echo "${output}" + } >&2 + exit 1 + fi +fi + +# lint each script, tracking failures +errors=() +for f in "${all_shell_scripts[@]}"; do + set +o errexit + if ${HAVE_SHELLCHECK}; then + failedLint=$(shellcheck --exclude="${SHELLCHECK_DISABLED}" "${f}") + else + failedLint=$(docker exec -t ${SHELLCHECK_CONTAINER} \ + shellcheck --exclude="${SHELLCHECK_DISABLED}" "${f}") + fi + set -o errexit + if [[ -n "${failedLint}" ]]; then + errors+=( "${failedLint}" ) + fi +done + +# Check to be sure all the packages that should pass lint are. +if [ ${#errors[@]} -eq 0 ]; then + echo 'Congratulations! All shell files are passing lint.' +else + { + echo "Errors from shellcheck:" + for err in "${errors[@]}"; do + echo "$err" + done + echo + echo 'Please review the above warnings. You can test via "./hack/verify-shellcheck"' + echo 'If the above warnings do not make sense, you can exempt them from shellcheck' + echo 'checking by adding the "shellcheck disable" directive' + echo '(https://github.com/koalaman/shellcheck/wiki/Directive#disable).' + echo + } >&2 + false +fi diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-spelling.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-spelling.sh new file mode 100755 index 00000000..6e87b1db --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-spelling.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +TOOL_VERSION="v0.3.4" + +# The csi-release-tools directory (absolute path). +TOOLS="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" + +# Directory to check. Default is the parent of the tools themselves. +ROOT="${1:-${TOOLS}/..}" + +# create a temporary directory +TMP_DIR=$(mktemp -d) + +# cleanup +exitHandler() ( + echo "Cleaning up..." + rm -rf "${TMP_DIR}" +) +trap exitHandler EXIT + +if [[ -z "$(command -v misspell)" ]]; then + echo "Cannot find misspell. Installing misspell..." + # perform go get in a temp dir as we are not tracking this version in a go module + # if we do the go get in the repo, it will create / update a go.mod and go.sum + cd "${TMP_DIR}" + GO111MODULE=on GOBIN="${TMP_DIR}" go install "github.com/client9/misspell/cmd/misspell@${TOOL_VERSION}" + export PATH="${TMP_DIR}:${PATH}" +fi + +# check spelling +RES=0 +echo "Checking spelling..." +ERROR_LOG="${TMP_DIR}/errors.log" +cd "${ROOT}" +git ls-files | grep -v vendor | xargs misspell > "${ERROR_LOG}" +if [[ -s "${ERROR_LOG}" ]]; then + sed 's/^/error: /' "${ERROR_LOG}" # add 'error' to each line to highlight in e2e status + echo "Found spelling errors!" + RES=1 +fi +exit "${RES}" diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-subtree.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-subtree.sh new file mode 100755 index 00000000..aa72194a --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-subtree.sh @@ -0,0 +1,41 @@ +#! /bin/sh -e + +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This script verifies that the content of a directory managed +# by "git subtree" has not been modified locally. It does that +# by looking for commits that modify the files with the +# subtree prefix (aka directory) while ignoring merge +# commits. Merge commits are where "git subtree" pulls the +# upstream files into the directory. +# +# Theoretically a developer can subvert this check by modifying files +# in a merge commit, but in practice that shouldn't happen. + +DIR="$1" +if [ ! "$DIR" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +REV=$(git log -n1 --remove-empty --format=format:%H --no-merges -- "$DIR") +if [ "$REV" ]; then + echo "Directory '$DIR' contains non-upstream changes:" + echo + git log --no-merges -- "$DIR" + exit 1 +else + echo "$DIR is a clean copy of upstream." +fi diff --git a/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-vendor.sh b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-vendor.sh new file mode 100755 index 00000000..b413e4b4 --- /dev/null +++ b/applications/nfsserver/nfs-subdir-external-provisioner/release-tools/verify-vendor.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +# Copyright 2019 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if [ -f Gopkg.toml ]; then + echo "Repo uses 'dep' for vendoring." + case "$(dep version 2>/dev/null | grep 'version *:')" in + *v0.[56789]*) + if dep check; then + echo "vendor up-to-date" + else + exit 1 + fi + ;; + *) echo "skipping check, dep >= 0.5 required";; + esac +elif [ -f go.mod ]; then + echo "Repo uses 'go mod'." + # shellcheck disable=SC2235 + if [ "${JOB_NAME}" ] && + ( [ "${JOB_TYPE}" != "presubmit" ] || + [ "$( (git diff "${PULL_BASE_SHA}..HEAD" -- go.mod go.sum vendor release-tools; + git diff "${PULL_BASE_SHA}..HEAD" | grep -e '^@@.*@@ import (' -e '^[+-]import') | + wc -l)" -eq 0 ] ); then + echo "Skipping vendor check because the Prow pre-submit job does not affect dependencies." + elif ! (set -x; env GO111MODULE=on go mod tidy); then + echo "ERROR: vendor check failed." + exit 1 + elif [ "$(git status --porcelain -- go.mod go.sum | wc -l)" -gt 0 ]; then + echo "ERROR: go module files *not* up-to-date, they did get modified by 'GO111MODULE=on go mod tidy':"; + git diff -- go.mod go.sum + exit 1 + elif [ -d vendor ]; then + if ! (set -x; env GO111MODULE=on go mod vendor); then + echo "ERROR: vendor check failed." + exit 1 + elif [ "$(git status --porcelain -- vendor | wc -l)" -gt 0 ]; then + echo "ERROR: vendor directory *not* up-to-date, it did get modified by 'GO111MODULE=on go mod vendor':" + git status -- vendor + git diff -- vendor + exit 1 + else + echo "Go dependencies and vendor directory up-to-date." + fi + else + echo "Go dependencies up-to-date." + fi +fi diff --git a/applications/nfsserver/resources/mklimdir.sh b/applications/nfsserver/resources/mklimdir.sh new file mode 100644 index 00000000..a0381b49 --- /dev/null +++ b/applications/nfsserver/resources/mklimdir.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +# Author: Zoran Sinnema +# Date: 14-11-2022 + + +# example of resizing a mounted pvc: +# dd if=/dev/zero bs=1MiB of=/export/ conv=notrunc oflag=append count= + +set -e + +print_usage(){ + +cat < -s + +-m directory +-s size in bytes +-mo mount only +-h this message + +Exit statuses: +0: +1: Invalid option +2: Missing argument +3: No args +4: root privillege required +EOF +} > /dev/stderr + +parse_args(){ + options=$(getopt -l "h,m:,s:,mountonly" -o "hm:s:" -a -- "$@") + eval set -- "$options" + while true + do + case "$1" in + -h) + print_usage; exit 0 ;; + -m) + shift; export mountpoint="$1" ;; + -s) + shift; export size="$1" ;; + --mountonly) + export mountonly=1 ;; + --) + shift + break;; + esac + shift + done +} + +unmount(){ + mountpoint=$1 + echo Unmount ${mountpoint} + for lodev in $(losetup -a|grep ${mountpoint}|awk '{print $1}'|cut -f 1 -d :); do + losetup -d ${lodev}|| true + done +} + +mkmount(){ + mountpoint=$1 + quota_fs=$2 + + unmount "${mountpoint}" + + echo Mounting ${quota_fs} on ${mountpoint} + i=$(losetup -f|cut -f 2 -d p) + lodev=/dev/loop${i} + + mknod -m666 ${lodev} b 7 ${i} 2>/dev/null || true + losetup -P ${lodev} ${quota_fs} + + rm -rf ${mountpoint} + mkdir ${mountpoint} + # chmod go+w ${mountpoint} + chmod 777 ${mountpoint} + mount ${lodev} ${mountpoint} + # chmod go+w ${mountpoint} + chmod 777 ${mountpoint} +} + +mklimfile(){ + quota_fs=$1 + size=$2 + + count_mb=$(( ${size}/1024/1024 + 1)) + + echo Create file ${quota_fs} size ${count_mb}Mb + truncate -s ${size} ${quota_fs} + #dd if=/dev/zero of=${quota_fs} bs=1M count=${count_mb} + yes | mkfs.ext4 ${quota_fs} +} + +main(){ + if [ $EUID -ne 0 ]; then + echo ">>> Please run the script with sudo/as root" > /dev/stderr + exit 4 + fi + + local mountpoint="" + local size=0 + local mountonly= + + parse_args "$@" + quota_fs=${mountpoint}.quota + + if [ -z ${mountonly} ]; then + # cleanup before creating the folder and quota file + bash -c "rmlimdir.sh -m ${mountpoint}" || true + mklimfile "${quota_fs}" "${size}" + fi + mkmount "${mountpoint}" "${quota_fs}" +} + +main "$@" diff --git a/applications/nfsserver/resources/pre-startup.sh b/applications/nfsserver/resources/pre-startup.sh new file mode 100644 index 00000000..c83b4534 --- /dev/null +++ b/applications/nfsserver/resources/pre-startup.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +source /usr/local/bin/remount.sh diff --git a/applications/nfsserver/resources/remount.sh b/applications/nfsserver/resources/remount.sh new file mode 100644 index 00000000..19dfbd10 --- /dev/null +++ b/applications/nfsserver/resources/remount.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# remount +losetup -D +for lodev in `losetup -a|grep deleted|awk '{print $1}'|cut -f 1 -d :` +do + losetup -d ${lodev} +done + +for qf in `ls /exports/*.quota` +do + mountpoint=${qf%.*} + mklimdir.sh -m ${mountpoint} --mountonly +done diff --git a/applications/nfsserver/resources/rmlimdir.sh b/applications/nfsserver/resources/rmlimdir.sh new file mode 100644 index 00000000..22749c5b --- /dev/null +++ b/applications/nfsserver/resources/rmlimdir.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# Author: Zoran Sinnema +# Date: 14-11-2022 + +print_usage(){ + +cat < + +-m directory +-h this message + +Exit statuses: +0: +1: Invalid option +2: Missing argument +3: No args +4: root privillege required +EOF +} > /dev/stderr + +parse_args(){ + set -x + + option_handler(){ + + case ${opt} in + m) mountpoint=${OPTARG} ;; + h) print_usage; exit 0 ;; + \?) echo ">>>Invalid option: -$OPTARG" > /dev/stderr; exit 1;; + \:) echo ">>>Missing argument to -${OPTARG}" > /dev/stderr; exit 2;; + esac + } + + local OPTIND opt + getopts "m:s:f:h" opt || { echo "No args passed">/dev/stderr;print_usage;exit 3;} + option_handler + while getopts "m:h" opt; do + option_handler + done + shift $((OPTIND-1)) + +} + + +main(){ + if [ $EUID -ne 0 ]; then + echo ">>> Please run the script with sudo/as root" > /dev/stderr + exit 4 + fi + + local mountpoint="" + + parse_args "$@" + quota_fs=${mountpoint}.quota + mountname=`basename ${mountpoint}` + + # find the loop back device and delete/unmount it + lodev=`losetup -a | grep ${mountname} | awk '{print $1}' | cut -f 1 -d :` || true + + losetup -d ${lodev} || true + umount -df ${mountpoint} || true + + rm -rf ${mountpoint} || true + mv ${quota_fs} ${mountpoint} || true + +} + +main "$@" diff --git a/applications/nfsserver/resources/run_nfs.sh b/applications/nfsserver/resources/run_nfs.sh new file mode 100644 index 00000000..d884b2dd --- /dev/null +++ b/applications/nfsserver/resources/run_nfs.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +# Copyright 2015 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +function start() +{ + # run pre startup script + bash -c "/usr/local/bin/pre-startup.sh" + bash -c "/usr/local/bin/start_provisioner.sh&" + + unset gid + # accept "-G gid" option + while getopts "G:" opt; do + case ${opt} in + G) gid=${OPTARG};; + esac + done + shift $(($OPTIND - 1)) + + # start rpcbind if it is not started yet + /usr/sbin/rpcinfo 127.0.0.1 > /dev/null; s=$? + if [ $s -ne 0 ]; then + echo "Starting rpcbind" + /usr/sbin/rpcbind -w + fi + + mount -t nfsd nfds /proc/fs/nfsd + + # -V 3: enable NFSv3 + /usr/sbin/rpc.mountd -N 2 -V 3 -V 4 + + /usr/sbin/exportfs -r + # -G 10 to reduce grace time to 10 seconds (the lowest allowed) + /usr/sbin/rpc.nfsd -G 10 -N 2 -V 3 -V 4 + /usr/sbin/rpc.statd --no-notify + echo "NFS started" +} + +function stop() +{ + echo "Stopping NFS" + + /usr/sbin/rpc.nfsd 0 + /usr/sbin/exportfs -au + /usr/sbin/exportfs -f + + kill $( pidof rpc.mountd ) + umount /proc/fs/nfsd + echo > /etc/exports + exit 0 +} + + +trap stop TERM + +start "$@" + +# Ugly hack to do nothing and wait for SIGTERM +while true; do + sleep 5 +done diff --git a/applications/nfsserver/resources/start_provisioner.sh b/applications/nfsserver/resources/start_provisioner.sh new file mode 100644 index 00000000..9f07c478 --- /dev/null +++ b/applications/nfsserver/resources/start_provisioner.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +echo Starting provisioner... +while true; do + /usr/local/bin/nfs-subdir-external-provisioner + sleep 1 +done +echo Starting provisioner done. diff --git a/applications/samples/Dockerfile b/applications/samples/Dockerfile index e7e5d6d9..405bf911 100644 --- a/applications/samples/Dockerfile +++ b/applications/samples/Dockerfile @@ -22,7 +22,8 @@ ENV PORT=8080 COPY backend/requirements.txt /usr/src/app/ -RUN pip3 install --no-cache-dir -r requirements.txt +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip3 install -r requirements.txt --prefer-binary COPY backend/ /usr/src/app diff --git a/applications/samples/backend/samples/controllers/resource_controller.py b/applications/samples/backend/samples/controllers/resource_controller.py index 27a6103f..3204708b 100644 --- a/applications/samples/backend/samples/controllers/resource_controller.py +++ b/applications/samples/backend/samples/controllers/resource_controller.py @@ -21,6 +21,11 @@ def create_sample_resource(sample_resource=None): # noqa: E501 sample_resource = SampleResource.from_dict(connexion.request.get_json()) # noqa: E501 except: return "Payload is not of type SampleResource", 400 + + # Create a file inside the nfs + with open("/mnt/myvolume/myfile", "w") as f: + print("test", file=f) + return resource_service.create_sample_resource(sample_resource), 201 diff --git a/applications/samples/deploy/values.yaml b/applications/samples/deploy/values.yaml index 366fbadc..6ba035a4 100644 --- a/applications/samples/deploy/values.yaml +++ b/applications/samples/deploy/values.yaml @@ -7,6 +7,12 @@ harness: port: 8080 auto: true deployment: + volume: + name: my-shared-volume + mountpath: /mnt/myvolume + auto: true + size: 10Mi + usenfs: false auto: true port: 8080 uri_role_mapping: @@ -37,6 +43,7 @@ harness: - events - accounts - common + - nfsserver build: - cloudharness-flask - cloudharness-frontend-build @@ -49,6 +56,7 @@ harness: dst: "/usr/src/app/important_config.yaml" secrets: asecret: "value" + test: unit: enabled: true diff --git a/applications/volumemanager/server/Dockerfile b/applications/volumemanager/server/Dockerfile index abcbb7e5..c098bfb5 100644 --- a/applications/volumemanager/server/Dockerfile +++ b/applications/volumemanager/server/Dockerfile @@ -9,7 +9,8 @@ ENV PORT=8080 COPY requirements.txt /usr/src/app/ -RUN pip3 install --no-cache-dir -r requirements.txt +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip3 install --no-cache-dir -r requirements.txt --prefer-binary COPY . /usr/src/app diff --git a/applications/workflows/server/Dockerfile b/applications/workflows/server/Dockerfile index ca28d34a..6d2efaf4 100644 --- a/applications/workflows/server/Dockerfile +++ b/applications/workflows/server/Dockerfile @@ -6,7 +6,8 @@ ENV MODULE_NAME=workflows_api COPY ./requirements.txt /usr/src/app/ -RUN pip3 install --no-cache-dir -r requirements.txt +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip3 install --no-cache-dir -r requirements.txt COPY . /usr/src/app diff --git a/applications/workflows/tasks/notify-queue/main.py b/applications/workflows/tasks/notify-queue/main.py index 800695cc..8c58da54 100644 --- a/applications/workflows/tasks/notify-queue/main.py +++ b/applications/workflows/tasks/notify-queue/main.py @@ -1,12 +1,14 @@ import sys +import os import logging logging.basicConfig(stream=sys.stdout, level=logging.INFO) -assert len(sys.argv) > 3, 'Not all arguments not specified. Cannot notify queue. Usage: [workflow status] [queue name] [payload]' +assert len( + sys.argv) > 3, 'Not all arguments not specified. Cannot notify queue. Usage: [workflow status] [queue name] [payload]' from cloudharness.workflows.utils import notify_queue queue = sys.argv[2] -message = {'status': sys.argv[1], 'payload': sys.argv[3]} +message = {'status': sys.argv[1], 'payload': sys.argv[3], 'workflow': os.getenv('CH_WORKFLOW_NAME')} notify_queue(queue, message) diff --git a/deployment-configuration/codefresh-build-template.yaml b/deployment-configuration/codefresh-build-template.yaml index c225d623..f3e4377c 100644 --- a/deployment-configuration/codefresh-build-template.yaml +++ b/deployment-configuration/codefresh-build-template.yaml @@ -1,10 +1,8 @@ type: build stage: build -tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} diff --git a/deployment-configuration/codefresh-template-dev.yaml b/deployment-configuration/codefresh-template-dev.yaml index fc450345..e11bcf6d 100644 --- a/deployment-configuration/codefresh-template-dev.yaml +++ b/deployment-configuration/codefresh-template-dev.yaml @@ -33,7 +33,9 @@ steps: working_directory: . commands: - bash cloud-harness/install.sh - - harness-deployment $PATHS -t ${{CF_BUILD_ID}} -d ${{DOMAIN}} -r ${{REGISTRY}} -rs ${{REGISTRY_SECRET}} -n ${{NAMESPACE}} -e $ENV $PARAMS + - harness-deployment $PATHS -d ${{DOMAIN}} -r ${{REGISTRY}} -rs ${{REGISTRY_SECRET}} -n ${{NAMESPACE}} --write-env -e $ENV $PARAMS + - cat deployment/.env >> ${{CF_VOLUME_PATH}}/env_vars_to_export + - cat ${{CF_VOLUME_PATH}}/env_vars_to_export prepare_deployment_view: commands: - 'helm template ./deployment/helm --debug -n ${{NAMESPACE}}' @@ -73,7 +75,7 @@ steps: kube_context: ${{CLUSTER_NAME}} namespace: ${{NAMESPACE}} chart_version: ${{CF_BUILD_ID}} - cmd_ps: --wait --timeout 600s + cmd_ps: --wait --timeout 600s --create-namespace custom_value_files: - ./deployment/helm/values.yaml build_test_images: diff --git a/deployment-configuration/codefresh-template-prod.yaml b/deployment-configuration/codefresh-template-prod.yaml index aa69f883..ce5ed02c 100644 --- a/deployment-configuration/codefresh-template-prod.yaml +++ b/deployment-configuration/codefresh-template-prod.yaml @@ -51,7 +51,7 @@ steps: kube_context: ${{CLUSTER_NAME}} namespace: ${{NAMESPACE}} chart_version: ${{DEPLOYMENT_TAG}} - cmd_ps: --wait --timeout 600s + cmd_ps: --wait --timeout 600s --create-namespace custom_value_files: - ./deployment/helm/values.yaml diff --git a/deployment-configuration/codefresh-template-stage.yaml b/deployment-configuration/codefresh-template-stage.yaml index d15187b5..ae6725b2 100644 --- a/deployment-configuration/codefresh-template-stage.yaml +++ b/deployment-configuration/codefresh-template-stage.yaml @@ -52,7 +52,7 @@ steps: kube_context: ${{CLUSTER_NAME}} namespace: ${{NAMESPACE}} chart_version: ${{DEPLOYMENT_TAG}} - cmd_ps: --wait --timeout 600s + cmd_ps: --wait --timeout 600s --create-namespace custom_value_files: - ./deployment/helm/values.yaml wait_deployment: diff --git a/deployment-configuration/codefresh-template-test.yaml b/deployment-configuration/codefresh-template-test.yaml index 1b04d326..bfaee7ad 100644 --- a/deployment-configuration/codefresh-template-test.yaml +++ b/deployment-configuration/codefresh-template-test.yaml @@ -32,7 +32,9 @@ steps: working_directory: . commands: - bash cloud-harness/install.sh - - harness-deployment $PATHS -n test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} -t ${{CF_BUILD_ID}} -d ${{CF_SHORT_REVISION}}.${{DOMAIN}} -r ${{REGISTRY}} -rs ${{REGISTRY_SECRET}} -e $ENV -N $PARAMS + - harness-deployment $PATHS -n test-${{NAMESPACE_BASENAME}} -d ${{DOMAIN}} -r ${{REGISTRY}} -rs ${{REGISTRY_SECRET}} -e $ENV --write-env -N $PARAMS + - cat deployment/.env >> ${{CF_VOLUME_PATH}}/env_vars_to_export + - cat ${{CF_VOLUME_PATH}}/env_vars_to_export prepare_deployment_view: commands: - "helm template ./deployment/helm --debug -n test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}}" @@ -60,13 +62,6 @@ steps: stage: unittest type: parallel steps: {} - prepare_cluster: - stage: deploy - image: codefresh/kubectl - fail_fast: false - commands: - - kubectl config use-context ${{CLUSTER_NAME}} - - kubectl create ns test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} deployment: stage: deploy type: helm @@ -75,11 +70,11 @@ steps: arguments: helm_version: 3.6.2 chart_name: deployment/helm - release_name: test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + release_name: test-${{NAMESPACE_BASENAME}} kube_context: ${{CLUSTER_NAME}} - namespace: test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} - chart_version: ${{CF_BUILD_ID}} - cmd_ps: --timeout 600s + namespace: test-${{NAMESPACE_BASENAME}} + chart_version: ${{CF_SHORT_REVISION}} + cmd_ps: --timeout 600s --create-namespace custom_value_files: - ./deployment/helm/values.yaml build_test_images: @@ -93,7 +88,7 @@ steps: image: codefresh/kubectl commands: - kubectl config use-context ${{CLUSTER_NAME}} - - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} tests_api: stage: qa title: Api tests @@ -128,7 +123,7 @@ steps: approval: type: pending-approval stage: qa - title: Approve with failed tests + title: Approve anyway and delete deployment description: The pipeline will fail after ${{WAIT_ON_FAIL}} minutes timeout: timeUnit: minutes @@ -138,20 +133,11 @@ steps: condition: all: error: '"${{FAILED}}" == "failed"' - wait_on_fail: ${{WAIT_ON_FAIL}} - dummy_end: - title: "Dummy step" - description: Without this, the on_finish hook is executed before the approval step - image: python:3.9.10 - stage: qa - when: - condition: - all: - error: '"${{FAILED}}" == "failed"' - wait_on_fail: ${{WAIT_ON_FAIL}} -hooks: - on_finish: + delete_deployment: + title: "Delete deployment" + description: The deployment is deleted at the end of the pipeline image: codefresh/kubectl + stage: qa commands: - kubectl config use-context ${{CLUSTER_NAME}} - - kubectl delete ns test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + - kubectl delete ns test-${{NAMESPACE_BASENAME}} diff --git a/deployment-configuration/helm/templates/auto-database.yaml b/deployment-configuration/helm/templates/auto-database.yaml index 2fb7c125..2deba7fe 100644 --- a/deployment-configuration/helm/templates/auto-database.yaml +++ b/deployment-configuration/helm/templates/auto-database.yaml @@ -31,6 +31,8 @@ kind: Deployment metadata: name: {{ .app.harness.database.name | quote }} namespace: {{ .root.Values.namespace }} + labels: + usesvolume: {{ .app.harness.database.name }} spec: replicas: 1 selector: @@ -41,7 +43,18 @@ spec: labels: app: {{ .app.harness.database.name | quote }} service: db + usesvolume: {{ .app.harness.database.name }} spec: + affinity: + podAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: usesvolume + operator: In + values: + - {{ .app.harness.database.name }} + topologyKey: "kubernetes.io/hostname" containers: - name: {{ .app.harness.database.name | quote }} imagePullPolicy: IfNotPresent @@ -66,10 +79,19 @@ spec: mountPath: {{ (printf "%s/%s/%s" .root.Values.backup.dir .app.harness.database.type .app.harness.database.name) | quote }} readOnly: true {{- end }} + {{- if eq .app.harness.database.type "postgres" }} + - mountPath: /dev/shm + name: dshm + {{- end }} volumes: - name: {{ .app.harness.database.name | quote }} persistentVolumeClaim: claimName: {{ .app.harness.database.name | quote }} + {{- if eq .app.harness.database.type "postgres" }} + - emptyDir: + medium: Memory + name: dshm + {{- end }} {{- if .root.Values.backup.active }} - name: "db-backups" persistentVolumeClaim: @@ -100,16 +122,18 @@ spec: --- {{ end }} {{- range $app := .Values.apps }} - {{- if $app.harness.database.auto }} - {{ include "deploy_utils.database" (dict "root" $ "app" $app) }} - {{- end }} - {{- range $subapp := $app }} - {{- if contains "map" (typeOf $subapp) }} - {{- if hasKey $subapp "harness"}} - {{- if and (hasKey $subapp.harness "database") $subapp.harness.database.auto }} - {{ include "deploy_utils.database" (dict "root" $ "app" $subapp) }} - {{- end }} - {{- end }} - {{- end }} - {{- end }} - {{- end }} + {{- if $app.harness.database }} + {{- if $app.harness.database.auto }} + {{ include "deploy_utils.database" (dict "root" $ "app" $app) }} + {{- end }} + {{- range $subapp := $app }} + {{- if contains "map" (typeOf $subapp) }} + {{- if hasKey $subapp "harness"}} + {{- if and (hasKey $subapp.harness "database") $subapp.harness.database.auto }} + {{ include "deploy_utils.database" (dict "root" $ "app" $subapp) }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} \ No newline at end of file diff --git a/deployment-configuration/helm/templates/auto-deployments.yaml b/deployment-configuration/helm/templates/auto-deployments.yaml index 9c2e612a..23d4f61c 100644 --- a/deployment-configuration/helm/templates/auto-deployments.yaml +++ b/deployment-configuration/helm/templates/auto-deployments.yaml @@ -35,6 +35,7 @@ spec: - name: {{ .root.Values.registry.secret }} {{- end }} {{- if and .app.harness.deployment.volume }} + {{- if or (not (hasKey .app.harness.deployment.volume "usenfs")) (not .app.harness.deployment.volume.usenfs) }} affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -46,6 +47,7 @@ spec: - {{ .app.harness.deployment.volume.name }} topologyKey: "kubernetes.io/hostname" {{- end }} + {{- end }} containers: - name: {{ .app.harness.deployment.name| default "cloudharness-docs" | quote }} image: {{ .app.harness.deployment.image }} @@ -110,7 +112,7 @@ spec: mountPath: /opt/cloudharness/resources/auth readOnly: true {{- end }} - {{- if .app.harness.deployment.volume }} + {{- if .app.harness.deployment.volume }} - name: {{ .app.harness.deployment.volume.name }} mountPath: {{ .app.harness.deployment.volume.mountpath }} readOnly: {{ .app.harness.deployment.volume.readonly | default false }} diff --git a/deployment-configuration/helm/templates/auto-volumes.yaml b/deployment-configuration/helm/templates/auto-volumes.yaml index c6d220e9..8e217aeb 100644 --- a/deployment-configuration/helm/templates/auto-volumes.yaml +++ b/deployment-configuration/helm/templates/auto-volumes.yaml @@ -7,12 +7,18 @@ metadata: labels: app: {{ .app.harness.deployment.name| quote }} spec: - storageClassName: standard - accessModes: - - ReadWriteOnce resources: requests: storage: {{ .app.harness.deployment.volume.size }} + + accessModes: +{{- if or (not (hasKey .app.harness.deployment.volume "usenfs")) (not .app.harness.deployment.volume.usenfs) }} + - ReadWriteOnce + storageClassName: standard +{{- else }} + - ReadWriteMany + storageClassName: {{ printf "%s-%s" .root.Values.namespace .root.Values.apps.nfsserver.storageClass.name }} +{{- end }} {{- end }} --- {{- end }} diff --git a/deployment-configuration/helm/templates/certs/letsencrypt.yaml b/deployment-configuration/helm/templates/certs/letsencrypt.yaml index 67765b99..be45ac34 100644 --- a/deployment-configuration/helm/templates/certs/letsencrypt.yaml +++ b/deployment-configuration/helm/templates/certs/letsencrypt.yaml @@ -1,6 +1,6 @@ {{- if and (not .Values.local) (not (not .Values.tls)) }} -apiVersion: cert-manager.io/v1alpha2 -kind: ClusterIssuer +apiVersion: cert-manager.io/v1 +kind: Issuer metadata: name: {{ printf "%s-%s" "letsencrypt" .Values.namespace }} spec: @@ -8,9 +8,9 @@ spec: server: https://acme-v02.api.letsencrypt.org/directory email: {{ .Values.ingress.letsencrypt.email }} privateKeySecretRef: - name: tls-secret + name: tls-secret-issuer solvers: - http01: ingress: - ingressName: cloudharness-ingress + class: nginx {{ end }} diff --git a/deployment-configuration/helm/templates/ingress.yaml b/deployment-configuration/helm/templates/ingress.yaml index 299a2469..af59d0a4 100644 --- a/deployment-configuration/helm/templates/ingress.yaml +++ b/deployment-configuration/helm/templates/ingress.yaml @@ -35,7 +35,7 @@ metadata: kubernetes.io/ingress.class: nginx {{- if and (not .Values.local) $tls }} kubernetes.io/tls-acme: 'true' - cert-manager.io/cluster-issuer: {{ printf "%s-%s" "letsencrypt" .Values.namespace }} + cert-manager.io/issuer: {{ printf "%s-%s" "letsencrypt" .Values.namespace }} {{- end }} nginx.ingress.kubernetes.io/ssl-redirect: {{ (and $tls .Values.ingress.ssl_redirect) | quote }} nginx.ingress.kubernetes.io/proxy-body-size: '250m' diff --git a/deployment-configuration/value-template.yaml b/deployment-configuration/value-template.yaml index 3dba8211..16c00b3a 100644 --- a/deployment-configuration/value-template.yaml +++ b/deployment-configuration/value-template.yaml @@ -19,7 +19,7 @@ harness: uri_role_mapping: - uri: /* roles: - - administrator + - administrator - uri: /api/openapi.json white-listed: true # -- Defines reference deployment parameters. Values maps to k8s spec @@ -34,6 +34,8 @@ harness: name: # -- Deployment port. port: 8080 + # -- volume specification + volume: # -- Deployment resources. resources: requests: @@ -54,6 +56,8 @@ harness: secrets: # -- Specify which services this application uses in the frontend to create proxy ingresses. e.g. - name: mnp-checkout use_services: [] + # -- enabled sentry for automated error report + sentry: false # -- Reference database specs database: # -- When true, enables automatic database deployment @@ -120,4 +124,4 @@ harness: enabled: false smoketest: true ignoreConsoleErrors: false - ignoreRequestErrors: false \ No newline at end of file + ignoreRequestErrors: false diff --git a/deployment/Dockerfile b/deployment/Dockerfile new file mode 100644 index 00000000..05f1e561 --- /dev/null +++ b/deployment/Dockerfile @@ -0,0 +1,2 @@ +FROM codefresh/cf-docker-puller +RUN docker images diff --git a/deployment/codefresh-test-local.yaml b/deployment/codefresh-test-local.yaml new file mode 100644 index 00000000..612e214b --- /dev/null +++ b/deployment/codefresh-test-local.yaml @@ -0,0 +1,556 @@ +version: '1.0' +stages: +- prepare +- build +- unittest +- deploy +- qa +steps: + main_clone: + title: Clone main repository + type: git-clone + stage: prepare + repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' + revision: '${{CF_BRANCH}}' + git: github + post_main_clone: + title: Post main clone + type: parallel + stage: prepare + steps: + - title: Cloning cloud-harness repository... + type: git-clone + stage: prepare + repo: https://github.com/MetaCell/cloud-harness.git + revision: '${{CLOUDHARNESS_BRANCH}}' + working_directory: . + git: github + prepare_deployment: + title: Prepare helm chart + image: python:3.9.10 + stage: prepare + working_directory: . + commands: + - bash cloud-harness/install.sh + - harness-deployment . -n test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + -d ${{CF_SHORT_REVISION}}.${{DOMAIN}} -r ${{REGISTRY}} -rs ${{REGISTRY_SECRET}} + -e test-local --write-env -N -i samples + - cat deployment/.env >> ${{CF_VOLUME_PATH}}/env_vars_to_export + - cat ${{CF_VOLUME_PATH}}/env_vars_to_export + prepare_deployment_view: + commands: + - helm template ./deployment/helm --debug -n test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + environment: + - ACTION=auth + - KUBE_CONTEXT=test-${{CF_BUILD_ID}} + image: codefresh/cfstep-helm:3.6.2 + stage: prepare + title: View helm chart + build_base_images: + title: Build base images + type: parallel + stage: build + steps: + cloudharness-base: + type: build + stage: build + dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + image_name: cloudharness/cloudharness-base + title: Cloudharness base + working_directory: ./. + tag: '${{CLOUDHARNESS_BASE_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') + == false + cloudharness-frontend-build: + type: build + stage: build + dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + image_name: cloudharness/cloudharness-frontend-build + title: Cloudharness frontend build + working_directory: ./. + tag: '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true + forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false + build_static_images: + title: Build static images + type: parallel + stage: build + steps: + cloudharness-flask: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloudharness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask + tag: '${{CLOUDHARNESS_FLASK_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + == false + build_application_images: + type: parallel + stage: build + steps: + nfsserver: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + image_name: cloudharness/nfsserver + title: Nfsserver + working_directory: ./applications/nfsserver + tag: '${{NFSSERVER_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{NFSSERVER_TAG_EXISTS}}', '{{NFSSERVER_TAG_EXISTS}}') + == true + forceNoCache: includes('${{NFSSERVER_TAG_FORCE_BUILD}}', '{{NFSSERVER_TAG_FORCE_BUILD}}') + == false + accounts: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + image_name: cloudharness/accounts + title: Accounts + working_directory: ./applications/accounts + tag: '${{ACCOUNTS_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{ACCOUNTS_TAG_EXISTS}}', '{{ACCOUNTS_TAG_EXISTS}}') + == true + forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') + == false + samples: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloudharness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} + - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloudharness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} + image_name: cloudharness/samples + title: Samples + working_directory: ./applications/samples + tag: '${{SAMPLES_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') + == false + samples-print-file: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloudharness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file + tag: '${{SAMPLES_PRINT_FILE_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + == false + samples-secret: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloudharness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret + tag: '${{SAMPLES_SECRET_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + == false + samples-sum: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloudharness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum + tag: '${{SAMPLES_SUM_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + == false + common: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloudharness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} + image_name: cloudharness/common + title: Common + working_directory: ./applications/common/server + tag: '${{COMMON_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + == true + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + == false + workflows-send-result-event: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloudharness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event + tag: '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false + workflows-extract-download: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + image_name: cloudharness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download + tag: '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + workflows-notify-queue: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloudharness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue + tag: '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + workflows: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloudharness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} + image_name: cloudharness/workflows + title: Workflows + working_directory: ./applications/workflows/server + tag: '${{WORKFLOWS_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + == true + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + == false + tests_unit: + stage: unittest + type: parallel + steps: + samples_ut: + title: Unit tests for samples + commands: + - pytest /usr/src/app/samples/test + image: '${{REGISTRY}}/cloudharness/samples:${{SAMPLES_TAG}}' + deployment: + stage: deploy + type: helm + working_directory: ./${{CF_REPO_NAME}} + title: Installing chart + arguments: + helm_version: 3.6.2 + chart_name: deployment/helm + release_name: test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + kube_context: '${{CLUSTER_NAME}}' + namespace: test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + chart_version: '${{CF_BUILD_ID}}' + cmd_ps: --timeout 600s --create-namespace + custom_value_files: + - ./deployment/helm/values.yaml + custom_values: + - apps_samples_harness_secrets_asecret=${{ASECRET}} + build_test_images: + title: Build test images + type: parallel + stage: qa + steps: + test-e2e: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + image_name: cloudharness/test-e2e + title: Test e2e + working_directory: ./test/test-e2e + tag: '${{TEST_E2E_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') + == false + test-api: + type: build + stage: build + dockerfile: test/test-api/Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} + image_name: cloudharness/test-api + title: Test api + working_directory: ./. + tag: '${{TEST_API_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + == false + wait_deployment: + stage: qa + title: Wait deployment to be ready + image: codefresh/kubectl + commands: + - kubectl config use-context ${{CLUSTER_NAME}} + - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + - kubectl rollout status deployment/accounts + - kubectl rollout status deployment/samples + - kubectl rollout status deployment/common + - kubectl rollout status deployment/workflows + - sleep 60 + tests_api: + stage: qa + title: Api tests + working_directory: /home/test + image: '${{REGISTRY}}/cloudharness/test-api:${{TEST_API_TAG}}' + fail_fast: false + commands: + - echo $APP_NAME + scale: + samples_api_test: + title: samples api test + volumes: + - '${{CF_REPO_NAME}}/applications/samples:/home/test' + - '${{CF_REPO_NAME}}/deployment/helm/values.yaml:/opt/cloudharness/resources/allvalues.yaml' + environment: + - APP_URL=https://samples.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api + - USERNAME=sample@testuser.com + - PASSWORD=test + commands: + - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url + https://samples.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api -c all --skip-deprecated-operations + --hypothesis-suppress-health-check=too_slow --hypothesis-deadline=180000 + --request-timeout=180000 --hypothesis-max-examples=2 --show-errors-tracebacks + - pytest -v test/api + common_api_test: + title: common api test + volumes: + - '${{CF_REPO_NAME}}/applications/common:/home/test' + - '${{CF_REPO_NAME}}/deployment/helm/values.yaml:/opt/cloudharness/resources/allvalues.yaml' + environment: + - APP_URL=https://common.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api + commands: + - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url + https://common.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api -c all + workflows_api_test: + title: workflows api test + volumes: + - '${{CF_REPO_NAME}}/applications/workflows:/home/test' + - '${{CF_REPO_NAME}}/deployment/helm/values.yaml:/opt/cloudharness/resources/allvalues.yaml' + environment: + - APP_URL=https://workflows.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api + commands: + - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url + https://workflows.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api -c all + hooks: + on_fail: + exec: + image: alpine + commands: + - cf_export FAILED=failed + tests_e2e: + stage: qa + title: End to end tests + working_directory: /home/test + image: '${{REGISTRY}}/cloudharness/test-e2e:${{TEST_E2E_TAG}}' + fail_fast: false + commands: + - yarn test + scale: + samples_e2e_test: + title: samples e2e test + volumes: + - '${{CF_REPO_NAME}}/applications/samples/test/e2e:/home/test/__tests__/samples' + environment: + - APP_URL=https://samples.${{CF_SHORT_REVISION}}.${{DOMAIN}} + - USERNAME=sample@testuser.com + - PASSWORD=test + hooks: + on_fail: + exec: + image: alpine + commands: + - cf_export FAILED=failed + approval: + type: pending-approval + stage: qa + title: Approve with failed tests + description: The pipeline will fail after ${{WAIT_ON_FAIL}} minutes + timeout: + timeUnit: minutes + duration: '${{WAIT_ON_FAIL}}' + finalState: denied + when: + condition: + all: + error: '"${{FAILED}}" == "failed"' + wait_on_fail: '${{WAIT_ON_FAIL}}' + dummy_end: + title: Dummy step + description: Without this, the on_finish hook is executed before the approval + step + image: python:3.9.10 + stage: qa + when: + condition: + all: + error: '"${{FAILED}}" == "failed"' + wait_on_fail: '${{WAIT_ON_FAIL}}' +hooks: + on_finish: + image: codefresh/kubectl + commands: + - kubectl config use-context ${{CLUSTER_NAME}} + - kubectl delete ns test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 10bb0a6e..ff7a88af 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -32,9 +32,10 @@ steps: working_directory: . commands: - bash cloud-harness/install.sh - - harness-deployment . -n test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} - -t ${{CF_BUILD_ID}} -d ${{CF_SHORT_REVISION}}.${{DOMAIN}} -r ${{REGISTRY}} -rs - ${{REGISTRY_SECRET}} -e test -N -i samples + - harness-deployment . -n test-${{NAMESPACE_BASENAME}} -d ${{DOMAIN}} -r ${{REGISTRY}} + -rs ${{REGISTRY_SECRET}} -e test --write-env -N -i samples + - cat deployment/.env >> ${{CF_VOLUME_PATH}}/env_vars_to_export + - cat ${{CF_VOLUME_PATH}}/env_vars_to_export prepare_deployment_view: commands: - helm template ./deployment/helm --debug -n test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} @@ -52,33 +53,45 @@ steps: cloudharness-base: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: infrastructure/base-images/cloudharness-base/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ image_name: cloudharness/cloudharness-base title: Cloudharness base working_directory: ./. + tag: '${{CLOUDHARNESS_BASE_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_BASE_TAG_EXISTS}}', '{{CLOUDHARNESS_BASE_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') + == false cloudharness-frontend-build: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ image_name: cloudharness/cloudharness-frontend-build title: Cloudharness frontend build working_directory: ./. + tag: '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true + forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false build_static_images: title: Build static images type: parallel @@ -87,197 +100,269 @@ steps: cloudharness-flask: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} image_name: cloudharness/cloudharness-flask title: Cloudharness flask working_directory: ./infrastructure/common-images/cloudharness-flask + tag: '${{CLOUDHARNESS_FLASK_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + == false build_application_images: type: parallel stage: build steps: + nfsserver: + type: build + stage: build + dockerfile: Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - DOMAIN=${{DOMAIN}} + - NOCACHE=${{CF_BUILD_ID}} + - REGISTRY=${{REGISTRY}}/cloudharness/ + image_name: cloudharness/nfsserver + title: Nfsserver + working_directory: ./applications/nfsserver + tag: '${{NFSSERVER_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{NFSSERVER_TAG_EXISTS}}', '{{NFSSERVER_TAG_EXISTS}}') + == true + forceNoCache: includes('${{NFSSERVER_TAG_FORCE_BUILD}}', '{{NFSSERVER_TAG_FORCE_BUILD}}') + == false accounts: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ image_name: cloudharness/accounts title: Accounts working_directory: ./applications/accounts + tag: '${{ACCOUNTS_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{ACCOUNTS_TAG_EXISTS}}', '{{ACCOUNTS_TAG_EXISTS}}') + == true + forceNoCache: includes('${{ACCOUNTS_TAG_FORCE_BUILD}}', '{{ACCOUNTS_TAG_FORCE_BUILD}}') + == false samples: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ - - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloudharness/cloudharness-frontend-build:${{CF_BUILD_ID}} - - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloudharness/cloudharness-flask:${{CF_BUILD_ID}} + - CLOUDHARNESS_FRONTEND_BUILD=${{REGISTRY}}/cloudharness/cloudharness-frontend-build:${{CLOUDHARNESS_FRONTEND_BUILD_TAG}} + - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloudharness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} image_name: cloudharness/samples title: Samples working_directory: ./applications/samples + tag: '${{SAMPLES_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{SAMPLES_TAG_EXISTS}}', '{{SAMPLES_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') + == false samples-print-file: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} image_name: cloudharness/samples-print-file title: Samples print file working_directory: ./applications/samples/tasks/print-file + tag: '${{SAMPLES_PRINT_FILE_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + == false samples-secret: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} image_name: cloudharness/samples-secret title: Samples secret working_directory: ./applications/samples/tasks/secret + tag: '${{SAMPLES_SECRET_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') + == false samples-sum: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} image_name: cloudharness/samples-sum title: Samples sum working_directory: ./applications/samples/tasks/sum + tag: '${{SAMPLES_SUM_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') + == true + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') + == false common: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ - - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloudharness/cloudharness-flask:${{CF_BUILD_ID}} + - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloudharness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} image_name: cloudharness/common title: Common working_directory: ./applications/common/server - events: - type: build - stage: build - tag: '${{CF_BUILD_ID}}' - dockerfile: Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - TAG=${{CF_BUILD_ID}} - - DOMAIN=${{DOMAIN}} - - NOCACHE=${{CF_BUILD_ID}} - - REGISTRY=${{REGISTRY}}/cloudharness/ - image_name: cloudharness/events - title: Events - working_directory: ./applications/events + tag: '${{COMMON_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + == true + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + == false workflows-send-result-event: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} image_name: cloudharness/workflows-send-result-event title: Workflows send result event working_directory: ./applications/workflows/tasks/send-result-event + tag: '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false workflows-extract-download: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ image_name: cloudharness/workflows-extract-download title: Workflows extract download working_directory: ./applications/workflows/tasks/extract-download + tag: '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false workflows-notify-queue: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} image_name: cloudharness/workflows-notify-queue title: Workflows notify queue working_directory: ./applications/workflows/tasks/notify-queue + tag: '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false workflows: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ - - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloudharness/cloudharness-flask:${{CF_BUILD_ID}} + - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloudharness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} image_name: cloudharness/workflows title: Workflows working_directory: ./applications/workflows/server + tag: '${{WORKFLOWS_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + == true + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + == false tests_unit: stage: unittest type: parallel @@ -286,14 +371,7 @@ steps: title: Unit tests for samples commands: - pytest /usr/src/app/samples/test - image: '${{samples}}' - prepare_cluster: - stage: deploy - image: codefresh/kubectl - fail_fast: false - commands: - - kubectl config use-context ${{CLUSTER_NAME}} - - kubectl create ns test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + image: '${{REGISTRY}}/cloudharness/samples:${{SAMPLES_TAG}}' deployment: stage: deploy type: helm @@ -302,11 +380,11 @@ steps: arguments: helm_version: 3.6.2 chart_name: deployment/helm - release_name: test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + release_name: test-${{NAMESPACE_BASENAME}} kube_context: '${{CLUSTER_NAME}}' - namespace: test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} - chart_version: '${{CF_BUILD_ID}}' - cmd_ps: --timeout 600s + namespace: test-${{NAMESPACE_BASENAME}} + chart_version: '${{CF_SHORT_REVISION}}' + cmd_ps: --timeout 600s --create-namespace custom_value_files: - ./deployment/helm/values.yaml custom_values: @@ -319,88 +397,104 @@ steps: test-e2e: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ image_name: cloudharness/test-e2e title: Test e2e working_directory: ./test/test-e2e + tag: '${{TEST_E2E_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{TEST_E2E_TAG_EXISTS}}', '{{TEST_E2E_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_E2E_TAG_FORCE_BUILD}}', '{{TEST_E2E_TAG_FORCE_BUILD}}') + == false test-api: type: build stage: build - tag: '${{CF_BUILD_ID}}' dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - - TAG=${{CF_BUILD_ID}} - DOMAIN=${{DOMAIN}} - NOCACHE=${{CF_BUILD_ID}} - REGISTRY=${{REGISTRY}}/cloudharness/ - - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CF_BUILD_ID}} + - CLOUDHARNESS_BASE=${{REGISTRY}}/cloudharness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} image_name: cloudharness/test-api title: Test api working_directory: ./. + tag: '${{TEST_API_TAG}}' + when: + condition: + any: + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + == true + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + == false wait_deployment: stage: qa title: Wait deployment to be ready image: codefresh/kubectl commands: - kubectl config use-context ${{CLUSTER_NAME}} - - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - kubectl rollout status deployment/accounts + - kubectl rollout status deployment/argo-server-gk - kubectl rollout status deployment/samples + - kubectl rollout status deployment/samples-gk - kubectl rollout status deployment/common - - kubectl rollout status deployment/events - kubectl rollout status deployment/workflows - sleep 60 tests_api: stage: qa title: Api tests working_directory: /home/test - image: '${{test-api}}' + image: '${{REGISTRY}}/cloudharness/test-api:${{TEST_API_TAG}}' fail_fast: false commands: - echo $APP_NAME scale: samples_api_test: + title: samples api test volumes: - '${{CF_REPO_NAME}}/applications/samples:/home/test' - '${{CF_REPO_NAME}}/deployment/helm/values.yaml:/opt/cloudharness/resources/allvalues.yaml' environment: - - APP_URL=https://samples.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api + - APP_URL=https://samples.${{DOMAIN}}/api - USERNAME=sample@testuser.com - PASSWORD=test commands: - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url - https://samples.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api -c all --skip-deprecated-operations - --hypothesis-suppress-health-check=too_slow --hypothesis-deadline=180000 - --request-timeout=180000 --hypothesis-max-examples=2 --show-errors-tracebacks + https://samples.${{DOMAIN}}/api -c all --skip-deprecated-operations --hypothesis-suppress-health-check=too_slow + --hypothesis-deadline=180000 --request-timeout=180000 --hypothesis-max-examples=2 + --show-errors-tracebacks - pytest -v test/api common_api_test: + title: common api test volumes: - '${{CF_REPO_NAME}}/applications/common:/home/test' - '${{CF_REPO_NAME}}/deployment/helm/values.yaml:/opt/cloudharness/resources/allvalues.yaml' environment: - - APP_URL=https://common.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api + - APP_URL=https://common.${{DOMAIN}}/api commands: - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url - https://common.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api -c all + https://common.${{DOMAIN}}/api -c all workflows_api_test: + title: workflows api test volumes: - '${{CF_REPO_NAME}}/applications/workflows:/home/test' - '${{CF_REPO_NAME}}/deployment/helm/values.yaml:/opt/cloudharness/resources/allvalues.yaml' environment: - - APP_URL=https://workflows.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api + - APP_URL=https://workflows.${{DOMAIN}}/api commands: - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url - https://workflows.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api -c all + https://workflows.${{DOMAIN}}/api -c all hooks: on_fail: exec: @@ -411,16 +505,17 @@ steps: stage: qa title: End to end tests working_directory: /home/test - image: '${{test-e2e}}' + image: '${{REGISTRY}}/cloudharness/test-e2e:${{TEST_E2E_TAG}}' fail_fast: false commands: - yarn test scale: samples_e2e_test: + title: samples e2e test volumes: - '${{CF_REPO_NAME}}/applications/samples/test/e2e:/home/test/__tests__/samples' environment: - - APP_URL=https://samples.${{CF_SHORT_REVISION}}.${{DOMAIN}} + - APP_URL=https://samples.${{DOMAIN}} - USERNAME=sample@testuser.com - PASSWORD=test hooks: @@ -432,7 +527,7 @@ steps: approval: type: pending-approval stage: qa - title: Approve with failed tests + title: Approve anyway and delete deployment description: The pipeline will fail after ${{WAIT_ON_FAIL}} minutes timeout: timeUnit: minutes @@ -442,21 +537,11 @@ steps: condition: all: error: '"${{FAILED}}" == "failed"' - wait_on_fail: '${{WAIT_ON_FAIL}}' - dummy_end: - title: Dummy step - description: Without this, the on_finish hook is executed before the approval - step - image: python:3.9.10 - stage: qa - when: - condition: - all: - error: '"${{FAILED}}" == "failed"' - wait_on_fail: '${{WAIT_ON_FAIL}}' -hooks: - on_finish: + delete_deployment: + title: Delete deployment + description: The deployment is deleted at the end of the pipeline image: codefresh/kubectl + stage: qa commands: - kubectl config use-context ${{CLUSTER_NAME}} - - kubectl delete ns test-${{NAMESPACE_BASENAME}}-${{CF_SHORT_REVISION}} + - kubectl delete ns test-${{NAMESPACE_BASENAME}} diff --git a/docs/applications/development/workflows-api.md b/docs/applications/development/workflows-api.md index 5ccc50e2..a766b42e 100644 --- a/docs/applications/development/workflows-api.md +++ b/docs/applications/development/workflows-api.md @@ -162,7 +162,16 @@ op = operations.PipelineOperation('my-op-gpu-', [my_task]) ## Pod execution context / affinity -Affinity is set through the +The execution context is set allows to group pods in the same node (see [here](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)). +This is important in particular when pods are sharing node resources like ReadWriteOnce volumes within a parallel execution or with other deployments in the cluster. +The execution context sets the affinity and the metadata attributes so that all pods with the same context +run in the same node. +By default affinity is added to cover shared volumes (`usesvolume` label). + +> Note: if using ReadWriteMany volumes (e.g. through a NFS) the affinity is not needed. To explicitly state the +> volume is ReadWriteMany specify the "rwx" type like `"myvolume:/my/path:rwx"` + +Additional affinity is set through the PodExecutionContext specification. ```Python def f(): @@ -173,13 +182,6 @@ op = operations.ParallelOperation('test-parallel-op-', (tasks.PythonTask('p1', f ``` - -The execution context is set allows to group pods in the same node (see [here](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)). -This is important in particular when pods are sharing node resources like ReadWriteOnce volumes within a parallel execution or with other deployments in the cluster. -The execution context sets the affinity and the metadata attributes so that all pods with the same context -run in the same node. - - Is is also possible to specify a tuple or list for multiple affinities like: ```Python diff --git a/docs/applications/volumes.md b/docs/applications/volumes.md index 3dcee74a..0764fc6a 100644 --- a/docs/applications/volumes.md +++ b/docs/applications/volumes.md @@ -1,16 +1,15 @@ # Application Volume Application Volumes are defined at `harness.deployment.volume`. -At the time of writing this documentation CloudHarness supports only one volume per deployment. +CloudHarness supports only one volume per deployment. The Application Volume will be mounted in the container at a specific path at **deployment** time. -A Volume can be mounted by one or more pods (shared Volume). Be careful: only one of the deployments -should create the Volume, the other deployment should only mount it. +## Auto volume creation and mount This can be established through setting the `auto` attribute (default false) of the Volume object -auto: true --> auto create the volume and mount -auto: false --> only mount the volume +- `auto: true` --> auto create the volume and mount +- `auto: false` --> only mount the volume Shared volumes are handy when you have e.g. 2 deployments for one app: frontend & backend deployment in such a case it could be helpfull that the frontend can access files stored by the backend. @@ -24,8 +23,41 @@ harness: deployment: ... volume: - name: myFirstVolume + name: my-first-volume mountpath: /usr/src/app/myvolume auto: true size: 5Gi + usenfs: false +``` + +## Shared volumes +A Volume can be mounted by one or more pods (shared Volume). Be careful: only one of the deployments +should create the Volume, the other deployment should only mount it. + +Cloudharness uses the `standard` StorageClass for the volume and ReadWriteOnce +mount strategy. +In order to support volume sharing affinity rules are added so that all pods using +the same volume end up in the same node. +This strategy works for basic use cases but can easily cause deadlocks if more than +one node is available on the cluster and other affinity rules or taints are present. + +A better support for volume sharing is achieved by using a Network File System (NFS). +In order to use the nfs, the NFS must be added to the deployment (e.g. as a dependency and `usenfs` must be set to true. + ``` +harness: + ... + dependencies: + ... + hard: + - nfsserver + ... + deployment: + ... + volume: + name: my-shared-volume + mountpath: /usr/src/app/myvolume + auto: true + size: 5Gi + usenfs: true +``` \ No newline at end of file diff --git a/docs/build-deploy/ci-cd/README.md b/docs/build-deploy/ci-cd/README.md new file mode 100644 index 00000000..77b59024 --- /dev/null +++ b/docs/build-deploy/ci-cd/README.md @@ -0,0 +1,20 @@ +# CI/CD with CloudHarness + +CloudHarness supports continuous deployment natively by creating the Helm Chart for you and with a few +ways to build containers. + +## CI/CD with Skaffold + +[Skaffold](https://skaffold.dev/) is a command line tool that simplifies build and deployment on a Kubernetes cluster. The configuration as `skaffold.yaml` file is created when running +`harness-deployment`. + +All you need to to is: +- Configure the Kubernetes cluster in your local shell (e.g. `gcloud init` on Google Cloud) +- Configure the local Docker to be able to push to the remote registry +- Create the deployment specifying the registry and remote domain -- `harness-deployment ... -r myregistry -d mydomain` +- Run `skaffold build` +- Run `skaffold run` + +## CI/CD with Codefresh + +[Codefresh](https://codefresh.io/) is a nice platform for CI/CD see details in the [dedicated document](./codefresh.md). \ No newline at end of file diff --git a/docs/build-deploy/ci-cd/codefresh.md b/docs/build-deploy/ci-cd/codefresh.md new file mode 100644 index 00000000..3e691334 --- /dev/null +++ b/docs/build-deploy/ci-cd/codefresh.md @@ -0,0 +1,88 @@ +# Continuous deployment with Codefresh + +Codefresh pipelines are generated as `deployment/codefresh-[ENV].yaml`. +These files can be loaded from codefresh as documented [here](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/pipelines/). + +The pipeline will take care of building the images from the source code and deploy the helm chart. +Log in to codefresh and run the pipeline associated to the repository. + +- To setup a new dev pipeline, indicate the remote yaml path `./deployment/codefresh-dev.yaml` +- To setup a new production pipeline, indicate the remote yaml path `./deployment/codefresh-prod.yaml` + +## Preconfigured pipelines + +- [codefresh-dev.yaml](../../../deployment-configuration/codefresh-template-dev.yaml). The main CI/CD pipeline. Includes build, deployment, testing and final tagging and push. Tagging and push is made upon approval. +- [codefresh-prod.yaml](../../../deployment-configuration/codefresh-template-prod.yaml). The Production deployment pipeline. The main idea is to reuse the builds tagged in the dev pipeline with specific configurations for the production environment. +- [codefresh-stage.yaml](../../../deployment-configuration/codefresh-template-stage.yaml). The Staging deployment pipeline. The main idea is to reuse the builds tagged in the dev pipeline with specific configurations for the production environment. +- [codefresh-test.yaml](../../../deployment-configuration/codefresh-template-test.yaml). The Testing pipeline. It creates a new deployment from the current codebase and runs all tests. The deployment is deleted after the completion of the tests. See also the [testing documentation](../../testing.md). + +The templates for the predefined pipeline are in the [deployment-configuration](../../../deployment-configuration) directory. + +## Variables + +Variables are used to customize the deployment + +### General variables +- **CLOUDHARNESS_BRANCH**. Specifies the cloudharness branch or tag to use. + +### Build and deploy variables +- **DOMAIN*** - The deployment's base domain +- **CLUSTER_NAME*** - The cluster context name as configured in Codefresh +- **NAMESPACE*** - The Kubernetes namespace to use +- **REGISTRY*** - The base registry address +- **CODEFRESH_REGISTRY*** - the name of the registry as configured inside Codefresh +- **REGISTRY_SECRET** - define a secret to push on the registry (not mandatory) + +### Test variables + +- **SKIP_TESTS** - if defined, skips all tests + +### Releasing variables + +- **REGISTRY_PUBLISH_URL**. The base url of the registry to push to publish +- **DEPLOYMENT_PUBLISH_TAG**. The tag in which to publish +- **DEPLOYMENT_TAG**. Required for stage and prod pipelines, specifies the tag from a previous publish step. For instance, if the dev pipeline had `DEPLOYMENT_PUBLISH_TAG=1.0` then we need to set `DEPLOYMENT_TAG=1.0` in the stage and production steps. + +### Automatic variables + +- Codefresh variables. All variables starting with `CF_` are managed by codefresh +- **[APPNAME]_TAG**. This set of variables are created in the `prepare_deployment` step. The tag is derived from an hash of the content being built. +- **[APPNAME]_TAG_EXISTS**. This set of variables are created in the `prepare_deployment` step. If a manifest for `[APPNAME]_TAG` exists, `[APPNAME]_TAG_EXISTS` is set. This is used to implement smart caching + +### Cache variables +**[APPNAME]_FORCE_BUILD**. Set it to force the build of the build of the image named `[APPNAME]_TAG` + +## Update a deployment specification + +The deployment must be updated whenever new build artifacts are added/removed, or opon changes in the templates. + +To update a pipeline for a specific env, run +``` +harness-deployment . -e [ENV] +``` + +A file `./deployment/codefresh-dev.yaml` is created, provided that a file `./deployment/codefresh-[ENV].yaml` exists either as a preconfigured pipeline on cloudharness or as a custom pipeline in your application. + +## Override Codefresh pipeline templates +Edit `./deployment-configuration/codefresh-template-[ENV].yaml` to override any helm chart values file. +Notice that Codefresh templates will be generated only if a specific environment file is defined. +By default, the *dev* and *prod* environments are defined. + +To override the single image build template, edit `deployment-configuration/codefresh-build-template.yaml` + + + +## Create and override the pipelines + +Create a file named `./deployment-configuration/codefresh-template-[ENV].yaml` to create a specific +pipeline. The file can include any additional step in addition to the predefined ones. + +If [ENV] is one of `dev`, `stage`, `prod`, `test`, you only need to specify the additional steps you want to add, or change the bit in the file you need to change. + +## Caching and conditional build + +The dev and test pipelines use content hash to avoid doing the same build twice. +The `.dockerignore` file is used to determine the content which is part of the hashing. + +Caching may be problematic if the build is relying on data which is not in the repo which has to be updated. +In this case, set the `[APPNAME]_FORCE_BUILD` variable to force a new build. \ No newline at end of file diff --git a/docs/build-deploy/codefresh.md b/docs/build-deploy/codefresh.md deleted file mode 100644 index bae357e8..00000000 --- a/docs/build-deploy/codefresh.md +++ /dev/null @@ -1,26 +0,0 @@ -# Continuous deployment with Codefresh - -Codefresh pipelines are generated as `deployment/codefresh-[ENV].yaml`. -These files can be loaded from codefresh as documented [here](https://codefresh.io/docs/docs/configure-ci-cd-pipeline/pipelines/). - -The pipeline will take care of building the images from the source code and deploy the helm chart. -Log in to codefresh and run the pipeline associated to the repository. - -- To setup a new dev pipeline, indicate the remote yaml path `./deployment/codefresh-dev.yaml` -- To setup a new production pipeline, indicate the remote yaml path `./deployment/codefresh-prod.yaml` - -## Update a deployment specification - -The deployment must be updated whenever new build artifacts are added/removed, or opon changes in the templates. - -In order to update the deployment, run -``` -harness-deployment . -e [ENV] -``` - -## Override Codefresh pipeline templates -Edit `./deployment-configuration/codefresh-template-[ENV].yaml` to override any helm chart values file. -Notice that Codefresh templates will be generated only if a specific environment file is defined. -By default, the *dev* and *prod* environments are defined. - -To override the single image build template, edit `deployment-configuration/codefresh-build-template.yaml` \ No newline at end of file diff --git a/docs/model/ApiTestsConfig.md b/docs/model/ApiTestsConfig.md index 9aa745b1..fab49ebc 100644 --- a/docs/model/ApiTestsConfig.md +++ b/docs/model/ApiTestsConfig.md @@ -1,15 +1,46 @@ -# ApiTestsConfig +# cloudharness_model.model.api_tests_config.ApiTestsConfig +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**[checks](#checks)** | list, tuple, | tuple, | One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers. | +**autotest** | bool, | BoolClass, | Specify whether to run the common smoke tests | +**enabled** | bool, | BoolClass, | Enables api tests for this application (default: false) | +**[runParams](#runParams)** | list, tuple, | tuple, | Additional schemathesis parameters | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# checks + +One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers. + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers. | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# runParams + +Additional schemathesis parameters -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**enabled** | **bool** | Enables api tests for this application (default: false) | -**autotest** | **bool** | Specify whether to run the common smoke tests | -**checks** | **[str]** | One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers. | -**run_params** | **[str]** | Additional schemathesis parameters | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +list, tuple, | tuple, | Additional schemathesis parameters | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/ApplicationAccountsConfig.md b/docs/model/ApplicationAccountsConfig.md index e9e98c26..5cbbdf7d 100644 --- a/docs/model/ApplicationAccountsConfig.md +++ b/docs/model/ApplicationAccountsConfig.md @@ -1,13 +1,44 @@ -# ApplicationAccountsConfig +# cloudharness_model.model.application_accounts_config.ApplicationAccountsConfig +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**[roles](#roles)** | list, tuple, | tuple, | Specify roles to be created in this deployment specific for this application | [optional] +**[users](#users)** | list, tuple, | tuple, | Defines test users to be added to the deployment, specific for this application | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# roles + +Specify roles to be created in this deployment specific for this application + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | Specify roles to be created in this deployment specific for this application | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# users + +Defines test users to be added to the deployment, specific for this application -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**roles** | **[str]** | Specify roles to be created in this deployment specific for this application | [optional] -**users** | [**[ApplicationUser]**](ApplicationUser.md) | Defines test users to be added to the deployment, specific for this application | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +list, tuple, | tuple, | Defines test users to be added to the deployment, specific for this application | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[**ApplicationUser**](ApplicationUser.md) | [**ApplicationUser**](ApplicationUser.md) | [**ApplicationUser**](ApplicationUser.md) | | +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/ApplicationConfig.md b/docs/model/ApplicationConfig.md index 2bec7dce..667d4b9a 100644 --- a/docs/model/ApplicationConfig.md +++ b/docs/model/ApplicationConfig.md @@ -1,13 +1,17 @@ -# ApplicationConfig +# cloudharness_model.model.application_config.ApplicationConfig Place here the values to configure your application helm templates. -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**harness** | [**ApplicationHarnessConfig**](ApplicationHarnessConfig.md) | | -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | Place here the values to configure your application helm templates. | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**harness** | [**ApplicationHarnessConfig**](ApplicationHarnessConfig.md) | [**ApplicationHarnessConfig**](ApplicationHarnessConfig.md) | | +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/ApplicationDependenciesConfig.md b/docs/model/ApplicationDependenciesConfig.md index 6409549d..8d3ba917 100644 --- a/docs/model/ApplicationDependenciesConfig.md +++ b/docs/model/ApplicationDependenciesConfig.md @@ -1,14 +1,59 @@ -# ApplicationDependenciesConfig +# cloudharness_model.model.application_dependencies_config.ApplicationDependenciesConfig +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**[hard](#hard)** | list, tuple, | tuple, | Hard dependencies indicate that the application may not start without these other applications. | [optional] +**[soft](#soft)** | list, tuple, | tuple, | Soft dependencies indicate that the application will work partially without these other applications. | [optional] +**[build](#build)** | list, tuple, | tuple, | Hard dependencies indicate that the application Docker image build requires these base/common images | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# hard + +Hard dependencies indicate that the application may not start without these other applications. + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | Hard dependencies indicate that the application may not start without these other applications. | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# soft + +Soft dependencies indicate that the application will work partially without these other applications. + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | Soft dependencies indicate that the application will work partially without these other applications. | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# build + +Hard dependencies indicate that the application Docker image build requires these base/common images -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**hard** | **[str]** | Hard dependencies indicate that the application may not start without these other applications. | [optional] -**soft** | **[str]** | Soft dependencies indicate that the application will work partially without these other applications. | [optional] -**build** | **[str]** | Hard dependencies indicate that the application Docker image build requires these base/common images | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +list, tuple, | tuple, | Hard dependencies indicate that the application Docker image build requires these base/common images | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/ApplicationHarnessConfig.md b/docs/model/ApplicationHarnessConfig.md index 89419129..a83f853a 100644 --- a/docs/model/ApplicationHarnessConfig.md +++ b/docs/model/ApplicationHarnessConfig.md @@ -1,32 +1,92 @@ -# ApplicationHarnessConfig +# cloudharness_model.model.application_harness_config.ApplicationHarnessConfig Define helm variables that allow CloudHarness to enable and configure your application's deployment -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**deployment** | [**DeploymentAutoArtifactConfig**](DeploymentAutoArtifactConfig.md) | | [optional] -**service** | [**ServiceAutoArtifactConfig**](ServiceAutoArtifactConfig.md) | | [optional] -**subdomain** | **str** | If specified, an ingress will be created at [subdomain].[.Values.domain] | [optional] -**aliases** | **[str]** | If specified, an ingress will be created at [alias].[.Values.domain] for each alias | [optional] -**domain** | **str** | If specified, an ingress will be created at [domain] | [optional] -**dependencies** | [**ApplicationDependenciesConfig**](ApplicationDependenciesConfig.md) | | [optional] -**secured** | **bool** | When true, the application is shielded with a getekeeper | [optional] -**uri_role_mapping** | [**[UriRoleMappingConfig]**](UriRoleMappingConfig.md) | Map uri/roles to secure with the Gatekeeper (if `secured: true`) | [optional] -**secrets** | [**SimpleMap**](SimpleMap.md) | | [optional] -**use_services** | **[str]** | Specify which services this application uses in the frontend to create proxy ingresses. e.g. ``` - name: samples ``` | [optional] -**database** | [**DatabaseDeploymentConfig**](DatabaseDeploymentConfig.md) | | [optional] -**resources** | [**[FileResourcesConfig]**](FileResourcesConfig.md) | Application file resources. Maps from deploy/resources folder and mounts as configmaps | [optional] -**readiness_probe** | [**ApplicationProbe**](ApplicationProbe.md) | | [optional] -**startup_probe** | [**ApplicationProbe**](ApplicationProbe.md) | | [optional] -**liveness_probe** | [**ApplicationProbe**](ApplicationProbe.md) | | [optional] -**source_root** | [**Filename**](Filename.md) | | [optional] -**name** | **str** | Application's name. Do not edit, the value is automatically set from the application directory's name | [optional] -**jupyterhub** | [**JupyterHubConfig**](JupyterHubConfig.md) | | [optional] -**accounts** | [**ApplicationAccountsConfig**](ApplicationAccountsConfig.md) | | [optional] -**test** | [**ApplicationTestConfig**](ApplicationTestConfig.md) | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +dict, frozendict.frozendict, | frozendict.frozendict, | Define helm variables that allow CloudHarness to enable and configure your application's deployment | +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**deployment** | [**DeploymentAutoArtifactConfig**](DeploymentAutoArtifactConfig.md) | [**DeploymentAutoArtifactConfig**](DeploymentAutoArtifactConfig.md) | | [optional] +**service** | [**ServiceAutoArtifactConfig**](ServiceAutoArtifactConfig.md) | [**ServiceAutoArtifactConfig**](ServiceAutoArtifactConfig.md) | | [optional] +**subdomain** | str, | str, | If specified, an ingress will be created at [subdomain].[.Values.domain] | [optional] +**[aliases](#aliases)** | list, tuple, | tuple, | If specified, an ingress will be created at [alias].[.Values.domain] for each alias | [optional] +**domain** | str, | str, | If specified, an ingress will be created at [domain] | [optional] +**dependencies** | [**ApplicationDependenciesConfig**](ApplicationDependenciesConfig.md) | [**ApplicationDependenciesConfig**](ApplicationDependenciesConfig.md) | | [optional] +**secured** | bool, | BoolClass, | When true, the application is shielded with a getekeeper | [optional] +**[uri_role_mapping](#uri_role_mapping)** | list, tuple, | tuple, | Map uri/roles to secure with the Gatekeeper (if `secured: true`) | [optional] +**secrets** | [**SimpleMap**](SimpleMap.md) | [**SimpleMap**](SimpleMap.md) | | [optional] +**[use_services](#use_services)** | list, tuple, | tuple, | Specify which services this application uses in the frontend to create proxy ingresses. e.g. ``` - name: samples ``` | [optional] +**database** | [**DatabaseDeploymentConfig**](DatabaseDeploymentConfig.md) | [**DatabaseDeploymentConfig**](DatabaseDeploymentConfig.md) | | [optional] +**[resources](#resources)** | list, tuple, | tuple, | Application file resources. Maps from deploy/resources folder and mounts as configmaps | [optional] +**readinessProbe** | [**ApplicationProbe**](ApplicationProbe.md) | [**ApplicationProbe**](ApplicationProbe.md) | | [optional] +**startupProbe** | [**ApplicationProbe**](ApplicationProbe.md) | [**ApplicationProbe**](ApplicationProbe.md) | | [optional] +**livenessProbe** | [**ApplicationProbe**](ApplicationProbe.md) | [**ApplicationProbe**](ApplicationProbe.md) | | [optional] +**sourceRoot** | [**Filename**](Filename.md) | [**Filename**](Filename.md) | | [optional] +**name** | str, | str, | Application's name. Do not edit, the value is automatically set from the application directory's name | [optional] +**jupyterhub** | [**JupyterHubConfig**](JupyterHubConfig.md) | [**JupyterHubConfig**](JupyterHubConfig.md) | | [optional] +**accounts** | [**ApplicationAccountsConfig**](ApplicationAccountsConfig.md) | [**ApplicationAccountsConfig**](ApplicationAccountsConfig.md) | | [optional] +**test** | [**ApplicationTestConfig**](ApplicationTestConfig.md) | [**ApplicationTestConfig**](ApplicationTestConfig.md) | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# aliases + +If specified, an ingress will be created at [alias].[.Values.domain] for each alias + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | If specified, an ingress will be created at [alias].[.Values.domain] for each alias | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# uri_role_mapping + +Map uri/roles to secure with the Gatekeeper (if `secured: true`) + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | Map uri/roles to secure with the Gatekeeper (if `secured: true`) | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[**UriRoleMappingConfig**](UriRoleMappingConfig.md) | [**UriRoleMappingConfig**](UriRoleMappingConfig.md) | [**UriRoleMappingConfig**](UriRoleMappingConfig.md) | | + +# use_services + +Specify which services this application uses in the frontend to create proxy ingresses. e.g. ``` - name: samples ``` + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | Specify which services this application uses in the frontend to create proxy ingresses. e.g. ``` - name: samples ``` | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# resources + +Application file resources. Maps from deploy/resources folder and mounts as configmaps + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | Application file resources. Maps from deploy/resources folder and mounts as configmaps | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[**FileResourcesConfig**](FileResourcesConfig.md) | [**FileResourcesConfig**](FileResourcesConfig.md) | [**FileResourcesConfig**](FileResourcesConfig.md) | | + +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/ApplicationProbe.md b/docs/model/ApplicationProbe.md index 51b412b2..a3375c46 100644 --- a/docs/model/ApplicationProbe.md +++ b/docs/model/ApplicationProbe.md @@ -1,16 +1,20 @@ -# ApplicationProbe +# cloudharness_model.model.application_probe.ApplicationProbe Define a Kubernetes probe See also the [official documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**path** | **str** | | -**period_seconds** | **float** | | [optional] -**failure_threshold** | **float** | | [optional] -**initial_delay_seconds** | **float** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | Define a Kubernetes probe See also the [official documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**path** | str, | str, | | +**periodSeconds** | decimal.Decimal, int, float, | decimal.Decimal, | | [optional] +**failureThreshold** | decimal.Decimal, int, float, | decimal.Decimal, | | [optional] +**initialDelaySeconds** | decimal.Decimal, int, float, | decimal.Decimal, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/ApplicationTestConfig.md b/docs/model/ApplicationTestConfig.md index bfd41972..96aced5a 100644 --- a/docs/model/ApplicationTestConfig.md +++ b/docs/model/ApplicationTestConfig.md @@ -1,14 +1,17 @@ -# ApplicationTestConfig +# cloudharness_model.model.application_test_config.ApplicationTestConfig - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**unit** | [**UnitTestsConfig**](UnitTestsConfig.md) | | -**api** | [**ApiTestsConfig**](ApiTestsConfig.md) | | -**e2e** | [**E2ETestsConfig**](E2ETestsConfig.md) | | -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**unit** | [**UnitTestsConfig**](UnitTestsConfig.md) | [**UnitTestsConfig**](UnitTestsConfig.md) | | +**e2e** | [**E2ETestsConfig**](E2ETestsConfig.md) | [**E2ETestsConfig**](E2ETestsConfig.md) | | +**api** | [**ApiTestsConfig**](ApiTestsConfig.md) | [**ApiTestsConfig**](ApiTestsConfig.md) | | +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/ApplicationUser.md b/docs/model/ApplicationUser.md index 4f1cc232..c55a18e8 100644 --- a/docs/model/ApplicationUser.md +++ b/docs/model/ApplicationUser.md @@ -1,16 +1,44 @@ -# ApplicationUser +# cloudharness_model.model.application_user.ApplicationUser Defines a user -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**username** | **str** | | -**password** | **str** | | [optional] -**client_roles** | **[str]** | | [optional] -**realm_roles** | **[str]** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | Defines a user | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**username** | str, | str, | | +**password** | str, | str, | | [optional] +**[clientRoles](#clientRoles)** | list, tuple, | tuple, | | [optional] +**[realmRoles](#realmRoles)** | list, tuple, | tuple, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +# clientRoles + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# realmRoles + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/ApplicationsConfigsMap.md b/docs/model/ApplicationsConfigsMap.md index ed15a264..7bfc31e5 100644 --- a/docs/model/ApplicationsConfigsMap.md +++ b/docs/model/ApplicationsConfigsMap.md @@ -1,11 +1,14 @@ -# ApplicationsConfigsMap +# cloudharness_model.model.applications_configs_map.ApplicationsConfigsMap - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**any string name** | [**ApplicationConfig**](ApplicationConfig.md) | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | [**ApplicationConfig**](ApplicationConfig.md) | [**ApplicationConfig**](ApplicationConfig.md) | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/AutoArtifactSpec.md b/docs/model/AutoArtifactSpec.md index 9f80e997..7d149b70 100644 --- a/docs/model/AutoArtifactSpec.md +++ b/docs/model/AutoArtifactSpec.md @@ -1,13 +1,16 @@ -# AutoArtifactSpec +# cloudharness_model.model.auto_artifact_spec.AutoArtifactSpec - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | -**name** | **str** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**auto** | bool, | BoolClass, | When true, enables automatic template | +**name** | str, | str, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/BackupConfig.md b/docs/model/BackupConfig.md index 7e08ba44..29cbce3b 100644 --- a/docs/model/BackupConfig.md +++ b/docs/model/BackupConfig.md @@ -1,20 +1,23 @@ -# BackupConfig +# cloudharness_model.model.backup_config.BackupConfig - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**dir** | [**Filename**](Filename.md) | | -**resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | -**active** | **bool** | | [optional] -**keep_days** | **int** | | [optional] -**keep_weeks** | **int** | | [optional] -**keep_months** | **int** | | [optional] -**schedule** | **str** | Cron expression | [optional] -**suffix** | **bool, date, datetime, dict, float, int, list, str, none_type** | The file suffix added to backup files | [optional] -**volumesize** | **str** | The volume size for backups (all backups share the same volume) | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | +**dir** | [**Filename**](Filename.md) | [**Filename**](Filename.md) | | +**active** | bool, | BoolClass, | | [optional] +**keep_days** | decimal.Decimal, int, | decimal.Decimal, | | [optional] +**keep_weeks** | decimal.Decimal, int, | decimal.Decimal, | | [optional] +**keep_months** | decimal.Decimal, int, | decimal.Decimal, | | [optional] +**schedule** | str, | str, | Cron expression | [optional] +**suffix** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | The file suffix added to backup files | [optional] +**volumesize** | str, | str, | The volume size for backups (all backups share the same volume) | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/CDCEvent.md b/docs/model/CDCEvent.md index ef9c1a49..c33e1081 100644 --- a/docs/model/CDCEvent.md +++ b/docs/model/CDCEvent.md @@ -1,17 +1,21 @@ -# CDCEvent +# cloudharness_model.model.cdc_event.CDCEvent A message sent to the orchestration queue. Applications can listen to these events to react to data change events happening on other applications. -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**operation** | **str** | the operation on the object e.g. create / update / delete | -**uid** | **str** | the unique identifier attribute of the object | -**message_type** | **str** | the type of the message (relates to the object type) e.g. jobs | -**meta** | [**CDCEventMeta**](CDCEventMeta.md) | | -**resource** | [**FreeObject**](FreeObject.md) | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | A message sent to the orchestration queue. Applications can listen to these events to react to data change events happening on other applications. | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**uid** | str, | str, | the unique identifier attribute of the object | +**meta** | [**CDCEventMeta**](CDCEventMeta.md) | [**CDCEventMeta**](CDCEventMeta.md) | | +**message_type** | str, | str, | the type of the message (relates to the object type) e.g. jobs | +**operation** | str, | str, | the operation on the object e.g. create / update / delete | must be one of ["create", "update", "delete", "other", ] +**resource** | [**FreeObject**](FreeObject.md) | [**FreeObject**](FreeObject.md) | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/CDCEventMeta.md b/docs/model/CDCEventMeta.md index a90f4b95..747246d3 100644 --- a/docs/model/CDCEventMeta.md +++ b/docs/model/CDCEventMeta.md @@ -1,16 +1,33 @@ -# CDCEventMeta +# cloudharness_model.model.cdc_event_meta.CDCEventMeta +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**app_name** | str, | str, | The name of the application/microservice sending the message | +**user** | [**User**](User.md) | [**User**](User.md) | | [optional] +**[args](#args)** | list, tuple, | tuple, | the caller function arguments | [optional] +**kwargs** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | the caller function keyword arguments | [optional] +**description** | str, | str, | General description -- for human consumption | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# args + +the caller function arguments -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**app_name** | **str** | The name of the application/microservice sending the message | -**user** | [**User**](User.md) | | [optional] -**args** | [**[FreeObject]**](FreeObject.md) | the caller function arguments | [optional] -**kwargs** | **bool, date, datetime, dict, float, int, list, str, none_type** | the caller function keyword arguments | [optional] -**description** | **str** | General description -- for human consumption | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +list, tuple, | tuple, | the caller function arguments | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[**FreeObject**](FreeObject.md) | [**FreeObject**](FreeObject.md) | [**FreeObject**](FreeObject.md) | | +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/CpuMemoryConfig.md b/docs/model/CpuMemoryConfig.md index 48d91152..f64cd7d3 100644 --- a/docs/model/CpuMemoryConfig.md +++ b/docs/model/CpuMemoryConfig.md @@ -1,13 +1,16 @@ -# CpuMemoryConfig +# cloudharness_model.model.cpu_memory_config.CpuMemoryConfig - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**cpu** | **str** | | [optional] -**memory** | **str** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**cpu** | str, | str, | | [optional] +**memory** | str, | str, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/DatabaseDeploymentConfig.md b/docs/model/DatabaseDeploymentConfig.md index f42cccec..864d5ef1 100644 --- a/docs/model/DatabaseDeploymentConfig.md +++ b/docs/model/DatabaseDeploymentConfig.md @@ -1,22 +1,37 @@ -# DatabaseDeploymentConfig +# cloudharness_model.model.database_deployment_config.DatabaseDeploymentConfig +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Composed Schemas (allOf/anyOf/oneOf/not) +#### allOf +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[all_of_0](#all_of_0) | dict, frozendict.frozendict, | frozendict.frozendict, | | +[AutoArtifactSpec](AutoArtifactSpec.md) | [**AutoArtifactSpec**](AutoArtifactSpec.md) | [**AutoArtifactSpec**](AutoArtifactSpec.md) | | + +# all_of_0 -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | -**type** | **str** | Define the database type. One of (mongo, postgres, neo4j, sqlite3) | [optional] -**size** | **str** | Specify database disk size | [optional] -**user** | **str** | database username | [optional] -**_pass** | **str** | Database password | [optional] -**image_ref** | **str** | Used for referencing images from the build | [optional] -**mongo** | [**FreeObject**](FreeObject.md) | | [optional] -**postgres** | [**FreeObject**](FreeObject.md) | | [optional] -**neo4j** | **bool, date, datetime, dict, float, int, list, str, none_type** | Neo4j database specific configuration | [optional] -**resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | [optional] -**name** | **str** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**type** | str, | str, | Define the database type. One of (mongo, postgres, neo4j, sqlite3) | [optional] +**size** | str, | str, | Specify database disk size | [optional] +**user** | str, | str, | database username | [optional] +**pass** | str, | str, | Database password | [optional] +**image_ref** | str, | str, | Used for referencing images from the build | [optional] +**mongo** | [**FreeObject**](FreeObject.md) | [**FreeObject**](FreeObject.md) | | [optional] +**postgres** | [**FreeObject**](FreeObject.md) | [**FreeObject**](FreeObject.md) | | [optional] +**neo4j** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | Neo4j database specific configuration | [optional] +**resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/DatabaseDeploymentConfigAllOf.md b/docs/model/DatabaseDeploymentConfigAllOf.md deleted file mode 100644 index 5fa6fe05..00000000 --- a/docs/model/DatabaseDeploymentConfigAllOf.md +++ /dev/null @@ -1,20 +0,0 @@ -# DatabaseDeploymentConfigAllOf - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**type** | **str** | Define the database type. One of (mongo, postgres, neo4j, sqlite3) | [optional] -**size** | **str** | Specify database disk size | [optional] -**user** | **str** | database username | [optional] -**_pass** | **str** | Database password | [optional] -**image_ref** | **str** | Used for referencing images from the build | [optional] -**mongo** | [**FreeObject**](FreeObject.md) | | [optional] -**postgres** | [**FreeObject**](FreeObject.md) | | [optional] -**neo4j** | **bool, date, datetime, dict, float, int, list, str, none_type** | Neo4j database specific configuration | [optional] -**resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/docs/model/DeploymentAutoArtifactConfig.md b/docs/model/DeploymentAutoArtifactConfig.md index 875e4d51..4367e949 100644 --- a/docs/model/DeploymentAutoArtifactConfig.md +++ b/docs/model/DeploymentAutoArtifactConfig.md @@ -1,17 +1,33 @@ -# DeploymentAutoArtifactConfig +# cloudharness_model.model.deployment_auto_artifact_config.DeploymentAutoArtifactConfig +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Composed Schemas (allOf/anyOf/oneOf/not) +#### allOf +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[all_of_0](#all_of_0) | dict, frozendict.frozendict, | frozendict.frozendict, | | +[AutoArtifactSpec](AutoArtifactSpec.md) | [**AutoArtifactSpec**](AutoArtifactSpec.md) | [**AutoArtifactSpec**](AutoArtifactSpec.md) | | + +# all_of_0 -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | -**port** | **bool, date, datetime, dict, float, int, list, str, none_type** | Deployment port | [optional] -**replicas** | **int** | Number of replicas | [optional] -**image** | **str** | Image name to use in the deployment. Leave it blank to set from the application's Docker file | [optional] -**resources** | **bool, date, datetime, dict, float, int, list, str, none_type** | Deployment resources | [optional] -**name** | **str** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**port** | str, | str, | Deployment port | [optional] +**replicas** | decimal.Decimal, int, | decimal.Decimal, | Number of replicas | [optional] +**image** | str, | str, | Image name to use in the deployment. Leave it blank to set from the application's Docker file | [optional] +**resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | [optional] +**volume** | [**DeploymentVolumeSpec**](DeploymentVolumeSpec.md) | [**DeploymentVolumeSpec**](DeploymentVolumeSpec.md) | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/DeploymentResourcesConf.md b/docs/model/DeploymentResourcesConf.md index b9788bb8..6ca517a3 100644 --- a/docs/model/DeploymentResourcesConf.md +++ b/docs/model/DeploymentResourcesConf.md @@ -1,13 +1,16 @@ -# DeploymentResourcesConf +# cloudharness_model.model.deployment_resources_conf.DeploymentResourcesConf - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**requests** | [**CpuMemoryConfig**](CpuMemoryConfig.md) | | [optional] -**limits** | [**CpuMemoryConfig**](CpuMemoryConfig.md) | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**requests** | [**CpuMemoryConfig**](CpuMemoryConfig.md) | [**CpuMemoryConfig**](CpuMemoryConfig.md) | | [optional] +**limits** | [**CpuMemoryConfig**](CpuMemoryConfig.md) | [**CpuMemoryConfig**](CpuMemoryConfig.md) | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/DeploymentVolumeSpec.md b/docs/model/DeploymentVolumeSpec.md new file mode 100644 index 00000000..14900102 --- /dev/null +++ b/docs/model/DeploymentVolumeSpec.md @@ -0,0 +1,33 @@ +# cloudharness_model.model.deployment_volume_spec.DeploymentVolumeSpec + +Defines a volume attached to the deployment. Automatically created the volume claim and mounts. + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | Defines a volume attached to the deployment. Automatically created the volume claim and mounts. | + +### Composed Schemas (allOf/anyOf/oneOf/not) +#### allOf +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[all_of_0](#all_of_0) | dict, frozendict.frozendict, | frozendict.frozendict, | | +[AutoArtifactSpec](AutoArtifactSpec.md) | [**AutoArtifactSpec**](AutoArtifactSpec.md) | [**AutoArtifactSpec**](AutoArtifactSpec.md) | | + +# all_of_0 + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**mountpath** | str, | str, | The mount path for the volume | +**size** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | The volume size. E.g. 5Gi | [optional] +**usenfs** | bool, | BoolClass, | Set to `true` to use the nfs on the created volume and mount as ReadWriteMany. | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) + diff --git a/docs/model/E2ETestsConfig.md b/docs/model/E2ETestsConfig.md index 83b2ee44..8b7383d1 100644 --- a/docs/model/E2ETestsConfig.md +++ b/docs/model/E2ETestsConfig.md @@ -1,15 +1,18 @@ -# E2ETestsConfig +# cloudharness_model.model.e2_e_tests_config.E2ETestsConfig - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**enabled** | **bool** | Enables end to end testing for this application (default: false) | -**smoketest** | **bool** | Specify whether to run the common smoke tests | -**ignore_console_errors** | **bool** | | [optional] -**ignore_request_errors** | **bool** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**smoketest** | bool, | BoolClass, | Specify whether to run the common smoke tests | +**enabled** | bool, | BoolClass, | Enables end to end testing for this application (default: false) | +**ignoreConsoleErrors** | bool, | BoolClass, | | [optional] +**ignoreRequestErrors** | bool, | BoolClass, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/FileResourcesConfig.md b/docs/model/FileResourcesConfig.md index af671647..6936d87c 100644 --- a/docs/model/FileResourcesConfig.md +++ b/docs/model/FileResourcesConfig.md @@ -1,14 +1,17 @@ -# FileResourcesConfig +# cloudharness_model.model.file_resources_config.FileResourcesConfig - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**name** | [**Filename**](Filename.md) | | -**src** | [**Filename**](Filename.md) | | -**dst** | **str** | | -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**dst** | str, | str, | | +**src** | [**Filename**](Filename.md) | [**Filename**](Filename.md) | | +**name** | [**Filename**](Filename.md) | [**Filename**](Filename.md) | | +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/Filename.md b/docs/model/Filename.md index 0230048f..ccbf7b0e 100644 --- a/docs/model/Filename.md +++ b/docs/model/Filename.md @@ -1,11 +1,9 @@ -# Filename +# cloudharness_model.model.filename.Filename - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**value** | **str** | | - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +str, | str, | | +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/FreeObject.md b/docs/model/FreeObject.md index 2d0bc683..e131e846 100644 --- a/docs/model/FreeObject.md +++ b/docs/model/FreeObject.md @@ -1,11 +1,14 @@ -# FreeObject +# cloudharness_model.model.free_object.FreeObject - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/HarnessMainConfig.md b/docs/model/HarnessMainConfig.md index b563b5c5..d7d72df1 100644 --- a/docs/model/HarnessMainConfig.md +++ b/docs/model/HarnessMainConfig.md @@ -1,24 +1,41 @@ -# HarnessMainConfig +# cloudharness_model.model.harness_main_config.HarnessMainConfig +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**mainapp** | str, | str, | Defines the app to map to the root domain | +**domain** | str, | str, | The root domain | +**namespace** | str, | str, | The K8s namespace. | +**secured_gatekeepers** | bool, | BoolClass, | Enables/disables Gatekeepers on secured applications. Set to false for testing/development | +**local** | bool, | BoolClass, | If set to true, local DNS mapping is added to pods. | +**apps** | [**ApplicationsConfigsMap**](ApplicationsConfigsMap.md) | [**ApplicationsConfigsMap**](ApplicationsConfigsMap.md) | | +**registry** | [**RegistryConfig**](RegistryConfig.md) | [**RegistryConfig**](RegistryConfig.md) | | [optional] +**tag** | str, | str, | Docker tag used to push/pull the built images. | [optional] +**[env](#env)** | list, tuple, | tuple, | Environmental variables added to all pods | [optional] +**privenv** | [**NameValue**](NameValue.md) | [**NameValue**](NameValue.md) | | [optional] +**backup** | [**BackupConfig**](BackupConfig.md) | [**BackupConfig**](BackupConfig.md) | | [optional] +**name** | str, | str, | Base name | [optional] +**task-images** | [**SimpleMap**](SimpleMap.md) | [**SimpleMap**](SimpleMap.md) | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# env -## Properties -Name | Type | Description | Notes +Environmental variables added to all pods + +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**local** | **bool** | If set to true, local DNS mapping is added to pods. | -**secured_gatekeepers** | **bool** | Enables/disables Gatekeepers on secured applications. Set to false for testing/development | -**domain** | **str** | The root domain | -**namespace** | **str** | The K8s namespace. | -**mainapp** | **str** | Defines the app to map to the root domain | -**apps** | [**ApplicationsConfigsMap**](ApplicationsConfigsMap.md) | | -**registry** | [**RegistryConfig**](RegistryConfig.md) | | [optional] -**tag** | **str** | Docker tag used to push/pull the built images. | [optional] -**env** | [**[NameValue]**](NameValue.md) | Environmental variables added to all pods | [optional] -**privenv** | [**NameValue**](NameValue.md) | | [optional] -**backup** | [**BackupConfig**](BackupConfig.md) | | [optional] -**name** | **str** | Base name | [optional] -**task_images** | [**SimpleMap**](SimpleMap.md) | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +list, tuple, | tuple, | Environmental variables added to all pods | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[**NameValue**](NameValue.md) | [**NameValue**](NameValue.md) | [**NameValue**](NameValue.md) | | +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/IngressConfig.md b/docs/model/IngressConfig.md index f1803ea2..fcdc67ea 100644 --- a/docs/model/IngressConfig.md +++ b/docs/model/IngressConfig.md @@ -1,15 +1,43 @@ -# IngressConfig +# cloudharness_model.model.ingress_config.IngressConfig +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Composed Schemas (allOf/anyOf/oneOf/not) +#### allOf +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[all_of_0](#all_of_0) | dict, frozendict.frozendict, | frozendict.frozendict, | | +[AutoArtifactSpec](AutoArtifactSpec.md) | [**AutoArtifactSpec**](AutoArtifactSpec.md) | [**AutoArtifactSpec**](AutoArtifactSpec.md) | | + +# all_of_0 + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**ssl_redirect** | bool, | BoolClass, | | [optional] +**[letsencrypt](#letsencrypt)** | dict, frozendict.frozendict, | frozendict.frozendict, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# letsencrypt -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | -**ssl_redirect** | **bool** | | [optional] -**letsencrypt** | [**IngressConfigAllOfLetsencrypt**](IngressConfigAllOfLetsencrypt.md) | | [optional] -**name** | **str** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**email** | str, | str, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/IngressConfigAllOf.md b/docs/model/IngressConfigAllOf.md deleted file mode 100644 index 3ba52e51..00000000 --- a/docs/model/IngressConfigAllOf.md +++ /dev/null @@ -1,13 +0,0 @@ -# IngressConfigAllOf - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**ssl_redirect** | **bool** | | [optional] -**letsencrypt** | [**IngressConfigAllOfLetsencrypt**](IngressConfigAllOfLetsencrypt.md) | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/docs/model/IngressConfigAllOfLetsencrypt.md b/docs/model/IngressConfigAllOfLetsencrypt.md deleted file mode 100644 index d5c218ea..00000000 --- a/docs/model/IngressConfigAllOfLetsencrypt.md +++ /dev/null @@ -1,12 +0,0 @@ -# IngressConfigAllOfLetsencrypt - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**email** | **str** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/docs/model/JupyterHubConfig.md b/docs/model/JupyterHubConfig.md index 7c7f2361..59ac9c84 100644 --- a/docs/model/JupyterHubConfig.md +++ b/docs/model/JupyterHubConfig.md @@ -1,15 +1,32 @@ -# JupyterHubConfig +# cloudharness_model.model.jupyter_hub_config.JupyterHubConfig +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**[args](#args)** | list, tuple, | tuple, | arguments passed to the container | [optional] +**extraConfig** | [**SimpleMap**](SimpleMap.md) | [**SimpleMap**](SimpleMap.md) | | [optional] +**spawnerExtraConfig** | [**FreeObject**](FreeObject.md) | [**FreeObject**](FreeObject.md) | | [optional] +**applicationHook** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | change the hook function (advanced) Specify the Python name of the function (full module path, the module must be installed in the Docker image) | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# args + +arguments passed to the container -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**args** | **[str]** | arguments passed to the container | [optional] -**extra_config** | [**SimpleMap**](SimpleMap.md) | | [optional] -**spawner_extra_config** | [**FreeObject**](FreeObject.md) | | [optional] -**application_hook** | **bool, date, datetime, dict, float, int, list, str, none_type** | change the hook function (advanced) Specify the Python name of the function (full module path, the module must be installed in the Docker image) | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +list, tuple, | tuple, | arguments passed to the container | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/NameValue.md b/docs/model/NameValue.md index 0a2fea07..deb57553 100644 --- a/docs/model/NameValue.md +++ b/docs/model/NameValue.md @@ -1,13 +1,16 @@ -# NameValue +# cloudharness_model.model.name_value.NameValue - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**name** | **str** | | -**value** | **str** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**name** | str, | str, | | +**value** | str, | str, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/PathSpecifier.md b/docs/model/PathSpecifier.md index baa172d4..e8062e36 100644 --- a/docs/model/PathSpecifier.md +++ b/docs/model/PathSpecifier.md @@ -1,11 +1,9 @@ -# PathSpecifier +# cloudharness_model.model.path_specifier.PathSpecifier - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**value** | **str** | | - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +str, | str, | | +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/Quota.md b/docs/model/Quota.md new file mode 100644 index 00000000..ddf78dea --- /dev/null +++ b/docs/model/Quota.md @@ -0,0 +1,14 @@ +# cloudharness_model.model.quota.Quota + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | str, | str, | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) + diff --git a/docs/model/RegistryConfig.md b/docs/model/RegistryConfig.md index 419be9e9..c63d22b6 100644 --- a/docs/model/RegistryConfig.md +++ b/docs/model/RegistryConfig.md @@ -1,13 +1,16 @@ -# RegistryConfig +# cloudharness_model.model.registry_config.RegistryConfig - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**name** | **str** | | -**secret** | **str** | Optional secret used for pulling from docker registry. | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**name** | str, | str, | | +**secret** | str, | str, | Optional secret used for pulling from docker registry. | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/ServiceAutoArtifactConfig.md b/docs/model/ServiceAutoArtifactConfig.md index 4f382876..6ac6050c 100644 --- a/docs/model/ServiceAutoArtifactConfig.md +++ b/docs/model/ServiceAutoArtifactConfig.md @@ -1,14 +1,29 @@ -# ServiceAutoArtifactConfig +# cloudharness_model.model.service_auto_artifact_config.ServiceAutoArtifactConfig +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Composed Schemas (allOf/anyOf/oneOf/not) +#### allOf +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[all_of_0](#all_of_0) | dict, frozendict.frozendict, | frozendict.frozendict, | | +[AutoArtifactSpec](AutoArtifactSpec.md) | [**AutoArtifactSpec**](AutoArtifactSpec.md) | [**AutoArtifactSpec**](AutoArtifactSpec.md) | | + +# all_of_0 -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | -**port** | **int** | Service port | [optional] -**name** | **str** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**port** | decimal.Decimal, int, | decimal.Decimal, | Service port | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/ServiceAutoArtifactConfigAllOf.md b/docs/model/ServiceAutoArtifactConfigAllOf.md deleted file mode 100644 index ca629355..00000000 --- a/docs/model/ServiceAutoArtifactConfigAllOf.md +++ /dev/null @@ -1,12 +0,0 @@ -# ServiceAutoArtifactConfigAllOf - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**port** | **int** | Service port | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/docs/model/SimpleMap.md b/docs/model/SimpleMap.md index 380d5da2..4106066b 100644 --- a/docs/model/SimpleMap.md +++ b/docs/model/SimpleMap.md @@ -1,11 +1,14 @@ -# SimpleMap +# cloudharness_model.model.simple_map.SimpleMap - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**any string name** | **str** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | str, | str, | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/URL.md b/docs/model/URL.md new file mode 100644 index 00000000..ac2bc6d8 --- /dev/null +++ b/docs/model/URL.md @@ -0,0 +1,9 @@ +# cloudharness_model.model.url.URL + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +str, | str, | | + +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) + diff --git a/docs/model/UnitTestsConfig.md b/docs/model/UnitTestsConfig.md index 85b13f1f..1c2f16d6 100644 --- a/docs/model/UnitTestsConfig.md +++ b/docs/model/UnitTestsConfig.md @@ -1,13 +1,30 @@ -# UnitTestsConfig +# cloudharness_model.model.unit_tests_config.UnitTestsConfig +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**[commands](#commands)** | list, tuple, | tuple, | Commands to run unit tests | +**enabled** | bool, | BoolClass, | Enables unit tests for this application (default: true) | +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# commands + +Commands to run unit tests -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**enabled** | **bool** | Enables unit tests for this application (default: true) | -**commands** | **[str]** | Commands to run unit tests | -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +list, tuple, | tuple, | Commands to run unit tests | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/UriRoleMappingConfig.md b/docs/model/UriRoleMappingConfig.md index 4ea3fb85..ff645e73 100644 --- a/docs/model/UriRoleMappingConfig.md +++ b/docs/model/UriRoleMappingConfig.md @@ -1,14 +1,32 @@ -# UriRoleMappingConfig +# cloudharness_model.model.uri_role_mapping_config.UriRoleMappingConfig Defines the application Gatekeeper configuration, if enabled (i.e. `secured: true`. -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**uri** | [**PathSpecifier**](PathSpecifier.md) | | -**roles** | **[str]** | Roles allowed to access the present uri | -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | Defines the application Gatekeeper configuration, if enabled (i.e. `secured: true`. | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**[roles](#roles)** | list, tuple, | tuple, | Roles allowed to access the present uri | +**uri** | [**PathSpecifier**](PathSpecifier.md) | [**PathSpecifier**](PathSpecifier.md) | | +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +# roles + +Roles allowed to access the present uri + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | Roles allowed to access the present uri | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/User.md b/docs/model/User.md index 443f33d7..cd49ceaa 100644 --- a/docs/model/User.md +++ b/docs/model/User.md @@ -1,30 +1,129 @@ -# User - - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**access** | **{str: (bool, date, datetime, dict, float, int, list, str, none_type)}** | | [optional] -**attributes** | **{str: (bool, date, datetime, dict, float, int, list, str, none_type)}** | | [optional] -**client_roles** | **{str: (bool, date, datetime, dict, float, int, list, str, none_type)}** | | [optional] -**created_timestamp** | **int** | | [optional] -**credentials** | [**[UserCredential]**](UserCredential.md) | | [optional] -**disableable_credential_types** | **[str]** | | [optional] -**email** | **str** | | [optional] -**email_verified** | **bool** | | [optional] -**enabled** | **bool** | | [optional] -**federation_link** | **str** | | [optional] -**first_name** | **str** | | [optional] -**groups** | **[str]** | | [optional] -**id** | **str** | | [optional] -**last_name** | **str** | | [optional] -**realm_roles** | **[str]** | | [optional] -**required_actions** | **[str]** | | [optional] -**service_account_client_id** | **str** | | [optional] -**username** | **str** | | [optional] -**additional_properties** | **bool, date, datetime, dict, float, int, list, str, none_type** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +# cloudharness_model.model.user.User +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**[access](#access)** | dict, frozendict.frozendict, | frozendict.frozendict, | | [optional] +**[attributes](#attributes)** | dict, frozendict.frozendict, | frozendict.frozendict, | | [optional] +**[clientRoles](#clientRoles)** | dict, frozendict.frozendict, | frozendict.frozendict, | | [optional] +**createdTimestamp** | decimal.Decimal, int, | decimal.Decimal, | | [optional] value must be a 64 bit integer +**[credentials](#credentials)** | list, tuple, | tuple, | | [optional] +**[disableableCredentialTypes](#disableableCredentialTypes)** | list, tuple, | tuple, | | [optional] +**email** | str, | str, | | [optional] +**emailVerified** | bool, | BoolClass, | | [optional] +**enabled** | bool, | BoolClass, | | [optional] +**federationLink** | str, | str, | | [optional] +**firstName** | str, | str, | | [optional] +**[groups](#groups)** | list, tuple, | tuple, | | [optional] +**id** | str, | str, | | [optional] +**lastName** | str, | str, | | [optional] +**[realmRoles](#realmRoles)** | list, tuple, | tuple, | | [optional] +**[requiredActions](#requiredActions)** | list, tuple, | tuple, | | [optional] +**serviceAccountClientId** | str, | str, | | [optional] +**username** | str, | str, | | [optional] +**additionalProperties** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# access + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# attributes + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# clientRoles + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# credentials + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[**UserCredential**](UserCredential.md) | [**UserCredential**](UserCredential.md) | [**UserCredential**](UserCredential.md) | | + +# disableableCredentialTypes + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# groups + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# realmRoles + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# requiredActions + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/UserCredential.md b/docs/model/UserCredential.md index 35b54178..d29edc20 100644 --- a/docs/model/UserCredential.md +++ b/docs/model/UserCredential.md @@ -1,20 +1,23 @@ -# UserCredential +# cloudharness_model.model.user_credential.UserCredential - -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**created_date** | **int** | | [optional] -**credential_data** | **str** | | [optional] -**id** | **str** | | [optional] -**priority** | **int** | | [optional] -**secret_data** | **str** | | [optional] -**temporary** | **bool** | | [optional] -**type** | **str** | | [optional] -**user_label** | **str** | | [optional] -**value** | **str** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**createdDate** | decimal.Decimal, int, | decimal.Decimal, | | [optional] value must be a 64 bit integer +**credentialData** | str, | str, | | [optional] +**id** | str, | str, | | [optional] +**priority** | decimal.Decimal, int, | decimal.Decimal, | | [optional] value must be a 32 bit integer +**secretData** | str, | str, | | [optional] +**temporary** | bool, | BoolClass, | | [optional] +**type** | str, | str, | | [optional] +**userLabel** | str, | str, | | [optional] +**value** | str, | str, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/UserGroup.md b/docs/model/UserGroup.md index 5bb41d0b..87aee711 100644 --- a/docs/model/UserGroup.md +++ b/docs/model/UserGroup.md @@ -1,19 +1,82 @@ -# UserGroup +# cloudharness_model.model.user_group.UserGroup +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**[access](#access)** | dict, frozendict.frozendict, | frozendict.frozendict, | | [optional] +**[attributes](#attributes)** | dict, frozendict.frozendict, | frozendict.frozendict, | | [optional] +**[clientRoles](#clientRoles)** | dict, frozendict.frozendict, | frozendict.frozendict, | | [optional] +**id** | str, | str, | | [optional] +**name** | str, | str, | | [optional] +**path** | str, | str, | | [optional] +**[realmRoles](#realmRoles)** | list, tuple, | tuple, | | [optional] +**[subGroups](#subGroups)** | list, tuple, | tuple, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# access + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# attributes + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] -## Properties -Name | Type | Description | Notes +# clientRoles + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# realmRoles + +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**access** | **{str: (bool, date, datetime, dict, float, int, list, str, none_type)}** | | [optional] -**attributes** | [**SimpleMap**](SimpleMap.md) | | [optional] -**client_roles** | **{str: (bool, date, datetime, dict, float, int, list, str, none_type)}** | | [optional] -**id** | **str** | | [optional] -**name** | **str** | | [optional] -**path** | **str** | | [optional] -**realm_roles** | **[str]** | | [optional] -**sub_groups** | [**[UserGroup]**](UserGroup.md) | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +list, tuple, | tuple, | | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +items | str, | str, | | + +# subGroups + +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +list, tuple, | tuple, | | + +### Tuple Items +Class Name | Input Type | Accessed Type | Description | Notes +------------- | ------------- | ------------- | ------------- | ------------- +[**UserGroup**](UserGroup.md) | [**UserGroup**](UserGroup.md) | [**UserGroup**](UserGroup.md) | | +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/docs/model/UserRole.md b/docs/model/UserRole.md index 412ab624..ba0d5fe0 100644 --- a/docs/model/UserRole.md +++ b/docs/model/UserRole.md @@ -1,18 +1,33 @@ -# UserRole +# cloudharness_model.model.user_role.UserRole +## Model Type Info +Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- +dict, frozendict.frozendict, | frozendict.frozendict, | | + +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**[attributes](#attributes)** | dict, frozendict.frozendict, | frozendict.frozendict, | | [optional] +**clientRole** | bool, | BoolClass, | | [optional] +**composite** | bool, | BoolClass, | | [optional] +**containerId** | str, | str, | | [optional] +**description** | str, | str, | | [optional] +**id** | str, | str, | | [optional] +**name** | str, | str, | | [optional] +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] + +# attributes -## Properties -Name | Type | Description | Notes +## Model Type Info +Input Type | Accessed Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**attributes** | **{str: (bool, date, datetime, dict, float, int, list, str, none_type)}** | | [optional] -**client_role** | **bool** | | [optional] -**composite** | **bool** | | [optional] -**container_id** | **str** | | [optional] -**description** | **str** | | [optional] -**id** | **str** | | [optional] -**name** | **str** | | [optional] -**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] +dict, frozendict.frozendict, | frozendict.frozendict, | | -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) +### Dictionary Keys +Key | Input Type | Accessed Type | Description | Notes +------------ | ------------- | ------------- | ------------- | ------------- +**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional] +[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md) diff --git a/infrastructure/base-images/cloudharness-base-debian/Dockerfile b/infrastructure/base-images/cloudharness-base-debian/Dockerfile index 9cd45615..18975b71 100644 --- a/infrastructure/base-images/cloudharness-base-debian/Dockerfile +++ b/infrastructure/base-images/cloudharness-base-debian/Dockerfile @@ -1,13 +1,19 @@ ARG PARENT=python:3.9.10 FROM ${PARENT} -RUN pip install pytest --no-cache-dir +RUN apt-get update && apt-get install -y nfs-common && rm -rf /var/lib/apt/lists/* + +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip install pytest --prefer-binary COPY libraries/models/requirements.txt /libraries/models/requirements.txt -RUN pip install -r /libraries/models/requirements.txt --no-cache-dir +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip install -r /libraries/models/requirements.txt --prefer-binary COPY libraries/cloudharness-common/requirements.txt /libraries/cloudharness-common/requirements.txt -RUN pip install -r /libraries/cloudharness-common/requirements.txt --no-cache-dir +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip install -r /libraries/cloudharness-common/requirements.txt --prefer-binary COPY libraries/client/cloudharness_cli/requirements.txt /libraries/client/cloudharness_cli/requirements.txt -RUN pip install -r /libraries/client/cloudharness_cli/requirements.txt --no-cache-dir +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip install -r /libraries/client/cloudharness_cli/requirements.txt --prefer-binary COPY libraries/models /libraries/models RUN pip install -e /libraries/models --no-cache-dir diff --git a/infrastructure/base-images/cloudharness-base/Dockerfile b/infrastructure/base-images/cloudharness-base/Dockerfile index c4fd9074..782c7d55 100644 --- a/infrastructure/base-images/cloudharness-base/Dockerfile +++ b/infrastructure/base-images/cloudharness-base/Dockerfile @@ -9,14 +9,18 @@ RUN apk add bash # dev tools needed by some python libraries RUN apk add gcc libc-dev g++ python3-dev libffi-dev openssl-dev rust musl-dev cargo -RUN pip install pytest --no-cache-dir - +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip install pytest --prefer-binary + COPY libraries/models/requirements.txt /libraries/models/requirements.txt -RUN pip install -r /libraries/models/requirements.txt --no-cache-dir +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip install -r /libraries/models/requirements.txt --prefer-binary COPY libraries/cloudharness-common/requirements.txt /libraries/cloudharness-common/requirements.txt -RUN pip install -r /libraries/cloudharness-common/requirements.txt --no-cache-dir +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip install -r /libraries/cloudharness-common/requirements.txt --prefer-binary COPY libraries/client/cloudharness_cli/requirements.txt /libraries/client/cloudharness_cli/requirements.txt -RUN pip install -r /libraries/client/cloudharness_cli/requirements.txt --no-cache-dir +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip install -r /libraries/client/cloudharness_cli/requirements.txt --prefer-binary COPY libraries/models /libraries/models RUN pip install -e /libraries/models diff --git a/infrastructure/common-images/cloudharness-django/Dockerfile b/infrastructure/common-images/cloudharness-django/Dockerfile index 32e5c30d..941dad57 100644 --- a/infrastructure/common-images/cloudharness-django/Dockerfile +++ b/infrastructure/common-images/cloudharness-django/Dockerfile @@ -8,13 +8,14 @@ ENV APP_DIR=/usr/src/app ENV PRODUCTION=true -RUN apt install -y libjpeg-dev zlib1g-dev git +RUN apt-get update && apt-get install -y libjpeg-dev zlib1g-dev git && rm -rf /var/lib/apt/lists/* RUN python3 -m pip install --upgrade pip COPY libraries/fastapi/requirements.txt /tmp -RUN python3 -m pip install -r /tmp/requirements.txt && \ +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + python3 -m pip install -r /tmp/requirements.txt --prefer-binary && \ rm /tmp/requirements.txt COPY libraries/cloudharness-django /libraries/cloudharness-django diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/middleware.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/middleware.py index b32cf1a2..dfe399c1 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/middleware.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/middleware.py @@ -1,3 +1,4 @@ + import jwt from django.contrib.auth.models import User @@ -5,15 +6,16 @@ from keycloak.exceptions import KeycloakGetError from cloudharness.middleware import get_authentication_token +from cloudharness.auth.exceptions import InvalidToken from cloudharness_django.services import get_user_service, get_auth_service - +from cloudharness import log def _get_user(): bearer = get_authentication_token() if bearer: # found bearer token get the Django user try: - token = bearer.split(" ")[1] + token = bearer.split(" ")[-1] payload = jwt.decode(token, algorithms=["RS256"], options={"verify_signature": False}, audience="web-client") kc_id = payload["sub"] try: @@ -24,6 +26,12 @@ def _get_user(): except KeycloakGetError: # KC user not found return None + except InvalidToken: + return None + except Exception as e: + log.exception("User mapping error, %s", payload["email"]) + return None + return None diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/migrations/0001_initial.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/migrations/0001_initial.py index d86b92cf..c7dc43e0 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/migrations/0001_initial.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/migrations/0001_initial.py @@ -28,7 +28,7 @@ class Migration(migrations.Migration): name='Member', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('kc_id', models.CharField(max_length=100)), + ('kc_id', models.CharField(max_length=100, db_index=True)), ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/models.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/models.py index 5c33092a..2a44315b 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/models.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/models.py @@ -13,7 +13,7 @@ def __str__(self): class Member(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) - kc_id = models.CharField(max_length = 100) + kc_id = models.CharField(max_length = 100, db_index=True) def __str__(self): return f"{self.user.first_name} {self.user.last_name}" diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/auth.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/auth.py index 66b96258..cb3a9ae8 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/auth.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/auth.py @@ -3,7 +3,7 @@ from enum import Enum from typing import List -from keycloak.exceptions import KeycloakGetError +from keycloak.exceptions import KeycloakGetError, KeycloakError from cloudharness import log from cloudharness.auth import AuthClient, get_auth_realm @@ -21,8 +21,12 @@ class AuthorizationLevel(Enum): # create the auth client if os.path.isfile(ALLVALUES_PATH): + try: # CH values exists so running with a valid config - auth_client = AuthClient() + auth_client = AuthClient(os.getenv("ACCOUNTS_ADMIN_USERNAME", None), os.getenv("ACCOUNTS_ADMIN_PASSWORD", None)) + except: + log.exception("Failed to initialize auth client") + auth_client = None else: auth_client = None @@ -30,13 +34,13 @@ class AuthorizationLevel(Enum): class AuthService: def __init__( - self, - client_name: str, - client_roles: List[str], - privileged_roles: List[str], - admin_role: str, - default_user_role: str=None, - ): + self, + client_name: str, + client_roles: List[str], + privileged_roles: List[str], + admin_role: str, + default_user_role: str = None, + ): if not admin_role: raise KeycloakOIDCNoAdminRole("No admin role given.") self.client_name = client_name @@ -60,48 +64,45 @@ def create_client(self): Create the client and client roles Checks if the client is present, if not the creates it """ - nap_time = 30 - installed = False - while not installed: + + try: + auth_client.refresh_token() try: - auth_client.refresh_token() + client = auth_client.get_client(self.get_client_name()) + except KeycloakGetError as e: + # thrown if client doesn't exist + auth_client.create_client(client_name=self.get_client_name()) + client = auth_client.get_client(self.get_client_name()) + + for role in self.client_roles: try: - client = auth_client.get_client(self.get_client_name()) - except KeycloakGetError as e: - # thrown if client doesn't exist - auth_client.create_client(client_name=self.get_client_name()) - client = auth_client.get_client(self.get_client_name()) - - for role in self.client_roles: - try: - auth_client.create_client_role(client["id"], role) - except KeycloakGetError as e: - # Thrown if role already exists - log.debug(e.error_message) - - if self.default_user_role: - # add the default user role to the default realm role - realm = get_auth_realm() - admin_client = auth_client.get_admin_client() - admin_client.refresh_token() - default_user_role = admin_client.get_client_role( - self.get_client_name(), - self.default_user_role - ) - admin_client.add_composite_realm_roles_to_role( - f'default-roles-{realm}', - [default_user_role,] - ) - - installed = True - except Exception as e: - log.error(e) - time.sleep(nap_time) + log.info("Creating role %s", role) + auth_client.create_client_role(client["id"], role) + except KeycloakError as e: + # Thrown if role already exists + log.error(e.error_message) + + if self.default_user_role: + # add the default user role to the default realm role + realm = get_auth_realm() + admin_client = auth_client.get_admin_client() + admin_client.refresh_token() + default_user_role = admin_client.get_client_role( + self.get_client_name(), + self.default_user_role + ) + admin_client.add_composite_realm_roles_to_role( + f'default-roles-{realm}', + [default_user_role, ] + ) + except Exception as e: + log.error("Error creating Keycloak client %s. May need to manually migrate the client.", self.get_client_name(), exc_info=True) + raise Exception("Error creating Keycloak client.") from e def get_auth_level(self, kc_user=None, kc_roles=None): if not kc_user: kc_user = auth_client.get_current_user() - + if not kc_roles: kc_roles = auth_client.get_user_client_roles( kc_user.get("id"), @@ -113,11 +114,13 @@ def get_auth_level(self, kc_user=None, kc_roles=None): if admin: return AuthorizationLevel.ADMIN - privileged = any([role in assigned_roles for role in self.privileged_roles]) + privileged = any( + [role in assigned_roles for role in self.privileged_roles]) if privileged: return AuthorizationLevel.PRIVILEGED - non_privileged = any([role in assigned_roles for role in self.client_roles]) + non_privileged = any( + [role in assigned_roles for role in self.client_roles]) if non_privileged: return AuthorizationLevel.NON_PRIVILEGED diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/user.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/user.py index f6419abf..e2ec8219 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/user.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/user.py @@ -3,6 +3,12 @@ from cloudharness_django.models import Team, Member from cloudharness_django.services.auth import AuthorizationLevel +def get_user_by_kc_id(kc_id) -> User: + try: + return Member.objects.get(kc_id=kc_id).user + except Member.DoesNotExist: + return None + class UserService: def __init__(self, auth_service): self.auth_service = auth_service @@ -28,6 +34,7 @@ def _map_kc_user(self, user, kc_user=None, is_superuser=False, delete=False): user.username = kc_user.get("username", kc_user["email"]) user.first_name = kc_user.get("firstName", "") user.last_name = kc_user.get("lastName", "") + user.email = kc_user.get("email", "") user.is_active = kc_user.get("enabled", delete) return user @@ -88,16 +95,17 @@ def sync_kc_groups(self, kc_groups=None): def sync_kc_user(self, kc_user, is_superuser=False, delete=False): # sync the kc user with the django user - user, created = User.objects.get_or_create(email=kc_user["email"]) - if created: - Member(user=user, kc_id=kc_user["id"]).save() + + user, created = User.objects.get_or_create(username=kc_user["username"]) + + Member.objects.get_or_create(user=user, kc_id=kc_user["id"]) user = self._map_kc_user(user, kc_user, is_superuser, delete) user.save() return user def sync_kc_user_groups(self, kc_user): # Sync the user usergroups and memberships - user = User.objects.get(email=kc_user["email"]) + user = User.objects.get(username=kc_user["email"]) user_groups = [] for kc_group in kc_user["userGroups"]: user_groups += [Group.objects.get(name=kc_group["name"])] diff --git a/infrastructure/common-images/cloudharness-fastapi/Dockerfile b/infrastructure/common-images/cloudharness-fastapi/Dockerfile index 74c82687..257438fa 100644 --- a/infrastructure/common-images/cloudharness-fastapi/Dockerfile +++ b/infrastructure/common-images/cloudharness-fastapi/Dockerfile @@ -7,6 +7,6 @@ ENV WORKERS=2 ENV APP_DIR=/usr/src/app COPY libraries/fastapi/requirements.txt /tmp -RUN python3 -m pip install --upgrade pip && \ - python3 -m pip install -r /tmp/requirements.txt --no-cache-dir && \ +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + python3 -m pip install -r /tmp/requirements.txt --prefer-binary && \ rm /tmp/requirements.txt diff --git a/infrastructure/common-images/cloudharness-flask/Dockerfile b/infrastructure/common-images/cloudharness-flask/Dockerfile index f347ddb8..d8046b0b 100644 --- a/infrastructure/common-images/cloudharness-flask/Dockerfile +++ b/infrastructure/common-images/cloudharness-flask/Dockerfile @@ -12,7 +12,8 @@ WORKDIR $DIR # install dependencies RUN pip install --upgrade pip COPY ./requirements.txt requirements.txt -RUN pip install --no-cache-dir -r requirements.txt +RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ + pip install --prefer-binary -r requirements.txt --default-timeout=1000 EXPOSE $PORT CMD gunicorn --workers=$WORKERS --bind=0.0.0.0:$PORT $MODULE_NAME.__main__:app \ No newline at end of file diff --git a/infrastructure/common-images/cloudharness-flask/requirements.txt b/infrastructure/common-images/cloudharness-flask/requirements.txt index fffe1a34..cb03aa81 100644 --- a/infrastructure/common-images/cloudharness-flask/requirements.txt +++ b/infrastructure/common-images/cloudharness-flask/requirements.txt @@ -1,90 +1,17 @@ -argo-workflows==5.0.0 -asn1crypto==0.24.0 -atomicwrites==1.4.0 -attrs==21.4. -black==22.1.0 -blinker==1.4 -cachetools==5.0.0 -certifi==2019.3.9 -cffi==1.15.0 -chardet==3.0.4 -charset-normalizer==2.0.12 -click==8.0.4 -clickclick==20.10.2 connexion==2.6.0 -coverage==6.3.2 -cryptography==3.3.2 -distlib==0.3.4 -ecdsa==0.17.0 -filelock==3.6.0 -flake8==4.0.1 Flask==1.1.2 Flask-Cors==3.0.9 flask-oidc==1.4.0 -Flask-SQLAlchemy==2.4.1 Flask-Testing==0.6.1 -google-auth==2.6.2 -greenlet==1.1.2 gunicorn==20.1.0 -httplib2==0.20.4 -idna==2.8 -importlib-metadata==4.2.0 -importlib-resources==5.4.0 -inflection==0.5.1 -isort==5.10.1 itsdangerous==2.0.1 Jinja2==3.0.3 jsonschema<4.0.0 -kafka-python==2.0.2 -kazoo==2.5.0 -MarkupSafe==2.1.1 -mccabe==0.6.1 -more-itertools==8.12.0 -mypy-extensions==0.4.3 -oauth2client==4.1.3 -oauthlib==3.2.0 -packaging==21.3 -pathspec==0.9.0 -pip-tools==6.5.1 -platformdirs==2.5.1 -pluggy==0.13.1 -pyaml==21.10.1 -pyasn1==0.4.8 -pyasn1-modules==0.2.8 -pycodestyle==2.8.0 -pycparser==2.21 -pyflakes==2.4.0 -PyJWT==1.7.1 -pykafka==2.8.0 -pyOpenSSL==19.0.0 -pyparsing==3.0.7 -pyrsistent==0.18.1 -PySocks==1.6.8 +openapi-spec-validator==0.4.0 pytest==4.6.11 pytest-cov==3.0.0 pytest-randomly==1.2.3 -python-dateutil==2.8.2 -python-jose==3.3.0 -python-keycloak==2.6.0 -PyYAML==6.0 -requests==2.27.1 -requests-oauthlib==1.3.1 -rsa==4.8 -ruamel.yaml==0.16.13 -ruamel.yaml.clib==0.2.6 sentry-sdk==0.14.4 -six==1.16.0 SQLAlchemy==1.4.32 swagger-ui-bundle==0.0.8 -tabulate==0.8.9 -toml==0.10.2 -tomli==2.0.1 -tox==3.24.5 -typed-ast==1.5.2 -typing_extensions==4.1.1 -urllib3==1.26.9 -virtualenv==20.13.4 -wcwidth==0.2.5 -websocket-client==1.3.1 -Werkzeug==2.0.3 -zipp==3.7.0 \ No newline at end of file +Werkzeug==2.0.3 \ No newline at end of file diff --git a/libraries/cloudharness-common/api/config.json b/libraries/api/config.json similarity index 100% rename from libraries/cloudharness-common/api/config.json rename to libraries/api/config.json diff --git a/libraries/cloudharness-common/api/openapi.yaml b/libraries/api/openapi.yaml similarity index 80% rename from libraries/cloudharness-common/api/openapi.yaml rename to libraries/api/openapi.yaml index d358f71b..a2d8400e 100644 --- a/libraries/cloudharness-common/api/openapi.yaml +++ b/libraries/api/openapi.yaml @@ -1,3 +1,4 @@ +--- openapi: 3.0.2 info: title: cloudharness @@ -17,7 +18,9 @@ components: description: "" type: string UriRoleMappingConfig: - description: "Defines the application Gatekeeper configuration, if enabled (i.e. `secured: true`." + description: + "Defines the application Gatekeeper configuration, if enabled (i.e.\ + \ `secured: true`." required: - roles - uri @@ -41,48 +44,28 @@ components: description: Service port type: integer - $ref: "#/components/schemas/AutoArtifactSpec" - DeploymentAutoArtifactConfig: - description: "" - type: object - allOf: - - type: object - - $ref: "#/components/schemas/AutoArtifactSpec" - properties: - port: - description: Deployment port - replicas: - description: Number of replicas - type: integer - image: - description: |- - Image name to use in the deployment. Leave it blank to set from the application's - Docker file - pattern: "(?:[a-z]+/)?([a-z]+)(?::[0-9]+)?" - type: string - resources: - description: Deployment resources ApplicationDependenciesConfig: description: "" type: object properties: hard: - description: >- - Hard dependencies indicate that the application may not start without these other - applications. + description: + Hard dependencies indicate that the application may not start + without these other applications. type: array items: type: string soft: - description: >- - Soft dependencies indicate that the application will work partially without these - other applications. + description: + Soft dependencies indicate that the application will work partially + without these other applications. type: array items: type: string build: - description: >- - Hard dependencies indicate that the application Docker image build requires these - base/common images + description: + Hard dependencies indicate that the application Docker image + build requires these base/common images type: array items: type: string @@ -124,11 +107,9 @@ components: description: "" type: string ApplicationProbe: - description: >- + description: |- Define a Kubernetes probe See also the - - [official - documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) + [official documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) required: - path type: object @@ -156,9 +137,9 @@ components: properties: harness: $ref: "#/components/schemas/ApplicationHarnessConfig" - description: >- - Values inside this section have a special meaning to cloudharness (e.g. enabling and - configuring automatic deployment) + description: + Values inside this section have a special meaning to cloudharness + (e.g. enabling and configuring automatic deployment) additionalProperties: true HarnessMainConfig: description: "" @@ -175,9 +156,9 @@ components: description: "If set to true, local DNS mapping is added to pods." type: boolean secured_gatekeepers: - description: >- - Enables/disables Gatekeepers on secured applications. Set to false for - testing/development + description: + Enables/disables Gatekeepers on secured applications. Set to + false for testing/development type: boolean domain: description: The root domain @@ -331,9 +312,10 @@ components: type: integer schedule: description: Cron expression - pattern: >- - /(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every - (\d+(ns|us|µs|ms|s|m|h))+)|((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,7})/ + pattern: + "/(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every\ + \ (\\d+(ns|us|µs|ms|s|m|h))+)|((((\\d+,)+\\d+|(\\d+(\\/|-)\\d+)|\\d+|\\\ + *) ?){5,7})/" type: string suffix: description: The file suffix added to backup files @@ -342,10 +324,20 @@ components: type: string dir: $ref: "#/components/schemas/Filename" - description: "Target directory of backups, the mount point of the persistent volume." + description: + "Target directory of backups, the mount point of the persistent\ + \ volume." resources: $ref: "#/components/schemas/DeploymentResourcesConf" description: "" + Quota: + description: "" + type: object + additionalProperties: + type: string + example: + quota-ws-max: 5 + quota-storage-max: 1G UserGroup: type: object properties: @@ -512,15 +504,17 @@ components: description: General description -- for human consumption type: string ApplicationHarnessConfig: - description: |- - Define helm variables that allow CloudHarness to enable and configure your - application's deployment + description: + "Define helm variables that allow CloudHarness to enable and configure\ + \ your \napplication's deployment" required: [] type: object properties: deployment: $ref: "#/components/schemas/DeploymentAutoArtifactConfig" - description: Defines reference deployment parameters. Values maps to k8s spec + description: + Defines reference deployment parameters. Values maps to k8s + spec service: $ref: "#/components/schemas/ServiceAutoArtifactConfig" description: Defines automatic service parameters. @@ -528,7 +522,9 @@ components: description: "If specified, an ingress will be created at [subdomain].[.Values.domain]" type: string aliases: - description: "If specified, an ingress will be created at [alias].[.Values.domain] for each alias" + description: + "If specified, an ingress will be created at [alias].[.Values.domain]\ + \ for each alias" type: array items: type: string @@ -537,14 +533,17 @@ components: type: string dependencies: $ref: "#/components/schemas/ApplicationDependenciesConfig" - description: >- - Application dependencies are used to define what is required in the deployment when - --include (-i) is used. Specify application names in the list. + description: + Application dependencies are used to define what is required + in the deployment when --include (-i) is used. Specify application names + in the list. secured: description: "When true, the application is shielded with a getekeeper" type: boolean uri_role_mapping: - description: "Map uri/roles to secure with the Gatekeeper (if `secured: true`)" + description: + "Map uri/roles to secure with the Gatekeeper (if `secured:\ + \ true`)" type: array items: $ref: "#/components/schemas/UriRoleMappingConfig" @@ -563,15 +562,9 @@ components: Values if left empty are randomly generated use_services: - description: >- - Specify which services this application uses in the frontend to create proxy - ingresses. e.g. - - ``` - - - name: samples - - ``` + description: + "Specify which services this application uses in the frontend\ + \ to create proxy ingresses. e.g. \n```\n- name: samples\n```" type: array items: type: string @@ -625,16 +618,19 @@ components: type: string extraConfig: $ref: "#/components/schemas/SimpleMap" - description: allows you to add Python snippets to the jupyterhub_config.py file + description: + allows you to add Python snippets to the jupyterhub_config.py + file spawnerExtraConfig: $ref: "#/components/schemas/FreeObject" - description: allows you to add values to the spawner object without the need of creating a new hook + description: + allows you to add values to the spawner object without the + need of creating a new hook applicationHook: - description: |- - change the hook function (advanced) - - Specify the Python name of the function (full module path, the module must be - installed in the Docker image) + description: + "change the hook function (advanced)\n\nSpecify the Python\ + \ name of the function (full module path, the module must be \ninstalled\ + \ in the Docker image)" example: my_lib.change_pod_manifest additionalProperties: true UserRole: @@ -661,12 +657,16 @@ components: type: object properties: roles: - description: Specify roles to be created in this deployment specific for this application + description: + Specify roles to be created in this deployment specific for + this application type: array items: type: string users: - description: "Defines test users to be added to the deployment, specific for this application" + description: + "Defines test users to be added to the deployment, specific\ + \ for this application" type: array items: $ref: "#/components/schemas/ApplicationUser" @@ -734,7 +734,9 @@ components: type: object properties: enabled: - description: "Enables end to end testing for this application (default: false)" + description: + "Enables end to end testing for this application (default:\ + \ false)" type: boolean smoketest: description: Specify whether to run the common smoke tests @@ -765,23 +767,73 @@ components: items: type: string checks: - description: >- + description: |- One of the Schemathesis checks: - - not_a_server_error. The response has 5xx HTTP status; - - status_code_conformance. The response status is not defined in the API schema; - - - content_type_conformance. The response content type is not defined in the API - schema; - - - response_schema_conformance. The response content does not conform to the schema - defined for this specific response; - - - response_headers_conformance. The response headers does not contain all defined - headers. + - content_type_conformance. The response content type is not defined in the API schema; + - response_schema_conformance. The response content does not conform to the schema defined for this specific response; + - response_headers_conformance. The response headers does not contain all defined headers. type: array items: type: string example: '["not_a_server_error", "status_code_conformance"]' + DeploymentAutoArtifactConfig: + description: "" + type: object + allOf: + - type: object + properties: + port: + description: Deployment port + type: string + replicas: + description: Number of replicas + type: integer + image: + description: |- + Image name to use in the deployment. Leave it blank to set from the application's + Docker file + pattern: "(?:[a-z]+/)?([a-z]+)(?::[0-9]+)?" + type: string + resources: + $ref: "#/components/schemas/DeploymentResourcesConf" + description: Deployment resources + volume: + $ref: "#/components/schemas/DeploymentVolumeSpec" + description: Volume specification + resources: + description: Deployment resources + type: string + test: + description: ssaa + type: string + - $ref: "#/components/schemas/AutoArtifactSpec" + DeploymentVolumeSpec: + description: |- + Defines a volume attached to the deployment. + Automatically created the volume claim and mounts. + type: object + allOf: + - required: + - mountpath + type: object + properties: + mountpath: + description: The mount path for the volume + type: string + size: + description: "The volume size. \n\nE.g. 5Gi" + usenfs: + description: + Set to `true` to use the nfs on the created volume and mount + as ReadWriteMany. + type: boolean + - $ref: "#/components/schemas/AutoArtifactSpec" + example: + auto: true + mountpath: /usr/src/app/persistent + name: my-files + size: 5Gi + usenfs: true diff --git a/libraries/cloudharness-common/cloudharness/__init__.py b/libraries/cloudharness-common/cloudharness/__init__.py index 7f8590c8..333321f2 100644 --- a/libraries/cloudharness-common/cloudharness/__init__.py +++ b/libraries/cloudharness-common/cloudharness/__init__.py @@ -46,8 +46,9 @@ def init(appname: str): if not appname: raise NotCorrectlyInitialized try: - from cloudharness import sentry - sentry.init(appname) + from cloudharness import sentry, applications + if applications.get_current_configuration().is_sentry_enabled(): + sentry.init(appname) except Exception as e: log.warning(f'Error enabling Sentry for {appname}', exc_info=True) diff --git a/libraries/cloudharness-common/cloudharness/applications.py b/libraries/cloudharness-common/cloudharness/applications.py index 770d0cc8..cea37e32 100644 --- a/libraries/cloudharness-common/cloudharness/applications.py +++ b/libraries/cloudharness-common/cloudharness/applications.py @@ -31,7 +31,7 @@ def is_auto_db(self) -> bool: return self.harness.database.auto def is_sentry_enabled(self) -> bool: - return self.harness.sentry + return self.harness["sentry"] def get_db_connection_string(self, **kwargs) -> str: if not self.is_auto_db(): diff --git a/libraries/cloudharness-common/cloudharness/auth/__init__.py b/libraries/cloudharness-common/cloudharness/auth/__init__.py index df314e32..ecf2dc26 100644 --- a/libraries/cloudharness-common/cloudharness/auth/__init__.py +++ b/libraries/cloudharness-common/cloudharness/auth/__init__.py @@ -1 +1,3 @@ -from .keycloak import * \ No newline at end of file +from .exceptions import * +from .keycloak import * +from .quota import * diff --git a/libraries/cloudharness-common/cloudharness/auth/exceptions.py b/libraries/cloudharness-common/cloudharness/auth/exceptions.py new file mode 100644 index 00000000..254340b8 --- /dev/null +++ b/libraries/cloudharness-common/cloudharness/auth/exceptions.py @@ -0,0 +1,11 @@ +from keycloak.exceptions import KeycloakAuthenticationError, KeycloakGetError + +class UserNotFound(KeycloakGetError): + pass + +class InvalidToken(Exception): + pass + +class AuthSecretNotFound(Exception): + def __init__(self, secret_name): + Exception.__init__(self, f"Secret {secret_name} not found.") \ No newline at end of file diff --git a/libraries/cloudharness-common/cloudharness/auth/keycloak.py b/libraries/cloudharness-common/cloudharness/auth/keycloak.py index 3a7ab8e8..eb51fb15 100644 --- a/libraries/cloudharness-common/cloudharness/auth/keycloak.py +++ b/libraries/cloudharness-common/cloudharness/auth/keycloak.py @@ -5,12 +5,13 @@ import requests from keycloak import KeycloakAdmin, KeycloakOpenID -from keycloak.exceptions import KeycloakAuthenticationError +from keycloak.exceptions import KeycloakAuthenticationError, KeycloakGetError from cloudharness import log from cloudharness.middleware import get_authentication_token from cloudharness.models import UserGroup, User +from .exceptions import UserNotFound, InvalidToken, AuthSecretNotFound try: from cloudharness.utils.config import CloudharnessConfig as conf, ALLVALUES_PATH @@ -20,9 +21,7 @@ ALLVALUES_PATH, exc_info=True) -class AuthSecretNotFound(Exception): - def __init__(self, secret_name): - Exception.__init__(self, f"Secret {secret_name} not found.") + def get_api_password() -> str: @@ -58,8 +57,10 @@ def decode_token(token, **kwargs): :return: Decoded token information or None if token is invalid :rtype: dict | None """ - - decoded = AuthClient.decode_token(token) + try: + decoded = AuthClient.decode_token(token) + except InvalidToken: + return None return decoded @@ -85,6 +86,15 @@ def get_token(username, password): client_secret_key=conf["webclient"]["secret"]) return keycloak_openid.token(username, password)['access_token'] +def is_uuid(s): + import uuid + try: + uuid.UUID(s) + return True + except ValueError: + return False + + class AuthClient(): __public_key = None @@ -105,16 +115,22 @@ def _get_keycloak_user_id(): if not authentication_token or authentication_token == 'Bearer undefined': keycloak_user_id = "-1" # No authorization --> no user else: - token = authentication_token.split(' ')[1] + token = authentication_token.split(' ')[-1] + keycloak_user_id = AuthClient.decode_token(token)['sub'] + return keycloak_user_id - def __init__(self): + def __init__(self, username=None, password=None): """ Init the class and checks the connectivity to the KeyCloak server """ + + self.user = username or os.getenv('ACCOUNTS_ADMIN_USERNAME', None) or "admin_api" + self.passwd = password or os.getenv('ACCOUNTS_ADMIN_PASSWORD', None) or get_api_password() # test if we can connect to the Keycloak server dummy_client = self.get_admin_client() + def get_admin_client(self): """ @@ -127,14 +143,13 @@ def get_admin_client(self): :return: KeycloakAdmin """ - user = "admin_api" - passwd = get_api_password() + if not getattr(self, "_admin_client", None): self._admin_client = KeycloakAdmin( server_url=get_server_url(), - username=user, - password=passwd, + username=self.user, + password=self.passwd, realm_name=get_auth_realm(), user_realm_name='master', verify=True) @@ -172,9 +187,11 @@ def decode_token(cls, token, audience="web-client"): :return: Decoded token information or None if token is invalid :rtype: dict | None """ - - decoded = jwt.decode(token, cls.get_public_key(), - algorithms='RS256', audience=audience) + try: + decoded = jwt.decode(token, cls.get_public_key(), + algorithms='RS256', audience=audience) + except jwt.exceptions.InvalidTokenError as e: + raise InvalidToken(e) from e return decoded @with_refreshtoken @@ -250,9 +267,14 @@ def create_client_role(self, client_id, role): return True @with_refreshtoken - def get_group(self, group_id, with_members=False) -> UserGroup: + def get_group(self, group_id, with_members=False, with_details=False) -> UserGroup: """ Return the group in the application realm + + :param group_id: the group id to get + :param with_members: Default False, when set to True all members of the group are also retrieved + :param with_details: Default False, when set to True all attributes of the group are also retrieved + GroupRepresentation https://www.keycloak.org/docs-api/16.0/rest-api/index.html#_grouprepresentation @@ -266,7 +288,7 @@ def get_group(self, group_id, with_members=False) -> UserGroup: members = admin_client.get_group_members(group_id) for user in members: user.update( - {'userGroups': admin_client.get_user_groups(user['id'])}) + {'userGroups': admin_client.get_user_groups(user['id'], brief_representation=not with_details)}) user.update( {'realmRoles': admin_client.get_realm_roles_of_user(user['id'])}) group.update({'members': members}) @@ -369,9 +391,12 @@ def group_user_remove(self, user_id, group_id): return admin_client.group_user_remove(user_id, group_id) @with_refreshtoken - def get_users(self, query=None) -> List[User]: + def get_users(self, query=None, with_details=False) -> List[User]: """ Return a list of all users in the application realm + + :param query: Default None, the query filter for getting the users + :param with_details: Default False, when set to True all attributes of the group are also retrieved UserRepresentation https://www.keycloak.org/docs-api/16.0/rest-api/index.html#_userrepresentation @@ -386,18 +411,20 @@ def get_users(self, query=None) -> List[User]: users = [] for user in admin_client.get_users(query=query): user.update({ - "userGroups": admin_client.get_user_groups(user['id']), + "userGroups": admin_client.get_user_groups(user['id'], brief_representation=not with_details), 'realmRoles': admin_client.get_realm_roles_of_user(user['id']) }) users.append(User.from_dict(user)) return users @with_refreshtoken - def get_user(self, user_id): + def get_user(self, user_id, with_details=False) -> User: """ Get the user including the user groups - :param user_id: User id + :param user_id_or_username: User id or username + :param with_details: Default False, when set to True all attributes of the group are also retrieved + UserRepresentation https://www.keycloak.org/docs-api/16.0/rest-api/index.html#_userrepresentation @@ -408,14 +435,27 @@ def get_user(self, user_id): :return: UserRepresentation + GroupRepresentation """ admin_client = self.get_admin_client() - user = admin_client.get_user(user_id) + if is_uuid(user_id): + try: + user = admin_client.get_user(user_id) + except KeycloakGetError as e: + raise UserNotFound(user_id) + except InvalidToken as e: + raise UserNotFound(user_id) + + else: + found_users = admin_client.get_users({"username": user_id}) + if len(found_users) == 0: + raise UserNotFound(user_id) + user = admin_client.get_user(found_users[0]['id']) # Load full data + user.update({ - "userGroups": admin_client.get_user_groups(user['id']), + "userGroups": admin_client.get_user_groups(user_id=user['id'], brief_representation=not with_details), 'realmRoles': admin_client.get_realm_roles_of_user(user['id']) }) return User.from_dict(user) - def get_current_user(self): + def get_current_user(self) -> User: """ Get the current user including the user groups @@ -428,7 +468,7 @@ def get_current_user(self): :return: UserRepresentation + GroupRepresentation """ return self.get_user(self._get_keycloak_user_id()) - + @with_refreshtoken def get_user_realm_roles(self, user_id) -> List[str]: """ diff --git a/libraries/cloudharness-common/cloudharness/auth/quota.py b/libraries/cloudharness-common/cloudharness/auth/quota.py new file mode 100644 index 00000000..a4106ee8 --- /dev/null +++ b/libraries/cloudharness-common/cloudharness/auth/quota.py @@ -0,0 +1,146 @@ +from keycloak import KeycloakError +from .keycloak import AuthClient +from cloudharness.applications import get_current_configuration +from cloudharness_model.models import ApplicationConfig +from cloudharness import log + +# quota tree node to hold the tree quota attributes + + +class QuotaNode: + def __init__(self, name, attrs): + self.attrs = attrs + self.name = name + self.children = [] + + def addChild(self, child): + self.children.append(child) + + +def _filter_quota_attrs(attrs, valid_keys_map): + # only use the attributes defined by the valid keys map + valid_attrs = {} + if attrs is None: + return valid_attrs + for key in attrs: + if key in valid_keys_map: + # map to value + valid_attrs.update({key: attrs[key][0]}) + return valid_attrs + + +def get_group_quotas(group, application_config: ApplicationConfig): + base_quotas = application_config.get("harness", {}).get("quotas", {}) + valid_keys_map = {key for key in base_quotas} + return _compute_quotas_from_tree(_construct_quota_tree([group], valid_keys_map)) + + +def _construct_quota_tree(groups, valid_keys_map) -> QuotaNode: + root = QuotaNode("root", {}) + for group in groups: + r = root + paths = group["path"].split("/")[1:] + # loop through all segements except the last segment + # the last segment is the one we want to add the attributes to + for segment in paths[0: len(paths) - 1]: + for child in r.children: + if child.name == segment: + r = child + break + else: + # no child found, add it with the segment name of the path + n = QuotaNode(segment, {}) + r.addChild(n) + r = n + # add the child with it's attributes and last segment name + n = QuotaNode( + paths[len(paths) - 1], + _filter_quota_attrs(group["attributes"], valid_keys_map) + ) + r.addChild(n) + return root + + +def _compute_quotas_from_tree(node: QuotaNode): + """Recursively traverse the tree and find the quota per level + the lower leafs overrule parent leafs values + + Args: + node (QuotaNode): the quota tree of QuotaNodes of the user for the given application + + Returns: + dict: key/value pairs of the quotas + + Example: + {'quota-ws-maxcpu': 1000, 'quota-ws-open': 10, 'quota-ws-max': 8} + + Algorithm explanation: + /Base {'quota-ws-max': 12345, 'quota-ws-maxcpu': 50, 'quota-ws-open': 1}\n + /Base/Base 1/Base 1 1 {'quota-ws-maxcpu': 2, 'quota-ws-open': 10}\n + /Base/Base 2 {'quota-ws-max': 8, 'quota-ws-maxcpu': 250}\n + /Low CPU {'quota-ws-max': 3, 'quota-ws-maxcpu': 1000, 'quota-ws-open': 1}\n + + result: {'quota-ws-maxcpu': 1000, 'quota-ws-open': 10, 'quota-ws-max': 8}\n + quota-ws-maxcpu from path "/Low CPU"\n + --> overrules paths "/Base/Base 1/Base 1 1" and "/Base/Base 2" (higher value)\n + --> /Base quota-ws-max is not used because this one is not the lowest + leaf with this attribute (Base 1 1 and Base 2 are "lower")\n + quota-ws-open from path "/Base/Base 1/Base 1 1"\n + quota-ws-max from path "/Base/Base 2"\n + """ + new_attrs = {} + for child in node.children: + child_attrs = _compute_quotas_from_tree(child) + for key in child_attrs: + try: + child_val = float(child_attrs[key]) + except: + # value not a float, skip (use 0) + child_val = 0 + if not key in new_attrs or new_attrs[key] < child_val: + new_attrs.update({key: child_val}) + for key in new_attrs: + node.attrs.update({key: new_attrs[key]}) + return node.attrs + + +def get_user_quotas(application_config: ApplicationConfig = None, user_id: str = None) -> dict: + """Get the user quota from Keycloak and application + + Args: + application_config (ApplicationConfig): the application config to use for getting the quotas + user_id (str): the Keycloak user id or username to get the quotas for + + Returns: + dict: key/value pairs of the user quota + + Example: + {'quota-ws-maxcpu': 1000, 'quota-ws-open': 10, 'quota-ws-max': 8} + """ + if not application_config: + application_config = get_current_configuration() + + base_quotas = application_config.get("harness", {}).get("quotas", {}) + try: + auth_client = AuthClient() + if not user_id: + user_id = auth_client.get_current_user()["id"] + user = auth_client.get_user(user_id, with_details=True) + except KeycloakError as e: + log.warning("Quotas not available: error retrieving user: %s", user_id) + return base_quotas + + valid_keys_map = {key for key in base_quotas} + + group_quotas = _compute_quotas_from_tree( + _construct_quota_tree( + user["userGroups"], + valid_keys_map)) + user_quotas = _filter_quota_attrs(user["attributes"], valid_keys_map) + for key in group_quotas: + if key not in user_quotas: + user_quotas.update({key: group_quotas[key]}) + for key in base_quotas: + if key not in user_quotas: + user_quotas.update({key: base_quotas[key]}) + return user_quotas diff --git a/libraries/cloudharness-common/cloudharness/middleware/__init__.py b/libraries/cloudharness-common/cloudharness/middleware/__init__.py index 850b1432..780ebd49 100644 --- a/libraries/cloudharness-common/cloudharness/middleware/__init__.py +++ b/libraries/cloudharness-common/cloudharness/middleware/__init__.py @@ -3,7 +3,8 @@ _authentication_token = ContextVar("ch_authentication_token", default=None) def set_authentication_token(authentication_token): - _authentication_token.set(authentication_token) + if authentication_token: + _authentication_token.set(authentication_token) def get_authentication_token(): return _authentication_token.get() diff --git a/libraries/cloudharness-common/cloudharness/service/pvc.py b/libraries/cloudharness-common/cloudharness/service/pvc.py index f875113d..18c4f725 100644 --- a/libraries/cloudharness-common/cloudharness/service/pvc.py +++ b/libraries/cloudharness-common/cloudharness/service/pvc.py @@ -6,16 +6,65 @@ from cloudharness.utils import dict_merge -def _get_api(): +def _get_client(): try: configuration = kubernetes.config.load_incluster_config() except: configuration = kubernetes.config.load_kube_config() - api_instance = kubernetes.client.CoreV1Api(kubernetes.client.ApiClient(configuration)) - return api_instance + return kubernetes.client.ApiClient(configuration) -def create_persistent_volume_claim(name, size, logger, **kwargs): +def _get_corev1_api(): + return kubernetes.client.CoreV1Api(_get_client()) + + +def _get_nfs_storage_class() -> str: + """ + NFS storage class + + :return: Returns the NFS storage class name that belongs + to this namespace (deployment) + """ + nfsserver_conf = conf.get_application_by_filter(storageClass__name=True)[0] + return f"{conf.get_configuration()['namespace']}-{nfsserver_conf['storageClass']['name']}" + + +def _get_default_storage_class() -> str: + """ + Default storage class + + :return: Returns the default storage class name, if exists. + If not, it returns the first storage class. + If there are not storage classes, returns None + """ + + storagev1 = kubernetes.client.StorageV1Api(_get_client()) + storage_classes = storagev1.list_storage_class() + selected_sc = None + default_sc_annotations = { + "storageclass.kubernetes.io/is-default-class": "true", + # Older clusters still use the beta annotation. + "storageclass.beta.kubernetes.io/is-default-class": "true", + } + + # default to the first if there is no default + selected_sc = storage_classes.items[0].metadata.name + + for sc in storage_classes.items: + if not selected_sc: + # Select the first storage class in case there is no a default-class + selected_sc = sc.metadata.name + annotations = sc.metadata.annotations + if any( + k in annotations and annotations[k] == v + for k, v in default_sc_annotations.items() + ): + # Default storage + selected_sc = sc.metadata.name + break + return selected_sc + +def create_persistent_volume_claim(name, size, logger, storage_class=None, useNFS=False, template=None, access_mode=None, **kwargs): """ Create a Persistent Volume Claim in the Kubernetes cluster. If a PVC with the name given already exists then the function @@ -25,24 +74,47 @@ def create_persistent_volume_claim(name, size, logger, **kwargs): name (string): the name of the PVC size (string): the size of the PVC, e.g. 2Gi for a 2Gb PVC logger (logger): the logger where the information message is sent to + storage_class (string, optional): the name of the K8s storage class to use + useNFS (boolean, default False): if set to True CH will search + for the storage class that is linked to the local CH NFS Server + template (text, optional): the template to use to create the PVC **kwargs - the dictionary is used to override the default template Returns: - """ + if persistent_volume_claim_exists(name): + return + if not size: raise Exception(f"Size must be set. Got {size!r}.") - - if not persistent_volume_claim_exists(name): + + if not storage_class: + if not useNFS: + storage_class = _get_default_storage_class() + else: + # determine the NFS storage class + storage_class = _get_nfs_storage_class() + + if not access_mode and useNFS: + access_mode = "ReadWriteMany" + + if not template: path = os.path.join(os.path.dirname(__file__), 'templates', 'pvc.yaml') - tmpl = open(path, 'rt').read() - text = tmpl.format(name=name, size=size) - data = dict_merge(yaml.safe_load(text), kwargs) + template = open(path, 'rt').read() + text = template.format( + name=name, + size=size, + storageClass=storage_class) + data = dict_merge(yaml.safe_load(text), kwargs) + + if access_mode: + data["spec"]["accessModes"] = [access_mode] - obj = _get_api().create_namespaced_persistent_volume_claim( + obj = _get_corev1_api().create_namespaced_persistent_volume_claim( namespace=conf.get_configuration()['namespace'], body=data, ) - logger.info(f"PVC child is created: %s", obj) + logger.info(f"PVC child is created: %s", obj) def persistent_volume_claim_exists(name): @@ -71,7 +143,7 @@ def get_persistent_volume_claim(name): Returns: The PVC data (see https://kubernetes.io/docs/concepts/storage/persistent-volumes/) """ - foundPVCs = _get_api().list_namespaced_persistent_volume_claim( + foundPVCs = _get_corev1_api().list_namespaced_persistent_volume_claim( namespace=conf.get_configuration()['namespace'], field_selector=f'metadata.name={name}') if len(foundPVCs.items) > 0: @@ -80,6 +152,6 @@ def get_persistent_volume_claim(name): def delete_persistent_volume_claim(name): - _get_api().delete_namespaced_persistent_volume_claim( + _get_corev1_api().delete_namespaced_persistent_volume_claim( name=name, namespace=conf.get_configuration()['namespace']) diff --git a/libraries/cloudharness-common/cloudharness/service/templates/pvc.yaml b/libraries/cloudharness-common/cloudharness/service/templates/pvc.yaml index ccd19566..0e99a6df 100644 --- a/libraries/cloudharness-common/cloudharness/service/templates/pvc.yaml +++ b/libraries/cloudharness-common/cloudharness/service/templates/pvc.yaml @@ -3,7 +3,7 @@ kind: PersistentVolumeClaim metadata: name: "{name}" annotations: - volume.beta.kubernetes.io/storage-class: standard + volume.beta.kubernetes.io/storage-class: "{storageClass}" spec: accessModes: - ReadWriteOnce diff --git a/libraries/cloudharness-common/cloudharness/utils/env.py b/libraries/cloudharness-common/cloudharness/utils/env.py index a9d76cea..05588aad 100644 --- a/libraries/cloudharness-common/cloudharness/utils/env.py +++ b/libraries/cloudharness-common/cloudharness/utils/env.py @@ -5,6 +5,7 @@ from .. import log from .config import CloudharnessConfig as conf +from ..applications import get_configuration TEST = 'TEST' PROD = 'PROD' @@ -105,7 +106,7 @@ def get_sub_variable(*vars): def get_service_public_address(app_name): - return ".".join([get_sub_variable('CH', app_name.upper(), 'SUBDOMAIN'), get_public_domain()]) + return get_configuration(app_name).get_public_address() def get_public_domain(): @@ -113,28 +114,27 @@ def get_public_domain(): def get_cloudharness_workflows_service_url(): - return get_service_public_address('WORKFLOWS') + return get_service_public_address('workflows') def get_cloudharness_sentry_service_url(): - return 'https://' + get_service_public_address('sentry') + return get_configuration('sentry').get_public_address() def get_sentry_service_cluster_address(): - sentry_app = conf.get_application_by_filter(name='sentry')[0] - return f'http://{sentry_app.name}:{sentry_app.port}' + return get_configuration('sentry').get_service_address() def get_cloudharness_common_service_url(): - return 'https://' + get_service_public_address('common') + return get_configuration('common').get_public_address() def get_common_service_cluster_address(): - common_app = conf.get_application_by_filter(name='common')[0] - return f'http://{common_app.name}:{common_app.port}' + common_app = get_configuration('common') + return common_app.get_service_address() def get_auth_service_cluster_address(): - return get_service_cluster_address('ACCOUNTS') + return get_configuration('accounts').get_service_address() def get_auth_service_url(): - return get_service_public_address('ACCOUNTS') + return get_configuration('accounts').get_public_address() def get_auth_realm(): diff --git a/libraries/cloudharness-common/cloudharness/workflows/operations.py b/libraries/cloudharness-common/cloudharness/workflows/operations.py index 70a9ffef..1e0ee9f3 100644 --- a/libraries/cloudharness-common/cloudharness/workflows/operations.py +++ b/libraries/cloudharness-common/cloudharness/workflows/operations.py @@ -1,6 +1,6 @@ import time from collections.abc import Iterable -from typing import Union +from typing import List, Union import pyaml @@ -9,7 +9,7 @@ from cloudharness.utils import env, config from . import argo from .tasks import Task, SendResultTask, CustomTask -from .utils import is_accounts_present +from .utils import PodExecutionContext, affinity_spec, is_accounts_present, name_from_path, volume_mount_template POLLING_WAIT_SECONDS = 1 SERVICE_ACCOUNT = 'argo-workflows' @@ -25,16 +25,7 @@ class BadOperationConfiguration(RuntimeError): pass -class PodExecutionContext: - """ - Key-value pair representing the execution context with other pods. - Automatically assigns meta data and pod affinity - """ - def __init__(self, key, value, required=False): - self.key = str(key) - self.value = str(value) - self.required = required class ManagedOperation: @@ -95,6 +86,7 @@ def __init__(self, basename: str, pod_context: Union[PodExecutionContext, list, assert len(set(shared_directory)) == len(shared_directory), "Shared directories are not unique" assert len(set(s.split(":")[0] for s in shared_directory)) == len( shared_directory), "Shared directories volumes are not unique" + if shared_path: for task in self.task_list(): @@ -103,9 +95,9 @@ def __init__(self, basename: str, pod_context: Union[PodExecutionContext, list, self.volumes = tuple() self.pod_contexts += [PodExecutionContext('usesvolume', v.split(':')[0], True) for v in self.volumes if - ':' in v] + ':' in v and (len(v.split(':')) < 3 or v.split(':')[2] != "rwx")] - def task_list(self): + def task_list(self) -> List[Task]: raise NotImplementedError() @property @@ -152,51 +144,20 @@ def spec(self): spec = self.add_on_exit_notify_handler(spec) if self.pod_contexts: - spec['affinity'] = self.affinity_spec() - if self.volumes: - spec['volumeClaimTemplates'] = [self.spec_volumeclaim(volume) for volume in self.volumes if + spec['affinity'] = affinity_spec(self.pod_contexts) + + volumes_mounts = list(self.volumes) or [] + # Tasks volumes must be declared at workflow level + volumes_mounts += list({v for task in self.task_list() for v in task.volume_mounts if task.volume_mounts}) + + spec['volumeClaimTemplates'] = [self.spec_volumeclaim(volume) for volume in volumes_mounts if ':' not in volume] # without PVC prefix (e.g. /location) - spec['volumes'] += [self.spec_volume(volume) for volume in self.volumes if + spec['volumes'] += [self.spec_volume(volume) for volume in volumes_mounts if ':' in volume] # with PVC prefix (e.g. pvc-001:/location) - return spec - def affinity_spec(self): - contexts = self.pod_contexts - PREFERRED = 'preferredDuringSchedulingIgnoredDuringExecution' - REQUIRED = 'requiredDuringSchedulingIgnoredDuringExecution' - - pod_affinity = { - PREFERRED: [], - REQUIRED: [] - } + return spec - for context in contexts: - term = { - 'labelSelector': - { - 'matchExpressions': [ - { - 'key': context.key, - 'operator': 'In', - 'values': [context.value] - }, - ] - }, - 'topologyKey': 'kubernetes.io/hostname' - } - if not context.required: - pod_affinity[PREFERRED].append( - { - 'weight': 100, - 'podAffinityTerm': term - }) - else: - pod_affinity[REQUIRED].append(term) - - return { - 'podAffinity': pod_affinity - } def add_on_exit_notify_handler(self, spec): queue = self.on_exit_notify['queue'] @@ -217,15 +178,19 @@ def add_on_exit_notify_handler(self, spec): def modify_template(self, template): """Hook to modify templates (e.g. add volumes)""" - template["metadata"] = {"labels": {c.key: c.value for c in self.pod_contexts}} + if 'metadata' not in template: + template['metadata'] = dict() + if 'labels' not in template["metadata"]: + template["metadata"]["labels"] = dict() + template["metadata"]["labels"] = template["metadata"]["labels"] | {c.key: c.value for c in self.pod_contexts} if self.volumes: if 'container' in template: template['container']['volumeMounts'] += [ - self.volume_template(volume) for volume in self.volumes] + volume_mount_template(volume) for volume in self.volumes] elif 'script' in template: template['script']['volumeMounts'] += [ - self.volume_template(volume) for volume in self.volumes] + volume_mount_template(volume) for volume in self.volumes] return template @@ -254,26 +219,16 @@ def is_error(self): return self.persisted.status in (OperationStatus.ERROR, OperationStatus.FAILED) return False - def name_from_path(self, path): - return path.replace('/', '').replace('_', '').lower() + - def volume_template(self, volume): - path = volume - splitted = volume.split(':') - if len(splitted) > 1: - path = splitted[1] - return dict({ - 'name': self.name_from_path(path), - 'mountPath': path, - 'readonly': False if len(splitted) < 3 else splitted[2] == "ro" - }) + def spec_volumeclaim(self, volume): # when the volume is NOT prefixed by a PVC (e.g. /location) then create a temporary PVC for the workflow if ':' not in volume: return { 'metadata': { - 'name': self.name_from_path(volume.split(':')[0]), + 'name': name_from_path(volume.split(':')[0]), }, 'spec': { 'accessModes': ["ReadWriteOnce"], @@ -292,7 +247,7 @@ def spec_volume(self, volume): if ':' in volume: pvc, path, *c = volume.split(':') return { - 'name': self.name_from_path(path), + 'name': name_from_path(path), 'persistentVolumeClaim': { 'claimName': pvc }, diff --git a/libraries/cloudharness-common/cloudharness/workflows/tasks.py b/libraries/cloudharness-common/cloudharness/workflows/tasks.py index e881b482..c88ccc21 100644 --- a/libraries/cloudharness-common/cloudharness/workflows/tasks.py +++ b/libraries/cloudharness-common/cloudharness/workflows/tasks.py @@ -1,7 +1,7 @@ from . import argo from cloudharness.utils.env import get_cloudharness_variables, get_image_full_tag -from .utils import WORKFLOW_NAME_VARIABLE_NAME, is_accounts_present +from .utils import WORKFLOW_NAME_VARIABLE_NAME, PodExecutionContext, affinity_spec, is_accounts_present, volume_mount_template, volume_requires_affinity SERVICE_ACCOUNT = 'argo-workflows' @@ -11,13 +11,30 @@ class Task(argo.ArgoObject): Abstract interface for a task. """ - def __init__(self, name, resources={}, **env_args): + def __init__(self, name, resources={}, volume_mounts=[], **env_args): self.name = name.replace(' ', '-').lower() self.resources = resources self.__envs = get_cloudharness_variables() + self.volume_mounts = volume_mounts + self.external_volumes = [ + v.split(':')[0] for v in self.volume_mounts if volume_requires_affinity(v)] for k in env_args: self.__envs[k] = str(env_args[k]) + def metadata_spec(self): + return { + 'labels': { + 'usesvolume': self.external_volumes[0], + **{f'usesvolume-{v}': 'true' for v in self.external_volumes} + } + } if self.external_volumes else {} + + def affinity_spec(self): + return affinity_spec(([PodExecutionContext('usesvolume', self.external_volumes[0], True)] if self.external_volumes else []) + [ + PodExecutionContext(f'usesvolume-{v}', 'true', True) + for v in self.external_volumes + ] ) + @property def image_name(self): raise NotImplemented @@ -62,6 +79,9 @@ def cloudharness_configmap_spec(self): }) return base_spec + def volumes_mounts_spec(self): + return self.cloudharness_configmap_spec() + [volume_mount_template(volume) for volume in self.volume_mounts] + class ContainerizedTask(Task): @@ -71,18 +91,20 @@ def __init__(self, name, resources={}, image_pull_policy='IfNotPresent', command self.command = command def spec(self): + spec = { 'container': { 'image': self.image_name, 'env': self.envs, 'resources': self.resources, 'imagePullPolicy': self.image_pull_policy, - 'volumeMounts': self.cloudharness_configmap_spec(), + 'volumeMounts': self.volumes_mounts_spec(), }, 'inputs': {}, - 'metadata': {}, + 'metadata': self.metadata_spec(), 'name': self.name, - 'outputs': {} + 'outputs': {}, + 'affinity': self.affinity_spec() } if self.command is not None: @@ -95,21 +117,24 @@ class InlinedTask(Task): Allows to run Python tasks """ - def __init__(self, name, source): - super().__init__(name) + def __init__(self, name, source, **kwargs): + super().__init__(name, **kwargs) self.source = source def spec(self): + return { 'name': self.name, + 'affinity': self.affinity_spec(), + 'metadata': self.metadata_spec(), 'script': { 'image': self.image_name, 'env': self.envs, 'source': self.source, - 'volumeMounts': self.cloudharness_configmap_spec(), + 'volumeMounts': self.volumes_mounts_spec(), 'command': [self.command] - } + } } @property diff --git a/libraries/cloudharness-common/cloudharness/workflows/utils.py b/libraries/cloudharness-common/cloudharness/workflows/utils.py index 285a7d10..2ad94fd2 100644 --- a/libraries/cloudharness-common/cloudharness/workflows/utils.py +++ b/libraries/cloudharness-common/cloudharness/workflows/utils.py @@ -8,6 +8,16 @@ SHARED_DIRECTORY_VARIABLE_NAME = "shared_directory" +class PodExecutionContext: + """ + Key-value pair representing the execution context with other pods. + Automatically assigns meta data and pod affinity + """ + + def __init__(self, key, value, required=False): + self.key = str(key) + self.value = str(value) + self.required = required def get_workflow_name(): """Get the workflow name from inside a workflow""" @@ -15,6 +25,8 @@ def get_workflow_name(): remove = name.split("-")[-1] return name[0:-len(remove) - 1] +def volume_requires_affinity(v): + return ':' in v and 'rwx' not in v[-4:] def get_shared_directory(): return os.getenv(SHARED_DIRECTORY_VARIABLE_NAME) @@ -27,7 +39,62 @@ def notify_queue(queue, message): def is_accounts_present(): try: - applications.ApplicationConfiguration = applications.get_configuration('accounts') + applications.ApplicationConfiguration = applications.get_configuration( + 'accounts') return True except Exception: return False + + +def name_from_path(path): + return path.replace('/', '').replace('_', '').lower() + + +def volume_mount_template(volume): + path = volume + splitted = volume.split(':') + if len(splitted) > 1: + path = splitted[1] + return dict({ + 'name': name_from_path(path), + 'mountPath': path, + 'readonly': False if len(splitted) < 3 else splitted[2] == "ro" + }) + + +def affinity_spec(contexts: PodExecutionContext): + PREFERRED = 'preferredDuringSchedulingIgnoredDuringExecution' + REQUIRED = 'requiredDuringSchedulingIgnoredDuringExecution' + + pod_affinity = { + PREFERRED: [], + REQUIRED: [] + } + + for context in contexts: + term = { + 'labelSelector': + { + 'matchExpressions': [ + { + 'key': context.key, + 'operator': 'In', + 'values': [context.value] + }, + ] + }, + 'topologyKey': 'kubernetes.io/hostname' + } + if not context.required: + pod_affinity[PREFERRED].append( + { + 'weight': 100, + 'podAffinityTerm': term + + }) + else: + pod_affinity[REQUIRED].append(term) + + return { + 'podAffinity': pod_affinity + } diff --git a/libraries/cloudharness-common/requirements.txt b/libraries/cloudharness-common/requirements.txt index 6081e448..200b01d1 100644 --- a/libraries/cloudharness-common/requirements.txt +++ b/libraries/cloudharness-common/requirements.txt @@ -3,7 +3,7 @@ certifi==2019.3.9 chardet==3.0.4 idna==2.8 pyjwt==2.6.0 -pyOpenSSL==22.1.0 +pyOpenSSL<22.1.0 PySocks==1.6.8 requests>=2.27.0 ruamel.yaml==0.17.21 @@ -16,6 +16,7 @@ kubernetes sentry-sdk[flask]==0.14.4 python-keycloak==2.6.0 argo-workflows==5.0.0 +cryptography<3.4 hypothesis==6.54.2 jsonschema<4.0.0 -httpx==0.23.0 \ No newline at end of file +httpx==0.23.0 diff --git a/libraries/cloudharness-common/setup.py b/libraries/cloudharness-common/setup.py index b6a70e06..b07f056b 100644 --- a/libraries/cloudharness-common/setup.py +++ b/libraries/cloudharness-common/setup.py @@ -3,7 +3,7 @@ NAME = "cloudharness" -VERSION = "2.0.0" +VERSION = "2.1.0" # To install the library, run the following # # python setup.py install diff --git a/libraries/cloudharness-common/test-requirements.txt b/libraries/cloudharness-common/test-requirements.txt index 51b437b1..0fa41ffd 100644 --- a/libraries/cloudharness-common/test-requirements.txt +++ b/libraries/cloudharness-common/test-requirements.txt @@ -1,5 +1,6 @@ pytest pytest-cov +pytest-mock coverage nose randomize diff --git a/libraries/cloudharness-common/tests/test_quota.py b/libraries/cloudharness-common/tests/test_quota.py new file mode 100644 index 00000000..707ea8a6 --- /dev/null +++ b/libraries/cloudharness-common/tests/test_quota.py @@ -0,0 +1,42 @@ +from .test_env import set_test_environment + +set_test_environment() + +from cloudharness import set_debug +from cloudharness.applications import get_configuration +from cloudharness.auth.quota import get_user_quotas + +set_debug() + +jh_config = get_configuration("jupyterhub") +assert jh_config is not None + +def test_get_quotas(mocker): + def mock_get_admin_client(self): + return None + def mock_get_current_user(self): + return {"id":"123"} + def mock_get_user(self, user_id, with_details): + return { + "attributes": { + "quota-ws-guaranteemem": [0.5] + }, + "userGroups": [ + {"path": "/Base", "attributes": {'quota-ws-maxmem': [2.5], 'quota-ws-maxcpu': [1], 'quota-ws-open': [3], "quota-ws-guaranteemem": [0.1]} }, + {"path": "/Base/Base 1/Base 1 1", "attributes": {'quota-ws-maxcpu': [2], 'quota-ws-open': [10]}}, + {"path": "/Base/Base 2", "attributes": {'quota-ws-maxmem': [8], 'quota-ws-maxcpu': [0.25], 'quota-ws-guaranteecpu': [0.25]}}, + {"path": "/Low CU", "attributes": {'quota-ws-maxmem': [3], 'quota-ws-maxcpu': [2.5], 'quota-ws-open': [1]}} + ] + } + mocker.patch('cloudharness.auth.keycloak.AuthClient.get_admin_client', mock_get_admin_client) + mocker.patch('cloudharness.auth.keycloak.AuthClient.get_current_user', mock_get_current_user) + mocker.patch('cloudharness.auth.keycloak.AuthClient.get_user', mock_get_user) + user_quotas_jh = get_user_quotas(jh_config, user_id=None) + + assert user_quotas_jh.get("quota-ws-maxmem") == 8.0 + assert user_quotas_jh.get("quota-ws-maxcpu") == 2.5 + assert user_quotas_jh.get("quota-ws-open") == 10.0 + assert user_quotas_jh.get("quota-ws-guaranteecpu") == 0.25 + assert user_quotas_jh.get("quota-ws-guaranteemem") == 0.5 + assert user_quotas_jh.get("quota-storage-max") == 1.25 + print(user_quotas_jh) diff --git a/libraries/cloudharness-common/tests/test_workflow.py b/libraries/cloudharness-common/tests/test_workflow.py index 6b007b96..18a2c6d1 100644 --- a/libraries/cloudharness-common/tests/test_workflow.py +++ b/libraries/cloudharness-common/tests/test_workflow.py @@ -7,7 +7,7 @@ set_test_environment() -from cloudharness.workflows import operations, tasks +from cloudharness.workflows import operations, tasks, utils from cloudharness import set_debug from cloudharness.workflows import argo from cloudharness.utils.config import CloudharnessConfig @@ -19,6 +19,16 @@ assert 'registry' in CloudharnessConfig.get_configuration() +def check_wf(wf): + + assert wf["kind"] == "Workflow" + assert "spec" in wf + +def test_volume_affinity_check(): + assert not utils.volume_requires_affinity("a") + assert utils.volume_requires_affinity("a:b") + assert utils.volume_requires_affinity("a:b:ro") + assert not utils.volume_requires_affinity("a:b:rwx") def test_sync_workflow(): def f(): @@ -29,7 +39,9 @@ def f(): task = tasks.PythonTask('my-task', f) assert 'registry' in CloudharnessConfig.get_configuration() op = operations.DistributedSyncOperation('test-sync-op-', task) - print('\n', yaml.dump(op.to_workflow())) + # print('\n', yaml.dump(op.to_workflow())) + wf = op.to_workflow() + if execute: print(op.execute()) @@ -42,7 +54,8 @@ def f(): print('whatever') op = operations.PipelineOperation('test-pipeline-op-', (tasks.PythonTask('step1', f), tasks.PythonTask('step2', f))) - print('\n', yaml.dump(op.to_workflow())) + # print('\n', yaml.dump(op.to_workflow())) + wf = op.to_workflow() if execute: op.execute() @@ -54,7 +67,7 @@ def f(): print('whatever') op = operations.ParallelOperation('test-parallel-op-', (tasks.PythonTask('p1', f), tasks.PythonTask('p2', f))) - print('\n', yaml.dump(op.to_workflow())) + # print('\n', yaml.dump(op.to_workflow())) if execute: op.execute() @@ -68,7 +81,7 @@ def f(): # p3 runs after p1 and p2 finish op = operations.SimpleDagOperation('test-dag-op-', (tasks.PythonTask('p1', f), tasks.PythonTask('p2', f)), tasks.PythonTask('p3', f)) - print('\n', yaml.dump(op.to_workflow())) + # print('\n', yaml.dump(op.to_workflow())) if execute: print(op.execute()) @@ -76,7 +89,7 @@ def f(): def test_custom_task_workflow(): task = operations.CustomTask('download-file', 'workflows-extract-download', url='https://www.bing.com') op = operations.PipelineOperation('test-custom-op-', (task,)) - print('\n', yaml.dump(op.to_workflow())) + # print('\n', yaml.dump(op.to_workflow())) if execute: print(op.execute()) @@ -90,8 +103,8 @@ def test_custom_connected_task_workflow(): file_path=shared_directory + '/README.md') op = operations.PipelineOperation('test-custom-connected-op-', (task_write, task_print), shared_directory=shared_directory, shared_volume_size=100) - # op.execute() - print('\n', yaml.dump(op.to_workflow())) + wf = op.to_workflow() + # print('\n', yaml.dump(op.to_workflow())) if execute: print(op.execute()) @@ -103,6 +116,59 @@ def test_single_task_shared(): op = operations.SingleTaskOperation('test-custom-connected-op-', task_write, shared_directory=shared_directory, shared_volume_size=100) wf = op.to_workflow() + + accounts_offset = 1 if is_accounts_present() else 0 + assert len(op.volumes) == 1 + assert len(wf['spec']['volumes']) == 2 + accounts_offset + assert wf['spec']['volumes'][1+accounts_offset]['persistentVolumeClaim']['claimName'] == 'myclaim' + if accounts_offset == 1: + assert wf['spec']['volumes'][1]['secret']['secretName'] == 'accounts' + assert len(wf['spec']['templates'][0]['container']['volumeMounts']) == 2 + accounts_offset + assert wf['spec']['templates'][0]['metadata']['labels']['usesvolume'] == 'myclaim' + + affinity_glob = \ + wf['spec']['affinity']['podAffinity']['requiredDuringSchedulingIgnoredDuringExecution'][0]['labelSelector'][ + 'matchExpressions'][0] + assert affinity_glob['key'] == 'usesvolume' + assert affinity_glob['values'][0] == 'myclaim' + + if execute: + print(op.execute()) + +def test_pipeline_shared(): + shared_directory = 'myclaim:/mnt/shared' + task_write = operations.CustomTask('download-file', 'workflows-extract-download', + url='https://raw.githubusercontent.com/openworm/org.geppetto/master/README.md') + task_script = tasks.BashTask('print-file', source="ls -la") + op = operations.PipelineOperation('test-custom-connected-op-', [task_write, task_script], + shared_directory=shared_directory, shared_volume_size=100) + wf = op.to_workflow() + + accounts_offset = 1 if is_accounts_present() else 0 + assert len(op.volumes) == 1 + assert len(wf['spec']['volumes']) == 2 + accounts_offset + assert wf['spec']['volumes'][1+accounts_offset]['persistentVolumeClaim']['claimName'] == 'myclaim' + if accounts_offset == 1: + assert wf['spec']['volumes'][1]['secret']['secretName'] == 'accounts' + assert len(wf['spec']['templates'][1]['container']['volumeMounts']) == 2 + accounts_offset + assert wf['spec']['templates'][1]['metadata']['labels']['usesvolume'] == 'myclaim' + assert wf['spec']['templates'][2]['metadata']['labels']['usesvolume'] == 'myclaim' + affinity_glob = \ + wf['spec']['affinity']['podAffinity']['requiredDuringSchedulingIgnoredDuringExecution'][0]['labelSelector'][ + 'matchExpressions'][0] + assert affinity_glob['key'] == 'usesvolume' + assert affinity_glob['values'][0] == 'myclaim' + + if execute: + print(op.execute()) + +def test_single_task_shared_rwx(): + shared_directory = 'myclaim:/mnt/shared:rwx' + task_write = operations.CustomTask('download-file', 'workflows-extract-download', + url='https://raw.githubusercontent.com/openworm/org.geppetto/master/README.md') + op = operations.SingleTaskOperation('test-custom-connected-op-', task_write, + shared_directory=shared_directory, shared_volume_size=100) + wf = op.to_workflow() print('\n', yaml.dump(wf)) accounts_offset = 1 if is_accounts_present() else 0 @@ -112,9 +178,68 @@ def test_single_task_shared(): if accounts_offset == 1: assert wf['spec']['volumes'][1]['secret']['secretName'] == 'accounts' assert len(wf['spec']['templates'][0]['container']['volumeMounts']) == 2 + accounts_offset + + + + + assert not 'affinity' in wf['spec'], "Pod affinity should not be added for rwx volumes" + +def test_single_task_volume_notshared(): + + task_write = operations.CustomTask('download-file', 'workflows-extract-download', volume_mounts=["a:b"], + url='https://raw.githubusercontent.com/openworm/org.geppetto/master/README.md') + op = operations.SingleTaskOperation('test-custom-connected-op-', task_write, shared_volume_size=100) + wf = op.to_workflow() + + accounts_offset = 1 if is_accounts_present() else 0 + assert len(op.volumes) == 0 + assert len(wf['spec']['volumes']) == 2 + accounts_offset + assert wf['spec']['volumes'][1+accounts_offset]['persistentVolumeClaim']['claimName'] == 'a' + if accounts_offset == 1: + assert wf['spec']['volumes'][1]['secret']['secretName'] == 'accounts' + assert len(wf['spec']['templates'][0]['container']['volumeMounts']) == 2 + accounts_offset + + + assert 'affinity' not in wf['spec'] + + affinity_tpl = \ + wf['spec']['templates'][0]['affinity']['podAffinity']['requiredDuringSchedulingIgnoredDuringExecution'][0]['labelSelector'][ + 'matchExpressions'][0] + assert affinity_tpl['key'] == 'usesvolume' + assert affinity_tpl['values'][0] == 'a' + assert wf['spec']['templates'][0]['metadata']['labels']['usesvolume'] == 'a' if execute: print(op.execute()) +def test_single_task_volumes_notshared(): + shared_directory = 'myclaim:/mnt/shared' + task_write = operations.CustomTask('download-file', 'workflows-extract-download', volume_mounts=["a:b"], + url='https://raw.githubusercontent.com/openworm/org.geppetto/master/README.md') + op = operations.SingleTaskOperation('test-custom-connected-op-', task_write, shared_volume_size=100, shared_directory=shared_directory) + wf = op.to_workflow() + + accounts_offset = 1 if is_accounts_present() else 0 + assert len(op.volumes) == 1 + assert len(wf['spec']['volumes']) == 3 + accounts_offset + assert wf['spec']['volumes'][1+accounts_offset]['persistentVolumeClaim']['claimName'] == 'myclaim' + if accounts_offset == 1: + assert wf['spec']['volumes'][1]['secret']['secretName'] == 'accounts' + assert len(wf['spec']['templates'][0]['container']['volumeMounts']) == 3 + accounts_offset + + affinity_glob = \ + wf['spec']['affinity']['podAffinity']['requiredDuringSchedulingIgnoredDuringExecution'][0]['labelSelector'][ + 'matchExpressions'][0] + assert affinity_glob['key'] == 'usesvolume' + assert affinity_glob['values'][0] == 'myclaim' + + affinity_tpl = \ + wf['spec']['templates'][0]['affinity']['podAffinity']['requiredDuringSchedulingIgnoredDuringExecution'][0]['labelSelector'][ + 'matchExpressions'][0] + assert affinity_tpl['key'] == 'usesvolume' + assert affinity_tpl['values'][0] == 'a' + assert wf['spec']['templates'][0]['metadata']['labels']['usesvolume'] + if execute: + print(op.execute()) def test_single_task_shared_multiple(): shared_directory = ['myclaim:/mnt/shared', 'myclaim2:/mnt/shared2:ro'] @@ -147,6 +272,7 @@ def test_single_task_shared_multiple(): print(op.execute()) + def test_single_task_shared_script(): shared_directory = 'myclaim:/mnt/shared' task_write = tasks.BashTask('download-file', source="ls -la") @@ -172,7 +298,7 @@ def test_result_task_workflow(): op = operations.DistributedSyncOperationWithResults('test-sync-results-', task_write) # op.execute() - print('\n', yaml.dump(op.to_workflow())) + wf = op.to_workflow() if execute: print(op.execute()) diff --git a/libraries/cloudharness-common/tests/values.yaml b/libraries/cloudharness-common/tests/values.yaml index 2bd88002..0a0e8a34 100644 --- a/libraries/cloudharness-common/tests/values.yaml +++ b/libraries/cloudharness-common/tests/values.yaml @@ -592,6 +592,13 @@ apps: limits: memory: 500Mi cpu: 500m + quotas: + quota-ws-open: 3 + quota-ws-guaranteecpu: 0.05 + quota-ws-maxcpu: 0.4 + quota-ws-guaranteemem: 0.1 + quota-ws-maxmem: 0.5 + quota-storage-max: 1.25 service: auto: false name: proxy-public diff --git a/libraries/models/api/config.json b/libraries/models/api/config.json new file mode 100644 index 00000000..8c57239d --- /dev/null +++ b/libraries/models/api/config.json @@ -0,0 +1,4 @@ +{ + "packageName": "cloudharness_model", + "disallowAdditionalPropertiesIfNotPresent": false +} \ No newline at end of file diff --git a/libraries/models/api/openapi.yaml b/libraries/models/api/openapi.yaml new file mode 100644 index 00000000..a2d8400e --- /dev/null +++ b/libraries/models/api/openapi.yaml @@ -0,0 +1,839 @@ +--- +openapi: 3.0.2 +info: + title: cloudharness + version: 1.0.0 +components: + schemas: + AutoArtifactSpec: + description: "" + required: + - auto + type: object + properties: + auto: + description: "When true, enables automatic template" + type: boolean + name: + description: "" + type: string + UriRoleMappingConfig: + description: + "Defines the application Gatekeeper configuration, if enabled (i.e.\ + \ `secured: true`." + required: + - roles + - uri + type: object + properties: + uri: + $ref: "#/components/schemas/PathSpecifier" + description: Path to secure + roles: + description: Roles allowed to access the present uri + type: array + items: + type: string + ServiceAutoArtifactConfig: + description: "" + type: object + allOf: + - type: object + properties: + port: + description: Service port + type: integer + - $ref: "#/components/schemas/AutoArtifactSpec" + ApplicationDependenciesConfig: + description: "" + type: object + properties: + hard: + description: + Hard dependencies indicate that the application may not start + without these other applications. + type: array + items: + type: string + soft: + description: + Soft dependencies indicate that the application will work partially + without these other applications. + type: array + items: + type: string + build: + description: + Hard dependencies indicate that the application Docker image + build requires these base/common images + type: array + items: + type: string + DeploymentResourcesConf: + description: "" + type: object + properties: + requests: + $ref: "#/components/schemas/CpuMemoryConfig" + description: "" + limits: + $ref: "#/components/schemas/CpuMemoryConfig" + description: "" + CpuMemoryConfig: + description: "" + type: object + properties: + cpu: + description: "" + type: string + memory: + description: "" + type: string + FileResourcesConfig: + description: "" + required: + - name + - src + - dst + type: object + properties: + name: + $ref: "#/components/schemas/Filename" + description: "" + src: + $ref: "#/components/schemas/Filename" + description: "" + dst: + description: "" + type: string + ApplicationProbe: + description: |- + Define a Kubernetes probe See also the + [official documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) + required: + - path + type: object + properties: + path: + $ref: "#/components/schemas/URL" + description: "" + periodSeconds: + description: "" + type: number + failureThreshold: + description: "" + type: number + initialDelaySeconds: + description: "" + type: number + URL: + description: "" + type: string + ApplicationConfig: + description: Place here the values to configure your application helm templates. + required: + - harness + type: object + properties: + harness: + $ref: "#/components/schemas/ApplicationHarnessConfig" + description: + Values inside this section have a special meaning to cloudharness + (e.g. enabling and configuring automatic deployment) + additionalProperties: true + HarnessMainConfig: + description: "" + required: + - local + - secured_gatekeepers + - domain + - namespace + - mainapp + - apps + type: object + properties: + local: + description: "If set to true, local DNS mapping is added to pods." + type: boolean + secured_gatekeepers: + description: + Enables/disables Gatekeepers on secured applications. Set to + false for testing/development + type: boolean + domain: + description: The root domain + type: string + example: The root domain. + namespace: + description: The K8s namespace. + type: string + mainapp: + description: Defines the app to map to the root domain + type: string + registry: + $ref: "#/components/schemas/RegistryConfig" + description: "" + tag: + description: Docker tag used to push/pull the built images. + type: string + apps: + $ref: "#/components/schemas/ApplicationsConfigsMap" + description: "" + env: + description: Environmental variables added to all pods + type: array + items: + $ref: "#/components/schemas/NameValue" + privenv: + $ref: "#/components/schemas/NameValue" + description: Private environmental variables added to all pods + backup: + $ref: "#/components/schemas/BackupConfig" + description: "" + name: + description: Base name + type: string + task-images: + $ref: "#/components/schemas/SimpleMap" + description: "" + RegistryConfig: + description: "" + required: + - name + type: object + properties: + name: + $ref: "#/components/schemas/URL" + description: The docker registry where built images are pushed + secret: + description: Optional secret used for pulling from docker registry. + type: string + SimpleMap: + description: "" + type: object + additionalProperties: + type: string + FreeObject: + description: "" + type: object + additionalProperties: true + DatabaseDeploymentConfig: + description: "" + type: object + allOf: + - type: object + properties: + type: + description: |- + Define the database type. + + One of (mongo, postgres, neo4j, sqlite3) + pattern: ^(mongo|postgres|neo4j|sqlite3)$ + type: string + example: '"neo4j"' + size: + description: Specify database disk size + type: string + example: 1Gi + user: + description: database username + type: string + pass: + format: password + description: Database password + type: string + image_ref: + description: Used for referencing images from the build + type: string + example: "image_ref: myownpgimage" + mongo: + $ref: "#/components/schemas/FreeObject" + description: Mongo db specific configuration + postgres: + $ref: "#/components/schemas/FreeObject" + description: Postgres database specific configuration + neo4j: + description: Neo4j database specific configuration + resources: + $ref: "#/components/schemas/DeploymentResourcesConf" + description: Database deployment resources + - $ref: "#/components/schemas/AutoArtifactSpec" + ApplicationsConfigsMap: + description: "" + type: object + additionalProperties: + $ref: "#/components/schemas/ApplicationConfig" + NameValue: + description: "" + required: + - name + type: object + properties: + name: + description: "" + type: string + value: + description: "" + type: string + IngressConfig: + description: "" + type: object + allOf: + - type: object + properties: + ssl_redirect: + description: "" + type: boolean + letsencrypt: + description: "" + type: object + properties: + email: + type: string + - $ref: "#/components/schemas/AutoArtifactSpec" + BackupConfig: + description: "" + required: + - dir + - resources + type: object + properties: + active: + description: "" + type: boolean + keep_days: + description: "" + type: integer + keep_weeks: + description: "" + type: integer + keep_months: + description: "" + type: integer + schedule: + description: Cron expression + pattern: + "/(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every\ + \ (\\d+(ns|us|µs|ms|s|m|h))+)|((((\\d+,)+\\d+|(\\d+(\\/|-)\\d+)|\\d+|\\\ + *) ?){5,7})/" + type: string + suffix: + description: The file suffix added to backup files + volumesize: + description: The volume size for backups (all backups share the same volume) + type: string + dir: + $ref: "#/components/schemas/Filename" + description: + "Target directory of backups, the mount point of the persistent\ + \ volume." + resources: + $ref: "#/components/schemas/DeploymentResourcesConf" + description: "" + Quota: + description: "" + type: object + additionalProperties: + type: string + example: + quota-ws-max: 5 + quota-storage-max: 1G + UserGroup: + type: object + properties: + access: + type: object + additionalProperties: true + attributes: + $ref: "#/components/schemas/SimpleMap" + additionalProperties: true + clientRoles: + type: object + additionalProperties: true + id: + type: string + name: + type: string + path: + type: string + realmRoles: + type: array + items: + type: string + subGroups: + type: array + items: + $ref: "#/components/schemas/UserGroup" + UserCredential: + type: object + properties: + createdDate: + format: int64 + type: integer + credentialData: + type: string + id: + type: string + priority: + format: int32 + type: integer + secretData: + type: string + temporary: + type: boolean + type: + type: string + userLabel: + type: string + value: + type: string + User: + type: object + properties: + access: + type: object + additionalProperties: true + attributes: + type: object + additionalProperties: true + clientRoles: + type: object + additionalProperties: true + createdTimestamp: + format: int64 + type: integer + credentials: + type: array + items: + $ref: "#/components/schemas/UserCredential" + disableableCredentialTypes: + type: array + items: + type: string + email: + type: string + emailVerified: + type: boolean + enabled: + type: boolean + federationLink: + type: string + firstName: + type: string + groups: + type: array + items: + type: string + id: + type: string + lastName: + type: string + realmRoles: + type: array + items: + type: string + requiredActions: + type: array + items: + type: string + serviceAccountClientId: + type: string + username: + type: string + additionalProperties: {} + Filename: + description: "" + pattern: "^[^<>:;,?*|]+$" + type: string + PathSpecifier: + description: "" + pattern: "^[^<>:;,?|]+$" + type: string + CDCEvent: + description: |- + A message sent to the orchestration queue. + Applications can listen to these events to react to data change events happening + on other applications. + required: + - message_type + - operation + - uid + - meta + type: object + properties: + operation: + description: the operation on the object e.g. create / update / delete + enum: + - create + - update + - delete + - other + type: string + uid: + description: the unique identifier attribute of the object + type: string + message_type: + description: the type of the message (relates to the object type) e.g. jobs + type: string + resource: + $ref: "#/components/schemas/FreeObject" + description: The target object + meta: + $ref: "#/components/schemas/CDCEventMeta" + description: "" + CDCEventMeta: + description: "" + required: + - app_name + type: object + properties: + app_name: + description: The name of the application/microservice sending the message + type: string + user: + $ref: "#/components/schemas/User" + description: "" + args: + description: the caller function arguments + type: array + items: + $ref: "#/components/schemas/FreeObject" + kwargs: + description: the caller function keyword arguments + description: + description: General description -- for human consumption + type: string + ApplicationHarnessConfig: + description: + "Define helm variables that allow CloudHarness to enable and configure\ + \ your \napplication's deployment" + required: [] + type: object + properties: + deployment: + $ref: "#/components/schemas/DeploymentAutoArtifactConfig" + description: + Defines reference deployment parameters. Values maps to k8s + spec + service: + $ref: "#/components/schemas/ServiceAutoArtifactConfig" + description: Defines automatic service parameters. + subdomain: + description: "If specified, an ingress will be created at [subdomain].[.Values.domain]" + type: string + aliases: + description: + "If specified, an ingress will be created at [alias].[.Values.domain]\ + \ for each alias" + type: array + items: + type: string + domain: + description: "If specified, an ingress will be created at [domain]" + type: string + dependencies: + $ref: "#/components/schemas/ApplicationDependenciesConfig" + description: + Application dependencies are used to define what is required + in the deployment when --include (-i) is used. Specify application names + in the list. + secured: + description: "When true, the application is shielded with a getekeeper" + type: boolean + uri_role_mapping: + description: + "Map uri/roles to secure with the Gatekeeper (if `secured:\ + \ true`)" + type: array + items: + $ref: "#/components/schemas/UriRoleMappingConfig" + secrets: + $ref: "#/components/schemas/SimpleMap" + description: |- + Define secrets will be mounted in the deployment + + Define as + + ```yaml + secrets: + secret_name: 'value' + + ``` + + Values if left empty are randomly generated + use_services: + description: + "Specify which services this application uses in the frontend\ + \ to create proxy ingresses. e.g. \n```\n- name: samples\n```" + type: array + items: + type: string + database: + $ref: "#/components/schemas/DatabaseDeploymentConfig" + description: "" + resources: + description: |- + Application file resources. Maps from deploy/resources folder and mounts as + configmaps + type: array + items: + $ref: "#/components/schemas/FileResourcesConfig" + readinessProbe: + $ref: "#/components/schemas/ApplicationProbe" + description: Kubernetes readiness probe configuration + startupProbe: + $ref: "#/components/schemas/ApplicationProbe" + description: "" + livenessProbe: + $ref: "#/components/schemas/ApplicationProbe" + description: Kubernetes liveness probe configuration + sourceRoot: + $ref: "#/components/schemas/Filename" + description: "" + name: + description: |- + Application's name. Do not edit, the value is automatically set from the + application directory's name + type: string + jupyterhub: + $ref: "#/components/schemas/JupyterHubConfig" + description: | + Configurations specific to jupyterhub. Edit only if your application is + configured as a jupyterhub deployment + accounts: + $ref: "#/components/schemas/ApplicationAccountsConfig" + description: Define specific test users and roles for this application + test: + $ref: "#/components/schemas/ApplicationTestConfig" + description: Enable and configure automated testing for this application. + additionalProperties: true + JupyterHubConfig: + description: "" + type: object + properties: + args: + description: arguments passed to the container + type: array + items: + type: string + extraConfig: + $ref: "#/components/schemas/SimpleMap" + description: + allows you to add Python snippets to the jupyterhub_config.py + file + spawnerExtraConfig: + $ref: "#/components/schemas/FreeObject" + description: + allows you to add values to the spawner object without the + need of creating a new hook + applicationHook: + description: + "change the hook function (advanced)\n\nSpecify the Python\ + \ name of the function (full module path, the module must be \ninstalled\ + \ in the Docker image)" + example: my_lib.change_pod_manifest + additionalProperties: true + UserRole: + type: object + properties: + attributes: + type: object + additionalProperties: true + clientRole: + type: boolean + composite: + type: boolean + containerId: + type: string + description: + type: string + id: + type: string + name: + type: string + additionalProperties: true + ApplicationAccountsConfig: + description: "" + type: object + properties: + roles: + description: + Specify roles to be created in this deployment specific for + this application + type: array + items: + type: string + users: + description: + "Defines test users to be added to the deployment, specific\ + \ for this application" + type: array + items: + $ref: "#/components/schemas/ApplicationUser" + ApplicationUser: + description: Defines a user + required: + - username + type: object + properties: + username: + description: "" + type: string + password: + format: password + description: "" + type: string + clientRoles: + description: "" + type: array + items: + type: string + realmRoles: + description: "" + type: array + items: + type: string + ApplicationTestConfig: + description: "" + required: + - unit + - e2e + - api + type: object + properties: + unit: + $ref: "#/components/schemas/UnitTestsConfig" + description: "" + api: + $ref: "#/components/schemas/ApiTestsConfig" + description: "" + e2e: + $ref: "#/components/schemas/E2ETestsConfig" + description: "" + UnitTestsConfig: + description: "" + required: + - enabled + - commands + type: object + properties: + enabled: + description: "Enables unit tests for this application (default: true)" + type: boolean + commands: + description: Commands to run unit tests + type: array + items: + type: string + example: '["pytest /usr/src/app/samples/test"]' + E2ETestsConfig: + description: "" + required: + - enabled + - smoketest + type: object + properties: + enabled: + description: + "Enables end to end testing for this application (default:\ + \ false)" + type: boolean + smoketest: + description: Specify whether to run the common smoke tests + type: boolean + ignoreConsoleErrors: + description: "" + type: boolean + ignoreRequestErrors: + description: "" + type: boolean + ApiTestsConfig: + description: "" + required: + - enabled + - autotest + - checks + type: object + properties: + enabled: + description: "Enables api tests for this application (default: false)" + type: boolean + autotest: + description: Specify whether to run the common smoke tests + type: boolean + runParams: + description: Additional schemathesis parameters + type: array + items: + type: string + checks: + description: |- + One of the Schemathesis checks: + + - not_a_server_error. The response has 5xx HTTP status; + - status_code_conformance. The response status is not defined in the API schema; + - content_type_conformance. The response content type is not defined in the API schema; + - response_schema_conformance. The response content does not conform to the schema defined for this specific response; + - response_headers_conformance. The response headers does not contain all defined headers. + type: array + items: + type: string + example: '["not_a_server_error", "status_code_conformance"]' + DeploymentAutoArtifactConfig: + description: "" + type: object + allOf: + - type: object + properties: + port: + description: Deployment port + type: string + replicas: + description: Number of replicas + type: integer + image: + description: |- + Image name to use in the deployment. Leave it blank to set from the application's + Docker file + pattern: "(?:[a-z]+/)?([a-z]+)(?::[0-9]+)?" + type: string + resources: + $ref: "#/components/schemas/DeploymentResourcesConf" + description: Deployment resources + volume: + $ref: "#/components/schemas/DeploymentVolumeSpec" + description: Volume specification + resources: + description: Deployment resources + type: string + test: + description: ssaa + type: string + - $ref: "#/components/schemas/AutoArtifactSpec" + DeploymentVolumeSpec: + description: |- + Defines a volume attached to the deployment. + Automatically created the volume claim and mounts. + type: object + allOf: + - required: + - mountpath + type: object + properties: + mountpath: + description: The mount path for the volume + type: string + size: + description: "The volume size. \n\nE.g. 5Gi" + usenfs: + description: + Set to `true` to use the nfs on the created volume and mount + as ReadWriteMany. + type: boolean + - $ref: "#/components/schemas/AutoArtifactSpec" + example: + auto: true + mountpath: /usr/src/app/persistent + name: my-files + size: 5Gi + usenfs: true diff --git a/libraries/models/cloudharness_model/models/__init__.py b/libraries/models/cloudharness_model/models/__init__.py index 28e29665..78d8f9fc 100644 --- a/libraries/models/cloudharness_model/models/__init__.py +++ b/libraries/models/cloudharness_model/models/__init__.py @@ -19,7 +19,10 @@ from cloudharness_model.models.database_deployment_config import DatabaseDeploymentConfig from cloudharness_model.models.database_deployment_config_all_of import DatabaseDeploymentConfigAllOf from cloudharness_model.models.deployment_auto_artifact_config import DeploymentAutoArtifactConfig +from cloudharness_model.models.deployment_auto_artifact_config_all_of import DeploymentAutoArtifactConfigAllOf from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf +from cloudharness_model.models.deployment_volume_spec import DeploymentVolumeSpec +from cloudharness_model.models.deployment_volume_spec_all_of import DeploymentVolumeSpecAllOf from cloudharness_model.models.e2_e_tests_config import E2ETestsConfig from cloudharness_model.models.file_resources_config import FileResourcesConfig from cloudharness_model.models.harness_main_config import HarnessMainConfig diff --git a/libraries/models/cloudharness_model/models/application_harness_config.py b/libraries/models/cloudharness_model/models/application_harness_config.py index e1b237a9..4a083624 100644 --- a/libraries/models/cloudharness_model/models/application_harness_config.py +++ b/libraries/models/cloudharness_model/models/application_harness_config.py @@ -341,6 +341,7 @@ def uri_role_mapping(self, uri_role_mapping): def secrets(self): """Gets the secrets of this ApplicationHarnessConfig. + # noqa: E501 :return: The secrets of this ApplicationHarnessConfig. :rtype: Dict[str, str] @@ -351,6 +352,7 @@ def secrets(self): def secrets(self, secrets): """Sets the secrets of this ApplicationHarnessConfig. + # noqa: E501 :param secrets: The secrets of this ApplicationHarnessConfig. :type secrets: Dict[str, str] @@ -492,6 +494,7 @@ def liveness_probe(self, liveness_probe): def source_root(self): """Gets the source_root of this ApplicationHarnessConfig. + # noqa: E501 :return: The source_root of this ApplicationHarnessConfig. :rtype: str @@ -502,6 +505,7 @@ def source_root(self): def source_root(self, source_root): """Sets the source_root of this ApplicationHarnessConfig. + # noqa: E501 :param source_root: The source_root of this ApplicationHarnessConfig. :type source_root: str diff --git a/libraries/models/cloudharness_model/models/application_probe.py b/libraries/models/cloudharness_model/models/application_probe.py index bf5d28ea..b1819df4 100644 --- a/libraries/models/cloudharness_model/models/application_probe.py +++ b/libraries/models/cloudharness_model/models/application_probe.py @@ -61,6 +61,7 @@ def from_dict(cls, dikt) -> 'ApplicationProbe': def path(self): """Gets the path of this ApplicationProbe. + # noqa: E501 :return: The path of this ApplicationProbe. :rtype: str @@ -71,6 +72,7 @@ def path(self): def path(self, path): """Sets the path of this ApplicationProbe. + # noqa: E501 :param path: The path of this ApplicationProbe. :type path: str @@ -84,6 +86,7 @@ def path(self, path): def period_seconds(self): """Gets the period_seconds of this ApplicationProbe. + # noqa: E501 :return: The period_seconds of this ApplicationProbe. :rtype: float @@ -94,6 +97,7 @@ def period_seconds(self): def period_seconds(self, period_seconds): """Sets the period_seconds of this ApplicationProbe. + # noqa: E501 :param period_seconds: The period_seconds of this ApplicationProbe. :type period_seconds: float @@ -105,6 +109,7 @@ def period_seconds(self, period_seconds): def failure_threshold(self): """Gets the failure_threshold of this ApplicationProbe. + # noqa: E501 :return: The failure_threshold of this ApplicationProbe. :rtype: float @@ -115,6 +120,7 @@ def failure_threshold(self): def failure_threshold(self, failure_threshold): """Sets the failure_threshold of this ApplicationProbe. + # noqa: E501 :param failure_threshold: The failure_threshold of this ApplicationProbe. :type failure_threshold: float @@ -126,6 +132,7 @@ def failure_threshold(self, failure_threshold): def initial_delay_seconds(self): """Gets the initial_delay_seconds of this ApplicationProbe. + # noqa: E501 :return: The initial_delay_seconds of this ApplicationProbe. :rtype: float @@ -136,6 +143,7 @@ def initial_delay_seconds(self): def initial_delay_seconds(self, initial_delay_seconds): """Sets the initial_delay_seconds of this ApplicationProbe. + # noqa: E501 :param initial_delay_seconds: The initial_delay_seconds of this ApplicationProbe. :type initial_delay_seconds: float diff --git a/libraries/models/cloudharness_model/models/application_user.py b/libraries/models/cloudharness_model/models/application_user.py index 2be50c8d..823be12b 100644 --- a/libraries/models/cloudharness_model/models/application_user.py +++ b/libraries/models/cloudharness_model/models/application_user.py @@ -61,6 +61,7 @@ def from_dict(cls, dikt) -> 'ApplicationUser': def username(self): """Gets the username of this ApplicationUser. + # noqa: E501 :return: The username of this ApplicationUser. :rtype: str @@ -71,6 +72,7 @@ def username(self): def username(self, username): """Sets the username of this ApplicationUser. + # noqa: E501 :param username: The username of this ApplicationUser. :type username: str @@ -84,6 +86,7 @@ def username(self, username): def password(self): """Gets the password of this ApplicationUser. + # noqa: E501 :return: The password of this ApplicationUser. :rtype: str @@ -94,6 +97,7 @@ def password(self): def password(self, password): """Sets the password of this ApplicationUser. + # noqa: E501 :param password: The password of this ApplicationUser. :type password: str @@ -105,6 +109,7 @@ def password(self, password): def client_roles(self): """Gets the client_roles of this ApplicationUser. + # noqa: E501 :return: The client_roles of this ApplicationUser. :rtype: List[str] @@ -115,6 +120,7 @@ def client_roles(self): def client_roles(self, client_roles): """Sets the client_roles of this ApplicationUser. + # noqa: E501 :param client_roles: The client_roles of this ApplicationUser. :type client_roles: List[str] @@ -126,6 +132,7 @@ def client_roles(self, client_roles): def realm_roles(self): """Gets the realm_roles of this ApplicationUser. + # noqa: E501 :return: The realm_roles of this ApplicationUser. :rtype: List[str] @@ -136,6 +143,7 @@ def realm_roles(self): def realm_roles(self, realm_roles): """Sets the realm_roles of this ApplicationUser. + # noqa: E501 :param realm_roles: The realm_roles of this ApplicationUser. :type realm_roles: List[str] diff --git a/libraries/models/cloudharness_model/models/auto_artifact_spec.py b/libraries/models/cloudharness_model/models/auto_artifact_spec.py index 402d8ddc..9aebfd4f 100644 --- a/libraries/models/cloudharness_model/models/auto_artifact_spec.py +++ b/libraries/models/cloudharness_model/models/auto_artifact_spec.py @@ -76,6 +76,7 @@ def auto(self, auto): def name(self): """Gets the name of this AutoArtifactSpec. + # noqa: E501 :return: The name of this AutoArtifactSpec. :rtype: str @@ -86,6 +87,7 @@ def name(self): def name(self, name): """Sets the name of this AutoArtifactSpec. + # noqa: E501 :param name: The name of this AutoArtifactSpec. :type name: str diff --git a/libraries/models/cloudharness_model/models/backup_config.py b/libraries/models/cloudharness_model/models/backup_config.py index e45997b4..254c52f7 100644 --- a/libraries/models/cloudharness_model/models/backup_config.py +++ b/libraries/models/cloudharness_model/models/backup_config.py @@ -90,6 +90,7 @@ def from_dict(cls, dikt) -> 'BackupConfig': def active(self): """Gets the active of this BackupConfig. + # noqa: E501 :return: The active of this BackupConfig. :rtype: bool @@ -100,6 +101,7 @@ def active(self): def active(self, active): """Sets the active of this BackupConfig. + # noqa: E501 :param active: The active of this BackupConfig. :type active: bool @@ -111,6 +113,7 @@ def active(self, active): def keep_days(self): """Gets the keep_days of this BackupConfig. + # noqa: E501 :return: The keep_days of this BackupConfig. :rtype: int @@ -121,6 +124,7 @@ def keep_days(self): def keep_days(self, keep_days): """Sets the keep_days of this BackupConfig. + # noqa: E501 :param keep_days: The keep_days of this BackupConfig. :type keep_days: int @@ -132,6 +136,7 @@ def keep_days(self, keep_days): def keep_weeks(self): """Gets the keep_weeks of this BackupConfig. + # noqa: E501 :return: The keep_weeks of this BackupConfig. :rtype: int @@ -142,6 +147,7 @@ def keep_weeks(self): def keep_weeks(self, keep_weeks): """Sets the keep_weeks of this BackupConfig. + # noqa: E501 :param keep_weeks: The keep_weeks of this BackupConfig. :type keep_weeks: int @@ -153,6 +159,7 @@ def keep_weeks(self, keep_weeks): def keep_months(self): """Gets the keep_months of this BackupConfig. + # noqa: E501 :return: The keep_months of this BackupConfig. :rtype: int @@ -163,6 +170,7 @@ def keep_months(self): def keep_months(self, keep_months): """Sets the keep_months of this BackupConfig. + # noqa: E501 :param keep_months: The keep_months of this BackupConfig. :type keep_months: int @@ -245,6 +253,7 @@ def volumesize(self, volumesize): def dir(self): """Gets the dir of this BackupConfig. + # noqa: E501 :return: The dir of this BackupConfig. :rtype: str @@ -255,6 +264,7 @@ def dir(self): def dir(self, dir): """Sets the dir of this BackupConfig. + # noqa: E501 :param dir: The dir of this BackupConfig. :type dir: str diff --git a/libraries/models/cloudharness_model/models/cdc_event.py b/libraries/models/cloudharness_model/models/cdc_event.py index bcf92620..1ba4f017 100644 --- a/libraries/models/cloudharness_model/models/cdc_event.py +++ b/libraries/models/cloudharness_model/models/cdc_event.py @@ -147,6 +147,7 @@ def message_type(self, message_type): def resource(self): """Gets the resource of this CDCEvent. + # noqa: E501 :return: The resource of this CDCEvent. :rtype: Dict[str, object] @@ -157,6 +158,7 @@ def resource(self): def resource(self, resource): """Sets the resource of this CDCEvent. + # noqa: E501 :param resource: The resource of this CDCEvent. :type resource: Dict[str, object] diff --git a/libraries/models/cloudharness_model/models/cpu_memory_config.py b/libraries/models/cloudharness_model/models/cpu_memory_config.py index eeb3e3b0..cab9bf7c 100644 --- a/libraries/models/cloudharness_model/models/cpu_memory_config.py +++ b/libraries/models/cloudharness_model/models/cpu_memory_config.py @@ -51,6 +51,7 @@ def from_dict(cls, dikt) -> 'CpuMemoryConfig': def cpu(self): """Gets the cpu of this CpuMemoryConfig. + # noqa: E501 :return: The cpu of this CpuMemoryConfig. :rtype: str @@ -61,6 +62,7 @@ def cpu(self): def cpu(self, cpu): """Sets the cpu of this CpuMemoryConfig. + # noqa: E501 :param cpu: The cpu of this CpuMemoryConfig. :type cpu: str @@ -72,6 +74,7 @@ def cpu(self, cpu): def memory(self): """Gets the memory of this CpuMemoryConfig. + # noqa: E501 :return: The memory of this CpuMemoryConfig. :rtype: str @@ -82,6 +85,7 @@ def memory(self): def memory(self, memory): """Sets the memory of this CpuMemoryConfig. + # noqa: E501 :param memory: The memory of this CpuMemoryConfig. :type memory: str diff --git a/libraries/models/cloudharness_model/models/database_deployment_config.py b/libraries/models/cloudharness_model/models/database_deployment_config.py index 07fd4d2e..3786fb89 100644 --- a/libraries/models/cloudharness_model/models/database_deployment_config.py +++ b/libraries/models/cloudharness_model/models/database_deployment_config.py @@ -6,14 +6,10 @@ from typing import List, Dict # noqa: F401 from cloudharness_model.models.base_model_ import Model -from cloudharness_model.models.auto_artifact_spec import AutoArtifactSpec -from cloudharness_model.models.database_deployment_config_all_of import DatabaseDeploymentConfigAllOf from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf import re from cloudharness_model import util -from cloudharness_model.models.auto_artifact_spec import AutoArtifactSpec # noqa: E501 -from cloudharness_model.models.database_deployment_config_all_of import DatabaseDeploymentConfigAllOf # noqa: E501 from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf # noqa: E501 import re # noqa: E501 @@ -221,6 +217,7 @@ def image_ref(self, image_ref): def mongo(self): """Gets the mongo of this DatabaseDeploymentConfig. + # noqa: E501 :return: The mongo of this DatabaseDeploymentConfig. :rtype: Dict[str, object] @@ -231,6 +228,7 @@ def mongo(self): def mongo(self, mongo): """Sets the mongo of this DatabaseDeploymentConfig. + # noqa: E501 :param mongo: The mongo of this DatabaseDeploymentConfig. :type mongo: Dict[str, object] @@ -242,6 +240,7 @@ def mongo(self, mongo): def postgres(self): """Gets the postgres of this DatabaseDeploymentConfig. + # noqa: E501 :return: The postgres of this DatabaseDeploymentConfig. :rtype: Dict[str, object] @@ -252,6 +251,7 @@ def postgres(self): def postgres(self, postgres): """Sets the postgres of this DatabaseDeploymentConfig. + # noqa: E501 :param postgres: The postgres of this DatabaseDeploymentConfig. :type postgres: Dict[str, object] @@ -332,6 +332,7 @@ def auto(self, auto): def name(self): """Gets the name of this DatabaseDeploymentConfig. + # noqa: E501 :return: The name of this DatabaseDeploymentConfig. :rtype: str @@ -342,6 +343,7 @@ def name(self): def name(self, name): """Sets the name of this DatabaseDeploymentConfig. + # noqa: E501 :param name: The name of this DatabaseDeploymentConfig. :type name: str diff --git a/libraries/models/cloudharness_model/models/database_deployment_config_all_of.py b/libraries/models/cloudharness_model/models/database_deployment_config_all_of.py index 92953de2..1a9e1394 100644 --- a/libraries/models/cloudharness_model/models/database_deployment_config_all_of.py +++ b/libraries/models/cloudharness_model/models/database_deployment_config_all_of.py @@ -207,6 +207,7 @@ def image_ref(self, image_ref): def mongo(self): """Gets the mongo of this DatabaseDeploymentConfigAllOf. + # noqa: E501 :return: The mongo of this DatabaseDeploymentConfigAllOf. :rtype: Dict[str, object] @@ -217,6 +218,7 @@ def mongo(self): def mongo(self, mongo): """Sets the mongo of this DatabaseDeploymentConfigAllOf. + # noqa: E501 :param mongo: The mongo of this DatabaseDeploymentConfigAllOf. :type mongo: Dict[str, object] @@ -228,6 +230,7 @@ def mongo(self, mongo): def postgres(self): """Gets the postgres of this DatabaseDeploymentConfigAllOf. + # noqa: E501 :return: The postgres of this DatabaseDeploymentConfigAllOf. :rtype: Dict[str, object] @@ -238,6 +241,7 @@ def postgres(self): def postgres(self, postgres): """Sets the postgres of this DatabaseDeploymentConfigAllOf. + # noqa: E501 :param postgres: The postgres of this DatabaseDeploymentConfigAllOf. :type postgres: Dict[str, object] diff --git a/libraries/models/cloudharness_model/models/deployment_auto_artifact_config.py b/libraries/models/cloudharness_model/models/deployment_auto_artifact_config.py index 9f3a3748..c72ac477 100644 --- a/libraries/models/cloudharness_model/models/deployment_auto_artifact_config.py +++ b/libraries/models/cloudharness_model/models/deployment_auto_artifact_config.py @@ -6,11 +6,13 @@ from typing import List, Dict # noqa: F401 from cloudharness_model.models.base_model_ import Model -from cloudharness_model.models.auto_artifact_spec import AutoArtifactSpec +from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf +from cloudharness_model.models.deployment_volume_spec import DeploymentVolumeSpec import re from cloudharness_model import util -from cloudharness_model.models.auto_artifact_spec import AutoArtifactSpec # noqa: E501 +from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf # noqa: E501 +from cloudharness_model.models.deployment_volume_spec import DeploymentVolumeSpec # noqa: E501 import re # noqa: E501 class DeploymentAutoArtifactConfig(Model): @@ -19,27 +21,30 @@ class DeploymentAutoArtifactConfig(Model): Do not edit the class manually. """ - def __init__(self, port=None, replicas=None, image=None, resources=None, auto=None, name=None): # noqa: E501 + def __init__(self, port=None, replicas=None, image=None, resources=None, volume=None, auto=None, name=None): # noqa: E501 """DeploymentAutoArtifactConfig - a model defined in OpenAPI :param port: The port of this DeploymentAutoArtifactConfig. # noqa: E501 - :type port: object + :type port: str :param replicas: The replicas of this DeploymentAutoArtifactConfig. # noqa: E501 :type replicas: int :param image: The image of this DeploymentAutoArtifactConfig. # noqa: E501 :type image: str :param resources: The resources of this DeploymentAutoArtifactConfig. # noqa: E501 - :type resources: object + :type resources: DeploymentResourcesConf + :param volume: The volume of this DeploymentAutoArtifactConfig. # noqa: E501 + :type volume: DeploymentVolumeSpec :param auto: The auto of this DeploymentAutoArtifactConfig. # noqa: E501 :type auto: bool :param name: The name of this DeploymentAutoArtifactConfig. # noqa: E501 :type name: str """ self.openapi_types = { - 'port': object, + 'port': str, 'replicas': int, 'image': str, - 'resources': object, + 'resources': DeploymentResourcesConf, + 'volume': DeploymentVolumeSpec, 'auto': bool, 'name': str } @@ -49,6 +54,7 @@ def __init__(self, port=None, replicas=None, image=None, resources=None, auto=No 'replicas': 'replicas', 'image': 'image', 'resources': 'resources', + 'volume': 'volume', 'auto': 'auto', 'name': 'name' } @@ -57,6 +63,7 @@ def __init__(self, port=None, replicas=None, image=None, resources=None, auto=No self._replicas = replicas self._image = image self._resources = resources + self._volume = volume self._auto = auto self._name = name @@ -78,7 +85,7 @@ def port(self): Deployment port # noqa: E501 :return: The port of this DeploymentAutoArtifactConfig. - :rtype: object + :rtype: str """ return self._port @@ -89,7 +96,7 @@ def port(self, port): Deployment port # noqa: E501 :param port: The port of this DeploymentAutoArtifactConfig. - :type port: object + :type port: str """ self._port = port @@ -146,10 +153,9 @@ def image(self, image): def resources(self): """Gets the resources of this DeploymentAutoArtifactConfig. - Deployment resources # noqa: E501 :return: The resources of this DeploymentAutoArtifactConfig. - :rtype: object + :rtype: DeploymentResourcesConf """ return self._resources @@ -157,14 +163,34 @@ def resources(self): def resources(self, resources): """Sets the resources of this DeploymentAutoArtifactConfig. - Deployment resources # noqa: E501 :param resources: The resources of this DeploymentAutoArtifactConfig. - :type resources: object + :type resources: DeploymentResourcesConf """ self._resources = resources + @property + def volume(self): + """Gets the volume of this DeploymentAutoArtifactConfig. + + + :return: The volume of this DeploymentAutoArtifactConfig. + :rtype: DeploymentVolumeSpec + """ + return self._volume + + @volume.setter + def volume(self, volume): + """Sets the volume of this DeploymentAutoArtifactConfig. + + + :param volume: The volume of this DeploymentAutoArtifactConfig. + :type volume: DeploymentVolumeSpec + """ + + self._volume = volume + @property def auto(self): """Gets the auto of this DeploymentAutoArtifactConfig. @@ -194,6 +220,7 @@ def auto(self, auto): def name(self): """Gets the name of this DeploymentAutoArtifactConfig. + # noqa: E501 :return: The name of this DeploymentAutoArtifactConfig. :rtype: str @@ -204,6 +231,7 @@ def name(self): def name(self, name): """Sets the name of this DeploymentAutoArtifactConfig. + # noqa: E501 :param name: The name of this DeploymentAutoArtifactConfig. :type name: str diff --git a/libraries/models/cloudharness_model/models/deployment_auto_artifact_config_all_of.py b/libraries/models/cloudharness_model/models/deployment_auto_artifact_config_all_of.py new file mode 100644 index 00000000..68b4a55f --- /dev/null +++ b/libraries/models/cloudharness_model/models/deployment_auto_artifact_config_all_of.py @@ -0,0 +1,182 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf +from cloudharness_model.models.deployment_volume_spec import DeploymentVolumeSpec +import re +from cloudharness_model import util + +from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf # noqa: E501 +from cloudharness_model.models.deployment_volume_spec import DeploymentVolumeSpec # noqa: E501 +import re # noqa: E501 + +class DeploymentAutoArtifactConfigAllOf(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + + Do not edit the class manually. + """ + + def __init__(self, port=None, replicas=None, image=None, resources=None, volume=None): # noqa: E501 + """DeploymentAutoArtifactConfigAllOf - a model defined in OpenAPI + + :param port: The port of this DeploymentAutoArtifactConfigAllOf. # noqa: E501 + :type port: str + :param replicas: The replicas of this DeploymentAutoArtifactConfigAllOf. # noqa: E501 + :type replicas: int + :param image: The image of this DeploymentAutoArtifactConfigAllOf. # noqa: E501 + :type image: str + :param resources: The resources of this DeploymentAutoArtifactConfigAllOf. # noqa: E501 + :type resources: DeploymentResourcesConf + :param volume: The volume of this DeploymentAutoArtifactConfigAllOf. # noqa: E501 + :type volume: DeploymentVolumeSpec + """ + self.openapi_types = { + 'port': str, + 'replicas': int, + 'image': str, + 'resources': DeploymentResourcesConf, + 'volume': DeploymentVolumeSpec + } + + self.attribute_map = { + 'port': 'port', + 'replicas': 'replicas', + 'image': 'image', + 'resources': 'resources', + 'volume': 'volume' + } + + self._port = port + self._replicas = replicas + self._image = image + self._resources = resources + self._volume = volume + + @classmethod + def from_dict(cls, dikt) -> 'DeploymentAutoArtifactConfigAllOf': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The DeploymentAutoArtifactConfig_allOf of this DeploymentAutoArtifactConfigAllOf. # noqa: E501 + :rtype: DeploymentAutoArtifactConfigAllOf + """ + return util.deserialize_model(dikt, cls) + + @property + def port(self): + """Gets the port of this DeploymentAutoArtifactConfigAllOf. + + Deployment port # noqa: E501 + + :return: The port of this DeploymentAutoArtifactConfigAllOf. + :rtype: str + """ + return self._port + + @port.setter + def port(self, port): + """Sets the port of this DeploymentAutoArtifactConfigAllOf. + + Deployment port # noqa: E501 + + :param port: The port of this DeploymentAutoArtifactConfigAllOf. + :type port: str + """ + + self._port = port + + @property + def replicas(self): + """Gets the replicas of this DeploymentAutoArtifactConfigAllOf. + + Number of replicas # noqa: E501 + + :return: The replicas of this DeploymentAutoArtifactConfigAllOf. + :rtype: int + """ + return self._replicas + + @replicas.setter + def replicas(self, replicas): + """Sets the replicas of this DeploymentAutoArtifactConfigAllOf. + + Number of replicas # noqa: E501 + + :param replicas: The replicas of this DeploymentAutoArtifactConfigAllOf. + :type replicas: int + """ + + self._replicas = replicas + + @property + def image(self): + """Gets the image of this DeploymentAutoArtifactConfigAllOf. + + Image name to use in the deployment. Leave it blank to set from the application's Docker file # noqa: E501 + + :return: The image of this DeploymentAutoArtifactConfigAllOf. + :rtype: str + """ + return self._image + + @image.setter + def image(self, image): + """Sets the image of this DeploymentAutoArtifactConfigAllOf. + + Image name to use in the deployment. Leave it blank to set from the application's Docker file # noqa: E501 + + :param image: The image of this DeploymentAutoArtifactConfigAllOf. + :type image: str + """ + if image is not None and not re.search(r'(?:[a-z]+\/)?([a-z]+)(?::[0-9]+)?', image): # noqa: E501 + raise ValueError("Invalid value for `image`, must be a follow pattern or equal to `/(?:[a-z]+\/)?([a-z]+)(?::[0-9]+)?/`") # noqa: E501 + + self._image = image + + @property + def resources(self): + """Gets the resources of this DeploymentAutoArtifactConfigAllOf. + + + :return: The resources of this DeploymentAutoArtifactConfigAllOf. + :rtype: DeploymentResourcesConf + """ + return self._resources + + @resources.setter + def resources(self, resources): + """Sets the resources of this DeploymentAutoArtifactConfigAllOf. + + + :param resources: The resources of this DeploymentAutoArtifactConfigAllOf. + :type resources: DeploymentResourcesConf + """ + + self._resources = resources + + @property + def volume(self): + """Gets the volume of this DeploymentAutoArtifactConfigAllOf. + + + :return: The volume of this DeploymentAutoArtifactConfigAllOf. + :rtype: DeploymentVolumeSpec + """ + return self._volume + + @volume.setter + def volume(self, volume): + """Sets the volume of this DeploymentAutoArtifactConfigAllOf. + + + :param volume: The volume of this DeploymentAutoArtifactConfigAllOf. + :type volume: DeploymentVolumeSpec + """ + + self._volume = volume diff --git a/libraries/models/cloudharness_model/models/deployment_volume_spec.py b/libraries/models/cloudharness_model/models/deployment_volume_spec.py new file mode 100644 index 00000000..631bc55d --- /dev/null +++ b/libraries/models/cloudharness_model/models/deployment_volume_spec.py @@ -0,0 +1,182 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util + + +class DeploymentVolumeSpec(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + + Do not edit the class manually. + """ + + def __init__(self, mountpath=None, size=None, usenfs=None, auto=None, name=None): # noqa: E501 + """DeploymentVolumeSpec - a model defined in OpenAPI + + :param mountpath: The mountpath of this DeploymentVolumeSpec. # noqa: E501 + :type mountpath: str + :param size: The size of this DeploymentVolumeSpec. # noqa: E501 + :type size: object + :param usenfs: The usenfs of this DeploymentVolumeSpec. # noqa: E501 + :type usenfs: bool + :param auto: The auto of this DeploymentVolumeSpec. # noqa: E501 + :type auto: bool + :param name: The name of this DeploymentVolumeSpec. # noqa: E501 + :type name: str + """ + self.openapi_types = { + 'mountpath': str, + 'size': object, + 'usenfs': bool, + 'auto': bool, + 'name': str + } + + self.attribute_map = { + 'mountpath': 'mountpath', + 'size': 'size', + 'usenfs': 'usenfs', + 'auto': 'auto', + 'name': 'name' + } + + self._mountpath = mountpath + self._size = size + self._usenfs = usenfs + self._auto = auto + self._name = name + + @classmethod + def from_dict(cls, dikt) -> 'DeploymentVolumeSpec': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The DeploymentVolumeSpec of this DeploymentVolumeSpec. # noqa: E501 + :rtype: DeploymentVolumeSpec + """ + return util.deserialize_model(dikt, cls) + + @property + def mountpath(self): + """Gets the mountpath of this DeploymentVolumeSpec. + + The mount path for the volume # noqa: E501 + + :return: The mountpath of this DeploymentVolumeSpec. + :rtype: str + """ + return self._mountpath + + @mountpath.setter + def mountpath(self, mountpath): + """Sets the mountpath of this DeploymentVolumeSpec. + + The mount path for the volume # noqa: E501 + + :param mountpath: The mountpath of this DeploymentVolumeSpec. + :type mountpath: str + """ + if mountpath is None: + raise ValueError("Invalid value for `mountpath`, must not be `None`") # noqa: E501 + + self._mountpath = mountpath + + @property + def size(self): + """Gets the size of this DeploymentVolumeSpec. + + The volume size. E.g. 5Gi # noqa: E501 + + :return: The size of this DeploymentVolumeSpec. + :rtype: object + """ + return self._size + + @size.setter + def size(self, size): + """Sets the size of this DeploymentVolumeSpec. + + The volume size. E.g. 5Gi # noqa: E501 + + :param size: The size of this DeploymentVolumeSpec. + :type size: object + """ + + self._size = size + + @property + def usenfs(self): + """Gets the usenfs of this DeploymentVolumeSpec. + + Set to `true` to use the nfs on the created volume and mount as ReadWriteMany. # noqa: E501 + + :return: The usenfs of this DeploymentVolumeSpec. + :rtype: bool + """ + return self._usenfs + + @usenfs.setter + def usenfs(self, usenfs): + """Sets the usenfs of this DeploymentVolumeSpec. + + Set to `true` to use the nfs on the created volume and mount as ReadWriteMany. # noqa: E501 + + :param usenfs: The usenfs of this DeploymentVolumeSpec. + :type usenfs: bool + """ + + self._usenfs = usenfs + + @property + def auto(self): + """Gets the auto of this DeploymentVolumeSpec. + + When true, enables automatic template # noqa: E501 + + :return: The auto of this DeploymentVolumeSpec. + :rtype: bool + """ + return self._auto + + @auto.setter + def auto(self, auto): + """Sets the auto of this DeploymentVolumeSpec. + + When true, enables automatic template # noqa: E501 + + :param auto: The auto of this DeploymentVolumeSpec. + :type auto: bool + """ + if auto is None: + raise ValueError("Invalid value for `auto`, must not be `None`") # noqa: E501 + + self._auto = auto + + @property + def name(self): + """Gets the name of this DeploymentVolumeSpec. + + # noqa: E501 + + :return: The name of this DeploymentVolumeSpec. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name): + """Sets the name of this DeploymentVolumeSpec. + + # noqa: E501 + + :param name: The name of this DeploymentVolumeSpec. + :type name: str + """ + + self._name = name diff --git a/libraries/models/cloudharness_model/models/deployment_volume_spec_all_of.py b/libraries/models/cloudharness_model/models/deployment_volume_spec_all_of.py new file mode 100644 index 00000000..7aeef18c --- /dev/null +++ b/libraries/models/cloudharness_model/models/deployment_volume_spec_all_of.py @@ -0,0 +1,124 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util + + +class DeploymentVolumeSpecAllOf(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + + Do not edit the class manually. + """ + + def __init__(self, mountpath=None, size=None, usenfs=None): # noqa: E501 + """DeploymentVolumeSpecAllOf - a model defined in OpenAPI + + :param mountpath: The mountpath of this DeploymentVolumeSpecAllOf. # noqa: E501 + :type mountpath: str + :param size: The size of this DeploymentVolumeSpecAllOf. # noqa: E501 + :type size: object + :param usenfs: The usenfs of this DeploymentVolumeSpecAllOf. # noqa: E501 + :type usenfs: bool + """ + self.openapi_types = { + 'mountpath': str, + 'size': object, + 'usenfs': bool + } + + self.attribute_map = { + 'mountpath': 'mountpath', + 'size': 'size', + 'usenfs': 'usenfs' + } + + self._mountpath = mountpath + self._size = size + self._usenfs = usenfs + + @classmethod + def from_dict(cls, dikt) -> 'DeploymentVolumeSpecAllOf': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The DeploymentVolumeSpec_allOf of this DeploymentVolumeSpecAllOf. # noqa: E501 + :rtype: DeploymentVolumeSpecAllOf + """ + return util.deserialize_model(dikt, cls) + + @property + def mountpath(self): + """Gets the mountpath of this DeploymentVolumeSpecAllOf. + + The mount path for the volume # noqa: E501 + + :return: The mountpath of this DeploymentVolumeSpecAllOf. + :rtype: str + """ + return self._mountpath + + @mountpath.setter + def mountpath(self, mountpath): + """Sets the mountpath of this DeploymentVolumeSpecAllOf. + + The mount path for the volume # noqa: E501 + + :param mountpath: The mountpath of this DeploymentVolumeSpecAllOf. + :type mountpath: str + """ + if mountpath is None: + raise ValueError("Invalid value for `mountpath`, must not be `None`") # noqa: E501 + + self._mountpath = mountpath + + @property + def size(self): + """Gets the size of this DeploymentVolumeSpecAllOf. + + The volume size. E.g. 5Gi # noqa: E501 + + :return: The size of this DeploymentVolumeSpecAllOf. + :rtype: object + """ + return self._size + + @size.setter + def size(self, size): + """Sets the size of this DeploymentVolumeSpecAllOf. + + The volume size. E.g. 5Gi # noqa: E501 + + :param size: The size of this DeploymentVolumeSpecAllOf. + :type size: object + """ + + self._size = size + + @property + def usenfs(self): + """Gets the usenfs of this DeploymentVolumeSpecAllOf. + + Set to `true` to use the nfs on the created volume and mount as ReadWriteMany. # noqa: E501 + + :return: The usenfs of this DeploymentVolumeSpecAllOf. + :rtype: bool + """ + return self._usenfs + + @usenfs.setter + def usenfs(self, usenfs): + """Sets the usenfs of this DeploymentVolumeSpecAllOf. + + Set to `true` to use the nfs on the created volume and mount as ReadWriteMany. # noqa: E501 + + :param usenfs: The usenfs of this DeploymentVolumeSpecAllOf. + :type usenfs: bool + """ + + self._usenfs = usenfs diff --git a/libraries/models/cloudharness_model/models/e2_e_tests_config.py b/libraries/models/cloudharness_model/models/e2_e_tests_config.py index 27591dea..e856fe9d 100644 --- a/libraries/models/cloudharness_model/models/e2_e_tests_config.py +++ b/libraries/models/cloudharness_model/models/e2_e_tests_config.py @@ -111,6 +111,7 @@ def smoketest(self, smoketest): def ignore_console_errors(self): """Gets the ignore_console_errors of this E2ETestsConfig. + # noqa: E501 :return: The ignore_console_errors of this E2ETestsConfig. :rtype: bool @@ -121,6 +122,7 @@ def ignore_console_errors(self): def ignore_console_errors(self, ignore_console_errors): """Sets the ignore_console_errors of this E2ETestsConfig. + # noqa: E501 :param ignore_console_errors: The ignore_console_errors of this E2ETestsConfig. :type ignore_console_errors: bool @@ -132,6 +134,7 @@ def ignore_console_errors(self, ignore_console_errors): def ignore_request_errors(self): """Gets the ignore_request_errors of this E2ETestsConfig. + # noqa: E501 :return: The ignore_request_errors of this E2ETestsConfig. :rtype: bool @@ -142,6 +145,7 @@ def ignore_request_errors(self): def ignore_request_errors(self, ignore_request_errors): """Sets the ignore_request_errors of this E2ETestsConfig. + # noqa: E501 :param ignore_request_errors: The ignore_request_errors of this E2ETestsConfig. :type ignore_request_errors: bool diff --git a/libraries/models/cloudharness_model/models/file_resources_config.py b/libraries/models/cloudharness_model/models/file_resources_config.py index 50709712..da5993b4 100644 --- a/libraries/models/cloudharness_model/models/file_resources_config.py +++ b/libraries/models/cloudharness_model/models/file_resources_config.py @@ -58,6 +58,7 @@ def from_dict(cls, dikt) -> 'FileResourcesConfig': def name(self): """Gets the name of this FileResourcesConfig. + # noqa: E501 :return: The name of this FileResourcesConfig. :rtype: str @@ -68,6 +69,7 @@ def name(self): def name(self, name): """Sets the name of this FileResourcesConfig. + # noqa: E501 :param name: The name of this FileResourcesConfig. :type name: str @@ -83,6 +85,7 @@ def name(self, name): def src(self): """Gets the src of this FileResourcesConfig. + # noqa: E501 :return: The src of this FileResourcesConfig. :rtype: str @@ -93,6 +96,7 @@ def src(self): def src(self, src): """Sets the src of this FileResourcesConfig. + # noqa: E501 :param src: The src of this FileResourcesConfig. :type src: str @@ -108,6 +112,7 @@ def src(self, src): def dst(self): """Gets the dst of this FileResourcesConfig. + # noqa: E501 :return: The dst of this FileResourcesConfig. :rtype: str @@ -118,6 +123,7 @@ def dst(self): def dst(self, dst): """Sets the dst of this FileResourcesConfig. + # noqa: E501 :param dst: The dst of this FileResourcesConfig. :type dst: str diff --git a/libraries/models/cloudharness_model/models/harness_main_config.py b/libraries/models/cloudharness_model/models/harness_main_config.py index d611ce20..d3b4af7f 100644 --- a/libraries/models/cloudharness_model/models/harness_main_config.py +++ b/libraries/models/cloudharness_model/models/harness_main_config.py @@ -283,6 +283,7 @@ def tag(self, tag): def apps(self): """Gets the apps of this HarnessMainConfig. + # noqa: E501 :return: The apps of this HarnessMainConfig. :rtype: Dict[str, ApplicationConfig] @@ -293,6 +294,7 @@ def apps(self): def apps(self, apps): """Sets the apps of this HarnessMainConfig. + # noqa: E501 :param apps: The apps of this HarnessMainConfig. :type apps: Dict[str, ApplicationConfig] @@ -394,6 +396,7 @@ def name(self, name): def task_images(self): """Gets the task_images of this HarnessMainConfig. + # noqa: E501 :return: The task_images of this HarnessMainConfig. :rtype: Dict[str, str] @@ -404,6 +407,7 @@ def task_images(self): def task_images(self, task_images): """Sets the task_images of this HarnessMainConfig. + # noqa: E501 :param task_images: The task_images of this HarnessMainConfig. :type task_images: Dict[str, str] diff --git a/libraries/models/cloudharness_model/models/ingress_config.py b/libraries/models/cloudharness_model/models/ingress_config.py index 187a892e..6253941a 100644 --- a/libraries/models/cloudharness_model/models/ingress_config.py +++ b/libraries/models/cloudharness_model/models/ingress_config.py @@ -6,13 +6,9 @@ from typing import List, Dict # noqa: F401 from cloudharness_model.models.base_model_ import Model -from cloudharness_model.models.auto_artifact_spec import AutoArtifactSpec -from cloudharness_model.models.ingress_config_all_of import IngressConfigAllOf from cloudharness_model.models.ingress_config_all_of_letsencrypt import IngressConfigAllOfLetsencrypt from cloudharness_model import util -from cloudharness_model.models.auto_artifact_spec import AutoArtifactSpec # noqa: E501 -from cloudharness_model.models.ingress_config_all_of import IngressConfigAllOf # noqa: E501 from cloudharness_model.models.ingress_config_all_of_letsencrypt import IngressConfigAllOfLetsencrypt # noqa: E501 class IngressConfig(Model): @@ -67,6 +63,7 @@ def from_dict(cls, dikt) -> 'IngressConfig': def ssl_redirect(self): """Gets the ssl_redirect of this IngressConfig. + # noqa: E501 :return: The ssl_redirect of this IngressConfig. :rtype: bool @@ -77,6 +74,7 @@ def ssl_redirect(self): def ssl_redirect(self, ssl_redirect): """Sets the ssl_redirect of this IngressConfig. + # noqa: E501 :param ssl_redirect: The ssl_redirect of this IngressConfig. :type ssl_redirect: bool @@ -134,6 +132,7 @@ def auto(self, auto): def name(self): """Gets the name of this IngressConfig. + # noqa: E501 :return: The name of this IngressConfig. :rtype: str @@ -144,6 +143,7 @@ def name(self): def name(self, name): """Sets the name of this IngressConfig. + # noqa: E501 :param name: The name of this IngressConfig. :type name: str diff --git a/libraries/models/cloudharness_model/models/ingress_config_all_of.py b/libraries/models/cloudharness_model/models/ingress_config_all_of.py index 76fe8af2..a6fc69ea 100644 --- a/libraries/models/cloudharness_model/models/ingress_config_all_of.py +++ b/libraries/models/cloudharness_model/models/ingress_config_all_of.py @@ -53,6 +53,7 @@ def from_dict(cls, dikt) -> 'IngressConfigAllOf': def ssl_redirect(self): """Gets the ssl_redirect of this IngressConfigAllOf. + # noqa: E501 :return: The ssl_redirect of this IngressConfigAllOf. :rtype: bool @@ -63,6 +64,7 @@ def ssl_redirect(self): def ssl_redirect(self, ssl_redirect): """Sets the ssl_redirect of this IngressConfigAllOf. + # noqa: E501 :param ssl_redirect: The ssl_redirect of this IngressConfigAllOf. :type ssl_redirect: bool diff --git a/libraries/models/cloudharness_model/models/jupyter_hub_config.py b/libraries/models/cloudharness_model/models/jupyter_hub_config.py index 245556fe..51316ff2 100644 --- a/libraries/models/cloudharness_model/models/jupyter_hub_config.py +++ b/libraries/models/cloudharness_model/models/jupyter_hub_config.py @@ -84,6 +84,7 @@ def args(self, args): def extra_config(self): """Gets the extra_config of this JupyterHubConfig. + # noqa: E501 :return: The extra_config of this JupyterHubConfig. :rtype: Dict[str, str] @@ -94,6 +95,7 @@ def extra_config(self): def extra_config(self, extra_config): """Sets the extra_config of this JupyterHubConfig. + # noqa: E501 :param extra_config: The extra_config of this JupyterHubConfig. :type extra_config: Dict[str, str] @@ -105,6 +107,7 @@ def extra_config(self, extra_config): def spawner_extra_config(self): """Gets the spawner_extra_config of this JupyterHubConfig. + # noqa: E501 :return: The spawner_extra_config of this JupyterHubConfig. :rtype: Dict[str, object] @@ -115,6 +118,7 @@ def spawner_extra_config(self): def spawner_extra_config(self, spawner_extra_config): """Sets the spawner_extra_config of this JupyterHubConfig. + # noqa: E501 :param spawner_extra_config: The spawner_extra_config of this JupyterHubConfig. :type spawner_extra_config: Dict[str, object] diff --git a/libraries/models/cloudharness_model/models/name_value.py b/libraries/models/cloudharness_model/models/name_value.py index 26cda4c6..f4b75cdd 100644 --- a/libraries/models/cloudharness_model/models/name_value.py +++ b/libraries/models/cloudharness_model/models/name_value.py @@ -51,6 +51,7 @@ def from_dict(cls, dikt) -> 'NameValue': def name(self): """Gets the name of this NameValue. + # noqa: E501 :return: The name of this NameValue. :rtype: str @@ -61,6 +62,7 @@ def name(self): def name(self, name): """Sets the name of this NameValue. + # noqa: E501 :param name: The name of this NameValue. :type name: str @@ -74,6 +76,7 @@ def name(self, name): def value(self): """Gets the value of this NameValue. + # noqa: E501 :return: The value of this NameValue. :rtype: str @@ -84,6 +87,7 @@ def value(self): def value(self, value): """Sets the value of this NameValue. + # noqa: E501 :param value: The value of this NameValue. :type value: str diff --git a/libraries/models/cloudharness_model/models/registry_config.py b/libraries/models/cloudharness_model/models/registry_config.py index 07238dbd..79f27027 100644 --- a/libraries/models/cloudharness_model/models/registry_config.py +++ b/libraries/models/cloudharness_model/models/registry_config.py @@ -51,6 +51,7 @@ def from_dict(cls, dikt) -> 'RegistryConfig': def name(self): """Gets the name of this RegistryConfig. + # noqa: E501 :return: The name of this RegistryConfig. :rtype: str @@ -61,6 +62,7 @@ def name(self): def name(self, name): """Sets the name of this RegistryConfig. + # noqa: E501 :param name: The name of this RegistryConfig. :type name: str diff --git a/libraries/models/cloudharness_model/models/service_auto_artifact_config.py b/libraries/models/cloudharness_model/models/service_auto_artifact_config.py index 7a4fb452..8d14ac42 100644 --- a/libraries/models/cloudharness_model/models/service_auto_artifact_config.py +++ b/libraries/models/cloudharness_model/models/service_auto_artifact_config.py @@ -6,12 +6,8 @@ from typing import List, Dict # noqa: F401 from cloudharness_model.models.base_model_ import Model -from cloudharness_model.models.auto_artifact_spec import AutoArtifactSpec -from cloudharness_model.models.service_auto_artifact_config_all_of import ServiceAutoArtifactConfigAllOf from cloudharness_model import util -from cloudharness_model.models.auto_artifact_spec import AutoArtifactSpec # noqa: E501 -from cloudharness_model.models.service_auto_artifact_config_all_of import ServiceAutoArtifactConfigAllOf # noqa: E501 class ServiceAutoArtifactConfig(Model): """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). @@ -108,6 +104,7 @@ def auto(self, auto): def name(self): """Gets the name of this ServiceAutoArtifactConfig. + # noqa: E501 :return: The name of this ServiceAutoArtifactConfig. :rtype: str @@ -118,6 +115,7 @@ def name(self): def name(self, name): """Sets the name of this ServiceAutoArtifactConfig. + # noqa: E501 :param name: The name of this ServiceAutoArtifactConfig. :type name: str diff --git a/libraries/models/cloudharness_model/models/uri_role_mapping_config.py b/libraries/models/cloudharness_model/models/uri_role_mapping_config.py index 9fe54def..046becca 100644 --- a/libraries/models/cloudharness_model/models/uri_role_mapping_config.py +++ b/libraries/models/cloudharness_model/models/uri_role_mapping_config.py @@ -53,6 +53,7 @@ def from_dict(cls, dikt) -> 'UriRoleMappingConfig': def uri(self): """Gets the uri of this UriRoleMappingConfig. + # noqa: E501 :return: The uri of this UriRoleMappingConfig. :rtype: str @@ -63,6 +64,7 @@ def uri(self): def uri(self, uri): """Sets the uri of this UriRoleMappingConfig. + # noqa: E501 :param uri: The uri of this UriRoleMappingConfig. :type uri: str diff --git a/libraries/models/cloudharness_model/models/user_group.py b/libraries/models/cloudharness_model/models/user_group.py index 70c94921..50d3b30d 100644 --- a/libraries/models/cloudharness_model/models/user_group.py +++ b/libraries/models/cloudharness_model/models/user_group.py @@ -102,6 +102,7 @@ def access(self, access): def attributes(self): """Gets the attributes of this UserGroup. + # noqa: E501 :return: The attributes of this UserGroup. :rtype: Dict[str, str] @@ -112,6 +113,7 @@ def attributes(self): def attributes(self, attributes): """Sets the attributes of this UserGroup. + # noqa: E501 :param attributes: The attributes of this UserGroup. :type attributes: Dict[str, str] diff --git a/libraries/models/cloudharness_model/util.py b/libraries/models/cloudharness_model/util.py index 332417eb..8fe0a648 100644 --- a/libraries/models/cloudharness_model/util.py +++ b/libraries/models/cloudharness_model/util.py @@ -113,7 +113,8 @@ def deserialize_model(data, klass): instance = klass() except: raise - instance._raw_dict = data + if isinstance(data, dict): + instance._raw_dict = data if not hasattr(instance, "openapi_types") or isinstance(data, klass): return data diff --git a/libraries/models/setup.cfg b/libraries/models/setup.cfg deleted file mode 100644 index 11433ee8..00000000 --- a/libraries/models/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length=99 diff --git a/libraries/models/setup.py b/libraries/models/setup.py index 409bbf7f..82ef5a48 100644 --- a/libraries/models/setup.py +++ b/libraries/models/setup.py @@ -17,4 +17,4 @@ "oyaml" ] print(REQUIREMENTS) -setup(name=NAME, version=VERSION, install_requires=REQUIREMENTS) +setup(name=NAME, version=VERSION, install_requires=REQUIREMENTS, packages=find_packages(),) diff --git a/libraries/models/test-requirements.txt b/libraries/models/test-requirements.txt index 0970f28c..58f51d6a 100644 --- a/libraries/models/test-requirements.txt +++ b/libraries/models/test-requirements.txt @@ -1,4 +1,4 @@ -pytest~=4.6.7 # needed for python 2.7+3.4 +pytest~=7.1.0 pytest-cov>=2.8.1 -pytest-randomly==1.2.3 # needed for python 2.7+3.4 -Flask-Testing==0.8.0 +pytest-randomly>=1.2.3 +Flask-Testing==0.8.1 diff --git a/test/docker-compose.yml b/test/docker-compose.yml new file mode 100644 index 00000000..cf306ed1 --- /dev/null +++ b/test/docker-compose.yml @@ -0,0 +1,17 @@ +version: "3" +services: + tests: + image: python:3.9 + command: + - /bin/sh + - -c + - | + pip install tox + rm -rf /ch/libraries/models/.tox + rm -rf /ch/libraries/cloudharness-common/.tox + rm -rf /ch/tools/deployment-cli-tools/.tox + tox -c /ch/libraries/models/ + tox -c /ch/libraries/cloudharness-common/ + tox -c /ch/tools/deployment-cli-tools + volumes: + - ../:/ch diff --git a/test/test-e2e/Dockerfile b/test/test-e2e/Dockerfile index ad329787..48c8f855 100644 --- a/test/test-e2e/Dockerfile +++ b/test/test-e2e/Dockerfile @@ -1,4 +1,4 @@ -FROM node:14.18-slim +FROM node:lts-slim # Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others) # Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer @@ -23,21 +23,18 @@ RUN apt-get update \ # browser.launch({executablePath: 'google-chrome-stable'}) # ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true RUN mkdir -p /home/test +RUN groupadd -r test && useradd -r -g test -G audio,video test \ + && chown -R test:test /home/test WORKDIR /home/test - +USER test COPY package.json . -COPY package-lock.json . -RUN npm install -RUN groupadd -r test && useradd -r -g test -G audio,video test \ - && mkdir -p /home/test/Downloads \ - && chown -R test:test /home/test \ - && chown -R test:test node_modules \ - && chown -R test:test package.json \ - && chown -R test:test package-lock.json +COPY yarn.lock . +RUN yarn install --timeout 99999999 + # Run everything after as non-privileged user. COPY --chown=test . . USER test -CMD ["npm", "run", "test"] \ No newline at end of file +CMD ["yarn", "test"] \ No newline at end of file diff --git a/test/test-e2e/package-lock.json b/test/test-e2e/package-lock.json index 5a61a6e8..bc48f0f2 100644 --- a/test/test-e2e/package-lock.json +++ b/test/test-e2e/package-lock.json @@ -1,8 +1,4764 @@ { "name": "cloudharness-e2e-test", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "cloudharness-e2e-test", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "jest": "^28.1.0", + "puppeteer": "14.0.0", + "ts-jest": "^28.0.2", + "typescript": "^4.6.4" + }, + "devDependencies": { + "@types/jest": "26.0.24", + "@types/node": "13.13.52", + "@types/puppeteer": "3.0.8", + "husky": "6.0.0", + "lint-staged": "10.5.4", + "prettier": "2.6.2", + "tslint": "6.1.3", + "tslint-config-prettier": "1.18.0", + "tslint-plugin-prettier": "2.3.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "dependencies": { + "@babel/types": "^7.20.5", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "dependencies": { + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/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==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/core": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", + "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/reporters": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^28.1.3", + "jest-config": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-resolve-dependencies": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "jest-watcher": "^28.1.3", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "dependencies": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", + "dependencies": { + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "dependencies": { + "jest-get-type": "^28.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "dependencies": { + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", + "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/types": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", + "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "28.1.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", + "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.13", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", + "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", + "dependencies": { + "@jest/test-result": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", + "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.1.20", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", + "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" + }, + "node_modules/@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==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "26.0.24", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz", + "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==", + "dev": true, + "dependencies": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" + } + }, + "node_modules/@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" + }, + "node_modules/@types/puppeteer": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-3.0.8.tgz", + "integrity": "sha512-YmaPF3KLyDNJfTMlbONOWsAfUh9j0up8xA1G/uyz4c8yD80C2VUM5OTjf+sAS89EN6A6gas0oEzJThICf4OUpw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" + }, + "node_modules/@types/yargs": { + "version": "17.0.17", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz", + "integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", + "dependencies": { + "@jest/transform": "^28.1.3", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.1.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", + "dependencies": { + "babel-plugin-jest-hoist": "^28.1.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001439", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/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==", + "engines": { + "node": ">=10" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/ci-info": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/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==" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "dev": true + }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.982423", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.982423.tgz", + "integrity": "sha512-FnVW2nDbjGNw1uD/JRC+9U5768W7e1TfUwqbDTcSsAu1jXFjITSX8w3rkW5FEpHRMPPGpvNSmO1pOpqByiWscA==" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + }, + "node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz", + "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.1", + "jest-docblock": "^21.0.0" + }, + "engines": { + "node": ">=4.0.0" + }, + "peerDependencies": { + "prettier": ">= 0.11.0" + } + }, + "node_modules/eslint-plugin-prettier/node_modules/jest-docblock": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", + "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", + "dev": true + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", + "dependencies": { + "@jest/expect-utils": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/husky": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", + "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", + "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", + "dependencies": { + "@jest/core": "^28.1.3", + "@jest/types": "^28.1.3", + "import-local": "^3.0.2", + "jest-cli": "^28.1.3" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", + "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", + "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "p-limit": "^3.1.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-cli": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", + "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", + "dependencies": { + "@jest/core": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", + "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^28.1.3", + "@jest/types": "^28.1.3", + "babel-jest": "^28.1.3", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^28.1.3", + "jest-environment-node": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-config/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-diff/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-docblock": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", + "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-each": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", + "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", + "dependencies": { + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "jest-util": "^28.1.3", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-environment-node": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", + "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", + "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", + "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", + "dependencies": { + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", + "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", + "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", + "dependencies": { + "jest-regex-util": "^28.0.2", + "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runner": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", + "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/environment": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "graceful-fs": "^4.2.9", + "jest-docblock": "^28.1.1", + "jest-environment-node": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-leak-detector": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-resolve": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-util": "^28.1.3", + "jest-watcher": "^28.1.3", + "jest-worker": "^28.1.3", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", + "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/globals": "^28.1.3", + "@jest/source-map": "^28.1.2", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", + "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-haste-map": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "natural-compare": "^1.4.0", + "pretty-format": "^28.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", + "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", + "dependencies": { + "@jest/types": "^28.1.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "leven": "^3.1.0", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "dependencies": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/lint-staged": { + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", + "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "cli-truncate": "^2.1.0", + "commander": "^6.2.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.2.0", + "dedent": "^0.7.0", + "enquirer": "^2.3.6", + "execa": "^4.1.0", + "listr2": "^3.2.2", + "log-symbols": "^4.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.2.0", + "string-argv": "0.3.1", + "stringify-object": "^3.3.0" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/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, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/listr2": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", + "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.1", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/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, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" + }, + "node_modules/node-releases": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.7.tgz", + "integrity": "sha512-EJ3rzxL9pTWPjk5arA0s0dgXpnyiAbJDE6wHT62g7VsgrgQgmmZ+Ru++M1BFofncWja+Pnn3rEr3fieRySAdKQ==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/prettier": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", + "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/pretty-format/node_modules/@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/pretty-format/node_modules/@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/puppeteer": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-14.0.0.tgz", + "integrity": "sha512-Aj/cySGBMWpUYEWV0YOcwyhq5lOxuuiGScgdj/OvslAm/ydoywiI8OzAIXT4HzKmNTmzm/fKKHHtcsQa/fFgdw==", + "deprecated": "< 19.4.0 is no longer supported", + "hasInstallScript": true, + "dependencies": { + "cross-fetch": "3.1.5", + "debug": "4.3.4", + "devtools-protocol": "0.0.982423", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "pkg-dir": "4.2.0", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.6.0" + }, + "engines": { + "node": ">=14.1.0" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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==", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rxjs": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.6.0.tgz", + "integrity": "sha512-DDa7d8TFNUalGC9VqXvQ1euWNN7sc63TrUCuM9J998+ViviahMIjKSOU7rfcgFOF+FCD71BhDRv4hrFz+ImDLQ==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/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==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, + "node_modules/ts-jest": { + "version": "28.0.8", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", + "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^28.0.0", + "json5": "^2.2.1", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^28.0.0", + "babel-jest": "^28.0.0", + "jest": "^28.0.0", + "typescript": ">=4.3" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", + "dev": true + }, + "node_modules/tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" + } + }, + "node_modules/tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true, + "bin": { + "tslint-config-prettier-check": "bin/check.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/tslint-plugin-prettier": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz", + "integrity": "sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA==", + "dev": true, + "dependencies": { + "eslint-plugin-prettier": "^2.2.0", + "lines-and-columns": "^1.1.6", + "tslib": "^1.7.1" + }, + "engines": { + "node": ">= 4" + }, + "peerDependencies": { + "prettier": "^1.9.0 || ^2.0.0", + "tslint": "^5.0.0 || ^6.0.0" + } + }, + "node_modules/tslint-plugin-prettier/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/tslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/tslint/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/tslint/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type-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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/ws": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz", + "integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, "dependencies": { "@ampproject/remapping": { "version": "2.2.0", @@ -14,33 +4770,33 @@ } }, "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "requires": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.18.6" } }, "@babel/compat-data": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.5.tgz", - "integrity": "sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg==" + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==" }, "@babel/core": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz", - "integrity": "sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", "requires": { "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-compilation-targets": "^7.18.2", - "@babel/helper-module-transforms": "^7.18.0", - "@babel/helpers": "^7.18.2", - "@babel/parser": "^7.18.5", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.5", - "@babel/types": "^7.18.4", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -49,21 +4805,21 @@ } }, "@babel/generator": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", - "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", "requires": { - "@babel/types": "^7.18.2", - "@jridgewell/gen-mapping": "^0.3.0", + "@babel/types": "^7.20.5", + "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "requires": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } @@ -71,108 +4827,113 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz", - "integrity": "sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", "requires": { - "@babel/compat-data": "^7.17.10", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.20.2", + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", "semver": "^6.3.0" } }, "@babel/helper-environment-visitor": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", - "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==" + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" }, "@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "requires": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" } }, "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-transforms": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz", - "integrity": "sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.17.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.0", - "@babel/types": "^7.18.0" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" } }, "@babel/helper-plugin-utils": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", - "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==" + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" }, "@babel/helper-simple-access": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz", - "integrity": "sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "requires": { - "@babel/types": "^7.18.2" + "@babel/types": "^7.20.2" } }, "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.18.6" } }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + }, "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" }, "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==" + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" }, "@babel/helpers": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz", - "integrity": "sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2" + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" } }, "@babel/highlight": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", - "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -229,9 +4990,9 @@ } }, "@babel/parser": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz", - "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==" + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==" }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -330,46 +5091,47 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz", - "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "requires": { - "@babel/helper-plugin-utils": "^7.17.12" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" } }, "@babel/traverse": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz", - "integrity": "sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==", - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.5", - "@babel/types": "^7.18.4", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", - "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -396,49 +5158,49 @@ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" }, "@jest/console": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.1.tgz", - "integrity": "sha512-0RiUocPVFEm3WRMOStIHbRWllG6iW6E3/gUPnf4lkrVFyXIIDeCe+vlKeYyFOMhB2EPE6FLFCNADSOOQMaqvyA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", "requires": { - "@jest/types": "^28.1.1", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^28.1.1", - "jest-util": "^28.1.1", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0" } }, "@jest/core": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.1.tgz", - "integrity": "sha512-3pYsBoZZ42tXMdlcFeCc/0j9kOlK7MYuXs2B1QbvDgMoW1K9NJ4G/VYvIbMb26iqlkTfPHo7SC2JgjDOk/mxXw==", - "requires": { - "@jest/console": "^28.1.1", - "@jest/reporters": "^28.1.1", - "@jest/test-result": "^28.1.1", - "@jest/transform": "^28.1.1", - "@jest/types": "^28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", + "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", + "requires": { + "@jest/console": "^28.1.3", + "@jest/reporters": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^28.0.2", - "jest-config": "^28.1.1", - "jest-haste-map": "^28.1.1", - "jest-message-util": "^28.1.1", + "jest-changed-files": "^28.1.3", + "jest-config": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.1", - "jest-resolve-dependencies": "^28.1.1", - "jest-runner": "^28.1.1", - "jest-runtime": "^28.1.1", - "jest-snapshot": "^28.1.1", - "jest-util": "^28.1.1", - "jest-validate": "^28.1.1", - "jest-watcher": "^28.1.1", + "jest-resolve": "^28.1.3", + "jest-resolve-dependencies": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "jest-watcher": "^28.1.3", "micromatch": "^4.0.4", - "pretty-format": "^28.1.1", + "pretty-format": "^28.1.3", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" @@ -450,11 +5212,11 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" }, "pretty-format": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.1.tgz", - "integrity": "sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -468,67 +5230,67 @@ } }, "@jest/environment": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.1.tgz", - "integrity": "sha512-9auVQ2GzQ7nrU+lAr8KyY838YahElTX9HVjbQPPS2XjlxQ+na18G113OoBhyBGBtD6ZnO/SrUy5WR8EzOj1/Uw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "requires": { - "@jest/fake-timers": "^28.1.1", - "@jest/types": "^28.1.1", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.1" + "jest-mock": "^28.1.3" } }, "@jest/expect": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.1.tgz", - "integrity": "sha512-/+tQprrFoT6lfkMj4mW/mUIfAmmk/+iQPmg7mLDIFOf2lyf7EBHaS+x3RbeR0VZVMe55IvX7QRoT/2aK3AuUXg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", "requires": { - "expect": "^28.1.1", - "jest-snapshot": "^28.1.1" + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" } }, "@jest/expect-utils": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.1.tgz", - "integrity": "sha512-n/ghlvdhCdMI/hTcnn4qV57kQuV9OTsZzH1TTCVARANKhl6hXJqLKUkwX69ftMGpsbpt96SsDD8n8LD2d9+FRw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", "requires": { "jest-get-type": "^28.0.2" } }, "@jest/fake-timers": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.1.tgz", - "integrity": "sha512-BY/3+TyLs5+q87rGWrGUY5f8e8uC3LsVHS9Diz8+FV3ARXL4sNnkLlIB8dvDvRrp+LUCGM+DLqlsYubizGUjIA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "requires": { - "@jest/types": "^28.1.1", - "@sinonjs/fake-timers": "^9.1.1", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^28.1.1", - "jest-mock": "^28.1.1", - "jest-util": "^28.1.1" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" } }, "@jest/globals": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.1.tgz", - "integrity": "sha512-dEgl/6v7ToB4vXItdvcltJBgny0xBE6xy6IYQrPJAJggdEinGxCDMivNv7sFzPcTITGquXD6UJwYxfJ/5ZwDSg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", + "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", "requires": { - "@jest/environment": "^28.1.1", - "@jest/expect": "^28.1.1", - "@jest/types": "^28.1.1" + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/types": "^28.1.3" } }, "@jest/reporters": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.1.tgz", - "integrity": "sha512-597Zj4D4d88sZrzM4atEGLuO7SdA/YrOv9SRXHXRNC+/FwPCWxZhBAEzhXoiJzfRwn8zes/EjS8Lo6DouGN5Gg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", + "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^28.1.1", - "@jest/test-result": "^28.1.1", - "@jest/transform": "^28.1.1", - "@jest/types": "^28.1.1", - "@jridgewell/trace-mapping": "^0.3.7", + "@jest/console": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -540,72 +5302,72 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^28.1.1", - "jest-util": "^28.1.1", - "jest-worker": "^28.1.1", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^9.0.0" + "v8-to-istanbul": "^9.0.1" } }, "@jest/schemas": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.0.2.tgz", - "integrity": "sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", "requires": { - "@sinclair/typebox": "^0.23.3" + "@sinclair/typebox": "^0.24.1" } }, "@jest/source-map": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.0.2.tgz", - "integrity": "sha512-Y9dxC8ZpN3kImkk0LkK5XCEneYMAXlZ8m5bflmSL5vrwyeUpJfentacCUg6fOb8NOpOO7hz2+l37MV77T6BFPw==", + "version": "28.1.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", + "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", "requires": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.13", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" } }, "@jest/test-result": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.1.tgz", - "integrity": "sha512-hPmkugBktqL6rRzwWAtp1JtYT4VHwv8OQ+9lE5Gymj6dHzubI/oJHMUpPOt8NrdVWSrz9S7bHjJUmv2ggFoUNQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", "requires": { - "@jest/console": "^28.1.1", - "@jest/types": "^28.1.1", + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.1.tgz", - "integrity": "sha512-nuL+dNSVMcWB7OOtgb0EGH5AjO4UBCt68SLP08rwmC+iRhyuJWS9MtZ/MpipxFwKAlHFftbMsydXqWre8B0+XA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", + "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", "requires": { - "@jest/test-result": "^28.1.1", + "@jest/test-result": "^28.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.1", + "jest-haste-map": "^28.1.3", "slash": "^3.0.0" } }, "@jest/transform": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.1.tgz", - "integrity": "sha512-PkfaTUuvjUarl1EDr5ZQcCA++oXkFCP9QFUkG0yVKVmNObjhrqDy0kbMpMebfHWm3CCDHjYNem9eUSH8suVNHQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", + "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^28.1.1", - "@jridgewell/trace-mapping": "^0.3.7", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.1", + "jest-haste-map": "^28.1.3", "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.1", + "jest-util": "^28.1.3", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -613,11 +5375,11 @@ } }, "@jest/types": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.1.tgz", - "integrity": "sha512-vRXVqSg1VhDnB8bWcmvLzmg0Bt9CRKVgHPXqYwvWMX3TvAjeO+nRuK6+VdTKCtWOvYlmkF/HqNAL/z+N3B53Kw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -635,38 +5397,38 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" }, "@jridgewell/set-array": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", - "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" }, "@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==" + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@sinclair/typebox": { - "version": "0.23.5", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", - "integrity": "sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==" + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" }, "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "requires": { "type-detect": "4.0.8" } @@ -680,9 +5442,9 @@ } }, "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.1.20", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", + "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", "requires": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0", @@ -709,9 +5471,9 @@ } }, "@types/babel__traverse": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", - "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "requires": { "@babel/types": "^7.3.0" } @@ -767,9 +5529,9 @@ "dev": true }, "@types/prettier": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", - "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==" + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" }, "@types/puppeteer": { "version": "3.0.8", @@ -786,9 +5548,9 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, "@types/yargs": { - "version": "17.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", - "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "version": "17.0.17", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz", + "integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==", "requires": { "@types/yargs-parser": "*" } @@ -853,9 +5615,9 @@ } }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -876,14 +5638,14 @@ "dev": true }, "babel-jest": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.1.tgz", - "integrity": "sha512-MEt0263viUdAkTq5D7upHPNxvt4n9uLUGa6pPz3WviNBMtOmStb1lIXS3QobnoqM+qnH+vr4EKlvhe8QcmxIYw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", "requires": { - "@jest/transform": "^28.1.1", + "@jest/transform": "^28.1.3", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^28.1.1", + "babel-preset-jest": "^28.1.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -902,9 +5664,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.1.tgz", - "integrity": "sha512-NovGCy5Hn25uMJSAU8FaHqzs13cFoOI4lhIujiepssjCKRsAo3TA734RDWSGxuFTsUJXerYOqQQodlxgmtqbzw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", "requires": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -932,11 +5694,11 @@ } }, "babel-preset-jest": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.1.tgz", - "integrity": "sha512-FCq9Oud0ReTeWtcneYf/48981aTfXYuB9gbU4rBNNJVBSQ6ssv7E6v/qvbBxtOWwZFXjLZwpg+W3q7J6vhH25g==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", "requires": { - "babel-plugin-jest-hoist": "^28.1.1", + "babel-plugin-jest-hoist": "^28.1.3", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -978,15 +5740,14 @@ } }, "browserslist": { - "version": "4.20.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz", - "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==", + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "requires": { - "caniuse-lite": "^1.0.30001349", - "electron-to-chromium": "^1.4.147", - "escalade": "^3.1.1", - "node-releases": "^2.0.5", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" } }, "bs-logger": { @@ -1041,9 +5802,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caniuse-lite": { - "version": "1.0.30001354", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001354.tgz", - "integrity": "sha512-mImKeCkyGDAHNywYFA4bqnLAzTUvVkqPvhY4DV47X+Gl2c5Z8c3KNETnXp14GQt11LvxE8AwjzGxJ+rsikiOzg==" + "version": "1.0.30001439", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==" }, "chalk": { "version": "4.1.2", @@ -1065,9 +5826,9 @@ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "ci-info": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", - "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==" + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==" }, "cjs-module-lexer": { "version": "1.2.2", @@ -1100,12 +5861,12 @@ } }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -1150,17 +5911,14 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "requires": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, "requires": { "@types/parse-json": "^4.0.0", @@ -1229,9 +5987,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.155", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.155.tgz", - "integrity": "sha512-niPzKBSYPG06gxLKO0c2kEmgdRMTtIbNrBlvD31Ld8Q57b/K0218U4j8u/OOt25XE1eFOn47FcmQVdx9R1qqxA==" + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" }, "emittery": { "version": "0.10.2", @@ -1323,15 +6081,15 @@ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==" }, "expect": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.1.tgz", - "integrity": "sha512-/AANEwGL0tWBwzLNOvO0yUdy2D52jVdNXppOqswC49sxMN2cPWsGCQdzuIf9tj6hHoBQzNvx75JUYuQAckPo3w==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", "requires": { - "@jest/expect-utils": "^28.1.1", + "@jest/expect-utils": "^28.1.3", "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.1", - "jest-message-util": "^28.1.1", - "jest-util": "^28.1.1" + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" } }, "extract-zip": { @@ -1367,9 +6125,9 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "requires": { "bser": "2.1.1" } @@ -1570,9 +6328,9 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "requires": { "has": "^1.0.3" } @@ -1626,9 +6384,9 @@ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==" }, "istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "requires": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -1658,58 +6416,58 @@ } }, "istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, "jest": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.1.tgz", - "integrity": "sha512-qw9YHBnjt6TCbIDMPMpJZqf9E12rh6869iZaN08/vpOGgHJSAaLLUn6H8W3IAEuy34Ls3rct064mZLETkxJ2XA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", + "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", "requires": { - "@jest/core": "^28.1.1", - "@jest/types": "^28.1.1", + "@jest/core": "^28.1.3", + "@jest/types": "^28.1.3", "import-local": "^3.0.2", - "jest-cli": "^28.1.1" + "jest-cli": "^28.1.3" } }, "jest-changed-files": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.0.2.tgz", - "integrity": "sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", + "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", "requires": { "execa": "^5.0.0", - "throat": "^6.0.1" + "p-limit": "^3.1.0" } }, "jest-circus": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.1.tgz", - "integrity": "sha512-75+BBVTsL4+p2w198DQpCeyh1RdaS2lhEG87HkaFX/UG0gJExVq2skG2pT7XZEGBubNj2CytcWSPan4QEPNosw==", - "requires": { - "@jest/environment": "^28.1.1", - "@jest/expect": "^28.1.1", - "@jest/test-result": "^28.1.1", - "@jest/types": "^28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", + "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", + "requires": { + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^28.1.1", - "jest-matcher-utils": "^28.1.1", - "jest-message-util": "^28.1.1", - "jest-runtime": "^28.1.1", - "jest-snapshot": "^28.1.1", - "jest-util": "^28.1.1", - "pretty-format": "^28.1.1", + "jest-each": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "p-limit": "^3.1.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" + "stack-utils": "^2.0.3" }, "dependencies": { "ansi-styles": { @@ -1718,11 +6476,11 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" }, "pretty-format": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.1.tgz", - "integrity": "sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -1736,49 +6494,49 @@ } }, "jest-cli": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.1.tgz", - "integrity": "sha512-+sUfVbJqb1OjBZ0OdBbI6OWfYM1i7bSfzYy6gze1F1w3OKWq8ZTEKkZ8a7ZQPq6G/G1qMh/uKqpdWhgl11NFQQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", + "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", "requires": { - "@jest/core": "^28.1.1", - "@jest/test-result": "^28.1.1", - "@jest/types": "^28.1.1", + "@jest/core": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^28.1.1", - "jest-util": "^28.1.1", - "jest-validate": "^28.1.1", + "jest-config": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "prompts": "^2.0.1", "yargs": "^17.3.1" } }, "jest-config": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.1.tgz", - "integrity": "sha512-tASynMhS+jVV85zKvjfbJ8nUyJS/jUSYZ5KQxLUN2ZCvcQc/OmhQl2j6VEL3ezQkNofxn5pQ3SPYWPHb0unTZA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", + "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", "requires": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^28.1.1", - "@jest/types": "^28.1.1", - "babel-jest": "^28.1.1", + "@jest/test-sequencer": "^28.1.3", + "@jest/types": "^28.1.3", + "babel-jest": "^28.1.3", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^28.1.1", - "jest-environment-node": "^28.1.1", + "jest-circus": "^28.1.3", + "jest-environment-node": "^28.1.3", "jest-get-type": "^28.0.2", "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.1", - "jest-runner": "^28.1.1", - "jest-util": "^28.1.1", - "jest-validate": "^28.1.1", + "jest-resolve": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^28.1.1", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -1789,11 +6547,11 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" }, "pretty-format": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.1.tgz", - "integrity": "sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -1835,15 +6593,15 @@ } }, "jest-each": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.1.tgz", - "integrity": "sha512-A042rqh17ZvEhRceDMi784ppoXR7MWGDEKTXEZXb4svt0eShMZvijGxzKsx+yIjeE8QYmHPrnHiTSQVhN4nqaw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", + "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", "requires": { - "@jest/types": "^28.1.1", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "jest-get-type": "^28.0.2", - "jest-util": "^28.1.1", - "pretty-format": "^28.1.1" + "jest-util": "^28.1.3", + "pretty-format": "^28.1.3" }, "dependencies": { "ansi-styles": { @@ -1852,11 +6610,11 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" }, "pretty-format": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.1.tgz", - "integrity": "sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -1870,16 +6628,16 @@ } }, "jest-environment-node": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.1.tgz", - "integrity": "sha512-2aV/eeY/WNgUUJrrkDJ3cFEigjC5fqT1+fCclrY6paqJ5zVPoM//sHmfgUUp7WLYxIdbPwMiVIzejpN56MxnNA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", + "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", "requires": { - "@jest/environment": "^28.1.1", - "@jest/fake-timers": "^28.1.1", - "@jest/types": "^28.1.1", + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^28.1.1", - "jest-util": "^28.1.1" + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" } }, "jest-get-type": { @@ -1888,11 +6646,11 @@ "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==" }, "jest-haste-map": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.1.tgz", - "integrity": "sha512-ZrRSE2o3Ezh7sb1KmeLEZRZ4mgufbrMwolcFHNRSjKZhpLa8TdooXOOFlSwoUzlbVs1t0l7upVRW2K7RWGHzbQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", + "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", "requires": { - "@jest/types": "^28.1.1", + "@jest/types": "^28.1.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", @@ -1900,19 +6658,19 @@ "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.1", - "jest-worker": "^28.1.1", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-leak-detector": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.1.tgz", - "integrity": "sha512-4jvs8V8kLbAaotE+wFR7vfUGf603cwYtFf1/PYEsyX2BAjSzj8hQSVTP6OWzseTl0xL6dyHuKs2JAks7Pfubmw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", + "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", "requires": { "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.1" + "pretty-format": "^28.1.3" }, "dependencies": { "ansi-styles": { @@ -1921,11 +6679,11 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" }, "pretty-format": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.1.tgz", - "integrity": "sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -1939,14 +6697,14 @@ } }, "jest-matcher-utils": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.1.tgz", - "integrity": "sha512-NPJPRWrbmR2nAJ+1nmnfcKKzSwgfaciCCrYZzVnNoxVoyusYWIjkBMNvu0RHJe7dNj4hH3uZOPZsQA+xAYWqsw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", "requires": { "chalk": "^4.0.0", - "jest-diff": "^28.1.1", + "jest-diff": "^28.1.3", "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.1" + "pretty-format": "^28.1.3" }, "dependencies": { "ansi-styles": { @@ -1960,22 +6718,22 @@ "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==" }, "jest-diff": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.1.tgz", - "integrity": "sha512-/MUUxeR2fHbqHoMMiffe/Afm+U8U4olFRJ0hiVG2lZatPJcnGxx292ustVu7bULhjV65IYMxRdploAKLbcrsyg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", "requires": { "chalk": "^4.0.0", "diff-sequences": "^28.1.1", "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.1" + "pretty-format": "^28.1.3" } }, "pretty-format": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.1.tgz", - "integrity": "sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -1989,17 +6747,17 @@ } }, "jest-message-util": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.1.tgz", - "integrity": "sha512-xoDOOT66fLfmTRiqkoLIU7v42mal/SqwDKvfmfiWAdJMSJiU+ozgluO7KbvoAgiwIrrGZsV7viETjc8GNrA/IQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.1", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.1", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -2010,11 +6768,11 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" }, "pretty-format": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.1.tgz", - "integrity": "sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -2028,18 +6786,19 @@ } }, "jest-mock": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.1.tgz", - "integrity": "sha512-bDCb0FjfsmKweAvE09dZT59IMkzgN0fYBH6t5S45NoJfd2DHkS3ySG2K+hucortryhO3fVuXdlxWcbtIuV/Skw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "requires": { - "@jest/types": "^28.1.1", + "@jest/types": "^28.1.3", "@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==" + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "requires": {} }, "jest-regex-util": { "version": "28.0.2", @@ -2047,114 +6806,114 @@ "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==" }, "jest-resolve": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.1.tgz", - "integrity": "sha512-/d1UbyUkf9nvsgdBildLe6LAD4DalgkgZcKd0nZ8XUGPyA/7fsnaQIlKVnDiuUXv/IeZhPEDrRJubVSulxrShA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", + "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", "requires": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.1", + "jest-haste-map": "^28.1.3", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^28.1.1", - "jest-validate": "^28.1.1", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.1.tgz", - "integrity": "sha512-p8Y150xYJth4EXhOuB8FzmS9r8IGLEioiaetgdNGb9VHka4fl0zqWlVe4v7mSkYOuEUg2uB61iE+zySDgrOmgQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", + "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", "requires": { "jest-regex-util": "^28.0.2", - "jest-snapshot": "^28.1.1" + "jest-snapshot": "^28.1.3" } }, "jest-runner": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.1.tgz", - "integrity": "sha512-W5oFUiDBgTsCloTAj6q95wEvYDB0pxIhY6bc5F26OucnwBN+K58xGTGbliSMI4ChQal5eANDF+xvELaYkJxTmA==", - "requires": { - "@jest/console": "^28.1.1", - "@jest/environment": "^28.1.1", - "@jest/test-result": "^28.1.1", - "@jest/transform": "^28.1.1", - "@jest/types": "^28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", + "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", + "requires": { + "@jest/console": "^28.1.3", + "@jest/environment": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.10.2", "graceful-fs": "^4.2.9", "jest-docblock": "^28.1.1", - "jest-environment-node": "^28.1.1", - "jest-haste-map": "^28.1.1", - "jest-leak-detector": "^28.1.1", - "jest-message-util": "^28.1.1", - "jest-resolve": "^28.1.1", - "jest-runtime": "^28.1.1", - "jest-util": "^28.1.1", - "jest-watcher": "^28.1.1", - "jest-worker": "^28.1.1", - "source-map-support": "0.5.13", - "throat": "^6.0.1" + "jest-environment-node": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-leak-detector": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-resolve": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-util": "^28.1.3", + "jest-watcher": "^28.1.3", + "jest-worker": "^28.1.3", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" } }, "jest-runtime": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.1.tgz", - "integrity": "sha512-J89qEJWW0leOsqyi0D9zHpFEYHwwafFdS9xgvhFHtIdRghbadodI0eA+DrthK/1PebBv3Px8mFSMGKrtaVnleg==", - "requires": { - "@jest/environment": "^28.1.1", - "@jest/fake-timers": "^28.1.1", - "@jest/globals": "^28.1.1", - "@jest/source-map": "^28.0.2", - "@jest/test-result": "^28.1.1", - "@jest/transform": "^28.1.1", - "@jest/types": "^28.1.1", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", + "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", + "requires": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/globals": "^28.1.3", + "@jest/source-map": "^28.1.2", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "execa": "^5.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.1", - "jest-message-util": "^28.1.1", - "jest-mock": "^28.1.1", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.1", - "jest-snapshot": "^28.1.1", - "jest-util": "^28.1.1", + "jest-resolve": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0", "strip-bom": "^4.0.0" } }, "jest-snapshot": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.1.tgz", - "integrity": "sha512-1KjqHJ98adRcbIdMizjF5DipwZFbvxym/kFO4g4fVZCZRxH/dqV8TiBFCa6rqic3p0karsy8RWS1y4E07b7P0A==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", + "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", "requires": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^28.1.1", - "@jest/transform": "^28.1.1", - "@jest/types": "^28.1.1", + "@jest/expect-utils": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^28.1.1", + "expect": "^28.1.3", "graceful-fs": "^4.2.9", - "jest-diff": "^28.1.1", + "jest-diff": "^28.1.3", "jest-get-type": "^28.0.2", - "jest-haste-map": "^28.1.1", - "jest-matcher-utils": "^28.1.1", - "jest-message-util": "^28.1.1", - "jest-util": "^28.1.1", + "jest-haste-map": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "natural-compare": "^1.4.0", - "pretty-format": "^28.1.1", + "pretty-format": "^28.1.3", "semver": "^7.3.5" }, "dependencies": { @@ -2169,22 +6928,22 @@ "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==" }, "jest-diff": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.1.tgz", - "integrity": "sha512-/MUUxeR2fHbqHoMMiffe/Afm+U8U4olFRJ0hiVG2lZatPJcnGxx292ustVu7bULhjV65IYMxRdploAKLbcrsyg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", "requires": { "chalk": "^4.0.0", "diff-sequences": "^28.1.1", "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.1" + "pretty-format": "^28.1.3" } }, "pretty-format": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.1.tgz", - "integrity": "sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -2196,9 +6955,9 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } @@ -2206,11 +6965,11 @@ } }, "jest-util": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.1.tgz", - "integrity": "sha512-FktOu7ca1DZSyhPAxgxB6hfh2+9zMoJ7aEQA759Z6p45NuO8mWcqujH+UdHlCm/V6JTWwDztM2ITCzU1ijJAfw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "requires": { - "@jest/types": "^28.1.1", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -2219,16 +6978,16 @@ } }, "jest-validate": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.1.tgz", - "integrity": "sha512-Kpf6gcClqFCIZ4ti5++XemYJWUPCFUW+N2gknn+KgnDf549iLul3cBuKVe1YcWRlaF8tZV8eJCap0eECOEE3Ug==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", + "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", "requires": { - "@jest/types": "^28.1.1", + "@jest/types": "^28.1.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^28.0.2", "leven": "^3.1.0", - "pretty-format": "^28.1.1" + "pretty-format": "^28.1.3" }, "dependencies": { "ansi-styles": { @@ -2242,11 +7001,11 @@ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==" }, "pretty-format": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.1.tgz", - "integrity": "sha512-wwJbVTGFHeucr5Jw2bQ9P+VYHyLdAqedFLEkdQUVaBF/eiidDwH5OpilINq4mEfhbCjLnirt6HTTDhv1HaTIQw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "requires": { - "@jest/schemas": "^28.0.2", + "@jest/schemas": "^28.1.3", "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" @@ -2260,24 +7019,24 @@ } }, "jest-watcher": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.1.tgz", - "integrity": "sha512-RQIpeZ8EIJMxbQrXpJQYIIlubBnB9imEHsxxE41f54ZwcqWLysL/A0ZcdMirf+XsMn3xfphVQVV4EW0/p7i7Ug==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", "requires": { - "@jest/test-result": "^28.1.1", - "@jest/types": "^28.1.1", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.10.2", - "jest-util": "^28.1.1", + "jest-util": "^28.1.3", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.1.tgz", - "integrity": "sha512-Au7slXB08C6h+xbJPp7VIb6U0XX5Kc9uel/WFc6/rcTzGiaVCBRngBExSYuXSLFPULPSYU3cJ3ybS988lNFQhQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", "requires": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -2527,9 +7286,9 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true }, "mkdirp": { @@ -2570,9 +7329,9 @@ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" }, "node-releases": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", - "integrity": "sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==" + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.7.tgz", + "integrity": "sha512-EJ3rzxL9pTWPjk5arA0s0dgXpnyiAbJDE6wHT62g7VsgrgQgmmZ+Ru++M1BFofncWja+Pnn3rEr3fieRySAdKQ==" }, "normalize-path": { "version": "3.0.0", @@ -2604,11 +7363,11 @@ } }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { @@ -2617,6 +7376,16 @@ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "requires": { "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + } } }, "p-map": { @@ -2827,11 +7596,11 @@ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -2879,18 +7648,18 @@ } }, "rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.6.0.tgz", + "integrity": "sha512-DDa7d8TFNUalGC9VqXvQ1euWNN7sc63TrUCuM9J998+ViviahMIjKSOU7rfcgFOF+FCD71BhDRv4hrFz+ImDLQ==", "dev": true, "requires": { "tslib": "^2.1.0" } }, "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==" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "semver": { "version": "6.3.0", @@ -2962,13 +7731,21 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "requires": { "escape-string-regexp": "^2.0.0" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-argv": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", @@ -2994,21 +7771,6 @@ "strip-ansi": "^6.0.1" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, "stringify-object": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", @@ -3052,9 +7814,9 @@ } }, "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "requires": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -3107,11 +7869,6 @@ "minimatch": "^3.0.4" } }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==" - }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -3141,9 +7898,9 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "ts-jest": { - "version": "28.0.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.5.tgz", - "integrity": "sha512-Sx9FyP9pCY7pUzQpy4FgRZf2bhHY3za576HMKJFs+OnQ9jS96Du5vNsDKkyedQkik+sEabbKAnCliv9BEsHZgQ==", + "version": "28.0.8", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", + "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", "requires": { "bs-logger": "0.x", "fast-json-stable-stringify": "2.x", @@ -3156,9 +7913,9 @@ }, "dependencies": { "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "requires": { "lru-cache": "^6.0.0" } @@ -3166,9 +7923,9 @@ } }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", "dev": true }, "tslint": { @@ -3321,9 +8078,9 @@ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" }, "typescript": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", - "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==" + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==" }, "unbzip2-stream": { "version": "1.4.3", @@ -3334,17 +8091,26 @@ "through": "^2.3.8" } }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "v8-to-istanbul": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", - "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "requires": { - "@jridgewell/trace-mapping": "^0.3.7", + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0" } @@ -3395,9 +8161,9 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "requires": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" @@ -3406,7 +8172,8 @@ "ws": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz", - "integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==" + "integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==", + "requires": {} }, "y18n": { "version": "5.0.8", @@ -3425,23 +8192,23 @@ "dev": true }, "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" } }, "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==" + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" }, "yauzl": { "version": "2.10.0", @@ -3451,6 +8218,11 @@ "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/test/test-e2e/yarn.lock b/test/test-e2e/yarn.lock new file mode 100644 index 00000000..fc69b2de --- /dev/null +++ b/test/test-e2e/yarn.lock @@ -0,0 +1,2874 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ampproject/remapping@^2.1.0": + version "2.2.0" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== + dependencies: + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/compat-data@^7.20.0": + version "7.20.5" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz" + integrity sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3": + version "7.20.5" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz" + integrity sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.5" + "@babel/helper-compilation-targets" "^7.20.0" + "@babel/helper-module-transforms" "^7.20.2" + "@babel/helpers" "^7.20.5" + "@babel/parser" "^7.20.5" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/generator@^7.20.5", "@babel/generator@^7.7.2": + version "7.20.5" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz" + integrity sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA== + dependencies: + "@babel/types" "^7.20.5" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.20.0": + version "7.20.0" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz" + integrity sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ== + dependencies: + "@babel/compat-data" "^7.20.0" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.21.3" + semver "^6.3.0" + +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + +"@babel/helper-function-name@^7.19.0": + version "7.19.0" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz" + integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/types" "^7.19.0" + +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-transforms@^7.20.2": + version "7.20.2" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz" + integrity sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.1" + "@babel/types" "^7.20.2" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0": + version "7.20.2" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz" + integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== + +"@babel/helper-simple-access@^7.20.2": + version "7.20.2" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz" + integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== + dependencies: + "@babel/types" "^7.20.2" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.19.4": + version "7.19.4" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz" + integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== + +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helpers@^7.20.5": + version "7.20.6" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz" + integrity sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w== + dependencies: + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.20.5" + "@babel/types" "^7.20.5" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.20.5": + version "7.20.5" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz" + integrity sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA== + +"@babel/plugin-syntax-async-generators@^7.8.4": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + 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== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.20.0" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz" + integrity sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.19.0" + +"@babel/template@^7.18.10", "@babel/template@^7.3.3": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" + +"@babel/traverse@^7.20.1", "@babel/traverse@^7.20.5", "@babel/traverse@^7.7.2": + version "7.20.5" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz" + integrity sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.20.5" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.19.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.20.5" + "@babel/types" "^7.20.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.20.5" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz" + integrity sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz" + integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + slash "^3.0.0" + +"@jest/core@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz" + integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== + dependencies: + "@jest/console" "^28.1.3" + "@jest/reporters" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^28.1.3" + jest-config "^28.1.3" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-resolve-dependencies "^28.1.3" + jest-runner "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + jest-watcher "^28.1.3" + micromatch "^4.0.4" + pretty-format "^28.1.3" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz" + integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== + dependencies: + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-mock "^28.1.3" + +"@jest/expect-utils@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz" + integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== + dependencies: + jest-get-type "^28.0.2" + +"@jest/expect@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz" + integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== + dependencies: + expect "^28.1.3" + jest-snapshot "^28.1.3" + +"@jest/fake-timers@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz" + integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== + dependencies: + "@jest/types" "^28.1.3" + "@sinonjs/fake-timers" "^9.1.2" + "@types/node" "*" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-util "^28.1.3" + +"@jest/globals@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz" + integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/types" "^28.1.3" + +"@jest/reporters@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz" + integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + jest-worker "^28.1.3" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + terminal-link "^2.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz" + integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== + dependencies: + "@sinclair/typebox" "^0.24.1" + +"@jest/source-map@^28.1.2": + version "28.1.2" + resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz" + integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== + dependencies: + "@jridgewell/trace-mapping" "^0.3.13" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz" + integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== + dependencies: + "@jest/console" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz" + integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== + dependencies: + "@jest/test-result" "^28.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + slash "^3.0.0" + +"@jest/transform@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz" + integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.1" + +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + +"@jest/types@^28.1.3": + version "28.1.3" + resolved "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz" + integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== + dependencies: + "@jest/schemas" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.17" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@sinclair/typebox@^0.24.1": + version "0.24.51" + resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== + +"@sinonjs/commons@^1.7.0": + version "1.8.6" + resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz" + integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^9.1.2": + version "9.1.2" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz" + integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@types/babel__core@^7.1.14": + version "7.1.20" + resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz" + integrity sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.18.3" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz" + integrity sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w== + dependencies: + "@babel/types" "^7.3.0" + +"@types/graceful-fs@^4.1.3": + version "4.1.5" + resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@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== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@26.0.24": + version "26.0.24" + resolved "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz" + integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== + dependencies: + jest-diff "^26.0.0" + pretty-format "^26.0.0" + +"@types/node@*", "@types/node@13.13.52": + version "13.13.52" + resolved "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz" + integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/prettier@^2.1.5": + version "2.7.1" + resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz" + integrity sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow== + +"@types/puppeteer@3.0.8": + version "3.0.8" + resolved "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-3.0.8.tgz" + integrity sha512-YmaPF3KLyDNJfTMlbONOWsAfUh9j0up8xA1G/uyz4c8yD80C2VUM5OTjf+sAS89EN6A6gas0oEzJThICf4OUpw== + dependencies: + "@types/node" "*" + +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^15.0.0": + version "15.0.14" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz" + integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs@^17.0.8": + version "17.0.17" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz" + integrity sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g== + dependencies: + "@types/yargs-parser" "*" + +"@types/yauzl@^2.9.1": + version "2.10.0" + resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz" + integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw== + dependencies: + "@types/node" "*" + +agent-base@6: + version "6.0.2" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.0, ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + 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== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.3" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +babel-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz" + integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== + dependencies: + "@jest/transform" "^28.1.3" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^28.1.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz" + integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz" + integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== + dependencies: + babel-plugin-jest-hoist "^28.1.3" + babel-preset-current-node-syntax "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.21.3: + version "4.21.4" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== + dependencies: + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" + integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@^5.2.1, buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz" + integrity sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ== + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001400: + version "1.0.30001439" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz" + integrity sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A== + +chalk@^2.0.0, chalk@^2.3.0: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +ci-info@^3.2.0: + version "3.7.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz" + integrity sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog== + +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.16: + version "2.0.19" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + +commander@^2.12.1: + version "2.20.3" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^6.2.0: + version "6.2.1" + resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +cosmiconfig@^7.0.0: + version "7.1.0" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cross-fetch@3.1.5: + version "3.1.5" + resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== + dependencies: + node-fetch "2.6.7" + +cross-spawn@^7.0.0, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +devtools-protocol@0.0.982423: + version "0.0.982423" + resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.982423.tgz" + integrity sha512-FnVW2nDbjGNw1uD/JRC+9U5768W7e1TfUwqbDTcSsAu1jXFjITSX8w3rkW5FEpHRMPPGpvNSmO1pOpqByiWscA== + +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== + +diff-sequences@^28.1.1: + version "28.1.1" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz" + integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +electron-to-chromium@^1.4.251: + version "1.4.284" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz" + integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== + +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + 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== + dependencies: + once "^1.4.0" + +enquirer@^2.3.6: + version "2.3.6" + resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +eslint-plugin-prettier@^2.2.0: + version "2.7.0" + resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz" + integrity sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA== + dependencies: + fast-diff "^1.1.1" + jest-docblock "^21.0.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +execa@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + 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" + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz" + integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== + dependencies: + "@jest/expect-utils" "^28.1.3" + jest-get-type "^28.0.2" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz" + integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +fast-diff@^1.1.1: + version "1.2.0" + resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: + 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== + +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz" + integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== + dependencies: + pend "~1.2.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^5.0.0, get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob@^7.1.1, glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +https-proxy-agent@5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +husky@6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz" + integrity sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ== + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-core-module@^2.9.0: + version "2.11.0" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== + dependencies: + has "^1.0.3" + +is-fullwidth-code-point@^3.0.0: + 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== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" + integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" + integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.5" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz" + integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + +jest-circus@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz" + integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + is-generator-fn "^2.0.0" + jest-each "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + p-limit "^3.1.0" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz" + integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== + dependencies: + "@jest/core" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + prompts "^2.0.1" + yargs "^17.3.1" + +jest-config@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz" + integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^28.1.3" + "@jest/types" "^28.1.3" + babel-jest "^28.1.3" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^28.1.3" + jest-environment-node "^28.1.3" + jest-get-type "^28.0.2" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-runner "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^28.1.3" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^26.0.0: + version "26.6.2" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== + dependencies: + chalk "^4.0.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" + +jest-diff@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz" + integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== + dependencies: + chalk "^4.0.0" + diff-sequences "^28.1.1" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + +jest-docblock@^21.0.0: + version "21.2.0" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz" + integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== + +jest-docblock@^28.1.1: + version "28.1.1" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz" + integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== + dependencies: + detect-newline "^3.0.0" + +jest-each@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz" + integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== + dependencies: + "@jest/types" "^28.1.3" + chalk "^4.0.0" + jest-get-type "^28.0.2" + jest-util "^28.1.3" + pretty-format "^28.1.3" + +jest-environment-node@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz" + integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-mock "^28.1.3" + jest-util "^28.1.3" + +jest-get-type@^26.3.0: + version "26.3.0" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz" + integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== + +jest-get-type@^28.0.2: + version "28.0.2" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz" + integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== + +jest-haste-map@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz" + integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== + dependencies: + "@jest/types" "^28.1.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + jest-worker "^28.1.3" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz" + integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== + dependencies: + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + +jest-matcher-utils@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz" + integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== + dependencies: + chalk "^4.0.0" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + +jest-message-util@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz" + integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^28.1.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz" + integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^28.0.2: + version "28.0.2" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz" + integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== + +jest-resolve-dependencies@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz" + integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== + dependencies: + jest-regex-util "^28.0.2" + jest-snapshot "^28.1.3" + +jest-resolve@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz" + integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-pnp-resolver "^1.2.2" + jest-util "^28.1.3" + jest-validate "^28.1.3" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz" + integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== + dependencies: + "@jest/console" "^28.1.3" + "@jest/environment" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.10.2" + graceful-fs "^4.2.9" + jest-docblock "^28.1.1" + jest-environment-node "^28.1.3" + jest-haste-map "^28.1.3" + jest-leak-detector "^28.1.3" + jest-message-util "^28.1.3" + jest-resolve "^28.1.3" + jest-runtime "^28.1.3" + jest-util "^28.1.3" + jest-watcher "^28.1.3" + jest-worker "^28.1.3" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz" + integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/globals" "^28.1.3" + "@jest/source-map" "^28.1.2" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz" + integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/babel__traverse" "^7.0.6" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^28.1.3" + graceful-fs "^4.2.9" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + jest-haste-map "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + natural-compare "^1.4.0" + pretty-format "^28.1.3" + semver "^7.3.5" + +jest-util@^28.0.0, jest-util@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz" + integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz" + integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== + dependencies: + "@jest/types" "^28.1.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^28.0.2" + leven "^3.1.0" + pretty-format "^28.1.3" + +jest-watcher@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz" + integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== + dependencies: + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^28.1.3" + string-length "^4.0.1" + +jest-worker@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz" + integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^28.1.0: + version "28.1.3" + resolved "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz" + integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA== + dependencies: + "@jest/core" "^28.1.3" + "@jest/types" "^28.1.3" + import-local "^3.0.2" + jest-cli "^28.1.3" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json5@^2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +lint-staged@10.5.4: + version "10.5.4" + resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz" + integrity sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg== + dependencies: + chalk "^4.1.0" + cli-truncate "^2.1.0" + commander "^6.2.0" + cosmiconfig "^7.0.0" + debug "^4.2.0" + dedent "^0.7.0" + enquirer "^2.3.6" + execa "^4.1.0" + listr2 "^3.2.2" + log-symbols "^4.0.0" + micromatch "^4.0.2" + normalize-path "^3.0.0" + please-upgrade-node "^3.2.0" + string-argv "0.3.1" + stringify-object "^3.3.0" + +listr2@^3.2.2: + version "3.14.0" + resolved "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz" + integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.16" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.5.1" + through "^2.3.8" + wrap-ansi "^7.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +log-symbols@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.0.0: + 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== + dependencies: + semver "^6.0.0" + +make-error@1.x: + version "1.3.6" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.6: + version "1.2.7" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz" + integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== + +mkdirp-classic@^0.5.2: + version "0.5.3" + resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mkdirp@^0.5.3: + version "0.5.6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.6: + version "2.0.7" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.7.tgz" + integrity sha512-EJ3rzxL9pTWPjk5arA0s0dgXpnyiAbJDE6wHT62g7VsgrgQgmmZ+Ru++M1BFofncWja+Pnn3rEr3fieRySAdKQ== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.0, npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^5.0.0, parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" + integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +pkg-dir@4.2.0, pkg-dir@^4.2.0: + 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== + dependencies: + find-up "^4.0.0" + +please-upgrade-node@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz" + integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== + dependencies: + semver-compare "^1.0.0" + +prettier@2.6.2: + version "2.6.2" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz" + integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== + +pretty-format@^26.0.0, pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== + dependencies: + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" + +pretty-format@^28.1.3: + version "28.1.3" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz" + integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== + dependencies: + "@jest/schemas" "^28.1.3" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +progress@2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +proxy-from-env@1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +puppeteer@14.0.0: + version "14.0.0" + resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-14.0.0.tgz" + integrity sha512-Aj/cySGBMWpUYEWV0YOcwyhq5lOxuuiGScgdj/OvslAm/ydoywiI8OzAIXT4HzKmNTmzm/fKKHHtcsQa/fFgdw== + dependencies: + cross-fetch "3.1.5" + debug "4.3.4" + devtools-protocol "0.0.982423" + extract-zip "2.0.1" + https-proxy-agent "5.0.1" + pkg-dir "4.2.0" + progress "2.0.3" + proxy-from-env "1.1.0" + rimraf "3.0.2" + tar-fs "2.1.1" + unbzip2-stream "1.4.3" + ws "8.6.0" + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.0" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-cwd@^3.0.0: + 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== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + +resolve@^1.20.0, resolve@^1.3.2: + version "1.22.1" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@3.0.2, rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rxjs@^7.5.1: + version "7.6.0" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.6.0.tgz" + integrity sha512-DDa7d8TFNUalGC9VqXvQ1euWNN7sc63TrUCuM9J998+ViviahMIjKSOU7rfcgFOF+FCD71BhDRv4hrFz+ImDLQ== + dependencies: + tslib "^2.1.0" + +safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" + integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== + +semver@7.x, semver@^7.3.5: + version "7.3.8" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + +semver@^5.3.0: + version "5.7.1" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + +string-argv@0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" + integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.3.0" + resolved "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz" + integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tar-fs@2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + 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== + dependencies: + is-number "^7.0.0" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +ts-jest@^28.0.2: + version "28.0.8" + resolved "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz" + integrity sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^28.0.0" + json5 "^2.2.1" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "^21.0.1" + +tslib@^1.13.0, tslib@^1.7.1, tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.1.0: + version "2.4.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz" + integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== + +tslint-config-prettier@1.18.0: + version "1.18.0" + resolved "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz" + integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== + +tslint-plugin-prettier@2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz" + integrity sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA== + dependencies: + eslint-plugin-prettier "^2.2.0" + lines-and-columns "^1.1.6" + tslib "^1.7.1" + +tslint@6.1.3: + version "6.1.3" + resolved "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz" + integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^4.0.1" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.3" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.13.0" + tsutils "^2.29.0" + +tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + +type-detect@4.0.8: + 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== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +typescript@^4.6.4: + version "4.9.4" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz" + integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== + +unbzip2-stream@1.4.3: + version "1.4.3" + resolved "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + +update-browserslist-db@^1.0.9: + version "1.0.10" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +v8-to-istanbul@^9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz" + integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +ws@8.6.0: + version "8.6.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz" + integrity sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^21.0.1, yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.3.1: + version "17.6.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz" + integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz" + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index 5ecf00b6..6432233b 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -1,5 +1,6 @@ import os from os.path import join, relpath, exists, dirname +import requests import logging from cloudharness_model.models.api_tests_config import ApiTestsConfig @@ -9,8 +10,8 @@ from cloudharness_utils.testing.util import get_app_environment from .models import HarnessMainConfig, ApplicationTestConfig, ApplicationHarnessConfig from cloudharness_utils.constants import * -from .helm import KEY_APPS, KEY_TASK_IMAGES -from .utils import find_dockerfiles_paths, get_app_relative_to_base_path, guess_build_dependencies_from_dockerfile, \ +from .helm import KEY_APPS, KEY_TASK_IMAGES, KEY_TEST_IMAGES, generate_tag_from_content +from .utils import check_docker_manifest_exists, find_dockerfiles_paths, get_app_relative_to_base_path, guess_build_dependencies_from_dockerfile, \ get_image_name, get_template, dict_merge, app_name_from_path, clean_path from cloudharness_utils.testing.api import get_api_filename, get_schemathesis_command, get_urls_from_api_file @@ -32,6 +33,47 @@ def literal_presenter(dumper, data): yaml.add_representer(str, literal_presenter) +def write_env_file(helm_values: HarnessMainConfig, filename, registry_secret=None): + env = {} + logging.info("Create env file with image info %s", filename) + + def extract_tag(image_name): + return image_name.split(":")[1] if ":" in image_name else "latest" + + def check_image_exists(name, image): + tag = extract_tag(image) + chunks = image.split(":")[0].split("/") + registry = chunks[0] if "." in chunks[0] else "docker.io" + image_name = "/".join(chunks[1::] if "." in chunks[0] else chunks[0::]) + exists = check_docker_manifest_exists(registry, image_name, tag, registry_secret=registry_secret) + if exists: + # TODO the hash might be the same but not the parent's hash + env[app_specific_tag_variable(name) + "_EXISTS"] = 1 + else: + env[app_specific_tag_variable(name) + "_NEW"] = 1 + + + + for app in helm_values.apps.values(): + if app.harness and app.harness.deployment.image: + env[app_specific_tag_variable(app.name)] = extract_tag(app.harness.deployment.image) + check_image_exists(app.name, app.harness.deployment.image) + + for k, task_image in helm_values[KEY_TASK_IMAGES].items(): + env[app_specific_tag_variable(k)] = extract_tag(task_image) + check_image_exists(k, task_image) + + for k, task_image in helm_values[KEY_TEST_IMAGES].items(): + env[app_specific_tag_variable(k)] = extract_tag(task_image) + check_image_exists(k, task_image) + + logging.info("Writing env file %s", filename) + with open(filename, 'w') as f: + for k, v in env.items(): + f.write(f"{k}={v}\n") + + + def create_codefresh_deployment_scripts(root_paths, envs=(), include=(), exclude=(), template_name=CF_TEMPLATE_PATH, base_image_name=None, @@ -156,6 +198,7 @@ def codefresh_steps_from_base_path(base_path, build_step, fixed_context=None, in app_domain = get_app_domain( app_config) + app_domain steps[CD_API_TEST_STEP]['scale'][f"{app_name}_api_test"] = dict( + title=f"{app_name} api test", volumes=api_test_volumes(clean_path( dockerfile_relative_to_root)), environment=e2e_test_environment( @@ -171,6 +214,7 @@ def codefresh_steps_from_base_path(base_path, build_step, fixed_context=None, in if app_config.subdomain: steps[CD_E2E_TEST_STEP]['scale'][f"{app_name}_e2e_test"] = dict( + title=f"{app_name} e2e test", volumes=e2e_test_volumes( clean_path(dockerfile_relative_to_root), app_name), environment=e2e_test_environment(app_config) @@ -184,10 +228,11 @@ def add_unit_test_step(app_config: ApplicationHarnessConfig): app_name = app_config.name if test_config.unit.enabled and test_config.unit.commands: + tag = app_specific_tag_variable(app_name) steps[CD_UNIT_TEST_STEP]['steps'][f"{app_name}_ut"] = dict( title=f"Unit tests for {app_name}", commands=test_config.unit.commands, - image=r"${{%s}}" % app_name + image=image_tag_with_variables(app_name, tag, base_image_name), ) codefresh_steps_from_base_path(join(root_path, BASE_IMAGES_PATH), CD_BUILD_STEP_BASE, @@ -199,24 +244,17 @@ def add_unit_test_step(app_config: ApplicationHarnessConfig): root_path, APPS_PATH), CD_BUILD_STEP_PARALLEL) if CD_E2E_TEST_STEP in steps: + name = "test-e2e" codefresh_steps_from_base_path(join( - root_path, TEST_IMAGES_PATH), CD_BUILD_STEP_TEST, include=("test-e2e",), publish=False) + root_path, TEST_IMAGES_PATH), CD_BUILD_STEP_TEST, include=(name,), publish=False) + steps[CD_E2E_TEST_STEP]["image"] = image_tag_with_variables(name, app_specific_tag_variable(name), base_name=base_image_name) + if CD_API_TEST_STEP in steps: + name = "test-api" codefresh_steps_from_base_path(join( - root_path, TEST_IMAGES_PATH), CD_BUILD_STEP_TEST, include=("test-api",), fixed_context=relpath(root_path, os.getcwd()), publish=False) - - if CD_WAIT_STEP in steps: - rollout_commands = steps[CD_WAIT_STEP]['commands'] - for app_key in helm_values[KEY_APPS]: - app: ApplicationHarnessConfig = helm_values[KEY_APPS][app_key].harness - if app.deployment.auto: - rollout_commands.append( - ROLLOUT_CMD_TPL % app.deployment.name) - if app.secured and helm_values.secured_gatekeepers: - rollout_commands.append( - ROLLOUT_CMD_TPL % app.service.name + "-gk") - # some time to the certificates to settle - rollout_commands.append("sleep 60") + root_path, TEST_IMAGES_PATH), CD_BUILD_STEP_TEST, include=(name,), fixed_context=relpath(root_path, os.getcwd()), publish=False) + steps[CD_API_TEST_STEP]["image"] = image_tag_with_variables(name, app_specific_tag_variable(name), base_name=base_image_name) + if not codefresh: logging.warning( "No template file found. Codefresh script not created.") @@ -261,6 +299,22 @@ def add_unit_test_step(app_config: ApplicationHarnessConfig): del steps[CD_API_TEST_STEP] del steps[CD_BUILD_STEP_TEST]["steps"]["test-api"] + if CD_BUILD_STEP_TEST in steps and not steps[CD_BUILD_STEP_TEST]["steps"]: + del steps[CD_BUILD_STEP_TEST] + del steps[CD_WAIT_STEP] + if CD_WAIT_STEP in steps: + rollout_commands = steps[CD_WAIT_STEP]['commands'] + for app_key in helm_values[KEY_APPS]: + app: ApplicationHarnessConfig = helm_values[KEY_APPS][app_key].harness + if app.deployment.auto: + rollout_commands.append( + ROLLOUT_CMD_TPL % app.deployment.name) + if app.secured and helm_values.secured_gatekeepers: + rollout_commands.append( + ROLLOUT_CMD_TPL % app.service.name + "-gk") + # some time to the certificates to settle + rollout_commands.append("sleep 60") + if save: codefresh_abs_path = join( os.getcwd(), DEPLOYMENT_PATH, out_filename) @@ -306,12 +360,6 @@ def api_test_volumes(app_relative_to_root): ] - - - - - - def codefresh_app_publish_spec(app_name, build_tag, base_name=None): title = app_name.capitalize().replace( '-', ' ').replace('/', ' ').replace('.', ' ').strip() @@ -327,9 +375,13 @@ def codefresh_app_publish_spec(app_name, build_tag, base_name=None): step_spec['tags'].append('latest') return step_spec +def image_tag_with_variables(app_name, build_tag, base_name=""): + return "${{REGISTRY}}/%s:${{%s}}" % (get_image_name( + app_name, base_name), build_tag or '${{DEPLOYMENT_TAG}}') + def app_specific_tag_variable(app_name): - return "${{ %s }}_${{DEPLOYMENT_PUBLISH_TAG}}" % app_name.replace('-', '_').upper() + return "%s_TAG" % app_name.replace('-', '_').upper().strip() def codefresh_app_build_spec(app_name, app_context_path, dockerfile_path="Dockerfile", base_name=None, helm_values: HarnessMainConfig = {}, dependencies=None): @@ -342,6 +394,9 @@ def codefresh_app_build_spec(app_name, app_context_path, dockerfile_path="Docker title=title, working_directory='./' + app_context_path, dockerfile=dockerfile_path) + + tag = app_specific_tag_variable(app_name) + build["tag"] = "${{%s}}" % tag specific_build_template_path = join(app_context_path, 'build.yaml') if exists(specific_build_template_path): @@ -356,7 +411,7 @@ def codefresh_app_build_spec(app_name, app_context_path, dockerfile_path="Docker build['build_arguments'].append('REGISTRY=${{REGISTRY}}/%s/' % base_name) def add_arg_dependencies(dependencies): - arg_dependencies = [f"{d.upper().replace('-', '_')}=${{{{REGISTRY}}}}/{get_image_name(d, base_name)}:{build['tag']}" for + arg_dependencies = [f"{d.upper().replace('-', '_')}={image_tag_with_variables(d, app_specific_tag_variable(d), base_name)}" for d in dependencies] build['build_arguments'].extend(arg_dependencies) @@ -369,5 +424,26 @@ def add_arg_dependencies(dependencies): helm_values.apps[values_key].harness.dependencies.build) except (KeyError, AttributeError): add_arg_dependencies(helm_values['task-images']) - + + when_condition = existing_build_when_condition(tag) + build["when"] = when_condition return build + +def existing_build_when_condition(tag): + """ + See https://codefresh.io/docs/docs/pipelines/conditional-execution-of-steps/#execute-steps-according-to-the-presence-of-a-variable + the _EXISTS variable is added in the preparation step + the _FORCE_BUILD variable may be added manually by the user to force the build of a specific image + """ + is_built = tag + "_EXISTS" + force_build = tag + "_FORCE_BUILD" + when_condition = { + "condition": { + "any": { + "buildDoesNotExist": "includes('${{%s}}', '{{%s}}') == true" % (is_built, is_built), + "forceNoCache": "includes('${{%s}}', '{{%s}}') == false" % (force_build, force_build), + } + } + } + + return when_condition diff --git a/tools/deployment-cli-tools/ch_cli_tools/helm.py b/tools/deployment-cli-tools/ch_cli_tools/helm.py index 52449856..4c75a909 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/helm.py +++ b/tools/deployment-cli-tools/ch_cli_tools/helm.py @@ -5,12 +5,15 @@ import os import shutil import logging +from hashlib import sha1 import subprocess +from functools import cache import tarfile from docker import from_env as DockerClient + from . import HERE, CH_ROOT -from cloudharness_utils.constants import VALUES_MANUAL_PATH, HELM_CHART_PATH, APPS_PATH, HELM_PATH, \ +from cloudharness_utils.constants import TEST_IMAGES_PATH, VALUES_MANUAL_PATH, HELM_CHART_PATH, APPS_PATH, HELM_PATH, \ DEPLOYMENT_CONFIGURATION_PATH, BASE_IMAGES_PATH, STATIC_IMAGES_PATH from .utils import get_cluster_ip, get_image_name, env_variable, get_sub_paths, guess_build_dependencies_from_dockerfile, image_name_from_dockerfile_path, \ get_template, merge_configuration_directories, merge_to_yaml_file, dict_merge, app_name_from_path, \ @@ -24,6 +27,9 @@ KEY_DEPLOYMENT = 'deployment' KEY_APPS = 'apps' KEY_TASK_IMAGES = 'task-images' +KEY_TEST_IMAGES = 'test-images' + +DEFAULT_IGNORE = ('/tasks', '.dockerignore', '.hypothesis', "__pycache__", '.node_modules', 'dist', 'build', '.coverage') def deploy(namespace, output_path='./deployment'): @@ -75,6 +81,7 @@ def __init__(self, root_paths, tag='latest', registry='', local=True, domain=Non self.static_images = set() self.base_images = {} + self.all_images = {} def __init_deployment(self): """ @@ -117,6 +124,7 @@ def process_values(self) -> HarnessMainConfig: self.__init_base_images(base_image_name) self.__init_static_images(base_image_name) + helm_values[KEY_TEST_IMAGES] = self.__init_test_images(base_image_name) self.__process_applications(helm_values, base_image_name) @@ -164,8 +172,7 @@ def collect_app_values(self, app_base_path, base_image_name=None): continue app_key = app_name.replace('-', '_') - app_values = create_app_values_spec(app_name, app_path, tag=self.tag, registry=self.registry, env=self.env, - base_image_name=base_image_name, base_images=self.base_images) + app_values = self.create_app_values_spec(app_name, app_path, base_image_name=base_image_name) values[app_key] = dict_merge( values[app_key], app_values) if app_key in values else app_values @@ -176,8 +183,8 @@ def __init_static_images(self, base_image_name): for static_img_dockerfile in self.static_images: img_name = image_name_from_dockerfile_path(os.path.basename( static_img_dockerfile), base_name=base_image_name) - self.base_images[os.path.basename(static_img_dockerfile)] = image_tag( - img_name, self.registry, self.tag) + self.base_images[os.path.basename(static_img_dockerfile)] = self.image_tag( + img_name, build_context_path=static_img_dockerfile) def __assign_static_build_dependencies(self, helm_values): for static_img_dockerfile in self.static_images: @@ -199,13 +206,25 @@ def __init_base_images(self, base_image_name): for base_img_dockerfile in self.__find_static_dockerfile_paths(root_path): img_name = image_name_from_dockerfile_path( os.path.basename(base_img_dockerfile), base_name=base_image_name) - self.base_images[os.path.basename(base_img_dockerfile)] = image_tag( - img_name, self.registry, self.tag) + self.base_images[os.path.basename(base_img_dockerfile)] = self.image_tag( + img_name, build_context_path=root_path) self.static_images.update(find_dockerfiles_paths( os.path.join(root_path, STATIC_IMAGES_PATH))) return self.base_images + + def __init_test_images(self, base_image_name): + test_images = {} + for root_path in self.root_paths: + for base_img_dockerfile in find_dockerfiles_paths(os.path.join(root_path, TEST_IMAGES_PATH)): + img_name = image_name_from_dockerfile_path( + os.path.basename(base_img_dockerfile), base_name=base_image_name) + test_images[os.path.basename(base_img_dockerfile)] = self.image_tag( + img_name, build_context_path=base_img_dockerfile) + + return test_images + def __find_static_dockerfile_paths(self, root_path): return find_dockerfiles_paths(os.path.join(root_path, BASE_IMAGES_PATH)) + find_dockerfiles_paths(os.path.join(root_path, STATIC_IMAGES_PATH)) @@ -235,7 +254,6 @@ def create_tls_certificate(self, helm_values): return helm_values['tls'] = self.domain.replace(".", "-") + "-tls" - bootstrap_file = 'bootstrap.sh' certs_parent_folder_path = os.path.join( self.output_path, 'helm', 'resources') @@ -345,9 +363,11 @@ def __finish_helm_values(self, values): harness[KEY_SERVICE]['name'] = app_name if not harness[KEY_DEPLOYMENT].get('name', None): harness[KEY_DEPLOYMENT]['name'] = app_name - if not harness[KEY_DATABASE].get('name', None): + + if harness[KEY_DATABASE] and not harness[KEY_DATABASE].get('name', None): harness[KEY_DATABASE]['name'] = app_name.strip() + '-db' + self.__clear_unused_db_configuration(harness) values_set_legacy(v) if self.include: @@ -367,6 +387,102 @@ def __finish_helm_values(self, values): create_env_variables(values) return values, self.include + def __clear_unused_db_configuration(self, harness_config): + database_config = harness_config[KEY_DATABASE] + database_type = database_config.get('type', None) + if database_type is None: + del harness_config[KEY_DATABASE] + return + db_specific_keys = [k for k, v in database_config.items() + if isinstance(v, dict) and 'image' in v and 'ports' in v] + for db in db_specific_keys: + if database_type != db: + del database_config[db] + + def image_tag(self, image_name, build_context_path=None, dependencies=()): + tag = self.tag + if tag is None and not self.local: + logging.info(f"Generating tag for {image_name} from {build_context_path} and {dependencies}") + ignore_path = os.path.join(build_context_path, '.dockerignore') + ignore = set(DEFAULT_IGNORE) + if os.path.exists(ignore_path): + with open(ignore_path) as f: + ignore = ignore.union({line.strip() for line in f}) + logging.info(f"Ignoring {ignore}") + tag = generate_tag_from_content(build_context_path, ignore) + logging.info(f"Content hash: {tag}") + dependencies = dependencies or guess_build_dependencies_from_dockerfile(build_context_path) + tag = sha1((tag + "".join(self.all_images.get(n , '') for n in dependencies)).encode("utf-8")).hexdigest() + logging.info(f"Generated tag: {tag}") + app_name = image_name.split("/")[-1] # the image name can have a prefix + self.all_images[app_name] = tag + return self.registry + image_name + (f':{tag}' if tag else '') + + def create_app_values_spec(self, app_name, app_path, base_image_name=None): + logging.info('Generating values script for ' + app_name) + + specific_template_path = os.path.join(app_path, 'deploy', 'values.yaml') + if os.path.exists(specific_template_path): + logging.info("Specific values template found: " + + specific_template_path) + values = get_template(specific_template_path) + else: + values = {} + + for e in self.env: + specific_template_path = os.path.join( + app_path, 'deploy', f'values-{e}.yaml') + if os.path.exists(specific_template_path): + logging.info( + "Specific environment values template found: " + specific_template_path) + with open(specific_template_path) as f: + values_env_specific = yaml.safe_load(f) + values = dict_merge(values, values_env_specific) + + if KEY_HARNESS in values and 'name' in values[KEY_HARNESS] and values[KEY_HARNESS]['name']: + logging.warning('Name is automatically set in applications: name %s will be ignored', + values[KEY_HARNESS]['name']) + + image_paths = [path for path in find_dockerfiles_paths( + app_path) if 'tasks/' not in path and 'subapps' not in path] + if len(image_paths) > 1: + logging.warning('Multiple Dockerfiles found in application %s. Picking the first one: %s', app_name, + image_paths[0]) + if KEY_HARNESS in values and 'dependencies' in values[KEY_HARNESS] and 'build' in values[KEY_HARNESS]['dependencies']: + build_dependencies = values[KEY_HARNESS]['dependencies']['build'] + else: + build_dependencies = [] + + if len(image_paths) > 0: + image_name = image_name_from_dockerfile_path(os.path.relpath( + image_paths[0], os.path.dirname(app_path)), base_image_name) + + values['image'] = self.image_tag( + image_name, build_context_path=app_path, dependencies=build_dependencies) + elif KEY_HARNESS in values and not values[KEY_HARNESS].get(KEY_DEPLOYMENT, {}).get('image', None) and values[ + KEY_HARNESS].get(KEY_DEPLOYMENT, {}).get('auto', False): + raise Exception(f"At least one Dockerfile must be specified on application {app_name}. " + f"Specify harness.deployment.image value if you intend to use a prebuilt image.") + + task_images_paths = [path for path in find_dockerfiles_paths( + app_path) if 'tasks/' in path] + values[KEY_TASK_IMAGES] = values.get(KEY_TASK_IMAGES, {}) + + if build_dependencies: + for build_dependency in values[KEY_HARNESS]['dependencies']['build']: + if build_dependency in self.base_images: + values[KEY_TASK_IMAGES][build_dependency] = self.base_images[build_dependency] + + for task_path in task_images_paths: + task_name = app_name_from_path(os.path.relpath( + task_path, os.path.dirname(app_path))) + img_name = image_name_from_dockerfile_path(task_name, base_image_name) + + values[KEY_TASK_IMAGES][task_name] = self.image_tag( + img_name, build_context_path=task_path, dependencies=values[KEY_TASK_IMAGES].keys()) + + return values + def get_included_with_dependencies(values, include): app_values = values['apps'].values() @@ -477,7 +593,8 @@ def collect_helm_values(deployment_root, env=()): return values -def init_app_values(deployment_root, exclude, values={}): +def init_app_values(deployment_root, exclude, values=None): + values = values if values is not None else {} app_base_path = os.path.join(deployment_root, APPS_PATH) overridden_template_path = os.path.join( deployment_root, DEPLOYMENT_CONFIGURATION_PATH, 'value-template.yaml') @@ -542,65 +659,9 @@ def values_set_legacy(values): values['resources'] = harness[KEY_DEPLOYMENT]['resources'] -def create_app_values_spec(app_name, app_path, tag=None, registry='', env=(), base_image_name=None, base_images=[]): - logging.info('Generating values script for ' + app_name) - - specific_template_path = os.path.join(app_path, 'deploy', 'values.yaml') - if os.path.exists(specific_template_path): - logging.info("Specific values template found: " + - specific_template_path) - values = get_template(specific_template_path) - else: - values = {} - - for e in env: - specific_template_path = os.path.join( - app_path, 'deploy', f'values-{e}.yaml') - if os.path.exists(specific_template_path): - logging.info( - "Specific environment values template found: " + specific_template_path) - with open(specific_template_path) as f: - values_env_specific = yaml.safe_load(f) - values = dict_merge(values, values_env_specific) - - if KEY_HARNESS in values and 'name' in values[KEY_HARNESS] and values[KEY_HARNESS]['name']: - logging.warning('Name is automatically set in applications: name %s will be ignored', - values[KEY_HARNESS]['name']) - - image_paths = [path for path in find_dockerfiles_paths( - app_path) if 'tasks/' not in path and 'subapps' not in path] - if len(image_paths) > 1: - logging.warning('Multiple Dockerfiles found in application %s. Picking the first one: %s', app_name, - image_paths[0]) - if len(image_paths) > 0: - image_name = image_name_from_dockerfile_path(os.path.relpath( - image_paths[0], os.path.dirname(app_path)), base_image_name) - values['image'] = image_tag(image_name, registry, tag) - elif KEY_HARNESS in values and values[KEY_HARNESS].get(KEY_DEPLOYMENT, {}).get('image', None) and values[ - KEY_HARNESS].get(KEY_DEPLOYMENT, {}).get('auto', False) and not values('image', None): - raise Exception(f"At least one Dockerfile must be specified on application {app_name}. " - f"Specify harness.deployment.image value if you intend to use a prebuilt image.") - - task_images_paths = [path for path in find_dockerfiles_paths( - app_path) if 'tasks/' in path] - values[KEY_TASK_IMAGES] = values.get(KEY_TASK_IMAGES, {}) - for task_path in task_images_paths: - task_name = app_name_from_path(os.path.relpath( - task_path, os.path.dirname(app_path))) - img_name = image_name_from_dockerfile_path(task_name, base_image_name) - - values[KEY_TASK_IMAGES][task_name] = image_tag(img_name, registry, tag) - - if KEY_HARNESS in values and 'dependencies' in values[KEY_HARNESS] and 'build' in values[KEY_HARNESS]['dependencies']: - for build_dependency in values[KEY_HARNESS]['dependencies']['build']: - if build_dependency in base_images: - values[KEY_TASK_IMAGES][build_dependency] = base_images[build_dependency] - - return values - - -def image_tag(image_name, registry, tag): - return registry + image_name + f':{tag}' if tag else '' +def generate_tag_from_content(content_path, ignore=()): + from dirhash import dirhash + return dirhash(content_path, 'sha1', ignore=ignore) def extract_env_variables_from_values(values, envs=tuple(), prefix=''): @@ -688,7 +749,7 @@ def validate_dependencies(values): d for d in app_values[KEY_HARNESS]['dependencies']['build']} not_found = { - d for d in build_dependencies if d not in values['task-images']} + d for d in build_dependencies if d not in values[KEY_TASK_IMAGES]} not_found = {d for d in not_found if d not in all_apps} if not_found: raise ValuesValidationException( diff --git a/tools/deployment-cli-tools/ch_cli_tools/openapi.py b/tools/deployment-cli-tools/ch_cli_tools/openapi.py index 1ebd8002..7f302498 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/openapi.py +++ b/tools/deployment-cli-tools/ch_cli_tools/openapi.py @@ -14,7 +14,7 @@ CODEGEN = os.path.join(HERE, 'bin', 'openapi-generator-cli.jar') APPLICATIONS_SRC_PATH = os.path.join('applications') LIB_NAME = 'cloudharness_cli' -ROOT = dn(dn(HERE)) +ROOT = dn(dn(dn(HERE))) OPENAPI_GEN_URL = 'https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.2.1/openapi-generator-cli-6.2.1.jar' @@ -27,7 +27,8 @@ def generate_server(app_path, overrides_folder=""): f"{app_path}/server") else f"server" out_path = f"{app_path}/{out_name}" command = f"java -jar {CODEGEN} generate -i {openapi_file} -g python-flask -o {out_path} " \ - f"-c {openapi_dir}/config.json " + (f"-t {overrides_folder}" if overrides_folder else "") + f"-c {openapi_dir}/config.json " + \ + (f"-t {overrides_folder}" if overrides_folder else "") os.system(command) @@ -41,15 +42,18 @@ def generate_model(base_path=ROOT): lib_path = f"{base_path}/libraries/models" # Generate model stuff: use python-flask generator - command = f"java -jar {CODEGEN} generate -i {base_path}/libraries/api/openapi.yaml -g python-flask -o {lib_path} --skip-validate-spec -c {base_path}/libraries/api/config.json" + command = f"java -jar {CODEGEN} generate -i {base_path}/libraries/models/api/openapi.yaml -g python-flask -o {lib_path} --skip-validate-spec -c {base_path}/libraries/models/api/config.json" os.system(command) # Generate docs: use python generator tmp_path = f"{lib_path}/tmp" - command = f"java -jar {CODEGEN} generate -i {base_path}/libraries/api/openapi.yaml -g python -o {tmp_path} --skip-validate-spec -c {base_path}/libraries/api/config.json" + command = f"java -jar {CODEGEN} generate -i {base_path}/libraries/models/api/openapi.yaml -g python -o {tmp_path} --skip-validate-spec -c {base_path}/libraries/models/api/config.json" os.system(command) try: - source_dir = join(tmp_path, "docs") + source_dir = join(tmp_path, "docs/models") + if not os.path.exists(source_dir): + os.makedirs(source_dir) + dest = join(base_path, "docs/model") if os.path.exists(dest): shutil.rmtree(dest) diff --git a/tools/deployment-cli-tools/ch_cli_tools/preprocessing.py b/tools/deployment-cli-tools/ch_cli_tools/preprocessing.py index 138cf6b3..8fc97313 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/preprocessing.py +++ b/tools/deployment-cli-tools/ch_cli_tools/preprocessing.py @@ -32,7 +32,9 @@ def merge_appdir(root_path, base_path): ) merge_configuration_directories(artifacts[app_name], dest_path) merge_configuration_directories(base_path, dest_path) - + + + for root_path in root_paths: @@ -68,7 +70,16 @@ def merge_appdir(root_path, base_path): elif app_name.replace("-", "_") in helm_values[KEY_APPS]: merge_appdir(root_path, base_path) merged = True - + + if exists(merge_build_path): + with open(join(merge_build_path, ".dockerignore"), "a") as dst: + + for root_path in root_paths: + ignore_file = join(root_path, ".dockerignore") + if os.path.exists(ignore_file): + with open(ignore_file) as src: + dst.write(src.read()) + return (root_paths + [merge_build_path]) if merged else root_paths def get_build_paths(root_paths, helm_values, merge_build_path=DEFAULT_MERGE_PATH): diff --git a/tools/deployment-cli-tools/ch_cli_tools/scripts/bootstrap.sh.tar b/tools/deployment-cli-tools/ch_cli_tools/scripts/bootstrap.sh.tar index 16e09a6e..a48e8f37 100644 Binary files a/tools/deployment-cli-tools/ch_cli_tools/scripts/bootstrap.sh.tar and b/tools/deployment-cli-tools/ch_cli_tools/scripts/bootstrap.sh.tar differ diff --git a/tools/deployment-cli-tools/ch_cli_tools/skaffold.py b/tools/deployment-cli-tools/ch_cli_tools/skaffold.py index 101bc783..1e6742a5 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/skaffold.py +++ b/tools/deployment-cli-tools/ch_cli_tools/skaffold.py @@ -25,7 +25,7 @@ def create_skaffold_configuration(root_paths, helm_values: HarnessMainConfig, ou overrides = {} def remove_tag(image_name): - return image_name[0:-len(helm_values.tag)-1] + return image_name.split(":")[0] def get_image_tag(name): return f"{get_image_name(name, base_image_name)}" @@ -203,18 +203,13 @@ def get_image_tag(name): if app_key in apps.keys(): debug_conf["debug"].append({ "image": get_image_tag(app_name), - # the double source map doesn't work at the moment. Hopefully will be fixed in future skaffold updates "sourceFileMap": { + "justMyCode": False, f"${{workspaceFolder}}/{app_relative_to_root}": apps[app_key].harness.get('sourceRoot', "/usr/src/app"), } }) - debug_conf["debug"].append({ - "image": get_image_tag(app_name), - "sourceFileMap": { - "${workspaceFolder}/cloud-harness/libraries": "/libraries" - } - }) + if not os.path.exists(os.path.dirname(vscode_launch_path)): os.makedirs(os.path.dirname(vscode_launch_path)) diff --git a/tools/deployment-cli-tools/ch_cli_tools/utils.py b/tools/deployment-cli-tools/ch_cli_tools/utils.py index 2ab5c5f7..41b96d87 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/utils.py +++ b/tools/deployment-cli-tools/ch_cli_tools/utils.py @@ -2,11 +2,13 @@ import socket import glob import subprocess +import requests import os +from functools import cache from os.path import join, dirname, isdir, basename, exists, relpath, sep, dirname as dn import json import collections -import requests +import re from ruamel.yaml import YAML import shutil import logging @@ -32,11 +34,14 @@ def image_name_from_dockerfile_path(dockerfile_path, base_name=None): def app_name_from_path(dockerfile_path): return "-".join(p for p in dockerfile_path.split("/") if p not in NEUTRAL_PATHS) + def clean_path(path): return "/".join(p for p in path.split("/") if p not in NEUTRAL_PATHS) - + + def get_app_relative_to_base_path(base_path, dockerfile_path): - return clean_path(relpath(dockerfile_path, base_path)) + return clean_path(relpath(dockerfile_path, base_path)) + def get_sub_paths(base_path): return tuple(path for path in glob.glob(base_path + "/*") if isdir(path)) @@ -72,8 +77,8 @@ def env_variable(name, value): def get_cluster_ip(): out = subprocess.check_output( ['kubectl', 'cluster-info'], timeout=10).decode("utf-8") - ip = out.split('\n')[0].split('://')[1].split(':')[0] - return ip if not "kubernetes.docker.internal" == ip else get_host_address() + ips = re.findall(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", out) + return ips[0] if ips else get_host_address() def get_host_address(): @@ -302,6 +307,9 @@ def dict_merge(dct, merge_dct, add_keys=True): dict: updated dict """ dct = dct.copy() + if merge_dct is None: + return dct + if not add_keys: merge_dct = { k: merge_dct[k] @@ -348,10 +356,13 @@ def to_python_module(name): return name.replace('-', '_') +@cache def guess_build_dependencies_from_dockerfile(filename): dependencies = [] if not "Dockerfile" in filename: filename = join(filename, "Dockerfile") + if not os.path.exists(filename): + return dependencies with open(filename) as f: for line in f: if line.startswith("ARG") and not "=" in line: @@ -361,4 +372,7 @@ def guess_build_dependencies_from_dockerfile(filename): return dependencies - +def check_docker_manifest_exists(registry, image_name, tag, registry_secret=None): + api_url = f"https://{registry}/v2/{image_name}/manifests/{tag}" + resp = requests.get(api_url) + return resp.status_code == 200 diff --git a/tools/deployment-cli-tools/harness-deployment b/tools/deployment-cli-tools/harness-deployment index 1c049016..a9cecabb 100644 --- a/tools/deployment-cli-tools/harness-deployment +++ b/tools/deployment-cli-tools/harness-deployment @@ -6,9 +6,10 @@ import os from ch_cli_tools.helm import create_helm_chart, hosts_info, deploy from ch_cli_tools.skaffold import create_skaffold_configuration, create_vscode_debug_configuration -from ch_cli_tools.codefresh import create_codefresh_deployment_scripts +from ch_cli_tools.codefresh import create_codefresh_deployment_scripts, write_env_file from ch_cli_tools.preprocessing import preprocess_build_overrides from ch_cli_tools.utils import merge_app_directories +from cloudharness_utils.constants import DEPLOYMENT_PATH HERE = os.path.dirname(os.path.realpath(__file__)).replace(os.path.sep, '/') ROOT = os.path.dirname(os.path.dirname(HERE)).replace(os.path.sep, '/') @@ -27,8 +28,8 @@ if __name__ == "__main__": help='Specify the applications to include and exclude the rest. ' 'Omit to build images for all Docker files.') - parser.add_argument('-t', '--tag', dest='tag', action="store", default='latest', - help='Add a tag with the current version (default `latest`)') + parser.add_argument('-t', '--tag', dest='tag', action="store", default=None, + help='Add a tag with the current version (default no value, content hash is used)') parser.add_argument('-n', '--namespace', dest='namespace', action="store", default=None, help='Specify the namespace of the deployment (default taken from values.yaml)') @@ -58,6 +59,9 @@ if __name__ == "__main__": help='Deploy helm chart') parser.add_argument('-N', '--no-cd', dest='no_cd_gen', action="store_const", default=None, const=True, help=f'Do not generate ci/cd files') + parser.add_argument('-we', '--write-env', dest='write_env', action="store_const", default=None, const=True, + help=f'Write build env to .env file in {DEPLOYMENT_PATH}') + args, unknown = parser.parse_known_args(sys.argv[1:]) @@ -93,21 +97,23 @@ if __name__ == "__main__": namespace=args.namespace ) - root_paths = preprocess_build_overrides( + merged_root_paths = preprocess_build_overrides( root_paths=root_paths, helm_values=helm_values) if not args.no_cd_gen and envs: create_codefresh_deployment_scripts( - root_paths, + merged_root_paths, include=args.include, exclude=args.exclude, envs=envs, base_image_name=helm_values['name'], helm_values=helm_values) + + if args.write_env: + write_env_file(helm_values, os.path.join(root_paths[-1], DEPLOYMENT_PATH, ".env")) - create_skaffold_configuration(root_paths, helm_values) - create_vscode_debug_configuration([os.path.join(os.getcwd(), path) for path in args.paths], - helm_values) + create_skaffold_configuration(merged_root_paths, helm_values) + create_vscode_debug_configuration(root_paths, helm_values) hosts_info(helm_values) diff --git a/tools/deployment-cli-tools/harness-generate b/tools/deployment-cli-tools/harness-generate index 7f55231a..ffec2055 100644 --- a/tools/deployment-cli-tools/harness-generate +++ b/tools/deployment-cli-tools/harness-generate @@ -61,13 +61,16 @@ def aggregate_packages(client_src_path, lib_name=LIB_NAME): test_req_lines_seen = set() for MODULE_TMP_PATH in glob.glob(client_src_path + '/tmp-*'): - module = MODULE_TMP_PATH.split(f'{lib_name}/tmp-')[-1].replace('-', '_') + module = MODULE_TMP_PATH.split( + f'{lib_name}/tmp-')[-1].replace('-', '_') # Moves package code_dest_dir = os.path.join(client_src_path, lib_name, module) - copymergedir(os.path.join(MODULE_TMP_PATH, lib_name, module), code_dest_dir) - copymergedir(f"{MODULE_TMP_PATH}/{lib_name}.{module}", code_dest_dir) # Fixes a a bug with nested packages + copymergedir(os.path.join(MODULE_TMP_PATH, + lib_name, module), code_dest_dir) + copymergedir(f"{MODULE_TMP_PATH}/{lib_name}.{module}", + code_dest_dir) # Fixes a a bug with nested packages # Adds Docs module_doc_path = os.path.join(DOCS_PATH, module) @@ -125,12 +128,14 @@ def generate_clients(root_path, client_lib_name=LIB_NAME, interactive=False): openapi_files = get_openapi_file_paths(root_path) applications = get_application_paths(openapi_files) - client_src_path = os.path.join(root_path, 'libraries/client', client_lib_name) + client_src_path = os.path.join( + root_path, 'libraries/client', client_lib_name) for i in range(len(applications)): app_name = applications[i] openapi_file = openapi_files[i] app_dir = os.path.dirname(os.path.dirname(openapi_file)) - generate_python_client(app_name, openapi_file, client_src_path, lib_name=client_lib_name) + generate_python_client(app_name, openapi_file, + client_src_path, lib_name=client_lib_name) if os.path.exists(os.path.join(app_dir, 'frontend')): generate_ts_client(openapi_file) @@ -150,10 +155,11 @@ if __name__ == "__main__": help='Asks before generate') args, unknown = parser.parse_known_args(sys.argv[1:]) - root_path = os.path.join(os.getcwd(), args.path) if not os.path.isabs(args.path) else args.path + root_path = os.path.join(os.getcwd(), args.path) if not os.path.isabs( + args.path) else args.path get_dependencies() - if not args.interactive or input("Do you want to generate the main model? [Y/n]").upper() != 'N': + if os.path.exists(os.path.join(root_path, "libraries/models")) and (not args.interactive or input("Do you want to generate the main model? [Y/n]").upper() != 'N'): generate_model() generate_servers(root_path, interactive=args.interactive) diff --git a/tools/deployment-cli-tools/requirements.txt b/tools/deployment-cli-tools/requirements.txt index 473311c9..622565b9 100644 --- a/tools/deployment-cli-tools/requirements.txt +++ b/tools/deployment-cli-tools/requirements.txt @@ -4,3 +4,4 @@ ruamel.yaml oyaml cloudharness_model cloudharness_utils +dirhash \ No newline at end of file diff --git a/tools/deployment-cli-tools/setup.py b/tools/deployment-cli-tools/setup.py index f9608be9..15fb7f01 100644 --- a/tools/deployment-cli-tools/setup.py +++ b/tools/deployment-cli-tools/setup.py @@ -27,7 +27,8 @@ 'six', 'cloudharness_model', 'cloudharness_utils', - 'fastapi-code-generator' + 'fastapi-code-generator', + 'dirhash' ] diff --git a/tools/deployment-cli-tools/tests/resources/.dockerignore b/tools/deployment-cli-tools/tests/resources/.dockerignore new file mode 100644 index 00000000..bba89d5b --- /dev/null +++ b/tools/deployment-cli-tools/tests/resources/.dockerignore @@ -0,0 +1,22 @@ +**/node_modules +.tox +docs +applications +/infrastructure +/blueprint +test +/tools/deployment-cli-tools +.github +.git +.vscode +/deployment +skaffold.yaml +*.egg-info +__pycache__ +.hypothesis +.coverage +.pytest_cache +/application-templates +/deployment-configuration +/cloud-harness +.openapi-generator \ No newline at end of file diff --git a/tools/deployment-cli-tools/tests/resources/applications/myapp/.dockerignore b/tools/deployment-cli-tools/tests/resources/applications/myapp/.dockerignore new file mode 100644 index 00000000..669be813 --- /dev/null +++ b/tools/deployment-cli-tools/tests/resources/applications/myapp/.dockerignore @@ -0,0 +1 @@ +*.ignored \ No newline at end of file diff --git a/tools/deployment-cli-tools/tests/resources/applications/myapp/deploy/values-withmongo.yaml b/tools/deployment-cli-tools/tests/resources/applications/myapp/deploy/values-withmongo.yaml new file mode 100644 index 00000000..f3519b50 --- /dev/null +++ b/tools/deployment-cli-tools/tests/resources/applications/myapp/deploy/values-withmongo.yaml @@ -0,0 +1,4 @@ +harness: + database: + auto: true + type: mongo \ No newline at end of file diff --git a/tools/deployment-cli-tools/tests/resources/applications/myapp/deploy/values-withoutdb.yaml b/tools/deployment-cli-tools/tests/resources/applications/myapp/deploy/values-withoutdb.yaml new file mode 100644 index 00000000..e69de29b diff --git a/tools/deployment-cli-tools/tests/resources/applications/myapp/deploy/values-withpostgres.yaml b/tools/deployment-cli-tools/tests/resources/applications/myapp/deploy/values-withpostgres.yaml new file mode 100644 index 00000000..4b260dbf --- /dev/null +++ b/tools/deployment-cli-tools/tests/resources/applications/myapp/deploy/values-withpostgres.yaml @@ -0,0 +1,2 @@ +harness: + database: {auto: true, type: postgres} \ No newline at end of file diff --git a/tools/deployment-cli-tools/tests/test_codefresh.py b/tools/deployment-cli-tools/tests/test_codefresh.py index 60c655bb..aee93d37 100644 --- a/tools/deployment-cli-tools/tests/test_codefresh.py +++ b/tools/deployment-cli-tools/tests/test_codefresh.py @@ -83,7 +83,7 @@ def test_create_codefresh_configuration(): RESOURCES, STATIC_IMAGES_PATH, "my-common")) steps = l1_steps["build_application_images"]["steps"] - assert len(steps) == 13 + assert len(steps) == 14 assert "myapp" in steps assert "samples" in steps assert "accounts" in steps @@ -119,7 +119,7 @@ def test_create_codefresh_configuration(): ) == 2, "Two unit test steps are expected" assert 'myapp_ut' in l1_steps[CD_UNIT_TEST_STEP]['steps'], "Myapp test step is expected" tstep = l1_steps[CD_UNIT_TEST_STEP]['steps']['myapp_ut'] - assert tstep['image'] == r"${{myapp}}", "The test image should be the one built for the current app" + assert tstep['image'] == r"${{REGISTRY}}/cloudharness/myapp:${{MYAPP_TAG}}", "The test image should be the one built for the current app" assert len( tstep['commands']) == 2, "Unit test commands are not properly loaded from the unit test configuration file" assert tstep['commands'][0] == "tox", "Unit test commands are not properly loaded from the unit test configuration file" @@ -214,14 +214,14 @@ def test_create_codefresh_configuration_tests(): assert "samples_e2e_test" in e2e_steps, "samples e2e test step must be included" test_step = e2e_steps["samples_e2e_test"] - assert "APP_URL=https://samples.${{CF_SHORT_REVISION}}.${{DOMAIN}}" in test_step[ + assert "APP_URL=https://samples.${{DOMAIN}}" in test_step[ 'environment'], "APP_URL must be provided as environment variable" assert len(test_step['volumes']) == 1 assert "test-api" in st_build_test_steps api_steps = l1_steps['tests_api']['scale'] test_step = api_steps["samples_api_test"] - assert "APP_URL=https://samples.${{CF_SHORT_REVISION}}.${{DOMAIN}}/api" in test_step[ + assert "APP_URL=https://samples.${{DOMAIN}}/api" in test_step[ 'environment'], "APP_URL must be provided as environment variable" assert len(test_step['volumes']) == 2 diff --git a/tools/deployment-cli-tools/tests/test_helm.py b/tools/deployment-cli-tools/tests/test_helm.py index bce1e01a..ed53ab86 100644 --- a/tools/deployment-cli-tools/tests/test_helm.py +++ b/tools/deployment-cli-tools/tests/test_helm.py @@ -69,7 +69,7 @@ def exists(*args): assert exists(helm_path, 'resources/myapp/aresource.txt') assert exists(helm_path, 'templates/myapp/mytemplate.yaml') - # Checl base and task images + # Checl base and task images assert values[KEY_TASK_IMAGES] assert 'cloudharness-base' in values[KEY_TASK_IMAGES] assert values[KEY_TASK_IMAGES]['cloudharness-base'] == 'reg/cloudharness/cloudharness-base:1' @@ -152,11 +152,11 @@ def test_collect_helm_values_multiple_envs(): values = create_helm_chart([CLOUDHARNESS_ROOT, RESOURCES], output_path=OUT, domain="my.local", namespace='test', env=['dev', 'test'], local=False, tag=1, include=["myapp"]) - + assert values[KEY_APPS]['myapp']['test'] == True, 'values-test not loaded' assert values[KEY_APPS]['myapp']['dev'] == True, 'values-dev not loaded' assert values[KEY_APPS]['myapp']['a'] == 'test', 'values-test not overriding' - + def test_collect_helm_values_wrong_dependencies_validate(): @@ -227,3 +227,164 @@ def test_collect_helm_values_build_dependencies_exclude(): assert 'cloudharness-flask' in values[KEY_TASK_IMAGES], "Cloudharness-flask is included in the build dependencies" assert 'cloudharness-base' in values[KEY_TASK_IMAGES], "Cloudharness-base is included in cloudharness-flask Dockerfile and it should be guessed" assert 'workflows-extract-download' not in values[KEY_TASK_IMAGES], "workflows-extract-download has been explicitly excluded" + + +def test_clear_unused_dbconfig(): + + values = create_helm_chart([CLOUDHARNESS_ROOT, RESOURCES], output_path=OUT, domain="my.local", + env='withpostgres', local=False, include=["myapp"], exclude=["legacy"]) + + # There is a DB config + assert KEY_DATABASE in values[KEY_APPS]['myapp'][KEY_HARNESS] + + db_config = values[KEY_APPS]['myapp'][KEY_HARNESS][KEY_DATABASE] + # postgres is set, but other entries are not. + assert db_config['postgres'] is not None + assert db_config['postgres']['image'].startswith('postgres:') + + # However, it seems that even after removing unused entries, + # the finale instance of the HarnessMainConfig class that is created + # adds back those entries and set them to None. + assert db_config['mongo'] is None + assert db_config['neo4j'] is None + + values = create_helm_chart([CLOUDHARNESS_ROOT, RESOURCES], output_path=OUT, domain="my.local", + env='withmongo', local=False, include=["myapp"], exclude=["legacy"]) + + assert KEY_DATABASE in values[KEY_APPS]['myapp'][KEY_HARNESS] + db_config = values[KEY_APPS]['myapp'][KEY_HARNESS][KEY_DATABASE] + + # mongo is set, but other entries are not. + assert db_config['mongo'] is not None + assert db_config['mongo']['image'].startswith('mongo:') + assert db_config['neo4j'] is None + + assert db_config['postgres'] is None + + +def test_clear_all_dbconfig_if_nodb(): + + values = create_helm_chart([CLOUDHARNESS_ROOT, RESOURCES], output_path=OUT, domain="my.local", + env='withoutdb', local=False, include=["myapp"], exclude=["legacy"]) + + # There is a DB config + assert KEY_DATABASE in values[KEY_APPS]['myapp'][KEY_HARNESS] + + # But it is None + db_config = values[KEY_APPS]['myapp'][KEY_HARNESS][KEY_DATABASE] + assert db_config is None + +def test_tag_hash_generation(): + v1 = generate_tag_from_content(RESOURCES) + v2 = generate_tag_from_content(RESOURCES, ignore=['myapp']) + assert v1 != v2 + v3 = generate_tag_from_content(RESOURCES, ignore=['*/myapp/*']) + assert v3 != v1 + v4 = generate_tag_from_content(RESOURCES, ignore=['applications/myapp/*']) + assert v4 == v3 + v5 = generate_tag_from_content(RESOURCES, ignore=['/applications/myapp/*']) + assert v5 == v4 + + try: + fname = os.path.join(RESOURCES, 'applications', 'myapp', 'afile.txt') + with open(fname, 'w') as f: + f.write('a') + + v6 = generate_tag_from_content(RESOURCES, ignore=['/applications/myapp/*']) + assert v6 == v5 + v7 = generate_tag_from_content(RESOURCES) + assert v7 != v1 + finally: + os.remove(fname) + +def test_collect_helm_values_auto_tag(): + def create(): + return create_helm_chart([CLOUDHARNESS_ROOT, RESOURCES], output_path=OUT, include=['samples', 'myapp'], + exclude=['events'], domain="my.local", + namespace='test', env='dev', local=False, tag=None, registry='reg') + + BASE_KEY = "cloudharness-base" + values = create() + + # Auto values are set by using the directory hash + assert 'reg/cloudharness/myapp:' in values[KEY_APPS]['myapp'][KEY_HARNESS]['deployment']['image'] + assert 'reg/cloudharness/myapp:' in values.apps['myapp'].harness.deployment.image + assert 'cloudharness/myapp-mytask' in values[KEY_TASK_IMAGES]['myapp-mytask'] + assert values[KEY_APPS]['myapp'][KEY_HARNESS]['deployment']['image'] == values.apps['myapp'].harness.deployment.image + v1 = values.apps['myapp'].harness.deployment.image + c1 = values["task-images"]["my-common"] + b1 = values["task-images"][BASE_KEY] + d1 = values["task-images"]["cloudharness-flask"] + + values = create() + assert v1 == values.apps['myapp'].harness.deployment.image, "Nothing changed the hash value" + assert values["task-images"][BASE_KEY] == b1, "Base image should not change following the root .dockerignore" + + + try: + fname = os.path.join(RESOURCES, 'applications', 'myapp', 'afile.txt') + with open(fname, 'w') as f: + f.write('a') + + values = create() + assert v1 != values.apps['myapp'].harness.deployment.image, "Adding the file changed the hash value" + v2 = values.apps['myapp'].harness.deployment.image + assert values["task-images"][BASE_KEY] == b1, "Application files should be ignored for base image following the root .dockerignore" + finally: + os.remove(fname) + + + try: + with open(fname, 'w') as f: + f.write('a') + + values = create() + assert v2 == values.apps['myapp'].harness.deployment.image, "Recreated an identical file, the hash value should be the same" + finally: + os.remove(fname) + + + fname = os.path.join(RESOURCES, 'applications', 'myapp', 'afile.ignored') + try: + with open(fname, 'w') as f: + f.write('a') + + values = create() + assert values["task-images"][BASE_KEY] == b1, "2: Application files should be ignored for base image following the root .dockerignore" + + assert v1 == values.apps['myapp'].harness.deployment.image, "Nothing should change the hash value as the file is ignored in the .dockerignore" + finally: + os.remove(fname) + + + + # Dependencies test: if a dependency is changed, the hash should change + fname = os.path.join(RESOURCES, 'infrastructure/common-images', 'my-common', 'afile') + + try: + with open(fname, 'w') as f: + f.write('a') + + values = create() + + assert c1 != values["task-images"]["my-common"], "If content of a static image is changed, the hash should change" + assert v1 != values.apps['myapp'].harness.deployment.image, "If a static image dependency is changed, the hash should change" + finally: + os.remove(fname) + + + fname = os.path.join(CLOUDHARNESS_ROOT, 'atestfile') + try: + with open(fname, 'w') as f: + f.write('a') + + values = create() + + assert b1 != values["task-images"][BASE_KEY], "Content for base image is changed, the hash should change" + assert d1 != values["task-images"]["cloudharness-flask"], "Content for base image is changed, the static image should change" + assert v1 != values.apps['myapp'].harness.deployment.image, "2 levels dependency: If a base image dependency is changed, the hash should change" + finally: + os.remove(fname) + + + diff --git a/tools/deployment-cli-tools/tests/test_skaffold.py b/tools/deployment-cli-tools/tests/test_skaffold.py index af5bbb7c..98036b21 100644 --- a/tools/deployment-cli-tools/tests/test_skaffold.py +++ b/tools/deployment-cli-tools/tests/test_skaffold.py @@ -37,7 +37,7 @@ def test_create_skaffold_configuration(): output_path=OUT ) assert os.path.exists(os.path.join(OUT, 'skaffold.yaml')) - exp_apps = ('accounts', 'samples', 'workflows', 'myapp', 'common') + exp_apps = ('accounts', 'samples', 'workflows', 'myapp', 'common', 'nfsserver') assert len(sk['build']['artifacts']) == len( exp_apps) + len(values[KEY_TASK_IMAGES]) assert 'reg' in sk['build']['artifacts'][0]['image'] diff --git a/tools/deployment-cli-tools/tests/test_utils.py b/tools/deployment-cli-tools/tests/test_utils.py index ea61a808..507f75b9 100644 --- a/tools/deployment-cli-tools/tests/test_utils.py +++ b/tools/deployment-cli-tools/tests/test_utils.py @@ -59,3 +59,9 @@ def test_guess_build_dependencies_from_dockerfile(): deps = guess_build_dependencies_from_dockerfile(os.path.join(HERE, "resources/applications/myapp/tasks/mytask")) assert len(deps) == 0 + + +def test_check_docker_manifest_exists(): + assert check_docker_manifest_exists("gcr.io/metacellllc", "cloudharness/cloudharness-base", "latest") + assert not check_docker_manifest_exists("gcr.io/metacellllc", "cloudharness/cloudharness-base", "RANDOM_TAG") + \ No newline at end of file