From 789744f5a8893327c9fe0a9db2f203b7e3a88e95 Mon Sep 17 00:00:00 2001 From: Owen Rumney Date: Fri, 7 Jan 2022 09:26:04 +0000 Subject: [PATCH 1/3] Some enhancements - break down by severity in the treeview - add Ignore all for all instances of a check - Fix the webview for check help --- CHANGELOG.md | 5 + README.md | 5 + package-lock.json | 2752 ++++++++++++++++++++++++++++++- package.json | 14 +- resources/dark/shield.svg | 3 + resources/light/shield.svg | 3 + src/explorer/check_helpview.ts | 39 +- src/explorer/check_result.ts | 25 +- src/explorer/issues_treeview.ts | 57 +- src/explorer/tfsec_treeitem.ts | 61 +- src/extension.ts | 59 +- src/ignore.ts | 91 + src/ignore_resolver.ts | 56 - src/utils.ts | 74 +- tsconfig.json | 18 +- 15 files changed, 3101 insertions(+), 161 deletions(-) create mode 100644 resources/dark/shield.svg create mode 100644 resources/light/shield.svg create mode 100644 src/ignore.ts delete mode 100644 src/ignore_resolver.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e23e12c..a7d1934 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to the "tfsec" extension will be documented in this file. +### 1.2.0 +- Restructure explorer to be by severity +- Fix the Help view for the checks +- Add "Ignore all" to ignore all instances of an issue + ### 1.1.11 - Add menu button to update tfsec from within vscode (post tfsec v0.39.39) - Add command to show the current version of tfsec running diff --git a/README.md b/README.md index e671842..f21f049 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,11 @@ Ignore codes will be automatically resolved and the description of the error wil ## Release Notes +### 1.2.0 +- Restructure explorer to be by severity +- Fix the Help view for the checks +- Add "Ignore all" to ignore all instances of an issue + ### 1.1.11 - Add menu button to update tfsec from within vscode (post tfsec v0.39.39) - Add command to show the current version of tfsec running diff --git a/package-lock.json b/package-lock.json index 7b67702..d857fe7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,2727 @@ { "name": "tfsec", "version": "1.1.11", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "tfsec", + "version": "1.1.11", + "dependencies": { + "semver": "^7.3.5", + "tsc": "^1.20150623.0", + "typescipt": "^1.0.0" + }, + "devDependencies": { + "@types/glob": "^7.1.3", + "@types/mocha": "^8.0.4", + "@types/node": "^12.20.13", + "@types/semver": "^7.3.6", + "@types/vscode": "^1.54.0", + "@typescript-eslint/eslint-plugin": "^4.25.0", + "@typescript-eslint/parser": "^4.25.0", + "eslint": "^7.27.0", + "glob": "^7.1.7", + "mocha": "^8.4.0", + "typescript": "^4.2.4", + "vscode-test": "^1.5.0" + }, + "engines": { + "vscode": "^1.54.0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "dev": true + }, + "node_modules/@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz", + "integrity": "sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/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, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@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, + "dependencies": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@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, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@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, + "dependencies": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@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, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", + "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "12.20.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.13.tgz", + "integrity": "sha512-1x8W5OpxPq+T85OUsHRP6BqXeosKmeXRtjoF39STcdf/UWLqUsoehstZKOi0CunhVqHG17AyZgpj20eRVooK6A==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.6.tgz", + "integrity": "sha512-0caWDWmpCp0uifxFh+FaqK3CuZ2SkRR/ZRxAV5+zNdC3QVUi6wyOJnefhPvtNt8NQWXB5OA93BUvZsXpWat2Xw==", + "dev": true + }, + "node_modules/@types/vscode": { + "version": "1.56.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.56.0.tgz", + "integrity": "sha512-Q5VmQxOx+L1Y6lIJiGcJzwcyV3pQo/eiW8P+7sNLhFI16tJCwtua2DLjHRcpjbCLNVYpQM73kzfFo1Z0HyP9eQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.25.0.tgz", + "integrity": "sha512-Qfs3dWkTMKkKwt78xp2O/KZQB8MPS1UQ5D3YW2s6LQWBE1074BE+Rym+b1pXZIX3M3fSvPUDaCvZLKV2ylVYYQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.25.0", + "@typescript-eslint/scope-manager": "4.25.0", + "debug": "^4.1.1", + "functional-red-black-tree": "^1.0.1", + "lodash": "^4.17.15", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.25.0.tgz", + "integrity": "sha512-f0doRE76vq7NEEU0tw+ajv6CrmPelw5wLoaghEHkA2dNLFb3T/zJQqGPQ0OYt5XlZaS13MtnN+GTPCuUVg338w==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.25.0", + "@typescript-eslint/types": "4.25.0", + "@typescript-eslint/typescript-estree": "4.25.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.25.0.tgz", + "integrity": "sha512-OZFa1SKyEJpAhDx8FcbWyX+vLwh7OEtzoo2iQaeWwxucyfbi0mT4DijbOSsTgPKzGHr6GrF2V5p/CEpUH/VBxg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.25.0", + "@typescript-eslint/types": "4.25.0", + "@typescript-eslint/typescript-estree": "4.25.0", + "debug": "^4.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.25.0.tgz", + "integrity": "sha512-2NElKxMb/0rya+NJG1U71BuNnp1TBd1JgzYsldsdA83h/20Tvnf/HrwhiSlNmuq6Vqa0EzidsvkTArwoq+tH6w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.25.0", + "@typescript-eslint/visitor-keys": "4.25.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.25.0.tgz", + "integrity": "sha512-+CNINNvl00OkW6wEsi32wU5MhHti2J25TJsJJqgQmJu3B3dYDBcmOxcE5w9cgoM13TrdE/5ND2HoEnBohasxRQ==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.25.0.tgz", + "integrity": "sha512-1B8U07TGNAFMxZbSpF6jqiDs1cVGO0izVkf18Q/SPcUAc9LhHxzvSowXDTvkHMWUVuPpagupaW63gB6ahTXVlg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.25.0", + "@typescript-eslint/visitor-keys": "4.25.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.25.0.tgz", + "integrity": "sha512-AmkqV9dDJVKP/TcZrbf6s6i1zYXt5Hl8qOLrRDTFfRNae4+LB8A4N3i+FLZPW85zIxRy39BgeWOfMS3HoH5ngg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.25.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/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, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-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, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/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/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/big-integer": { + "version": "1.6.48", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "dev": true, + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "dev": true, + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dev": true, + "dependencies": { + "traverse": ">=0.3.0 <0.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/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 + }, + "node_modules/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 + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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 + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/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/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.27.0.tgz", + "integrity": "sha512-JZuR6La2ZF0UD384lcbnd0Cgg6QJjiCwhMD6eU4h/VGPcVGwawNNzKU41tgokGXnfjOOyI6QIffthhJTPzzuRA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/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, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/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, + "engines": { + "node": ">= 4" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "dev": true, + "dependencies": { + "@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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/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 + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", + "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "bin": { + "he": "bin/he" + } + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", + "dev": true + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/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, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-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/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/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 + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/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, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/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, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/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 + }, + "node_modules/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "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==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "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/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/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, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/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 + }, + "node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz", + "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/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 + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/tsc": { + "version": "1.20150623.0", + "resolved": "https://registry.npmjs.org/tsc/-/tsc-1.20150623.0.tgz", + "integrity": "sha1-Trw8d04WkUjLx2inNCUz8ILHpuU=", + "deprecated": "you probably meant to install typescript", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + } + }, + "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": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typescipt": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typescipt/-/typescipt-1.0.0.tgz", + "integrity": "sha512-Rgg7DtWh0c0oJPz2p48B0hlINIkE5zxU5i+dGctkoiKjIu6twl0HXWzoy+mvp9bQfLJGx70zYuN6GK0S/x5Kxw==" + }, + "node_modules/typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/vscode-test": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.5.2.tgz", + "integrity": "sha512-x9PVfKxF6EInH9iSFGQi0V8H5zIW1fC7RAer6yNQR6sy3WyOwlWkuT3I+wf75xW/cO53hxMi1aj/EvqQfDFOAg==", + "dev": true, + "dependencies": { + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "rimraf": "^3.0.2", + "unzipper": "^0.10.11" + }, + "engines": { + "node": ">=8.9.3" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, "dependencies": { "@babel/code-frame": { "version": "7.12.11", @@ -260,7 +2979,8 @@ "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 + "dev": true, + "requires": {} }, "agent-base": { "version": "6.0.2", @@ -290,9 +3010,9 @@ "dev": true }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { @@ -1648,17 +4368,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -1676,6 +4385,17 @@ } } }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", diff --git a/package.json b/package.json index d376341..5cf5b8b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "tfsec", "publisher": "tfsec", "description": "Tfsec integration for Visual Studio Code", - "version": "1.1.11", + "version": "1.2.0", "engines": { "vscode": "^1.54.0" }, @@ -89,7 +89,11 @@ }, { "command": "tfsec.ignore", - "title": "Ignore this issue" + "title": "Ignore this issue instance" + }, + { + "command": "tfsec.ignoreAll", + "title": "Ignore all instances" }, { "command": "tfsec.version", @@ -160,6 +164,10 @@ { "command": "tfsec.ignore", "when": "view == tfsec.issueview && viewItem == TFSEC_FILE_LOCATION" + }, + { + "command": "tfsec.ignoreAll", + "when": "view == tfsec.issueview && viewItem == TFSEC_CODE" } ] } @@ -192,4 +200,4 @@ "tsc": "^1.20150623.0", "typescipt": "^1.0.0" } -} +} \ No newline at end of file diff --git a/resources/dark/shield.svg b/resources/dark/shield.svg new file mode 100644 index 0000000..744b7ff --- /dev/null +++ b/resources/dark/shield.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/light/shield.svg b/resources/light/shield.svg new file mode 100644 index 0000000..98a8cc2 --- /dev/null +++ b/resources/light/shield.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/explorer/check_helpview.ts b/src/explorer/check_helpview.ts index 9baed5d..f66da10 100644 --- a/src/explorer/check_helpview.ts +++ b/src/explorer/check_helpview.ts @@ -1,12 +1,11 @@ import { CancellationToken, Webview, WebviewView, WebviewViewProvider, WebviewViewResolveContext } from "vscode"; -import { CheckManager } from "../check_manager"; -import { TfSecCheck } from "../tfsec_check"; +import { CheckResult, CheckSeverity } from "./check_result"; import { TfsecTreeItem } from "./tfsec_treeitem"; export class TfsecHelpProvider implements WebviewViewProvider { - private view : Webview | undefined; - - resolveWebviewView(webviewView: WebviewView, context: WebviewViewResolveContext, token: CancellationToken): void | Thenable { + private view: Webview | undefined; + + resolveWebviewView(webviewView: WebviewView, _context: WebviewViewResolveContext, _token: CancellationToken): void | Thenable { this.view = webviewView.webview; this.update(null); } @@ -16,35 +15,51 @@ export class TfsecHelpProvider implements WebviewViewProvider { return; } if (item === null) { - return ; + return; } - const codeData = CheckManager.getInstance().get(item.code); + const codeData = item.check; if (codeData === undefined) { this.view.html = `

No check data available

This check may no longer be valid. Check your tfsec is the latest version. -` +`; return; } + if (item.contextValue === 'TFSEC_CODE') { + this.view.html = ` +

Select a specific instance for more details

+For more information about the issue found, select a specific instance. + `; + return; + } this.view.html = getHtml(codeData); } } -function getHtml(codeData: TfSecCheck | undefined): string { - if (codeData === undefined) { +function getHtml(codeData: CheckResult | CheckSeverity | undefined): string { + if (codeData === undefined || codeData instanceof CheckSeverity) { return ""; } - return` -

${codeData?.code}

+ return ` +

${codeData?.codeDescription}

${codeData?.summary} +

ID

+ ${codeData?.code} + +

Severity

+ ${codeData?.severity} +

Impact

${codeData?.impact}

Resolution

${codeData?.resolution} +

Filename

+ ${codeData?.filename} +

More Information

${codeData?.docUrl} `; diff --git a/src/explorer/check_result.ts b/src/explorer/check_result.ts index 3c75207..e9dad5f 100644 --- a/src/explorer/check_result.ts +++ b/src/explorer/check_result.ts @@ -1,3 +1,6 @@ +import { capitalize } from '../utils'; + + export class CheckResult { public code: string; public provider: string; @@ -5,14 +8,34 @@ export class CheckResult { public filename: string; public startLine: number; public endLine: number; + public severity: string; + public summary: string; + public impact: string; + public resolution: string; + public docUrl: any; constructor( - private result: any + result: any ) { this.code = result.rule_id; this.provider = result.rule_provider; this.codeDescription = result.rule_description; + this.summary = result.description; + this.impact = result.impact; + this.resolution = result.resolution; this.filename = result.location.filename; this.startLine = result.location.start_line; this.endLine = result.location.end_line; + this.severity = capitalize(result.severity); + + if (result.links.length > 0) { + this.docUrl = result.links[0]; + } + } +} + +export class CheckSeverity { + public severity: string; + constructor(result: any) { + this.severity = capitalize(result.severity); } } \ No newline at end of file diff --git a/src/explorer/issues_treeview.ts b/src/explorer/issues_treeview.ts index 2c43798..db990bb 100644 --- a/src/explorer/issues_treeview.ts +++ b/src/explorer/issues_treeview.ts @@ -1,22 +1,21 @@ import * as vscode from 'vscode'; import * as fs from 'fs'; import * as path from 'path'; -import { sortByCode, uniqueLocations } from '../utils'; -import { CheckResult } from './check_result'; -import { TfsecTreeItem } from './tfsec_treeitem'; -import { TfsecHelpProvider } from './check_helpview'; +import { sortByCode, sortBySeverity, uniqueLocations } from '../utils'; +import { CheckResult, CheckSeverity } from './check_result'; +import { TfsecTreeItem, TfsecTreeItemType } from './tfsec_treeitem'; export class TfsecIssueProvider implements vscode.TreeDataProvider { private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; - private resultData: CheckResult[] = []; + public resultData: CheckResult[] = []; private taintResults: boolean = true; private rootpath: string = ""; private storagePath: string = ""; public readonly resultsStoragePath: string = ""; - constructor(context: vscode.ExtensionContext, private tfsecHelpProvider: TfsecHelpProvider) { + constructor(context: vscode.ExtensionContext) { if (context.storageUri) { this.storagePath = context.storageUri.fsPath; console.log(`storage path is ${this.storagePath}`); @@ -28,7 +27,7 @@ export class TfsecIssueProvider implements vscode.TreeDataProvider { + fs.watch(this.resultsStoragePath, (eventType) => { if (eventType !== "change") { return; } @@ -46,7 +45,7 @@ export class TfsecIssueProvider implements vscode.TreeDataProvider 0) { + if (this.resultsStoragePath !== "" && vscode.workspace && vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders[0]) { this.rootpath = vscode.workspace.workspaceFolders[0].uri.fsPath; if (fs.existsSync(this.resultsStoragePath)) { let content = fs.readFileSync(this.resultsStoragePath, 'utf8'); @@ -79,14 +78,41 @@ export class TfsecIssueProvider implements vscode.TreeDataProvider c.code === code); for (let index = 0; index < filtered.length; index++) { const result = filtered[index]; + + if (result === undefined) { + continue; + } if (result.code !== code) { continue; } diff --git a/src/explorer/tfsec_treeitem.ts b/src/explorer/tfsec_treeitem.ts index dd6c160..83c274c 100644 --- a/src/explorer/tfsec_treeitem.ts +++ b/src/explorer/tfsec_treeitem.ts @@ -1,48 +1,69 @@ import * as vscode from 'vscode'; import * as path from 'path'; -import { CheckResult } from './check_result'; +import { CheckResult, CheckSeverity } from './check_result'; export class TfsecTreeItem extends vscode.TreeItem { treeItemType: TfsecTreeItemType; - code: string; + code: string; provider: string; startLineNumber: number; endLineNumber: number; filename: string; - contextValue = ''; + severity: string; + contextValue = ''; constructor( public readonly title: string, - checkResult: CheckResult, + public readonly check: CheckResult | CheckSeverity, public collapsibleState: vscode.TreeItemCollapsibleState, public command?: vscode.Command, ) { super(title, collapsibleState); - this.tooltip = `${checkResult.codeDescription}`; - this.code = checkResult.code; - this.provider = checkResult.provider; - this.description = checkResult.codeDescription; - this.startLineNumber = checkResult.startLine; - this.endLineNumber = checkResult.endLine; - this.filename = checkResult.filename; - - if (collapsibleState === vscode.TreeItemCollapsibleState.None) { - this.treeItemType = TfsecTreeItemType.issueLocation; - this.contextValue = "TFSEC_FILE_LOCATION"; + this.severity = check.severity; + + if (check instanceof CheckResult) { + this.tooltip = `${check.codeDescription}`; + this.code = check.code; + this.provider = check.provider; + this.description = check.codeDescription; + + if (collapsibleState === vscode.TreeItemCollapsibleState.None) { + this.treeItemType = TfsecTreeItemType.issueLocation; + this.contextValue = "TFSEC_FILE_LOCATION"; + this.startLineNumber = check.startLine; + this.endLineNumber = check.endLine; + this.filename = check.filename; + } else { + this.treeItemType = TfsecTreeItemType.issueCode; + this.contextValue = "TFSEC_CODE"; + this.startLineNumber = 0; + this.endLineNumber = 0; + this.filename = ""; + } + } else { - this.treeItemType = TfsecTreeItemType.issueCode; - this.contextValue = "TFSEC_CODE"; + this.code = ""; + this.provider = ""; + this.startLineNumber = 0; + this.endLineNumber = 0; + this.filename = ""; + this.treeItemType = TfsecTreeItemType.issueSeverity; + this.contextValue = "TFSEC_SEVERITY"; } + + + } iconPath = { - light: path.join(__filename, '..', '..', 'resources', 'light', 'dependency.svg'), - dark: path.join(__filename, '..', '..', 'resources', 'dark', 'dependency.svg') + light: path.join(__filename, '..', 'resources', 'light', 'shield.svg'), + dark: path.join(__filename, '..', 'resources', 'dark', 'shield.svg') }; } -enum TfsecTreeItemType { +export enum TfsecTreeItemType { issueCode = 0, issueLocation = 1, + issueSeverity = 2, } \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 8484cf7..34c3ae8 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,25 +1,26 @@ import * as vscode from 'vscode'; -import { triggerDecoration} from './ignore_resolver'; +import { addIgnore, triggerDecoration, IgnoreDetails } from './ignore'; import { TfsecIssueProvider } from './explorer/issues_treeview'; import { TfsecTreeItem } from './explorer/tfsec_treeitem'; import { getOrCreateTfsecTerminal, getInstalledTfsecVersion } from './utils'; import { TfsecHelpProvider } from './explorer/check_helpview'; import * as semver from 'semver'; + // this method is called when vs code is activated export function activate(context: vscode.ExtensionContext) { console.log('tfsec extension activated'); const helpProvider = new TfsecHelpProvider(); let activeEditor = vscode.window.activeTextEditor; - const issueProvider = new TfsecIssueProvider(context, helpProvider); + const issueProvider = new TfsecIssueProvider(context); context.subscriptions.push(vscode.window.registerWebviewViewProvider("tfsec.helpview", helpProvider)); // creating the issue tree explicitly to allow access to events let issueTree = vscode.window.createTreeView("tfsec.issueview", { treeDataProvider: issueProvider, }); - - issueTree.onDidChangeSelection(function(event) { + + issueTree.onDidChangeSelection(function (event) { const treeItem = event.selection[0]; if (treeItem) { helpProvider.update(treeItem); @@ -31,20 +32,38 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.commands.registerCommand('tfsec.version', () => showCurrentTfsecVersion())); context.subscriptions.push(vscode.commands.registerCommand('tfsec.ignore', (element: TfsecTreeItem) => { - vscode.workspace.openTextDocument(vscode.Uri.file(element.filename)).then((file: vscode.TextDocument) => { - vscode.window.showTextDocument(file, 1, false).then(e => { - e.edit(edit => { - if (element.startLineNumber === element.endLineNumber) { - let errorLine = vscode.window.activeTextEditor?.document.lineAt(element.startLineNumber); - if (errorLine !== null && errorLine !== undefined) { - edit.insert(new vscode.Position(errorLine.lineNumber-1, errorLine.firstNonWhitespaceCharacterIndex), `#tfsec:ignore:${element.code}\n`); - } - } else { - edit.insert(new vscode.Position(element.startLineNumber - 1, 0), `#tfsec:ignore:${element.code}\n`); - } - }); - }); + const details = [new IgnoreDetails(element.code, element.startLineNumber, element.endLineNumber)]; + addIgnore(element.filename, details); + const config = vscode.workspace.getConfiguration('tfsec'); + var reRunOnIgnore = config.get('runOnIgnore', true); + if (reRunOnIgnore) { + vscode.commands.executeCommand("tfsec.run"); + }; + })); + + + context.subscriptions.push(vscode.commands.registerCommand('tfsec.ignoreAll', (element: TfsecTreeItem) => { + let ignoreMap = new Map(); + + for (let index = 0; index < issueProvider.resultData.length; index++) { + const r = issueProvider.resultData[index]; + if (r === undefined) { + continue; + } + if (r.code !== element.code) { continue; } + + let ignores = ignoreMap.get(r.filename); + if (!ignores) { + ignores = []; + } + ignores.push(new IgnoreDetails(r.code, r.startLine, r.endLine)); + ignoreMap.set(r.filename, ignores); + } + + ignoreMap.forEach((ignores: IgnoreDetails[], filename: string) => { + addIgnore(filename, ignores); }); + Promise.resolve(); const config = vscode.workspace.getConfiguration('tfsec'); var reRunOnIgnore = config.get('runOnIgnore', true); if (reRunOnIgnore) { @@ -54,6 +73,7 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.commands.registerCommand("tfsec.run", () => { let terminal = getOrCreateTfsecTerminal(); + if (terminal === undefined) { vscode.window.showErrorMessage("Could not create terminal session"); return; } terminal.show(); if (vscode.workspace && vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { terminal.sendText(buildCommand(issueProvider.resultsStoragePath)); @@ -69,6 +89,7 @@ export function activate(context: vscode.ExtensionContext) { } let terminal = getOrCreateTfsecTerminal(); + if (terminal === undefined) { vscode.window.showErrorMessage("Could not create terminal session"); return; } terminal.hide(); terminal.sendText("tfsec --update"); })); @@ -96,10 +117,12 @@ export function activate(context: vscode.ExtensionContext) { function showCurrentTfsecVersion() { const currentVersion = getInstalledTfsecVersion(); if (currentVersion) { - vscode.window.showInformationMessage(`Current tfsec version is ${currentVersion}`); + vscode.window.showInformationMessage(`Current tfsec version is ${currentVersion}`); } } + + function buildCommand(resultsStoragePath: string) { const config = vscode.workspace.getConfiguration('tfsec'); var binary = config.get('binaryPath', 'tfsec'); diff --git a/src/ignore.ts b/src/ignore.ts new file mode 100644 index 0000000..f67f0a3 --- /dev/null +++ b/src/ignore.ts @@ -0,0 +1,91 @@ +import * as vscode from 'vscode'; +import { CheckManager } from './check_manager'; + +let timeout: NodeJS.Timer | undefined = undefined; +let activeEditor = vscode.window.activeTextEditor; + +class IgnoreDetails { + public readonly code: string; + public readonly startLine: number; + public readonly endLine: number; + public constructor(code: string, startLine: number, endLine: number) { + this.code = code; + this.startLine = startLine; + this.endLine = endLine; + } +} + +const tfsecIgnoreDecoration = vscode.window.createTextEditorDecorationType({ + fontStyle: 'italic', + color: new vscode.ThemeColor("editorGutter.commentRangeForeground"), + after: { + margin: '0 0 0 1em', + textDecoration: 'none', + }, + rangeBehavior: vscode.DecorationRangeBehavior.ClosedOpen, +}); + +function triggerDecoration() { + const config = vscode.workspace.getConfiguration('tfsec'); + if (!config.get('resolveIgnoreCodes', true)) { + return; + } + if (timeout) { + clearTimeout(timeout); + timeout = undefined; + } + timeout = setTimeout(updateTfsecIgnoreDecorators, 500); +} + +function updateTfsecIgnoreDecorators() { + if (!activeEditor) { + return; + } + const regEx = /tfsec:ignore:([A-Z]+?\d{3})/g; + const text = activeEditor.document.getText(); + const tfsecIgnores: vscode.DecorationOptions[] = []; + + let match; + while ((match = regEx.exec(text))) { + if (match[1] === undefined || match[0] === undefined) { break; } + const startPos = activeEditor.document.positionAt(match.index); + const endPos = activeEditor.document.positionAt(match.index + match[0].length); + const message = getTfsecDescription(match[1]); + const decoration = { range: new vscode.Range(startPos, endPos), renderOptions: { after: { fontStyle: 'italic', contentText: message, color: new vscode.ThemeColor("editorGutter.commentRangeForeground") } } }; + tfsecIgnores.push(decoration); + } + activeEditor.setDecorations(tfsecIgnoreDecoration, tfsecIgnores); +} + +function getTfsecDescription(tfsecCode: string) { + var check = CheckManager.getInstance().get(tfsecCode); + if (check === undefined) { + return "[Uknown tfsec code]"; + } + return check.summary; +} + + + +const addIgnore = (filename: string, ignores: IgnoreDetails[]) => { + Promise.resolve(vscode.workspace.openTextDocument(vscode.Uri.file(filename)).then((file: vscode.TextDocument) => { + Promise.resolve(vscode.window.showTextDocument(file, 1, false).then(e => { + e.edit(edit => { + for (let index = 0; index < ignores.length; index++) { + let element = ignores[index]; + if (element === undefined) { continue; } + if (element.startLine === element.endLine) { + let errorLine = vscode.window.activeTextEditor?.document.lineAt(element.startLine); + if (errorLine !== null && errorLine !== undefined) { + edit.insert(new vscode.Position(errorLine.lineNumber - 1, errorLine.firstNonWhitespaceCharacterIndex), `#tfsec:ignore:${element.code}\n`); + } + } else { + edit.insert(new vscode.Position(element.startLine - 1, 0), `#tfsec:ignore:${element.code}\n`); + } + } + }); + })); + })); +}; + +export { addIgnore, triggerDecoration, IgnoreDetails }; \ No newline at end of file diff --git a/src/ignore_resolver.ts b/src/ignore_resolver.ts deleted file mode 100644 index 6e0f4e7..0000000 --- a/src/ignore_resolver.ts +++ /dev/null @@ -1,56 +0,0 @@ -import * as vscode from 'vscode'; -import { CheckManager } from './check_manager'; - -let timeout: NodeJS.Timer | undefined = undefined; -let activeEditor = vscode.window.activeTextEditor; - -const tfsecIgnoreDecoration = vscode.window.createTextEditorDecorationType({ - fontStyle: 'italic', - color: new vscode.ThemeColor("editorGutter.commentRangeForeground"), - after: { - margin: '0 0 0 1em', - textDecoration: 'none', - }, - rangeBehavior: vscode.DecorationRangeBehavior.ClosedOpen, -}); - -function triggerDecoration() { - const config = vscode.workspace.getConfiguration('tfsec'); - if (!config.get('resolveIgnoreCodes', true)) { - return; - } - if (timeout) { - clearTimeout(timeout); - timeout = undefined; - } - timeout = setTimeout(updateTfsecIgnoreDecorators, 500); -} - -function updateTfsecIgnoreDecorators() { - if (!activeEditor) { - return; - } - const regEx = /tfsec:ignore:([A-Z]+?\d{3})/g; - const text = activeEditor.document.getText(); - const tfsecIgnores: vscode.DecorationOptions[] = []; - - let match; - while ((match = regEx.exec(text))) { - const startPos = activeEditor.document.positionAt(match.index); - const endPos = activeEditor.document.positionAt(match.index + match[0].length); - const message = getTfsecDescription(match[1]); - const decoration = { range: new vscode.Range(startPos, endPos), renderOptions: { after: {fontStyle: 'italic', contentText : message, color: new vscode.ThemeColor("editorGutter.commentRangeForeground") }}}; - tfsecIgnores.push(decoration); - } - activeEditor.setDecorations(tfsecIgnoreDecoration, tfsecIgnores); -} - -function getTfsecDescription(tfsecCode :string) { - var check = CheckManager.getInstance().get(tfsecCode); - if (check === undefined) { - return "[Uknown tfsec code]"; - } - return check.summary; -} - -export {triggerDecoration}; \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index f25833a..397a1da 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -3,9 +3,25 @@ import * as vscode from 'vscode'; import * as cp from 'child_process'; import { TfsecTreeItem } from './explorer/tfsec_treeitem'; + +function getSeverityPosition(severity: string): number { + switch (severity) { + case 'Critical': + return 0; + case 'High': + return 1; + case 'Medium': + return 2; + case 'Low': + return 3; + default: + return -1; + } +} + const sortByCode = (a: TfsecTreeItem, b: TfsecTreeItem): number => { if (a.code - > b.code) { + > b.code) { return 1; } else if (a.code < b.code) { return -1; @@ -13,6 +29,16 @@ const sortByCode = (a: TfsecTreeItem, b: TfsecTreeItem): number => { return 0; }; +const sortBySeverity = (a: TfsecTreeItem, b: TfsecTreeItem): number => { + if (getSeverityPosition(a.severity) > getSeverityPosition(b.severity)) { + return 1; + } else if (getSeverityPosition(a.severity) < getSeverityPosition(b.severity)) { + return -1; + } + + return 0; +}; + const sortByLineNumber = (a: TfsecTreeItem, b: TfsecTreeItem): number => { if (a.startLineNumber > b.startLineNumber) { return 1; @@ -29,12 +55,18 @@ const uniqueLocations = (input: TfsecTreeItem[]): TfsecTreeItem[] => { } input.sort(sortByLineNumber); let output: TfsecTreeItem[] = []; - let last: TfsecTreeItem = input[0]; + let last = input[0]; + if (last === undefined) { + return []; + } output.push(last); for (let index = 1; index < input.length; index++) { const element = input[index]; - if (last.code !== element.code || last.filename !== element.filename || last.startLineNumber !== element.startLineNumber) { + if (element === undefined) { + continue; + } + if (last?.code !== element?.code || last?.filename !== element?.filename || last?.startLineNumber !== element?.startLineNumber) { output.push(element); last = element; } @@ -44,20 +76,34 @@ const uniqueLocations = (input: TfsecTreeItem[]): TfsecTreeItem[] => { }; const getOrCreateTfsecTerminal = () => { - if (vscode.window.terminals.length > 0) { - for (let i = 0; i < vscode.window.terminals.length; i++) { - const t = vscode.window.terminals[i]; - if (t.name === "tfsec") { - return t; - } - } - } - return vscode.window.createTerminal("tfsec"); + if (vscode.window.terminals.length > 0) { + for (let i = 0; i < vscode.window.terminals.length; i++) { + const t = vscode.window.terminals[i]; + if (t === undefined) { + continue; + } + if (t.name === "tfsec") { + return t; + } + } + } + return vscode.window.createTerminal("tfsec"); }; const getInstalledTfsecVersion = () => { - const getVersion = cp.execSync("tfsec --version"); + const config = vscode.workspace.getConfiguration('tfsec'); + var binary = config.get('binaryPath', 'tfsec'); + if (binary === "") { + binary = "tfsec"; + } + + var command = []; + command.push(binary); + command.push('--version'); + const getVersion = cp.execSync(command.join(" "), { "shell": "/usr/bin/bash" }); return getVersion.toString(); }; -export { sortByCode, uniqueLocations, getOrCreateTfsecTerminal, getInstalledTfsecVersion }; \ No newline at end of file +const capitalize = (s: string) => (s && s[0] && s[0].toUpperCase() + s.slice(1).toLowerCase()) || ""; + +export { sortByCode, sortBySeverity, uniqueLocations, getOrCreateTfsecTerminal, getInstalledTfsecVersion, capitalize }; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 0eeaea8..e6cccd5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ /* Visit https://aka.ms/tsconfig.json to read more about this file */ /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ + "incremental": true, /* Enable incremental compilation */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ // "lib": [], /* Specify library files to be included in the compilation. */ @@ -12,9 +12,9 @@ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ // "declaration": true, /* Generates corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ + "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ + "outDir": "./out", /* Redirect output structure to the directory. */ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ @@ -35,12 +35,12 @@ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ + "noUnusedLocals": true, /* Report errors on unused locals. */ + "noUnusedParameters": true, /* Report errors on unused parameters. */ + "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ From 9c1f906edb86af4fddd33f8aa42cd04067c52e24 Mon Sep 17 00:00:00 2001 From: Owen Rumney Date: Fri, 7 Jan 2022 09:57:35 +0000 Subject: [PATCH 2/3] update the logo --- CHANGELOG.md | 4 +++ README.md | 9 +++-- package-lock.json | 20 ++--------- package.json | 3 +- tfsec.png | Bin 22321 -> 14422 bytes tsconfig.json | 82 +++++++++------------------------------------- 6 files changed, 29 insertions(+), 89 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7d1934..61d4625 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to the "tfsec" extension will be documented in this file. +### 1.2.1 +- Update the logo to the AquaSecurity one + + ### 1.2.0 - Restructure explorer to be by severity - Fix the Help view for the checks diff --git a/README.md b/README.md index f21f049..0a902c1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # tfsec -This VS Code extension is for [tfsec](https://tfsec.dev). A static analysis security scanner for your Terraform code that discovers problems with your infrastructure before hackers do. +![tfsec](tfsec.png) + +This VS Code extension is for [tfsec](https://aquasecurity.github.io/tfsec/latest). A static analysis security scanner for your Terraform code that discovers problems with your infrastructure before hackers do. ## Features @@ -9,7 +11,7 @@ The issue explorer displays an an organised view the issues that have been found The code runs tfsec in a VS Code integrated terminal so you can see the the output - when it is complete, press the refresh button to reload. -Right clicking on an tfsec code will let you view the associated page on [https://tfsec.dev](https://tfsec.dev) +Right clicking on an tfsec code will let you view the associated page on [https://aquasecurity.github.io/tfsec/latest](https://aquasecurity.github.io/tfsec/latest) Issues can be ignored by right clicking the location in the explorer and selecting `ignore this issue`. @@ -25,6 +27,9 @@ Ignore codes will be automatically resolved and the description of the error wil ## Release Notes +### 1.2.1 +- Update the logo to the AquaSecurity one + ### 1.2.0 - Restructure explorer to be by severity - Fix the Help view for the checks diff --git a/package-lock.json b/package-lock.json index d857fe7..1ca1725 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,14 @@ { "name": "tfsec", - "version": "1.1.11", + "version": "1.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "tfsec", - "version": "1.1.11", + "version": "1.2.0", "dependencies": { "semver": "^7.3.5", - "tsc": "^1.20150623.0", "typescipt": "^1.0.0" }, "devDependencies": { @@ -2391,16 +2390,6 @@ "node": "*" } }, - "node_modules/tsc": { - "version": "1.20150623.0", - "resolved": "https://registry.npmjs.org/tsc/-/tsc-1.20150623.0.tgz", - "integrity": "sha1-Trw8d04WkUjLx2inNCUz8ILHpuU=", - "deprecated": "you probably meant to install typescript", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - } - }, "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -4475,11 +4464,6 @@ "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", "dev": true }, - "tsc": { - "version": "1.20150623.0", - "resolved": "https://registry.npmjs.org/tsc/-/tsc-1.20150623.0.tgz", - "integrity": "sha1-Trw8d04WkUjLx2inNCUz8ILHpuU=" - }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", diff --git a/package.json b/package.json index 5cf5b8b..24bde69 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "tfsec", "publisher": "tfsec", "description": "Tfsec integration for Visual Studio Code", - "version": "1.2.0", + "version": "1.2.1", "engines": { "vscode": "^1.54.0" }, @@ -197,7 +197,6 @@ }, "dependencies": { "semver": "^7.3.5", - "tsc": "^1.20150623.0", "typescipt": "^1.0.0" } } \ No newline at end of file diff --git a/tfsec.png b/tfsec.png index 5858a11a67c9c5387926eeb3cfc216f60f43f5f4..1baa9941b1a8d6b628940129a635d37a0c21d879 100644 GIT binary patch literal 14422 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 DUcm-A literal 22321 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 diff --git a/tsconfig.json b/tsconfig.json index e6cccd5..950e7ef 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,71 +1,19 @@ { "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - - /* Basic Options */ - "incremental": true, /* Enable incremental compilation */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation. */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "./out", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - "noUnusedLocals": true, /* Report errors on unused locals. */ - "noUnusedParameters": true, /* Report errors on unused parameters. */ - "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ - "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ - - /* Module Resolution Options */ - // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ - "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - - /* Advanced Options */ - "skipLibCheck": true, /* Skip type checking of declaration files. */ - "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + "incremental": true, + "target": "es5", + "module": "commonjs", + "sourceMap": true, + "outDir": "./out", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noPropertyAccessFromIndexSignature": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true } } From 16422eee7563edbdef45fe10a5b4a47133f446cb Mon Sep 17 00:00:00 2001 From: Owen Rumney Date: Fri, 7 Jan 2022 10:08:50 +0000 Subject: [PATCH 3/3] Add the licence --- LICENSE | 21 +++++++++++++++++++++ media/tfsec.png | Bin 0 -> 14422 bytes 2 files changed, 21 insertions(+) create mode 100644 LICENSE create mode 100644 media/tfsec.png diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8912605 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 AquaSecurity + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/media/tfsec.png b/media/tfsec.png new file mode 100644 index 0000000000000000000000000000000000000000..1baa9941b1a8d6b628940129a635d37a0c21d879 GIT binary patch literal 14422 zcmb_@^;=Y5^e!c-bazP$h%^kHQi8-t$S{PYpuo@#5)uN^N-8J}GD8c}oq~KA2apyR zVJPXoXT0C%-unmK=fNMGv(MgZuf5`Z*V-rXk+JR_a#nIYJiI&ldRk_9c=#T`KL{x? z@Jm<}xD^kN8&6+L-8}H!_WJ zs`)p*og5vHDeR7{(h#Xr|9|<5m3^@kl^1E{^t0~+)*{_By?3GhgFTaGA2rG9im3+O z8htt@hvhi+#}KdJAHAr$T}V9DMws}^jE619SunbA-ny{u1~&n8Q4}|6w1wZ2aCM($ zpEqnx^g@wYq=T+Ns9cemiFlTc@eAF-nm#Yz*)EhXsB!So7y5&>>EqC#_X!g58zKu? zJboG72lNU*JMQQp#JgD21h9fwwKzDTK(59 z`K=m}xm9w`)Yl@D^v;P&yY0goZ=!ekpegJTR%nhNc1XpjbY{#Te?b{OGgGs{meDzm zUIeLA_d3RY8)-atsifjaUgN`_X&>~yihBWVUr89$Gv!_x*>&UV9!vGV(PX9ae_bk` zu0pNv#MEp2!%-tq`YDFr4zi0;ZP|*iO;a+s)I$GEyNa~8Xj?@u|-zsscv(LabYt__QR+Aex4wS9{H-N&m|K=G^lop={5bVOZh zzk(pYrd#R@(1<_;q5U6GskgeXQ<97yfCfENk6ve6$I^Z_6H4cxRy5GmGB&IELc7?` zK>~lC7FI(|R6=KVnpWm%%k1h6*9)z8Dsk;i742)ud+3w}75sA_SthnplwiO=xsDEC zRHv@)jj~!W^{n)xIe5LEkW4|>tCJ+=b(K4ybtH>2p$cpp)DM0tv_I#zi%~LJlHT1C zPmO|NL*8&F2x5jF&-ej0k!1LLO1nRfEaH3iG`i~pcva+O#sancu<>gSXPWM(?T#(& zTziyh10L~V9kfJ(ftdkg!+<>&CD>yGe~TU`p8YjIJ2;inZ#^UWHCbbg#hg@i&O{(P z-4=d!n>aP1Po&i`x9qA7TFFw#2NF_#(?H8gr^bSLVn2YJv=ZU}6ruDmto32&MfeVl zcT(6Q9Z}iYy9z0WeF|0N2GiN=)3|u;&^|9L203l~oPG->k}>E`lv+D=oEmNr$2H1^ zR$uW*0m+gQFxV_u7$86Y=<8~hd^DQFMR&j;gHE4fQi^y%4GKOlgPZ>57p0chFNXGw&-j2-xcFkw{S zbz8wQ*Kun5L5uwPN$JlGGM%MP!Uuqq+OBZYp!)hKE|CoA7{4~{ADI%Ze4&>a!IJ`( zvBrN;?U(-PiJ>jIHS!t;Y@=_XW9H5&8i`nm7ZM$6@hZL{Q}BWbNeDMiAi$k}VDmW4 z;4>w9ylnz6Gwzb!H4B*g{__bm%`ZAGbo_B%l2Mj8;O4P!Bx*WSsq~Sk0ANMJ5-ph8 zZ~miNe@c3&TqH!2BWQYCyMH(x+ODi0`z=UCAGuyn>lQPp4>S9XRhqw!`AUiQ;%1JF zC0U2|taS0Nb`z1;U+W=J657VK1USj&RDS$K6sTj~6e?$>OnmZ52HC%eG?;t!Qa`ET z`r$Ilmpu?7AS-^UK4^tyI#{DZI%=4~hh(b&B}S05hgFaT6U{ovy>g|4Ok~wyajr8} zuJ;Sj(EYnVh@;A|^@IAGN9%GWmgqH}e0?i}J|zuD?F5kh(?pIt8Bn85%XBSEzPE#v zI0Y2;j*zzM_R{&Szh_d|Tl3Y{`Fnsa;okoU&Wy0Ri&<;^p}um#2`iJQWX7rIxIam2 z_HB`;NMC-aS$Za14J&l?(T>1BVWPRdbplMoyCPbNC{vSqoFsE5rfvMg8h2hk#~h;+ zhRcp8hP#M0y9Rm|hM>u<1t;GR;LI^o{`9QGkh5DqUdypA-CfOSitA6JzHk46PzjGe z1Q>AdF-i!Q!AS?$kM!Jg{F?nvE!R&zfK~<&B%mQ3)mzN?_s8f@GOh>zR_JxAd4iR} zp5}qXA$u9Xi5YF$0`C25L;|s~A?k$~ne%+Q8kLAM2_T^2hfHMrdJ8ow6;7XLR2t@G zzA8{i5 zwvefeaP%^FLvbEEcHxoQ!1Y5!q1o;15erC56@9YQNas@jjm9tbBOcV)q~}isM1sm4 z%M#sA>lQXe!=!lQ#TtB@pAhQ9V_hnW&v7BW{zE#rS#be89r+HnT)k3H>7$St)8`>EiQz*op5yEvVwdDDE(@};jaKjnV+4AYrH3oX`r5i`fcL; z0wW(nESL%O^c7Rt?lwQLBGsk})!lZt|(g(?YMDXe(mhwSg{!IS% zF#d>)Fa#t>qj-fNCgQrMmc}WXrB|{VIlYZ+ofC;g{dLAHJ4O*G-SRuNB*WQAXvw(**nSp;y0VPO|+FRL^yu-HTpgA zHGl>@l+^XR$!uwQc_7`*41Q#AVDuRRijeSQZ78e@DJ2cQ)&6>ZPS!zCL@}1rgv0gX zIZb`hliLCvZ)>mh?B`tp_Xw?~7&E!;cx;|T^gl+1T>E5JPFMh!x>xv&WLhpko& z5YSgav+Joyj8$jSNJGj+LD7eKGYALFeTFo_F}dv^Ru!C3MS4X(!%bY zlwMWR8JZhZNu4i0lb@c^KLZ4`p33*qC)tX0!u)P$B^t-tiPM}MazxKtr*PL=FqXzQ zea#;%nW}h*0NW9~a;A4pYH)G9nniUKhrJXJ=Fj^yvtx^}4yRWP?vE_~9(st^q-C?A z#shmM6Wv)Z#0cvCZt8kBo^t1*9$%hpq2P9lumZ2Ql~-hxOb_ z@)y+%>$nMg)EeBm=3TC_Da3-!`$o^Z4v(98EgN%@)V8PoiwrTJmBMN4Id=Rz+Ts+c zyY(xKaMJPeSIEji+zEoM>OOn&Yh4GDGyABB<(pXu zw&hggh z(|Q)-FCbF8rixYFtg7XmRaG`%W};cLxslxxt=Zp`d@z>+gW~ynmp<-Out${h?%%tc zKIA#pw(yKj@Gk!9q5&qXuM&Z<0_+Ct~Y=3({{FnML%+} zcOvZ#1B^>?&YWWpTs_}PC1(TCI=z-keZ=Bnw%vm48KC-!)4ucoDye|-Z$E8BC;sTG{FH!1pTit~;%5j03 zSt(8$4H3tSgpDyh^_(6yO~ntfjqdE}i7TRBw+%}^vMXK|ht`wCv#P@L_p)Z|Bsb69 z!4<3&f6hRUdJK^$Te$t=U%}u{MQbVQnM;^cH86&YSzGI5m;8ObE&C(r1yxDaQdq_=6*TYLl9Nt zbwvRh9&1<_qpJ-+jB8M>c}26Vzl4ZcQ-$n|k&I+@s8^V7$(;X9iK*Ka0;ImBE~u?- zLtIk)ngH(9*D2w&D@9^&N5Hi(PgP4Ud>Op|xH;!}DyMx?!*l4>aHIJlX_I9`6$wr+ zyw9{d_p*k#4M%&ad_-mDvdK`j^FTEJFm|HZv=HSD39t}Nz`hN!Rz6MU0*yJeynb(! z!m7rix5E)VlXb8JS!VJP?4boU(tErE2h60Wa@rZqENznI@rCmIlA~>Z>iec)M1avW zLOFQ9T*f5x@X6krf2gX`k{Uo&1)$fB5z?<^#atGpbT`gzeQHvp0T=i*$XGm(1szKU zQvhzHYiXn6$3`N|iO+3AP1Pn_sFmjP`q^CK3@*B&DP6BUZ6tl%IAM<)`VDl*D>f*l z%Q~J-w$8}BmNn1m9tg;E&_6SIlfGDHA(4;JPx9Z2hSUj?fGS&Xu8Wv{#*$2GLZHsu zy3kT@n@PX{f~rl--JG5DY*1(-3M#e#fjWN^O7W7hvTEI#`nvZ|9BFR1vrtV|ra#Ja zj^})oBy-^C)h@vWDrH7}4eHiU!^^GndGPJM4wNX)#22Q*35%0kyA;(>*s4XJGT;Vv$yBZ(6m-qYkO9c?qDq8vhxiM{J})#s9eaI#|l{=m~KT?{UoC9{a?N4ZDe& zE44y0bMY?9znS?mj8P%}^tbY%)ze@r%Df~_ZP`HQ1UY!oS8`hv7yd!msI|!bvuXsR zQb`Npuu5O*11e4s;r7cAC4Qm!uKC*(horUII6;GFnx-Z+2W3a%&pW051p6f45Q6?I zzaa0FH!4hd|7ae+b3^^i3$E93#eJ*Wpl#`4_PyX!v=ET%Q`XLw>pCN@bpqXNSgqk_ zLBqGuWYhN^Ax(0kWWCIz0r}Wl_sBjyo+}|q8#99oqtK| zEQ?d7D+lUav4}rqxN(oi&L^45iM?WsTfe*AMG3GB$Dsf8;)@H*u(&zc$(~xCs|Pib zf?UtV0J+Efyea=iCn$K7gmkl{^v{Z!9D!i6FCvGJ@)P`aLpnN*`yijnba#YM^d7Z| zDdLvcackQ0cPko}8y8&Q`?XdXT{+qFPB+_iQL0}el$Q{sz0vK(ADS?cfr zGTuGLjh=2v`Di#kn1vqdB`gL}iBC89fr3XHEZ!7d5C_*c1M~$t=CVtfONukQ8t=0@ z?Vsa96|Nwd)QhO3$73wN)>FuHUno41IEi;D0Jhnn0^V3B3lWfrOLI(>lR&++Fu~fc z5abXP%6+=Wx+Zz`S7Y2ubJ$535IoFmdlSDSl_K_fi&FKVg{6XCrPKJX%A@P9DPrG? zR}@S3_nE#tgQ=y_;e__>QPmxRfP1eayyo5CR-V!+Wu4+N|1Dk#o|16`Lg%O9&1BBI z0C_~Nmn*1_MgfsBt!(VOXnxB3hc0*wN@tt2%)VX>pT_;w(`axLW-duFO6i_ z)wHyLU;->rb17bCLF1wr8eW`$fAzm#O7Dum_*i;IMPD!UP*VSU&&1bYFo_?lBb8M8 z%gPKT^iFY+ zjrMI1v?|%+}JCgQ(iV$w1-^kZ-`p- zOJ=|sK&iF(Z%efE0DZZX735UUzM9vt^tr#$K!RR&Y+;xoKnn)ML?+EhE}7 zAvj!WZ;QOY`~XW?8-3?4p9y5(jsC(gB6{l9IJK!1B@P|{*r#*=;M7Qz)oWdonx5y} z9=Tu!MOLLZ;Ds?n2HZ8Z~-`jx*_O`ayNR zpub}HP8fxKeWcm+f|@ra`hnx+a><gXi)Zerpw`pS_3KWAOXG2Vi1VbqoC zg2K)LwRXn+HGuT!g@S-S(xv_6A}!)FAOP)4*$$4NzufSST`iu6_Li>^}AJ2rIqERq9dZEOrRLX^;S zMPV1cx$67*m2pBbf^!c;c0Vt!R!kY z%I2D16gFYmUDZ)fF-6GF`=Y2`2f4KAcgi>Wcara>CS<&rI5DOT#uaUWmvrC-?(g4H z0154Zz%PgW{c&`gqf9ON45b}Wi?Yq3{KR%KJILi6s1=>LE1`@U&O-Xz!rX<1%@VsE zjqkv=z$P7Ytt9TE6HO1`+z(~QRa#ne2(H-Y)D_UGqmgO50zD_w>3aujcnLx*BzBzT zIM1^tI{`E*FaLt(zt*75-*r1S)cL9NipPYIK#QJ=0jJ+5ctCVRcnWDz@jRCHGS_ID zty=eg5~@Jh#pDfzuVHYWh1X3kzS5 z@%yLLPo&mEZ3x32l!3IWbhioiypzNnhux^KM*c2Ekw>G1I$ zA@W$XgKW@hAzk$01?M~KQ`GBhWL6|5Zbuux7;9gu0;?n~QmA~pDGeO-eH!&Ahspi- zp;x)v%p=l_ka!4?PjT_bm`PsKD<3)D4c`J&R5L*CiW0}L-MjH_;zy;;7f@Mt#dq$E z+@<$m>^tY06Wr(q%FN3(li~NS-#JW9Y9cSntwvkeefFMA;$m`)cmLKj9mh(1-qKT! zBl%H(x6uD2x1>)VHGs(LnhNgTv{s*iIKyn=4=_&NZ;6G0RXlRedjr=EesiVB2{ZD@B1g&1@ zB$0j7*zrvzmTa6NT2u_RsXT1}KuH3G30$8k5C%Rxc6twhJjOJxT?p4iq#yaR2E4Kd6 zUHgTFydf0F&h6=sxTqN_dbI=u;Nrrl5mqp=k;UTnw!8GHoref2VlKR^eZVBe=RV5B z8h|YkDaSF?ZuHGMoWxbXl@Gb)bnDvA_Qp2tx%>F=I-SL&TY}Zl+4ts=t>r~(AGu(D zHc*^1S}>3U8FJb36+^IX9R!h?4H<@_oJ%`onlmPDb*>rckv#nR(qvx)Dep5x`bY`8yo zr}#FIOQV74?E`o<=#^m(E~CH7d3CN__`+jLG51|gEA&}1o0@a3EP)-4nyJa+pqt0s z>zxMU~KFQl20!^wjy_4+%Stt6x;@&#UTa>q=P=|92cE&zBoKQ zW*XdGfGZ3|9g`RF{&;d@pQ43njwh?fYbyyNx?6E!7>L!6$t zlLbuh+t)SEgD+jz1c>&)eFkjk3yS8$g9Bo$jf^0G#9F6yEz@ypgn0VxM*_JYq80eV z_eA9Wb=#gStfiUcZQDitlluQ5H^GC=+&EyORdaj)mE@vc;8w@8>!T|+XZpfUV^kPeW~aQ=+1n@Sv)wiD{W;rvE5pulM!~b+JB7aq zw6AifNtT&O=9e$5cOz zCd>LPaQl>HVQYuU!0P13hF)`JJLU8yTNaC^@{R-W#CjLc02{Wyi$r=!p62iyq~Srf+%gkAUh%}i9=lcA&%m7t(ewv z5=7#|Do8ogn&3ZLRYC2#IMi?AYxC%o2CGA3G&r^!PNMYGHWP<2TaJL^T529kMTha` zBfj>6@c++~XBFQ&qUQxx$Sku*spr2-TRD;>8{p(MlyjM$rN+wAm@L1!93j9)z5t*{ zU;dC~`0f-n7ngU^{M{8{F^TuGx#6xKfL-YOuuv%F#B%gJr`>0lItc#Noyu&5dyu!; zbG^zfB))8i<)rz}qay=lfb}->;!eTbWYq3c_j8(kg3_*$%ZJ%^gs}fPPjjo9w8GeV z-clBR5#p;<4k>XxV1ExLHPVW>AaV(=0wdx?q)qN!ELV4C7r@^Wia04FlJ7*0EIt}6TED(kl84^ru_nc1reANfj^WT1 zt8sxv(=n+;H{9iv{3^n%(pE>Jh}tNNe+#Wvh)c}d>pL%7qN`^>U9sZ>^`m!Bt=)VM zVka^E_{WdCE7kh+OpLWWnc)1u!v?iGw9>jCl zmPrKA!qCkvVP!3V{9zJbnPM&3v{&;&clIFvUn-oc`%y`0YG)mqt}$Oa?X7B3A{%i`bM zF@qO8+r1-L(lt#7s?Ybi%0I$KSMx}B?v$!OLugi!aeXMz$ccBu+;?iB-&zj>$_BuM zB{=vxfwVhUN3Xffd;Bn(aI7Me6P}-R9P|@LNx)8roel@xhf^Fp%8+cDu5b9_uEZhn zmUNYm=b{eUVle7Xwe(vXb1Di<^f!4?oKK7b&q9h``6ni3qr-Tl2WyAjo&!Z};1)(~ z#rVl9*rQZV?Q)=Z)?RySACo@))+V~=#Gxr}f*`^cW0%NbZKUw`ob^yh$|C8gE(|E# z{9?t#;U*10GC-gYUzf zWSlkgc@Dot(1TJ9Goe@BI3RZG6P>;(Rn!2pq?u4Sfia|=7@jbR4#>L$#0A>hKe_QTgh>UYgfnaQ3e+zCf&*aClYzJV{ z9kbgSY5b2rfN#D7)$B<^gF5$8BfLm;hw&;Z1YebYM;lE%=R*NKWcY`xRKMnO-FTV_ zcz%yoR`Qcn4zQ7Ro-+x@CdGtf;=R7}bfvbVjXZZCICY$hr#s5Us1Y3QVQPT#>me9w zfE17P<~uGMu*gImRq(aSr>TGf?tD&@4Sw0ya0ir2@1YF1*Q5LYk$@2Shls@=1XxSz z+uVX37aYKjei+PX7)!+afKYQ4uS#)q+-9fxN37m+GplJ0#ePOdP1oBloaB!nVfJ5{ zKwt7@6(pq@T4{)4^gz3Q97>3M7})=Iu)Hv;1?Ph1VP&c&5s@R{X1TypMbDA!9dsBs zvsU2QThq<|V3?@s4^|J9qKd`YK!x-k^SRPN!ojvO+vCN1bhz6mga5J(iRF~Q&_&rm zCbT;2XnTzb*f@@jit8KJ59|C8A(0pxy9OM1e|5=e#uDVk$fJ^7Hef63uO7h?->pTBrOgh;Srh1K>oF=r?(n;&%T#e;KHhLy=!OR=}Wc)3f z;4?s8Hx+4Lkpu8eGp(}mvM<7o^B65~_@?ewTMb0l!UhO>U3;5Hn39ix^W`*EY|ii7 z8nr3-Wdys8uFD|?WJ==U&B|+axB@=HeWaCzac|*jal#SsB)kHU!W&t$h=@l-IY@+p zr$51QuE1fgR$uWVvaHfb!kMD$+JQLO=PSDhz&sFMn^K3l?o*d!zPlB;Qpv!Bk^y)# zsIF|&_NOBDllv4v{QqT4aVtj-{?|HbpJly(td@}5Jc)M9Tf+0OpmV`&6#!LfgZren zi*JLz*}iTVsI@DG9jQ@O%FZjP@)L&Krej~h#C@j+vR0$PNZ3Tr$Vc$W)PbNXKzPhA z_a28m@`U4sT+*^b0ZX&0aSm|rrL1h^i11ek4*g2K6+mmewO#ewD8-iHD|HB#mYu)R z>ChdU>pu5NTJzMzUphGQNC8#jX>e;gU}{pc(kpH3iCHqpg^bd7Gjw+Zw<^_Ca_2V6 z@{n}P5q_(+mU|;!0mC!hDA)cTPB~ZmQRz7FuDs!CmK)c?Nc}|X1Gb_=0Hq!R^c~cD zPQR53;Ez$}h{HFV-OX8BrHBC$^*!3RH#0FDkL?2Q)$xhK{y1vFt1}Lk24mweG}Cb` z3*mB+vhKXOYUCgG>c|(qrT`H)g6Q@IyRldppqPmsgC~H=D!0LGvuF zRI-_l93s=-59o^4^ZwvlAqM!>l{4#ZWr*O0tTL$(1HJ9wcQdqGU!w{p2rEUsZy!9r zos_a21>z)I$rEe+J%6B+eMj)$s=5;4{mqaE_fZQ5Og7eE^(HCPQ&8poXv z`xL$EE0AqV0$r1q&cs?=Uz#~*7vlqS`K5*8F@H7?LPaP6$gV=88g>+UFi&pS_wM<8dxuf@NKW>yjHba&y*8 zThr9UU?BAfsBDyUW!aRB7fGI6Z)(QRI;P1*yUHZKaebG5bA1Ol_I*;9Ygd2r(TV8s z%jY^_-g{a{wHTx4XvY-pSwo*c^g}6PY;B7d=lXJ@H!-xHaPSRtA(1~jg-mmD9D1+8 z13AE~?wWjbmlOXyoE}~0f^NB_P~Z;%$U?^Y ztjv=3lOrN9Cx;wqh#^fZ3Kz}@#oJOB{#*PWfoFM#=|}*DgF2JFFCEddu2`fNwY8v` z%u^IlyyP^wJ@t1nKK1Afp4M=4nS$x+%|Lx7Ge%asVrZ~Fn;wV;jxB(-9YUaa4~9<0 zTY9w&u=|?SiiCK#n;Rqa9{c`XAO`wJRZv{x5$NI;lhBQboP561^`d|SIY6n7dB@Q7 z3^w{bY>N{nj}%k+$?&vBp)Uyx^zpma-5h}RYF(BB!89x&#*k5JBGzTA@~}WqE8oV` z+_M1yTrCCOkd`^l1GUs=lucpTe#%Vhdx769oax$t4navg9WKD(>XCeo_Y6m4>&mVG zQ1PezR>>c^{ z$)p}8Rngv5fpUNjOD=D|)agCnj;$+Zm*oIu=l;v3GpOns$25v)2>axcb7AnpA4Qn- zeT$05n6FvkpO8DiU5hW2h0&Y_hTfF#KTxKna3p{PNTZQ(u{<7;(V!!Im^9L^f^}|_ z<6@R}Yu9o+K7>%9cz|{aSCpJ?VfMx%)u@vNo1yuR&e;e~rCc;;+v$_4rzYNB@CqXD z)!*YmMi#BXYPP4Fdf5AF)Nlvwz7IT2531$A#{chQxQJ)5PHC7~2nDY&#Q^B5S;lGY zDK?~t8$4h=9m~?-)(>dg(*Fy^w<~UKQDmd>aNPR^9!$DZbo^yDBV_S_sLL9fqzhkO zDY<15%s0iV($Qv6hHP9+A3uBc>1KcQFj6!zF|i+gqNI+<=NRtla2UuSLsjfM%x3km zCi>^2AjeKKUW!_g+|oo=CV4^mK!^G}NCc~m!y{Tf~3l+7Jqdl5`@_G zik?uS<(WMFeU>(Y&>W&?P>|?RqB52iMR6RzE90Uq_y_;r++jP1E>01ZG{FhIN9s22 zS|Ne40RQMd9HA&;+u|%RRu>;QIdyeElHAo%R88mhQ$xS+90%^B%y(1X%`^n=LX5oX zj_3;pm{PM6gg2NwZ)Lvg>1M*P2E#rwDrFef-k-*keaAU)b_FVA+#GB$ zZAYJosrzK>cJ1hNJzx3!R$^jxkl%wOImVx6ivYQ65xt~L?+Fl+P;>;l)|VvPgs?PP zqJ24aXVo?X177+qK~0VZS@-+LZTi%`bdL}~mBT$6LWX;6)4LDx1^w^;cYS=!Km0C- z3#tpC&kzsd)Cw*-vS_1NyF%3as)3jnGN_Y3`^wP}L5D2Wj<*GiSK=^bVbtu&xZKlC z8Pofj$X$hKZfpHVSw-A@H&<+Ed;mgzx6u^%Y}MbJ+|&M(G}@KVA%H-sqA;K(mBTct zVZCi#rQwA$w*LmQ=m>mUk>J1Nb@mUD;n3%J<+4hOC{&KJtG$UddO{L#tniiYfxBoN zl(fU0cs-YlI_5qeqwW75TrMUZ4Rs9c(L%8an{GeMwpS`?BbhJL=S=T3IPiFS+OGK?r~}hWI@7dH(Pr zIoCxv4=F)qBRBU_ z*jgd>0nyxGJzRN9=8pgdA9Vue0w|mguJvi}4LmZ`8agGjs#B7I0)-JrT(0cZ9x;L1 zJ4SOK#xDI3rfpOf?#>1;-UOE_z8stVi2j)kd^W=OY1m|MAZ{TGeIFGMw!dDe;Ng`D zCpwn7OR8alj~AoWx0H!ickzY$wtWbQUZGv+YtJT9_lay?*>&`oN}lW)Z3J^2*_qX! zPm~;^f2MJhQqq|2$dpPMfYUgh$@aE%jnTn~s+D8I#z>==gdBc`EesEDy`WQ?Fibs4 z@fNK5S#6`rbYV?H)b#=t)wGu09nOT{8|wu#1&@Cwd;R)?{(=?wCP&%DcYp6j#qa^p z5!p^upfLDX(6MKV=1zz}R(h5OSiqkB$K;A|oL^ceo6CmFlj0Ghf5vc=uH?nqodk() zf1C0b?{5jt4RHKDD`b!L0Q5X51_Tj#)BC6V{W_1p$nke#tqo!-<$}inCcr}|>TPmS zn9;yR5=IdP@O61=>X)gqP+rpL>DVlzfbpT-a9u9Pu+_Pt&7-YSCP>5p@Cg+w&r=5P z{141~6^ae-7kU*VfO~$2U`}=FV11`Qn2$iPt`E*=5r>8is$wqxrPAF@Zc+`8*ev6h z_i#Ca%@GGR{6~lVs}LQU(cGl(5oQdozG^$LR3oHi;3(XVGfR^BqLmNu7KImgRkaqz z>i@&kCY1j>@R);WUn_nASnqW^X*Bl)sc_zrsms$e8^dIOAjb87YA}6`?BD}t)p z58a;RIm_9&4+ZS@2^%NJM(Py@@Bta(6=o&fL9PyNbGhp10mWIM=C%4p4<$P$`RXef zV4}KuL-4fPzY89dX=(RTj;5C%v;F*%`Y!(J3GV3~JZ4XE&g;dCy!EksXP_%3_>3f5 zB4y^1`1lz=uwSu$=9x`e$Fk!S);~4fp?5Ogr8KF8KI^8hL~P^5RQK9^>XlpEYn9L^mvl z{+_X3;H?X9AagH?;VPJy)q8YnQ&2l)ca)|gT{`fhI^4o2w*-je$L7OKJ`oc{dbahK z{M!mf)I?osI2+Cgb@TM`gcDtO^8m;2|NrmHL4+-z=J|(y23_ELK|FnJW34Y5km&yf DUcm-A literal 0 HcmV?d00001