From 37b44c1ec337bdf1a1be19e6d7a3024bcf3f12ac Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 6 May 2021 14:37:39 -0700 Subject: [PATCH 001/163] use tap 15 --- .gitignore | 1 + README.md | 2 +- package-lock.json | 10335 ++++++++++++++++++++++++++++---------- package.json | 9 +- test/00-setup.js | 6 +- test/bash-comparison.js | 4 +- test/broken-symlink.js | 4 +- test/cwd-test.js | 20 +- test/follow.js | 4 +- test/mark.js | 8 +- test/pause-resume.js | 4 +- test/root-nomount.js | 12 +- test/root.js | 12 +- test/zz-cleanup.js | 10 +- 14 files changed, 7707 insertions(+), 2724 deletions(-) diff --git a/.gitignore b/.gitignore index bcafea68..06cc0e0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .*.swp +/*.tap node_modules/* v8.log profile.txt diff --git a/README.md b/README.md index 0916a482..2dde30a5 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Match files using the patterns the shell uses, like stars and stuff. This is a glob implementation in JavaScript. It uses the `minimatch` library to do its matching. -![](logo/glob.png) +![a fun cartoon logo made of glob characters](logo/glob.png) ## Usage diff --git a/package-lock.json b/package-lock.json index 64c08b26..017381ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,3493 +1,8217 @@ { "name": "glob", "version": "7.1.6", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "packages": { + "": { + "version": "7.1.6", + "license": "ISC", + "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" + }, + "devDependencies": { + "mkdirp": "0", + "rimraf": "^2.2.8", + "tap": "^15.0.6", + "tick": "0.0.6" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", + "dependencies": { + "@babel/highlight": "^7.12.13" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz", + "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==", + "dev": true + }, + "node_modules/@babel/core": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.0.tgz", + "integrity": "sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.0", + "@babel/helper-compilation-targets": "^7.13.16", + "@babel/helper-module-transforms": "^7.14.0", + "@babel/helpers": "^7.14.0", + "@babel/parser": "^7.14.0", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", + "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.1", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", + "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.12.13" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.13.12" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.13.12" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz", + "integrity": "sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.14.0", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.12.13" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.13.12" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.12.13" + } + }, + "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/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "dev": true + }, + "node_modules/@babel/helpers": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz", + "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" + } + }, + "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/parser": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", + "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.2" + } + }, + "node_modules/@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "node_modules/@babel/traverse": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz", + "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.0", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.14.0", + "@babel/types": "^7.14.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "node_modules/@babel/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", + "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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.3.0" + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "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/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.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, - "argparse": { + "node_modules/arg": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", + "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==", + "dev": true, + "optional": true, + "peer": true + }, + "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, - "requires": { + "dependencies": { "sprintf-js": "~1.0.2" } }, - "asn1": { + "node_modules/asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, - "requires": { + "dependencies": { "safer-buffer": "~2.1.0" } }, - "assert-plus": { + "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8" + } }, - "asynckit": { + "node_modules/async-hook-domain": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.3.tgz", + "integrity": "sha512-MadiLLDEZRZzZwcm0dgS+K99qXZ4H2saAUwUgwzFulbAkXrKi3AX5FvWS3FFTQtLMwrqcGqAJe6o12KrObejQA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "aws-sign2": { + "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, - "balanced-match": { + "node_modules/balanced-match": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" }, - "bcrypt-pbkdf": { + "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, - "optional": true, - "requires": { + "dependencies": { "tweetnacl": "^0.14.3" } }, - "bind-obj-methods": { + "node_modules/binary-extensions": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.0.tgz", - "integrity": "sha512-3/qRXczDi2Cdbz6jE+W3IflJOutRVica8frpBn14de1mBOkzDo+6tY33kNhvkw54Kn3PzRRD2VnGbGPcTAk4sw==", - "dev": true + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true + "node_modules/bind-obj-methods": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-3.0.0.tgz", + "integrity": "sha512-nLEaaz3/sEzNSyPWRsN9HNsqwk1AUyECtGj+XwGdIi3xABnEqecvXtIJ0wehQXuuER5uZ/5fTs2usONgYjG+iw==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", - "requires": { + "dependencies": { "balanced-match": "^0.4.1", "concat-map": "0.0.1" } }, - "buffer-from": { + "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/browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, - "byline": { + "node_modules/byline": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/byline/-/byline-2.0.3.tgz", "integrity": "sha1-gRskuHScHN0dJrWbd/zBnT4Nhsk=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001223", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz", + "integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==", "dev": true }, - "caseless": { + "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "clean-yaml-object": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", - "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", - "dev": true + "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/chokidar": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "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.3.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.2" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "dependencies": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.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" + } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "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 }, - "color-support": { + "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "requires": { + "dependencies": { "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "concat-map": { + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "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=" }, - "core-util-is": { + "node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "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 }, - "coveralls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.2.tgz", - "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==", + "node_modules/coveralls": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz", + "integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==", "dev": true, - "requires": { - "growl": "~> 1.10.0", - "js-yaml": "^3.11.0", - "lcov-parse": "^0.0.10", + "dependencies": { + "js-yaml": "^3.13.1", + "lcov-parse": "^1.0.0", "log-driver": "^1.2.7", - "minimist": "^1.2.0", - "request": "^2.85.0" + "minimist": "^1.2.5", + "request": "^2.88.2" }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "bin": { + "coveralls": "bin/coveralls.js" + }, + "engines": { + "node": ">=6" } }, - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "node_modules/coveralls/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/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "dashdash": { + "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, - "requires": { + "dependencies": { "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, - "requires": { - "ms": "2.0.0" + "dependencies": { + "ms": "^2.1.1" } }, - "delayed-stream": { + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", - "dev": true + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } }, - "ecc-jsbn": { + "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, - "optional": true, - "requires": { + "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, - "escape-string-regexp": { + "node_modules/electron-to-chromium": { + "version": "1.3.727", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", + "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==", + "dev": true + }, + "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/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "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": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "esprima": { + "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 + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "events-to-array": { + "node_modules/events-to-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", "dev": true }, - "extend": { + "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, - "extsprintf": { + "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.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 }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "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 }, - "fast-json-stable-stringify": { + "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-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/findit": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz", + "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", "dev": true }, - "foreground-child": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "node_modules/flow-parser": { + "version": "0.117.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.117.0.tgz", + "integrity": "sha512-B9wlFfFtE9R9+lvhfShHIuE1eGLfTmMDUxIBU3NfbVynVzB2LNT38A5xBUURW5AYlkJveIlCcEsouOsro/DNWg==", "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.0" } }, - "forever-agent": { + "node_modules/flow-remove-types": { + "version": "2.117.0", + "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.117.0.tgz", + "integrity": "sha512-qcHEALIeD7oDixDWK+yRiuC0wM/kc01p+lb1hcALb3cLfOrDIMTWHq2QisRqYWhSetfi7U3y2mwqVcsmumt3lw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "flow-parser": "^0.117.0", + "pirates": "^3.0.2", + "vlq": "^0.2.1" + }, + "bin": { + "flow-node": "flow-node", + "flow-remove-types": "flow-remove-types" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, - "requires": { + "dependencies": { "asynckit": "^0.4.0", - "combined-stream": "1.0.6", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" } }, - "fs-exists-cached": { + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "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/fs-exists-cached": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", "dev": true }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "function-loop": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-1.0.1.tgz", - "integrity": "sha1-gHa7MF6OajzO7ikgdl8zDRkPNAw=", + "node_modules/fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-loop": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-2.0.1.tgz", + "integrity": "sha512-ktIR+O6i/4h+j/ZhZJNdzeI4i9lEPeEK6UPR2EVyTVBqOwcU3Za9xYKLH64ZR9HmcROyRrOkizNyjjtWJzDDkQ==", "dev": true }, - "getpass": { + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, - "requires": { + "dependencies": { "assert-plus": "^1.0.0" } }, - "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, - "requires": { + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.2", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true + "node_modules/glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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 }, - "har-schema": { + "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "har-validator": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", "dev": true, - "requires": { - "ajv": "^5.3.0", + "dependencies": { + "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "http-signature": { + "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/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, - "requires": { + "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" } }, - "imurmurhash": { + "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.19" + } }, - "inflight": { + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "is-typedarray": { + "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": "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/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-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, - "optional": true + "engines": { + "node": ">=0.10.0" + } }, - "isexe": { + "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 }, - "isstream": { + "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, - "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "engines": { + "node": ">=8" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", "dev": true, - "optional": true + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/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/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/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/istanbul-lib-report/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/istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.0.tgz", + "integrity": "sha512-VDcSunT+wcccoG46FtzuBAyQKlzhHjli4q31e1fIHGOsRspqNUFjVzGb+7eIFDlTvqLygxapDHPHS0ouT2o/tw==", + "dev": true, + "dependencies": { + "cliui": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "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 }, - "json-stringify-safe": { + "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/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "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-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, - "jsprim": { + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5/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/jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, - "requires": { + "engines": [ + "node >=0.6.0" + ], + "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" } }, - "lcov-parse": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", - "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", + "node_modules/lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", + "dev": true, + "bin": { + "lcov-parse": "bin/cli.js" + } + }, + "node_modules/libtap": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.1.tgz", + "integrity": "sha512-Fye8fh1+G7E8qqmjQaY+pXGxy7HM0S6bqCCJFLa16+g2jODBByxbJFDpjbDNF69wfRVyvJ+foLZc1WTIv7dx+g==", + "dev": true, + "dependencies": { + "async-hook-domain": "^2.0.1", + "bind-obj-methods": "^3.0.0", + "diff": "^4.0.2", + "function-loop": "^2.0.1", + "minipass": "^3.1.1", + "own-or": "^1.0.0", + "own-or-env": "^1.0.1", + "signal-exit": "^3.0.2", + "stack-utils": "^2.0.1", + "tap-parser": "^10.0.1", + "tap-yaml": "^1.0.0", + "tcompare": "^5.0.1", + "trivial-deferred": "^1.0.1", + "yapool": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, - "log-driver": { + "node_modules/log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.6" + } }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" } }, - "mime-db": { - "version": "1.36.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", - "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==", - "dev": true + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "mime-types": { - "version": "2.1.20", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", - "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", + "node_modules/make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", "dev": true, - "requires": { - "mime-db": "~1.36.0" + "optional": true, + "peer": true + }, + "node_modules/mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "dev": true, + "engines": { + "node": ">= 0.6" } }, - "minimatch": { + "node_modules/mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "dev": true, + "dependencies": { + "mime-db": "1.47.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "minimist": { + "node_modules/minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, - "minipass": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.4.tgz", - "integrity": "sha512-mlouk1OHlaUE8Odt1drMtG1bAJA4ZA6B/ehysgV0LUIrDHdKgo1KorZq3pK0b/7Z7LJIQ12MNM6aC+Tn6lUZ5w==", + "node_modules/minipass": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - }, "dependencies": { - "yallist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", - "dev": true - } + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "mkdirp": { + "node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, - "requires": { + "dependencies": { "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "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 }, - "nyc": { - "version": "11.9.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.9.0.tgz", - "integrity": "sha512-w8OdJAhXL5izerzZMdqzYKMj/pgHJyY3qEPYBjLLxrhcVoHEY9pU5ENIiZyCgG9OR7x3VcUMoD40o6PtVpfR4g==", + "node_modules/node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", "dev": true, - "requires": { - "archy": "^1.0.0", - "arrify": "^1.0.1", - "caching-transform": "^1.0.0", - "convert-source-map": "^1.5.1", - "debug-log": "^1.0.1", - "default-require-extensions": "^1.0.0", - "find-cache-dir": "^0.1.1", - "find-up": "^2.1.0", - "foreground-child": "^1.5.3", - "glob": "^7.0.6", - "istanbul-lib-coverage": "^1.1.2", - "istanbul-lib-hook": "^1.1.0", - "istanbul-lib-instrument": "^1.10.0", - "istanbul-lib-report": "^1.1.3", - "istanbul-lib-source-maps": "^1.2.3", - "istanbul-reports": "^1.4.0", - "md5-hex": "^1.2.0", - "merge-source-map": "^1.1.0", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.0", - "resolve-from": "^2.0.0", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.1", - "spawn-wrap": "^1.4.2", - "test-exclude": "^4.2.0", - "yargs": "11.1.0", - "yargs-parser": "^8.0.0" - }, - "dependencies": { - "align-text": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "amdefine": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "bundled": true, - "dev": true - }, - "append-transform": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "requires": { - "default-require-extensions": "^1.0.0" - } - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "arr-diff": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "bundled": true, - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "async": { - "version": "1.5.2", - "bundled": true, - "dev": true - }, - "atob": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-generator": { - "version": "6.26.1", - "bundled": true, - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-runtime": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "bundled": true, - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "base": { - "version": "0.11.2", - "bundled": true, - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "builtin-modules": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } - } - }, - "caching-transform": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "md5-hex": "^1.2.0", - "mkdirp": "^0.5.1", - "write-file-atomic": "^1.1.4" - } - }, - "camelcase": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true - }, - "center-align": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "class-utils": { - "version": "0.3.6", - "bundled": true, - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } - } - }, - "cliui": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "commondir": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "convert-source-map": { - "version": "1.5.1", - "bundled": true, - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "core-js": { - "version": "2.5.6", - "bundled": true, - "dev": true - }, - "cross-spawn": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "debug-log": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "bundled": true, - "dev": true - }, - "default-require-extensions": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "strip-bom": "^2.0.0" - } - }, - "define-property": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "detect-indent": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "error-ex": { - "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "esutils": { - "version": "2.0.2", - "bundled": true, - "dev": true - }, - "execa": { - "version": "0.7.0", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "bundled": true, - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "fill-range": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-cache-dir": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "requires": { - "commondir": "^1.0.1", - "mkdirp": "^0.5.1", - "pkg-dir": "^1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "for-in": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "foreground-child": { - "version": "1.5.6", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "fragment-cache": { - "version": "0.2.1", - "bundled": true, - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "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/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/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/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "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=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/opener": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", + "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/own-or": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", + "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=", + "dev": true + }, + "node_modules/own-or-env": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", + "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", + "dev": true, + "dependencies": { + "own-or": "^1.0.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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=", + "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/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", + "dev": true, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/pirates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", + "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "node-modules-regexp": "^1.0.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "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/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/react": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", + "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "dev": true + }, + "node_modules/readdirp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", + "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.0.7" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "dev": true, + "dependencies": { + "glob": "^7.0.5" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "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/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-wrap/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/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/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/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/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/tap": { + "version": "15.0.6", + "resolved": "https://registry.npmjs.org/tap/-/tap-15.0.6.tgz", + "integrity": "sha512-f3LaBSGgXkwTh17Lj4H4DxKIl4BrDZlmxWHtLVGwl8vx+XxNKvf0qMbeFLVhsVTRVz9E5yTaSUweB00YcO+TMw==", + "bundleDependencies": [ + "ink", + "treport", + "@types/react" + ], + "dev": true, + "dependencies": { + "@types/react": "^16.9.23", + "chokidar": "^3.3.0", + "coveralls": "^3.0.11", + "findit": "^2.0.0", + "foreground-child": "^2.0.0", + "fs-exists-cached": "^1.0.0", + "glob": "^7.1.6", + "import-jsx": "^4.0.0", + "ink": "^2.7.1", + "isexe": "^2.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "jackspeak": "^1.4.0", + "libtap": "^1.1.1", + "minipass": "^3.1.1", + "mkdirp": "^1.0.4", + "nyc": "^15.1.0", + "opener": "^1.5.1", + "react": "^16.12.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.0", + "source-map-support": "^0.5.16", + "tap-mocha-reporter": "^5.0.0", + "tap-parser": "^10.0.1", + "tap-yaml": "^1.0.0", + "tcompare": "^5.0.4", + "treport": "^2.0.1", + "which": "^2.0.2" + }, + "bin": { + "tap": "bin/run.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "peerDependencies": { + "flow-remove-types": ">=2.112.0", + "ts-node": ">=8.5.2", + "typescript": ">=3.7.2" + }, + "peerDependenciesMeta": { + "flow-remove-types": { + "optional": true }, - "get-caller-file": { - "version": "1.0.2", - "bundled": true, - "dev": true + "ts-node": { + "optional": true }, - "get-stream": { - "version": "3.0.0", - "bundled": true, + "typescript": { + "optional": true + } + } + }, + "node_modules/tap-mocha-reporter": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.1.tgz", + "integrity": "sha512-1knFWOwd4khx/7uSEnUeaP9IPW3w+sqTgJMhrwah6t46nZ8P25atOKAjSvVDsT67lOPu0nfdOqUwoyKn+3E5pA==", + "dev": true, + "dependencies": { + "color-support": "^1.1.0", + "debug": "^4.1.1", + "diff": "^4.0.1", + "escape-string-regexp": "^2.0.0", + "glob": "^7.0.5", + "tap-parser": "^10.0.0", + "tap-yaml": "^1.0.0", + "unicode-length": "^2.0.2" + }, + "bin": { + "tap-mocha-reporter": "index.js" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tap-mocha-reporter/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap-parser": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.0.1.tgz", + "integrity": "sha512-qdT15H0DoJIi7zOqVXDn9X0gSM68JjNy1w3VemwTJlDnETjbi6SutnqmBfjDJAwkFS79NJ97gZKqie00ZCGmzg==", + "dev": true, + "dependencies": { + "events-to-array": "^1.0.1", + "minipass": "^3.0.0", + "tap-yaml": "^1.0.0" + }, + "bin": { + "tap-parser": "bin/cmd.js" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tap-yaml": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", + "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", + "dev": true, + "dependencies": { + "yaml": "^1.5.0" + } + }, + "node_modules/tap/node_modules/@babel/code-frame": { + "version": "7.12.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.12.13" + } + }, + "node_modules/tap/node_modules/@babel/compat-data": { + "version": "7.13.12", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/@babel/core": { + "version": "7.13.14", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.10", + "@babel/parser": "^7.13.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/tap/node_modules/@babel/generator": { + "version": "7.13.9", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.13.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "node_modules/tap/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.12.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.12.13" + } + }, + "node_modules/tap/node_modules/@babel/helper-compilation-targets": { + "version": "7.13.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.13.12", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/tap/node_modules/@babel/helper-function-name": { + "version": "7.12.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "node_modules/tap/node_modules/@babel/helper-get-function-arity": { + "version": "7.12.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.12.13" + } + }, + "node_modules/tap/node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.13.12" + } + }, + "node_modules/tap/node_modules/@babel/helper-module-imports": { + "version": "7.13.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.13.12" + } + }, + "node_modules/tap/node_modules/@babel/helper-module-transforms": { + "version": "7.13.14", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" + } + }, + "node_modules/tap/node_modules/@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.12.13" + } + }, + "node_modules/tap/node_modules/@babel/helper-plugin-utils": { + "version": "7.13.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/@babel/helper-replace-supers": { + "version": "7.13.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "node_modules/tap/node_modules/@babel/helper-simple-access": { + "version": "7.13.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.13.12" + } + }, + "node_modules/tap/node_modules/@babel/helper-split-export-declaration": { + "version": "7.12.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.12.13" + } + }, + "node_modules/tap/node_modules/@babel/helper-validator-identifier": { + "version": "7.12.11", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/@babel/helper-validator-option": { + "version": "7.12.17", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/@babel/helpers": { + "version": "7.13.10", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" + } + }, + "node_modules/tap/node_modules/@babel/highlight": { + "version": "7.13.10", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "node_modules/tap/node_modules/@babel/parser": { + "version": "7.13.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/tap/node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.13.8", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.13.8", + "@babel/helper-compilation-targets": "^7.13.8", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/tap/node_modules/@babel/plugin-syntax-jsx": { + "version": "7.12.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/tap/node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/tap/node_modules/@babel/plugin-transform-destructuring": { + "version": "7.13.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/tap/node_modules/@babel/plugin-transform-parameters": { + "version": "7.13.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/tap/node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.13.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-jsx": "^7.12.13", + "@babel/types": "^7.13.12" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/tap/node_modules/@babel/template": { + "version": "7.12.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "node_modules/tap/node_modules/@babel/traverse": { + "version": "7.13.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.13", + "@babel/types": "^7.13.13", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "node_modules/tap/node_modules/@babel/types": { + "version": "7.13.14", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/tap/node_modules/@types/prop-types": { + "version": "15.7.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/@types/react": { + "version": "16.14.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/tap/node_modules/@types/scheduler": { + "version": "0.16.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/@types/yoga-layout": { + "version": "1.9.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/ansi-escapes": { + "version": "4.3.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tap/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/ansicolors": { + "version": "0.3.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/arrify": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/astral-regex": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/auto-bind": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tap/node_modules/balanced-match": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/tap/node_modules/browserslist": { + "version": "4.16.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001181", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.649", + "escalade": "^3.1.1", + "node-releases": "^1.1.70" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/tap/node_modules/caller-callsite": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/caller-path": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/callsites": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/caniuse-lite": { + "version": "1.0.30001204", + "dev": true, + "inBundle": true, + "license": "CC-BY-4.0" + }, + "node_modules/tap/node_modules/cardinal": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "node_modules/tap/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/ci-info": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/cli-cursor": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/cli-truncate": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tap/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/tap/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/colorette": { + "version": "1.2.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/commondir": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/convert-source-map": { + "version": "1.7.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/tap/node_modules/csstype": { + "version": "3.0.7", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/debug": { + "version": "4.3.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/tap/node_modules/electron-to-chromium": { + "version": "1.3.703", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/escalade": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tap/node_modules/esprima": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/events-to-array": { + "version": "1.1.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/find-cache-dir": { + "version": "3.3.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/tap/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/tap/node_modules/glob": { + "version": "7.1.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "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/tap/node_modules/globals": { + "version": "11.12.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/import-jsx": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.5.5", + "@babel/plugin-proposal-object-rest-spread": "^7.5.5", + "@babel/plugin-transform-destructuring": "^7.5.0", + "@babel/plugin-transform-react-jsx": "^7.3.0", + "caller-path": "^2.0.0", + "find-cache-dir": "^3.2.0", + "make-dir": "^3.0.2", + "resolve-from": "^3.0.0", + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tap/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/tap/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/ink": { + "version": "2.7.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "arrify": "^2.0.1", + "auto-bind": "^4.0.0", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "is-ci": "^2.0.0", + "lodash.throttle": "^4.1.1", + "log-update": "^3.0.0", + "prop-types": "^15.6.2", + "react-reconciler": "^0.24.0", + "scheduler": "^0.18.0", + "signal-exit": "^3.0.2", + "slice-ansi": "^3.0.0", + "string-length": "^3.1.0", + "widest-line": "^3.1.0", + "wrap-ansi": "^6.2.0", + "yoga-layout-prebuilt": "^1.9.3" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "@types/react": ">=16.8.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/tap/node_modules/ink/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/tap/node_modules/ink/node_modules/chalk": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/ink/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/tap/node_modules/ink/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/ink/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/ink/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/is-ci": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/tap/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/js-tokens": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/jsesc": { + "version": "2.5.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/json5": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/lodash.throttle": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/log-update": { + "version": "3.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^3.2.0", + "cli-cursor": "^2.1.0", + "wrap-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tap/node_modules/log-update/node_modules/ansi-escapes": { + "version": "3.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/log-update/node_modules/ansi-regex": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/log-update/node_modules/cli-cursor": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/log-update/node_modules/emoji-regex": { + "version": "7.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/log-update/node_modules/mimic-fn": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/log-update/node_modules/onetime": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/log-update/node_modules/restore-cursor": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/log-update/node_modules/string-width": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/log-update/node_modules/strip-ansi": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/log-update/node_modules/wrap-ansi": { + "version": "5.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/loose-envify": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/tap/node_modules/make-dir": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tap/node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/minimatch": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tap/node_modules/minimist": { + "version": "1.2.5", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/minipass": { + "version": "3.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tap/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/node-releases": { + "version": "1.1.71", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/once": { + "version": "1.4.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/tap/node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tap/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tap/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/pkg-dir": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/prop-types": { + "version": "15.7.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "node_modules/tap/node_modules/punycode": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/react-is": { + "version": "16.13.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/react-reconciler": { + "version": "0.24.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.18.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^16.0.0" + } + }, + "node_modules/tap/node_modules/redeyed": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/tap/node_modules/resolve-from": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/restore-cursor": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tap/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/scheduler": { + "version": "0.18.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/tap/node_modules/semver": { + "version": "6.3.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/tap/node_modules/signal-exit": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/slice-ansi": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/tap/node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/tap/node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/source-map": { + "version": "0.5.7", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/string-length": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/string-length/node_modules/ansi-regex": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/string-length/node_modules/astral-regex": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/string-length/node_modules/strip-ansi": { + "version": "5.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tap/node_modules/string-width": { + "version": "4.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/tap-parser": { + "version": "10.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "events-to-array": "^1.0.1", + "minipass": "^3.0.0", + "tap-yaml": "^1.0.0" + }, + "bin": { + "tap-parser": "bin/cmd.js" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tap/node_modules/tap-yaml": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yaml": "^1.5.0" + } + }, + "node_modules/tap/node_modules/to-fast-properties": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tap/node_modules/treport": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cardinal": "^2.1.1", + "chalk": "^3.0.0", + "import-jsx": "^4.0.0", + "ink": "^2.6.0", + "ms": "^2.1.2", + "string-length": "^3.1.0", + "tap-parser": "^10.0.1", + "unicode-length": "^2.0.2" + }, + "peerDependencies": { + "react": "^16.8.6" + } + }, + "node_modules/tap/node_modules/treport/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/tap/node_modules/treport/node_modules/chalk": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/treport/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/tap/node_modules/treport/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/treport/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/treport/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "inBundle": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tap/node_modules/unicode-length": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.0.0", + "strip-ansi": "^3.0.1" + } + }, + "node_modules/tap/node_modules/unicode-length/node_modules/ansi-regex": { + "version": "2.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/unicode-length/node_modules/strip-ansi": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tap/node_modules/widest-line": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/wrap-ansi": { + "version": "6.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/tap/node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/tap/node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/tap/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/yaml": { + "version": "1.10.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/tap/node_modules/yoga-layout-prebuilt": { + "version": "1.10.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@types/yoga-layout": "1.9.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tcompare": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.4.tgz", + "integrity": "sha512-worXBcrmLoFu9oJYAKznjPE89APTEXk/XCazuDuSQfK1EqX3bpLPW3cY/RQucbcc7mW+yKW0duujsuFlU7dRCA==", + "dev": true, + "dependencies": { + "diff": "^4.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tick": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tick/-/tick-0.0.6.tgz", + "integrity": "sha1-XvgPPRHheef+gRDMintvfF2hycQ=", + "dev": true, + "dependencies": { + "byline": "~2.0.3" + }, + "bin": { + "node-tick-processor": "bin/tickprocessor-driver.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/trivial-deferred": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.0.1.tgz", + "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", + "dev": true + }, + "node_modules/ts-node": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", + "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-script": "dist/script.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "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/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", + "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unicode-length": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz", + "integrity": "sha512-Ph/j1VbS3/r77nhoY2WU0GWGjVYOHL3xpKp0y/Eq2e5r0mT/6b649vm7KFO6RdAdrZkYLdxphYVgvODxPB+Ebg==", + "dev": true, + "dependencies": { + "punycode": "^2.0.0", + "strip-ansi": "^3.0.1" + } + }, + "node_modules/unicode-length/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unicode-length/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true, + "optional": true, + "peer": true + }, + "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/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", + "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.6.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yapool": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", + "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", + "dev": true + }, + "node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/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/yargs/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/yargs/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/yargs/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/yargs/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/yargs/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/yargs/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/yargs/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/compat-data": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz", + "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==", + "dev": true + }, + "@babel/core": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.0.tgz", + "integrity": "sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.0", + "@babel/helper-compilation-targets": "^7.13.16", + "@babel/helper-module-transforms": "^7.14.0", + "@babel/helpers": "^7.14.0", + "@babel/parser": "^7.14.0", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true - }, - "get-value": { - "version": "2.0.6", - "bundled": true, + } + } + }, + "@babel/generator": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", + "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.1", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "9.18.0", - "bundled": true, + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", + "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-transforms": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz", + "integrity": "sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.14.0", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@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 + }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz", + "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==", + "dev": true, + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" + } + }, + "@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", + "dev": true + }, + "@babel/runtime": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", + "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz", + "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.0", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.14.0", + "@babel/types": "^7.14.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", + "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "arg": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", + "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==", + "dev": true, + "optional": true, + "peer": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "async-hook-domain": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.3.tgz", + "integrity": "sha512-MadiLLDEZRZzZwcm0dgS+K99qXZ4H2saAUwUgwzFulbAkXrKi3AX5FvWS3FFTQtLMwrqcGqAJe6o12KrObejQA==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true + }, + "bind-obj-methods": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-3.0.0.tgz", + "integrity": "sha512-nLEaaz3/sEzNSyPWRsN9HNsqwk1AUyECtGj+XwGdIi3xABnEqecvXtIJ0wehQXuuER5uZ/5fTs2usONgYjG+iw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", + "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "requires": { + "balanced-match": "^0.4.1", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "byline": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/byline/-/byline-2.0.3.tgz", + "integrity": "sha1-gRskuHScHN0dJrWbd/zBnT4Nhsk=", + "dev": true + }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001223", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz", + "integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", + "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.3.0" + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "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 + }, + "coveralls": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz", + "integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==", + "dev": true, + "requires": { + "js-yaml": "^3.13.1", + "lcov-parse": "^1.0.0", + "log-driver": "^1.2.7", + "minimist": "^1.2.5", + "request": "^2.88.2" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true - }, - "handlebars": { - "version": "4.0.11", - "bundled": true, - "dev": true, - "requires": { - "async": "^1.4.0", - "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "bundled": true, - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "has-ansi": { - "version": "2.0.0", - "bundled": true, + } + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "requires": { + "strip-bom": "^4.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "electron-to-chromium": { + "version": "1.3.727", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", + "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "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 + }, + "events-to-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", + "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "findit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz", + "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", + "dev": true + }, + "flow-parser": { + "version": "0.117.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.117.0.tgz", + "integrity": "sha512-B9wlFfFtE9R9+lvhfShHIuE1eGLfTmMDUxIBU3NfbVynVzB2LNT38A5xBUURW5AYlkJveIlCcEsouOsro/DNWg==", + "dev": true, + "optional": true, + "peer": true + }, + "flow-remove-types": { + "version": "2.117.0", + "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.117.0.tgz", + "integrity": "sha512-qcHEALIeD7oDixDWK+yRiuC0wM/kc01p+lb1hcALb3cLfOrDIMTWHq2QisRqYWhSetfi7U3y2mwqVcsmumt3lw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "flow-parser": "^0.117.0", + "pirates": "^3.0.2", + "vlq": "^0.2.1" + } + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true + }, + "fs-exists-cached": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", + "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, + "function-loop": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-2.0.1.tgz", + "integrity": "sha512-ktIR+O6i/4h+j/ZhZJNdzeI4i9lEPeEK6UPR2EVyTVBqOwcU3Za9xYKLH64ZR9HmcROyRrOkizNyjjtWJzDDkQ==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "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 + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + } + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "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, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "glob": "^7.1.3" } - }, + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { "has-flag": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "has-value": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hosted-git-info": { - "version": "2.6.0", - "bundled": true, - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "invariant": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "bundled": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "is-accessor-descriptor": { - "version": "0.1.6", - "bundled": true, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "kind-of": "^3.0.2" + "has-flag": "^4.0.0" } - }, - "is-arrayish": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "bundled": true, + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jackspeak": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.0.tgz", + "integrity": "sha512-VDcSunT+wcccoG46FtzuBAyQKlzhHjli4q31e1fIHGOsRspqNUFjVzGb+7eIFDlTvqLygxapDHPHS0ouT2o/tw==", + "dev": true, + "requires": { + "cliui": "^4.1.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "bundled": true, - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "bundled": true, + } + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", + "dev": true + }, + "libtap": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.1.tgz", + "integrity": "sha512-Fye8fh1+G7E8qqmjQaY+pXGxy7HM0S6bqCCJFLa16+g2jODBByxbJFDpjbDNF69wfRVyvJ+foLZc1WTIv7dx+g==", + "dev": true, + "requires": { + "async-hook-domain": "^2.0.1", + "bind-obj-methods": "^3.0.0", + "diff": "^4.0.2", + "function-loop": "^2.0.1", + "minipass": "^3.1.1", + "own-or": "^1.0.0", + "own-or-env": "^1.0.1", + "signal-exit": "^3.0.2", + "stack-utils": "^2.0.1", + "tap-parser": "^10.0.1", + "tap-yaml": "^1.0.0", + "tcompare": "^5.0.1", + "trivial-deferred": "^1.0.1", + "yapool": "^1.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true, + "optional": true, + "peer": true + }, + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "dev": true + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "dev": true, + "requires": { + "mime-db": "1.47.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "minipass": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true - }, - "is-finite": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "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-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true, + "optional": true, + "peer": true + }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "is-number": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-odd": { - "version": "2.0.0", - "bundled": true, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "bundled": true, - "dev": true - } + "glob": "^7.1.3" } - }, - "is-plain-object": { - "version": "2.0.4", - "bundled": true, + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", + "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "dev": true + }, + "own-or": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", + "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=", + "dev": true + }, + "own-or-env": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", + "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", + "dev": true, + "requires": { + "own-or": "^1.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", + "dev": true + }, + "pirates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", + "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "requires": { + "fromentries": "^1.2.0" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "react": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", + "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "dev": true + }, + "readdirp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", + "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.7" + } + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "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 + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } + "glob": "^7.1.3" } - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "isexe": { + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { "version": "2.0.0", - "bundled": true, - "dev": true - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "istanbul-lib-coverage": { - "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true - }, - "istanbul-lib-hook": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "append-transform": "^0.4.0" - } - }, - "istanbul-lib-instrument": { - "version": "1.10.1", + } + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tap": { + "version": "15.0.6", + "resolved": "https://registry.npmjs.org/tap/-/tap-15.0.6.tgz", + "integrity": "sha512-f3LaBSGgXkwTh17Lj4H4DxKIl4BrDZlmxWHtLVGwl8vx+XxNKvf0qMbeFLVhsVTRVz9E5yTaSUweB00YcO+TMw==", + "dev": true, + "requires": { + "@types/react": "^16.9.23", + "chokidar": "^3.3.0", + "coveralls": "^3.0.11", + "findit": "^2.0.0", + "foreground-child": "^2.0.0", + "fs-exists-cached": "^1.0.0", + "glob": "^7.1.6", + "import-jsx": "^4.0.0", + "ink": "^2.7.1", + "isexe": "^2.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "jackspeak": "^1.4.0", + "libtap": "^1.1.1", + "minipass": "^3.1.1", + "mkdirp": "^1.0.4", + "nyc": "^15.1.0", + "opener": "^1.5.1", + "react": "^16.12.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.0", + "source-map-support": "^0.5.16", + "tap-mocha-reporter": "^5.0.0", + "tap-parser": "^10.0.1", + "tap-yaml": "^1.0.0", + "tcompare": "^5.0.4", + "treport": "^2.0.1", + "which": "^2.0.2" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", "bundled": true, "dev": true, "requires": { - "babel-generator": "^6.18.0", - "babel-template": "^6.16.0", - "babel-traverse": "^6.18.0", - "babel-types": "^6.18.0", - "babylon": "^6.18.0", - "istanbul-lib-coverage": "^1.2.0", - "semver": "^5.3.0" + "@babel/highlight": "^7.12.13" } }, - "istanbul-lib-report": { - "version": "1.1.3", + "@babel/compat-data": { + "version": "7.13.12", "bundled": true, - "dev": true, - "requires": { - "istanbul-lib-coverage": "^1.1.2", - "mkdirp": "^0.5.1", - "path-parse": "^1.0.5", - "supports-color": "^3.1.2" - }, - "dependencies": { - "supports-color": { - "version": "3.2.3", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } + "dev": true }, - "istanbul-lib-source-maps": { - "version": "1.2.3", + "@babel/core": { + "version": "7.13.14", "bundled": true, "dev": true, "requires": { - "debug": "^3.1.0", - "istanbul-lib-coverage": "^1.1.2", - "mkdirp": "^0.5.1", - "rimraf": "^2.6.1", - "source-map": "^0.5.3" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.10", + "@babel/parser": "^7.13.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" } }, - "istanbul-reports": { - "version": "1.4.0", + "@babel/generator": { + "version": "7.13.9", "bundled": true, "dev": true, "requires": { - "handlebars": "^4.0.3" + "@babel/types": "^7.13.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" } }, - "js-tokens": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "jsesc": { - "version": "1.3.0", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "3.2.2", + "@babel/helper-annotate-as-pure": { + "version": "7.12.13", "bundled": true, "dev": true, "requires": { - "is-buffer": "^1.1.5" + "@babel/types": "^7.12.13" } }, - "lazy-cache": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "lcid": { - "version": "1.0.0", + "@babel/helper-compilation-targets": { + "version": "7.13.13", "bundled": true, "dev": true, "requires": { - "invert-kv": "^1.0.0" + "@babel/compat-data": "^7.13.12", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" } }, - "load-json-file": { - "version": "1.1.0", + "@babel/helper-function-name": { + "version": "7.12.13", "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" } }, - "locate-path": { - "version": "2.0.0", + "@babel/helper-get-function-arity": { + "version": "7.12.13", "bundled": true, "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - } + "@babel/types": "^7.12.13" } }, - "lodash": { - "version": "4.17.10", - "bundled": true, - "dev": true - }, - "longest": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "loose-envify": { - "version": "1.3.1", + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", "bundled": true, "dev": true, "requires": { - "js-tokens": "^3.0.0" + "@babel/types": "^7.13.12" } }, - "lru-cache": { - "version": "4.1.3", + "@babel/helper-module-imports": { + "version": "7.13.12", "bundled": true, "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "@babel/types": "^7.13.12" } }, - "map-cache": { - "version": "0.2.2", - "bundled": true, - "dev": true - }, - "map-visit": { - "version": "1.0.0", + "@babel/helper-module-transforms": { + "version": "7.13.14", "bundled": true, "dev": true, "requires": { - "object-visit": "^1.0.0" + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" } }, - "md5-hex": { - "version": "1.3.0", + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", "bundled": true, "dev": true, "requires": { - "md5-o-matic": "^0.1.1" + "@babel/types": "^7.12.13" } }, - "md5-o-matic": { - "version": "0.1.1", + "@babel/helper-plugin-utils": { + "version": "7.13.0", "bundled": true, "dev": true }, - "mem": { - "version": "1.1.0", + "@babel/helper-replace-supers": { + "version": "7.13.12", "bundled": true, "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" } }, - "merge-source-map": { - "version": "1.1.0", + "@babel/helper-simple-access": { + "version": "7.13.12", "bundled": true, "dev": true, "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } + "@babel/types": "^7.13.12" } }, - "micromatch": { - "version": "3.1.10", + "@babel/helper-split-export-declaration": { + "version": "7.12.13", "bundled": true, "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } + "@babel/types": "^7.12.13" } }, - "mimic-fn": { - "version": "1.2.0", + "@babel/helper-validator-identifier": { + "version": "7.12.11", "bundled": true, "dev": true }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", + "@babel/helper-validator-option": { + "version": "7.12.17", "bundled": true, "dev": true }, - "mixin-deep": { - "version": "1.3.1", + "@babel/helpers": { + "version": "7.13.10", "bundled": true, "dev": true, "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" } }, - "mkdirp": { - "version": "0.5.1", + "@babel/highlight": { + "version": "7.13.10", "bundled": true, "dev": true, "requires": { - "minimist": "0.0.8" + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" } }, - "ms": { - "version": "2.0.0", + "@babel/parser": { + "version": "7.13.13", "bundled": true, "dev": true }, - "nanomatch": { - "version": "1.2.9", - "bundled": true, - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-odd": "^2.0.0", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "normalize-package-data": { - "version": "2.4.0", + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.13.8", "bundled": true, "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "@babel/compat-data": "^7.13.8", + "@babel/helper-compilation-targets": "^7.13.8", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.13.0" } }, - "npm-run-path": { - "version": "2.0.2", + "@babel/plugin-syntax-jsx": { + "version": "7.12.13", "bundled": true, "dev": true, "requires": { - "path-key": "^2.0.0" + "@babel/helper-plugin-utils": "^7.12.13" } }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "object-copy": { - "version": "0.1.0", + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", "bundled": true, "dev": true, "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } + "@babel/helper-plugin-utils": "^7.8.0" } }, - "object-visit": { - "version": "1.0.1", + "@babel/plugin-transform-destructuring": { + "version": "7.13.0", "bundled": true, "dev": true, "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } + "@babel/helper-plugin-utils": "^7.13.0" } }, - "object.pick": { - "version": "1.3.0", + "@babel/plugin-transform-parameters": { + "version": "7.13.0", "bundled": true, "dev": true, "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } + "@babel/helper-plugin-utils": "^7.13.0" } }, - "once": { - "version": "1.4.0", + "@babel/plugin-transform-react-jsx": { + "version": "7.13.12", "bundled": true, "dev": true, "requires": { - "wrappy": "1" + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-jsx": "^7.12.13", + "@babel/types": "^7.13.12" } }, - "optimist": { - "version": "0.6.1", + "@babel/template": { + "version": "7.12.13", "bundled": true, "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, - "os-homedir": { - "version": "1.0.2", + "@babel/traverse": { + "version": "7.13.13", "bundled": true, - "dev": true + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.13", + "@babel/types": "^7.13.13", + "debug": "^4.1.0", + "globals": "^11.1.0" + } }, - "os-locale": { - "version": "2.1.0", + "@babel/types": { + "version": "7.13.14", "bundled": true, "dev": true, "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" } }, - "p-finally": { - "version": "1.0.0", + "@types/prop-types": { + "version": "15.7.3", "bundled": true, "dev": true }, - "p-limit": { - "version": "1.2.0", + "@types/react": { + "version": "16.14.5", "bundled": true, "dev": true, "requires": { - "p-try": "^1.0.0" + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" } }, - "p-locate": { - "version": "2.0.0", + "@types/scheduler": { + "version": "0.16.1", "bundled": true, - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } + "dev": true }, - "p-try": { - "version": "1.0.0", + "@types/yoga-layout": { + "version": "1.9.2", "bundled": true, "dev": true }, - "parse-json": { - "version": "2.2.0", + "ansi-escapes": { + "version": "4.3.2", "bundled": true, "dev": true, "requires": { - "error-ex": "^1.2.0" + "type-fest": "^0.21.3" } }, - "pascalcase": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "path-exists": { - "version": "2.1.0", + "ansi-styles": { + "version": "3.2.1", "bundled": true, "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "color-convert": "^1.9.0" } }, - "path-is-absolute": { - "version": "1.0.1", + "ansicolors": { + "version": "0.3.2", "bundled": true, "dev": true }, - "path-key": { + "arrify": { "version": "2.0.1", "bundled": true, "dev": true }, - "path-parse": { - "version": "1.0.5", + "astral-regex": { + "version": "2.0.0", "bundled": true, "dev": true }, - "path-type": { - "version": "1.1.0", + "auto-bind": { + "version": "4.0.0", "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } + "dev": true }, - "pify": { - "version": "2.3.0", + "balanced-match": { + "version": "1.0.0", "bundled": true, "dev": true }, - "pinkie": { - "version": "2.0.4", + "brace-expansion": { + "version": "1.1.11", "bundled": true, - "dev": true + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "pinkie-promise": { - "version": "2.0.1", + "browserslist": { + "version": "4.16.3", "bundled": true, "dev": true, "requires": { - "pinkie": "^2.0.0" + "caniuse-lite": "^1.0.30001181", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.649", + "escalade": "^3.1.1", + "node-releases": "^1.1.70" } }, - "pkg-dir": { - "version": "1.0.0", + "caller-callsite": { + "version": "2.0.0", "bundled": true, "dev": true, "requires": { - "find-up": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" } }, - "posix-character-classes": { - "version": "0.1.1", + "callsites": { + "version": "2.0.0", "bundled": true, "dev": true }, - "pseudomap": { - "version": "1.0.2", + "caniuse-lite": { + "version": "1.0.30001204", "bundled": true, "dev": true }, - "read-pkg": { - "version": "1.1.0", + "cardinal": { + "version": "2.1.1", "bundled": true, "dev": true, "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" } }, - "read-pkg-up": { - "version": "1.0.1", + "chalk": { + "version": "2.4.2", "bundled": true, "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "regenerator-runtime": { - "version": "0.11.1", + "ci-info": { + "version": "2.0.0", "bundled": true, "dev": true }, - "regex-not": { - "version": "1.0.2", + "cli-cursor": { + "version": "3.1.0", "bundled": true, "dev": true, "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "restore-cursor": "^3.1.0" } }, - "repeat-element": { - "version": "1.1.2", - "bundled": true, - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "bundled": true, - "dev": true - }, - "repeating": { - "version": "2.0.1", + "cli-truncate": { + "version": "2.1.0", "bundled": true, "dev": true, "requires": { - "is-finite": "^1.0.0" + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" } }, - "require-directory": { - "version": "2.1.1", + "color-convert": { + "version": "1.9.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "color-name": "1.1.3" + } }, - "require-main-filename": { - "version": "1.0.1", + "color-name": { + "version": "1.1.3", "bundled": true, "dev": true }, - "resolve-from": { - "version": "2.0.0", + "colorette": { + "version": "1.2.2", "bundled": true, "dev": true }, - "resolve-url": { - "version": "0.2.1", + "commondir": { + "version": "1.0.1", "bundled": true, "dev": true }, - "ret": { - "version": "0.1.15", + "concat-map": { + "version": "0.0.1", "bundled": true, "dev": true }, - "right-align": { - "version": "0.1.3", + "convert-source-map": { + "version": "1.7.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "align-text": "^0.1.1" + "safe-buffer": "~5.1.1" } }, - "rimraf": { - "version": "2.6.2", + "csstype": { + "version": "3.0.7", "bundled": true, - "dev": true, - "requires": { - "glob": "^7.0.5" - } + "dev": true }, - "safe-regex": { - "version": "1.1.0", + "debug": { + "version": "4.3.1", "bundled": true, "dev": true, "requires": { - "ret": "~0.1.10" + "ms": "2.1.2" } }, - "semver": { - "version": "5.5.0", + "electron-to-chromium": { + "version": "1.3.703", "bundled": true, "dev": true }, - "set-blocking": { - "version": "2.0.0", + "emoji-regex": { + "version": "8.0.0", "bundled": true, "dev": true }, - "set-value": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "shebang-command": { - "version": "1.2.0", + "escalade": { + "version": "3.1.1", "bundled": true, - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } + "dev": true }, - "shebang-regex": { - "version": "1.0.0", + "escape-string-regexp": { + "version": "1.0.5", "bundled": true, "dev": true }, - "signal-exit": { - "version": "3.0.2", + "esprima": { + "version": "4.0.1", "bundled": true, "dev": true }, - "slide": { - "version": "1.1.6", + "events-to-array": { + "version": "1.1.2", "bundled": true, "dev": true }, - "snapdragon": { - "version": "0.8.2", + "find-cache-dir": { + "version": "3.3.1", "bundled": true, "dev": true, "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" } }, - "snapdragon-node": { - "version": "2.1.1", + "find-up": { + "version": "4.1.0", "bundled": true, "dev": true, "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "snapdragon-util": { - "version": "3.0.1", + "fs.realpath": { + "version": "1.0.0", "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.2.0" - } + "dev": true }, - "source-map": { - "version": "0.5.7", + "gensync": { + "version": "1.0.0-beta.2", "bundled": true, "dev": true }, - "source-map-resolve": { - "version": "0.5.1", + "glob": { + "version": "7.1.6", "bundled": true, "dev": true, "requires": { - "atob": "^2.0.0", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "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" } }, - "source-map-url": { - "version": "0.4.0", + "globals": { + "version": "11.12.0", "bundled": true, "dev": true }, - "spawn-wrap": { - "version": "1.4.2", + "has-flag": { + "version": "3.0.0", "bundled": true, - "dev": true, - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - } + "dev": true }, - "spdx-correct": { - "version": "3.0.0", + "import-jsx": { + "version": "4.0.0", "bundled": true, "dev": true, "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "@babel/core": "^7.5.5", + "@babel/plugin-proposal-object-rest-spread": "^7.5.5", + "@babel/plugin-transform-destructuring": "^7.5.0", + "@babel/plugin-transform-react-jsx": "^7.3.0", + "caller-path": "^2.0.0", + "find-cache-dir": "^3.2.0", + "make-dir": "^3.0.2", + "resolve-from": "^3.0.0", + "rimraf": "^3.0.0" } }, - "spdx-exceptions": { - "version": "2.1.0", - "bundled": true, - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", + "inflight": { + "version": "1.0.6", "bundled": true, "dev": true, "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "spdx-license-ids": { - "version": "3.0.0", + "inherits": { + "version": "2.0.4", "bundled": true, "dev": true }, - "split-string": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "static-extend": { - "version": "0.1.2", + "ink": { + "version": "2.7.1", "bundled": true, "dev": true, "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "ansi-escapes": "^4.2.1", + "arrify": "^2.0.1", + "auto-bind": "^4.0.0", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "is-ci": "^2.0.0", + "lodash.throttle": "^4.1.1", + "log-update": "^3.0.0", + "prop-types": "^15.6.2", + "react-reconciler": "^0.24.0", + "scheduler": "^0.18.0", + "signal-exit": "^3.0.2", + "slice-ansi": "^3.0.0", + "string-length": "^3.1.0", + "widest-line": "^3.1.0", + "wrap-ansi": "^6.2.0", + "yoga-layout-prebuilt": "^1.9.3" }, "dependencies": { - "define-property": { - "version": "0.2.5", + "ansi-styles": { + "version": "4.3.0", "bundled": true, "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "color-convert": "^2.0.1" } - } - } - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { + }, + "chalk": { "version": "3.0.0", "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, "dev": true }, - "strip-ansi": { + "has-flag": { "version": "4.0.0", "bundled": true, + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "bundled": true, "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "has-flag": "^4.0.0" } } } }, - "strip-ansi": { - "version": "3.0.1", + "is-ci": { + "version": "2.0.0", "bundled": true, "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ci-info": "^2.0.0" } }, - "strip-bom": { - "version": "2.0.0", + "is-fullwidth-code-point": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "bundled": true, + "dev": true + }, + "json5": { + "version": "2.2.0", "bundled": true, "dev": true, "requires": { - "is-utf8": "^0.2.0" + "minimist": "^1.2.5" } }, - "strip-eof": { - "version": "1.0.0", + "locate-path": { + "version": "5.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", "bundled": true, "dev": true }, - "supports-color": { - "version": "2.0.0", + "lodash.throttle": { + "version": "4.1.1", "bundled": true, "dev": true }, - "test-exclude": { - "version": "4.2.1", + "log-update": { + "version": "3.4.0", "bundled": true, "dev": true, "requires": { - "arrify": "^1.0.1", - "micromatch": "^3.1.8", - "object-assign": "^4.1.0", - "read-pkg-up": "^1.0.1", - "require-main-filename": "^1.0.1" + "ansi-escapes": "^3.2.0", + "cli-cursor": "^2.1.0", + "wrap-ansi": "^5.0.0" }, "dependencies": { - "arr-diff": { - "version": "4.0.0", + "ansi-escapes": { + "version": "3.2.0", "bundled": true, "dev": true }, - "array-unique": { - "version": "0.3.2", + "ansi-regex": { + "version": "4.1.0", "bundled": true, "dev": true }, - "braces": { - "version": "2.3.2", + "cli-cursor": { + "version": "2.1.0", "bundled": true, "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "restore-cursor": "^2.0.0" } }, - "expand-brackets": { - "version": "2.1.4", + "emoji-regex": { + "version": "7.0.3", "bundled": true, - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "bundled": true, - "dev": true - } - } + "dev": true }, - "extglob": { - "version": "2.0.4", + "is-fullwidth-code-point": { + "version": "2.0.0", "bundled": true, - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } + "dev": true }, - "fill-range": { - "version": "4.0.0", + "mimic-fn": { + "version": "1.2.0", "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } + "dev": true }, - "is-accessor-descriptor": { - "version": "1.0.0", + "onetime": { + "version": "2.0.1", "bundled": true, "dev": true, "requires": { - "kind-of": "^6.0.0" + "mimic-fn": "^1.0.0" } }, - "is-data-descriptor": { - "version": "1.0.0", + "restore-cursor": { + "version": "2.0.0", "bundled": true, "dev": true, "requires": { - "kind-of": "^6.0.0" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" } }, - "is-descriptor": { - "version": "1.0.2", + "string-width": { + "version": "3.1.0", "bundled": true, "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, - "is-number": { - "version": "3.0.0", + "strip-ansi": { + "version": "5.2.0", "bundled": true, "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "ansi-regex": "^4.1.0" } }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - }, - "micromatch": { - "version": "3.1.10", + "wrap-ansi": { + "version": "5.1.0", "bundled": true, "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" } } } }, - "to-fast-properties": { - "version": "1.0.3", + "loose-envify": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", "bundled": true, "dev": true }, - "to-object-path": { - "version": "0.3.0", + "minimatch": { + "version": "3.0.4", "bundled": true, "dev": true, "requires": { - "kind-of": "^3.0.2" + "brace-expansion": "^1.1.7" } }, - "to-regex": { - "version": "3.0.2", + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "3.1.3", "bundled": true, "dev": true, "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "yallist": "^4.0.0" } }, - "to-regex-range": { - "version": "2.1.1", + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "node-releases": { + "version": "1.1.71", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", "bundled": true, "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - } + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.2.0" } }, - "trim-right": { + "p-try": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { "version": "1.0.1", "bundled": true, "dev": true }, - "uglify-js": { - "version": "2.8.29", + "pkg-dir": { + "version": "4.2.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "yargs": { - "version": "3.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } + "find-up": "^4.0.0" } }, - "uglify-to-browserify": { - "version": "1.0.2", + "prop-types": { + "version": "15.7.2", "bundled": true, "dev": true, - "optional": true + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } }, - "union-value": { - "version": "1.0.0", + "punycode": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "react-is": { + "version": "16.13.1", + "bundled": true, + "dev": true + }, + "react-reconciler": { + "version": "0.24.0", "bundled": true, "dev": true, "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.18.0" } }, - "unset-value": { - "version": "1.0.0", + "redeyed": { + "version": "2.1.1", "bundled": true, "dev": true, "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "bundled": true, - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } + "esprima": "~4.0.0" } }, - "urix": { - "version": "0.1.0", + "resolve-from": { + "version": "3.0.0", "bundled": true, "dev": true }, - "use": { + "restore-cursor": { "version": "3.1.0", "bundled": true, "dev": true, "requires": { - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" } }, - "validate-npm-package-license": { - "version": "3.0.3", + "rimraf": { + "version": "3.0.2", "bundled": true, "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "glob": "^7.1.3" } }, - "which": { - "version": "1.3.0", + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "scheduler": { + "version": "0.18.0", "bundled": true, "dev": true, "requires": { - "isexe": "^2.0.0" + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" } }, - "which-module": { - "version": "2.0.0", + "semver": { + "version": "6.3.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.3", "bundled": true, "dev": true }, - "window-size": { - "version": "0.1.0", + "slice-ansi": { + "version": "3.0.0", "bundled": true, "dev": true, - "optional": true + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, + "dev": true + } + } }, - "wordwrap": { - "version": "0.0.3", + "source-map": { + "version": "0.5.7", "bundled": true, "dev": true }, - "wrap-ansi": { - "version": "2.1.0", + "string-length": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "string-width": { + "version": "4.2.2", "bundled": true, "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", + "ansi-regex": { + "version": "5.0.0", "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } + "dev": true }, - "string-width": { - "version": "1.0.2", + "strip-ansi": { + "version": "6.0.0", "bundled": true, "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "ansi-regex": "^5.0.0" } } } }, - "wrappy": { - "version": "1.0.2", + "supports-color": { + "version": "5.5.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } }, - "write-file-atomic": { - "version": "1.3.4", + "tap-parser": { + "version": "10.1.0", "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" + "events-to-array": "^1.0.1", + "minipass": "^3.0.0", + "tap-yaml": "^1.0.0" } }, - "y18n": { - "version": "3.2.1", + "tap-yaml": { + "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "yaml": "^1.5.0" + } }, - "yallist": { - "version": "2.1.2", + "to-fast-properties": { + "version": "2.0.0", "bundled": true, "dev": true }, - "yargs": { - "version": "11.1.0", + "treport": { + "version": "2.0.1", "bundled": true, "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" + "cardinal": "^2.1.1", + "chalk": "^3.0.0", + "import-jsx": "^4.0.0", + "ink": "^2.6.0", + "ms": "^2.1.2", + "string-length": "^3.1.0", + "tap-parser": "^10.0.1", + "unicode-length": "^2.0.2" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "cliui": { - "version": "4.1.0", + "ansi-styles": { + "version": "4.3.0", "bundled": true, "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "color-convert": "^2.0.1" } }, - "strip-ansi": { - "version": "4.0.0", + "chalk": { + "version": "3.0.0", "bundled": true, "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "yargs-parser": { - "version": "9.0.2", + "color-convert": { + "version": "2.0.1", "bundled": true, "dev": true, "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "8.1.0", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "bundled": true, - "dev": true - } - } - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.0.tgz", - "integrity": "sha512-MD4s/o61y2slS27zm2s4229V2gAUHX0/e3/XOmY/jsXwhysjjCIHN8lx7gqZCrZk19ym+HjCUWHeMKD7YJtKCQ==", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "own-or": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", - "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=", - "dev": true - }, - "own-or-env": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", - "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", - "dev": true, - "requires": { - "own-or": "^1.0.0" - } - }, - "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=" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true, - "optional": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "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 - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", - "dev": true - }, - "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, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "tap": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/tap/-/tap-12.0.1.tgz", - "integrity": "sha512-iEJytWaZy8risvfRjuV4+ST+Lrrui/MW2ZCWn01ZaMn0NKFej4+PpBy6bXGOg9+cEGNmI7d3Sdka/zTUZUGidA==", - "dev": true, - "requires": { - "bind-obj-methods": "^2.0.0", - "bluebird": "^3.5.1", - "clean-yaml-object": "^0.1.0", - "color-support": "^1.1.0", - "coveralls": "^3.0.1", - "foreground-child": "^1.3.3", - "fs-exists-cached": "^1.0.0", - "function-loop": "^1.0.1", - "glob": "^7.0.0", - "isexe": "^2.0.0", - "js-yaml": "^3.11.0", - "minipass": "^2.3.0", - "mkdirp": "^0.5.1", - "nyc": "^11.8.0", - "opener": "^1.4.1", - "os-homedir": "^1.0.2", - "own-or": "^1.0.0", - "own-or-env": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.0", - "source-map-support": "^0.5.6", - "stack-utils": "^1.0.0", - "tap-mocha-reporter": "^3.0.7", - "tap-parser": "^7.0.0", - "tmatch": "^4.0.0", - "trivial-deferred": "^1.0.1", - "tsame": "^2.0.0", - "write-file-atomic": "^2.3.0", - "yapool": "^1.0.0" - }, - "dependencies": { - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "type-fest": { + "version": "0.21.3", + "bundled": true, + "dev": true + }, + "unicode-length": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "punycode": "^2.0.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "widest-line": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "bundled": true, + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yaml": { + "version": "1.10.2", + "bundled": true, + "dev": true + }, + "yoga-layout-prebuilt": { + "version": "1.10.0", + "bundled": true, "dev": true, "requires": { - "glob": "^7.0.5" + "@types/yoga-layout": "1.9.2" } } } }, "tap-mocha-reporter": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-3.0.7.tgz", - "integrity": "sha512-GHVXJ38C3oPRpM3YUc43JlGdpVZYiKeT1fmAd3HH2+J+ZWwsNAUFvRRdoGsXLw9+gU9o+zXpBqhS/oXyRQYwlA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.1.tgz", + "integrity": "sha512-1knFWOwd4khx/7uSEnUeaP9IPW3w+sqTgJMhrwah6t46nZ8P25atOKAjSvVDsT67lOPu0nfdOqUwoyKn+3E5pA==", "dev": true, "requires": { "color-support": "^1.1.0", - "debug": "^2.1.3", - "diff": "^1.3.2", - "escape-string-regexp": "^1.0.3", + "debug": "^4.1.1", + "diff": "^4.0.1", + "escape-string-regexp": "^2.0.0", "glob": "^7.0.5", - "js-yaml": "^3.3.1", - "readable-stream": "^2.1.5", - "tap-parser": "^5.1.0", - "unicode-length": "^1.0.0" + "tap-parser": "^10.0.0", + "tap-yaml": "^1.0.0", + "unicode-length": "^2.0.2" }, "dependencies": { - "tap-parser": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-5.4.0.tgz", - "integrity": "sha512-BIsIaGqv7uTQgTW1KLTMNPSEQf4zDDPgYOBRdgOfuB+JFOLRBfEu6cLa/KvMvmqggu1FKXDfitjLwsq4827RvA==", - "dev": true, - "requires": { - "events-to-array": "^1.0.1", - "js-yaml": "^3.2.7", - "readable-stream": "^2" - } + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true } } }, "tap-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz", - "integrity": "sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.0.1.tgz", + "integrity": "sha512-qdT15H0DoJIi7zOqVXDn9X0gSM68JjNy1w3VemwTJlDnETjbi6SutnqmBfjDJAwkFS79NJ97gZKqie00ZCGmzg==", "dev": true, "requires": { "events-to-array": "^1.0.1", - "js-yaml": "^3.2.7", - "minipass": "^2.2.0" + "minipass": "^3.0.0", + "tap-yaml": "^1.0.0" + } + }, + "tap-yaml": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", + "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", + "dev": true, + "requires": { + "yaml": "^1.5.0" + } + }, + "tcompare": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.4.tgz", + "integrity": "sha512-worXBcrmLoFu9oJYAKznjPE89APTEXk/XCazuDuSQfK1EqX3bpLPW3cY/RQucbcc7mW+yKW0duujsuFlU7dRCA==", + "dev": true, + "requires": { + "diff": "^4.0.2" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" } }, "tick": { @@ -3499,20 +8223,29 @@ "byline": "~2.0.3" } }, - "tmatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-4.0.0.tgz", - "integrity": "sha512-Ynn2Gsp+oCvYScQXeV+cCs7citRDilq0qDXA6tuvFwDgiYyyaq7D5vKUlAPezzZR5NDobc/QMeN6e5guOYmvxg==", + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" + "psl": "^1.1.28", + "punycode": "^2.1.1" } }, "trivial-deferred": { @@ -3521,11 +8254,20 @@ "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", "dev": true }, - "tsame": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tsame/-/tsame-2.0.0.tgz", - "integrity": "sha512-dAuzcnOPdqZYojylFQzEes95UDjve3HqKrlTCeLZKSDPMTsn3smzHZqsJj/sWD8wOUkg0RD++B11evyLn2+bIw==", - "dev": true + "ts-node": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", + "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "3.1.1" + } }, "tunnel-agent": { "version": "0.6.0", @@ -3540,30 +8282,71 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, - "optional": true + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", + "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", + "dev": true, + "optional": true, + "peer": true }, "unicode-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-1.0.3.tgz", - "integrity": "sha1-Wtp6f+1RhBpBijKM8UlHisg1irs=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz", + "integrity": "sha512-Ph/j1VbS3/r77nhoY2WU0GWGjVYOHL3xpKp0y/Eq2e5r0mT/6b649vm7KFO6RdAdrZkYLdxphYVgvODxPB+Ebg==", "dev": true, "requires": { - "punycode": "^1.3.2", + "punycode": "^2.0.0", "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "optional": true + "requires": { + "punycode": "^2.1.0" + } }, "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, "verror": { @@ -3577,42 +8360,230 @@ "extsprintf": "^1.2.0" } }, + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true, + "optional": true, + "peer": true + }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, + "yaml": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", + "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.6.3" + } + }, "yapool": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "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 + }, + "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", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "optional": true, + "peer": true } } } diff --git a/package.json b/package.json index 6477c307..6767fd92 100644 --- a/package.json +++ b/package.json @@ -27,13 +27,18 @@ "devDependencies": { "mkdirp": "0", "rimraf": "^2.2.8", - "tap": "^12.0.1", + "tap": "^15.0.6", "tick": "0.0.6" }, + "tap": { + "before": "test/00-setup.js", + "after": "test/zz-cleanup.js", + "jobs": 1 + }, "scripts": { "prepublish": "npm run benchclean", "profclean": "rm -f v8.log profile.txt", - "test": "tap test/*.js --cov", + "test": "tap", "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", "bench": "bash benchmark.sh", "prof": "bash prof.sh && cat profile.txt", diff --git a/test/00-setup.js b/test/00-setup.js index df9d523c..adb48a40 100644 --- a/test/00-setup.js +++ b/test/00-setup.js @@ -5,8 +5,10 @@ require("./global-leakage.js") var mkdirp = require("mkdirp") var path = require("path") var i = 0 +process.env.TAP_BAIL = '1' var tap = require("tap") var fs = require("fs") +tap.pipe(fs.createWriteStream(path.resolve(__dirname, '../00-setup.tap'))) var rimraf = require("rimraf") var fixtureDir = path.resolve(__dirname, 'fixtures') @@ -45,7 +47,7 @@ files.forEach(function (f) { return t.bailout() } fs.writeFile(f, "i like tests", function (er) { - t.ifError(er, "make file") + t.error(er, "make file") t.end() }) }) @@ -140,7 +142,7 @@ tap.test("save fixtures", function (t) { var fname = path.resolve(__dirname, "bash-results.json") var data = JSON.stringify(bashOutput, null, 2) + "\n" fs.writeFile(fname, data, function (er) { - t.ifError(er) + t.error(er) t.end() }) }) diff --git a/test/bash-comparison.js b/test/bash-comparison.js index 296cc514..25304bec 100644 --- a/test/bash-comparison.js +++ b/test/bash-comparison.js @@ -47,7 +47,7 @@ globs.forEach(function (pattern) { // sort and unmark, just to match the shell results matches = cleanResults(matches) - t.deepEqual(matches, expect, pattern) + t.same(matches, expect, pattern) // verify that path cache keys are all absolute cacheCheck(g, t) @@ -58,7 +58,7 @@ globs.forEach(function (pattern) { tap.test(pattern + " sync", function (t) { var matches = cleanResults(glob.sync(pattern)) - t.deepEqual(matches, expect, "should match shell (sync)") + t.same(matches, expect, "should match shell (sync)") t.end() }) }) diff --git a/test/broken-symlink.js b/test/broken-symlink.js index 4648d38e..dbf276cf 100644 --- a/test/broken-symlink.js +++ b/test/broken-symlink.js @@ -51,7 +51,7 @@ test('async test', function (t) { if (er) throw er var msg = pattern + ' ' + JSON.stringify(opt) - t.notEqual(res.indexOf(link), -1, msg) + t.not(res.indexOf(link), -1, msg) }} }) }) @@ -65,7 +65,7 @@ test('sync test', function (t) { opts.forEach(function (opt) { var res = glob.sync(pattern, opt) - t.notEqual(res.indexOf(link), -1, 'opt=' + JSON.stringify(opt)) + t.not(res.indexOf(link), -1, 'opt=' + JSON.stringify(opt)) }) }) }) diff --git a/test/cwd-test.js b/test/cwd-test.js index a57ddd0f..8f81a6ed 100644 --- a/test/cwd-test.js +++ b/test/cwd-test.js @@ -20,8 +20,8 @@ function cacheCheck(g, t) { tap.test("changing cwd and searching for **/d", function (t) { t.test('.', function (t) { var g = glob('**/d', function (er, matches) { - t.ifError(er) - t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) + t.error(er) + t.match(matches, [ 'a/b/c/d', 'a/c/d' ]) cacheCheck(g, t) t.end() }) @@ -29,8 +29,8 @@ tap.test("changing cwd and searching for **/d", function (t) { t.test('a', function (t) { var g = glob('**/d', {cwd:path.resolve('a')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'b/c/d', 'c/d' ]) + t.error(er) + t.match(matches, [ 'b/c/d', 'c/d' ]) cacheCheck(g, t) t.end() }) @@ -38,8 +38,8 @@ tap.test("changing cwd and searching for **/d", function (t) { t.test('a/b', function (t) { var g = glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'c/d' ]) + t.error(er) + t.match(matches, [ 'c/d' ]) cacheCheck(g, t) t.end() }) @@ -47,8 +47,8 @@ tap.test("changing cwd and searching for **/d", function (t) { t.test('a/b/', function (t) { var g = glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'c/d' ]) + t.error(er) + t.match(matches, [ 'c/d' ]) cacheCheck(g, t) t.end() }) @@ -56,8 +56,8 @@ tap.test("changing cwd and searching for **/d", function (t) { t.test('.', function (t) { var g = glob('**/d', {cwd: process.cwd()}, function (er, matches) { - t.ifError(er) - t.like(matches, [ 'a/b/c/d', 'a/c/d' ]) + t.error(er) + t.match(matches, [ 'a/b/c/d', 'a/c/d' ]) cacheCheck(g, t) t.end() }) diff --git a/test/follow.js b/test/follow.js index 5e1d0130..79df94dd 100644 --- a/test/follow.js +++ b/test/follow.js @@ -24,8 +24,8 @@ test('follow symlinks', function (t) { t.same(follow, syncFollow, 'sync and async follow should match') t.same(noFollow, syncNoFollow, 'sync and async noFollow should match') var long = 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c' - t.notEqual(follow.indexOf(long), -1, 'follow should have long entry') - t.notEqual(syncFollow.indexOf(long), -1, 'syncFollow should have long entry') + t.not(follow.indexOf(long), -1, 'follow should have long entry') + t.not(syncFollow.indexOf(long), -1, 'syncFollow should have long entry') t.end() }) }) diff --git a/test/mark.js b/test/mark.js index 764c332b..e10564fd 100644 --- a/test/mark.js +++ b/test/mark.js @@ -90,7 +90,7 @@ test("mark, no / on pattern", function (t) { t.same(glob.sync(pattern, opt), expect) t.end() }).on('match', function(m) { - t.similar(m, /\/$/) + t.match(m, /\/$/) }) }) @@ -118,7 +118,7 @@ test("mark=false, no / on pattern", function (t) { t.same(glob.sync(pattern, opt), expect) t.end() }).on('match', function(m) { - t.similar(m, /[^\/]$/) + t.match(m, /[^\/]$/) }) }) @@ -146,7 +146,7 @@ test("mark=true, / on pattern", function (t) { t.same(glob.sync(pattern, opt), expect) t.end() }).on('match', function(m) { - t.similar(m, /\/$/) + t.match(m, /\/$/) }) }) @@ -173,7 +173,7 @@ test("mark=false, / on pattern", function (t) { t.same(glob.sync(pattern, opt), expect) t.end() }).on('match', function(m) { - t.similar(m, /\/$/) + t.match(m, /\/$/) }) }) diff --git a/test/pause-resume.js b/test/pause-resume.js index d6fb8072..49f07f6f 100644 --- a/test/pause-resume.js +++ b/test/pause-resume.js @@ -51,10 +51,10 @@ tap.test("use a Glob object, and pause/resume it", function (t) { t.pass("reached glob end") globResults = cleanResults(globResults) matches = cleanResults(matches) - t.deepEqual(matches, globResults, + t.same(matches, globResults, "end event matches should be the same as match events") - t.deepEqual(matches, expect, + t.same(matches, expect, "glob matches should be the same as bash results") t.end() diff --git a/test/root-nomount.js b/test/root-nomount.js index db2f7214..1417d4d4 100644 --- a/test/root-nomount.js +++ b/test/root-nomount.js @@ -19,8 +19,8 @@ process.chdir(__dirname + '/fixtures') tap.test("changing root and searching for /b*/**", function (t) { t.test('.', function (t) { var g = glob('/b*/**', { root: '.', nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, []) + t.error(er) + t.same(matches, []) cacheCheck(g, t) t.end() }) @@ -28,8 +28,8 @@ tap.test("changing root and searching for /b*/**", function (t) { t.test('a', function (t) { var g = glob('/b*/**', { root: path.resolve('a'), nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) + t.error(er) + t.same(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) cacheCheck(g, t) t.end() }) @@ -37,8 +37,8 @@ tap.test("changing root and searching for /b*/**", function (t) { t.test('root=a, cwd=a/b', function (t) { var g = glob('/b*/**', { root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) { - t.ifError(er) - t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) + t.error(er) + t.same(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) cacheCheck(g, t) t.end() }) diff --git a/test/root.js b/test/root.js index 14ff15ac..eb87e3c2 100644 --- a/test/root.js +++ b/test/root.js @@ -19,7 +19,7 @@ function cacheCheck(g, t) { t.test('.', function (t) { var g = glob('/b*/**', { root: '.' }, function (er, matches) { - t.ifError(er) + t.error(er) t.same(matches, []) cacheCheck(g, t) t.end() @@ -29,7 +29,7 @@ t.test('.', function (t) { t.test('a', function (t) { var g = glob('/b*/**', { root: path.resolve('a') }, function (er, matches) { - t.ifError(er) + t.error(er) var wanted = [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { @@ -44,7 +44,7 @@ t.test('a', function (t) { t.test('root=a, cwd=a/b', function (t) { var g = glob('/b*/**', { root: 'a', cwd: path.resolve('a/b') }, function (er, matches) { - t.ifError(er) + t.error(er) t.same(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { return path.join(path.resolve('a'), m).replace(/\\/g, '/') })) @@ -55,7 +55,7 @@ t.test('root=a, cwd=a/b', function (t) { t.test('combined with absolute option', function(t) { var g = glob('/b*/**', { root: path.resolve('a'), absolute: true }, function (er, matches) { - t.ifError(er) + t.error(er) t.same(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { return path.join(path.resolve('a'), m).replace(/\\/g, '/') })) @@ -66,7 +66,7 @@ t.test('combined with absolute option', function(t) { t.test('cwdAbs when root=a, absolute=true', function(t) { var g = glob('/b*/**', { root: path.resolve('a'), absolute: true }, function (er, matches) { - t.ifError(er) + t.error(er) t.same(g.cwdAbs, process.cwd().replace(/\\/g, '/')) t.end() }) @@ -74,7 +74,7 @@ t.test('cwdAbs when root=a, absolute=true', function(t) { t.test('cwdAbs when root=a, absolute=true, cwd=__dirname', function(t) { var g = glob('/b*/**', { root: path.resolve('a'), absolute: true, cwd: __dirname }, function (er, matches) { - t.ifError(er) + t.error(er) t.same(g.cwdAbs, __dirname.replace(/\\/g, '/')) t.end() }) diff --git a/test/zz-cleanup.js b/test/zz-cleanup.js index f404df3f..62db2429 100644 --- a/test/zz-cleanup.js +++ b/test/zz-cleanup.js @@ -1,12 +1,16 @@ require("./global-leakage.js") // remove the fixtures +process.env.TAP_BAIL = '1' var tap = require("tap") -, rimraf = require("rimraf") -, path = require("path") +var fs = require('fs') +var rimraf = require("rimraf") +var path = require("path") +tap.pipe(fs.createWriteStream(path.resolve(__dirname, '../zz-cleanup.tap'))) + tap.test("cleanup fixtures", function (t) { rimraf(path.resolve(__dirname, "fixtures"), function (er) { - t.ifError(er, "removed") + t.error(er, "removed") t.end() }) }) From 66c102edf44038b74c26f86d134e8b215987f78c Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 6 May 2021 14:41:33 -0700 Subject: [PATCH 002/163] force 'en' locale in string sorting Re: https://github.com/npm/cli/issues/2829 --- common.js | 10 ++-------- glob.js | 2 -- sync.js | 2 -- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/common.js b/common.js index 66651bb3..d14157a0 100644 --- a/common.js +++ b/common.js @@ -1,5 +1,3 @@ -exports.alphasort = alphasort -exports.alphasorti = alphasorti exports.setopts = setopts exports.ownProp = ownProp exports.makeAbs = makeAbs @@ -17,12 +15,8 @@ var minimatch = require("minimatch") var isAbsolute = require("path-is-absolute") var Minimatch = minimatch.Minimatch -function alphasorti (a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()) -} - function alphasort (a, b) { - return a.localeCompare(b) + return a.localeCompare(b, 'en') } function setupIgnores (self, options) { @@ -150,7 +144,7 @@ function finish (self) { all = Object.keys(all) if (!self.nosort) - all = all.sort(self.nocase ? alphasorti : alphasort) + all = all.sort(alphasort) // at *some* point we statted all of these if (self.mark) { diff --git a/glob.js b/glob.js index 58dec0f6..dc27aef1 100644 --- a/glob.js +++ b/glob.js @@ -51,8 +51,6 @@ var assert = require('assert') var isAbsolute = require('path-is-absolute') var globSync = require('./sync.js') var common = require('./common.js') -var alphasort = common.alphasort -var alphasorti = common.alphasorti var setopts = common.setopts var ownProp = common.ownProp var inflight = require('inflight') diff --git a/sync.js b/sync.js index c952134b..10b0ed2c 100644 --- a/sync.js +++ b/sync.js @@ -11,8 +11,6 @@ var path = require('path') var assert = require('assert') var isAbsolute = require('path-is-absolute') var common = require('./common.js') -var alphasort = common.alphasort -var alphasorti = common.alphasorti var setopts = common.setopts var ownProp = common.ownProp var childrenIgnored = common.childrenIgnored From ce43ea071e270f4992d0cd321002816f9aa61de4 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 6 May 2021 14:41:49 -0700 Subject: [PATCH 003/163] 7.1.7 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 017381ce..16543417 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "glob", - "version": "7.1.6", + "version": "7.1.7", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "7.1.6", + "version": "7.1.7", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", diff --git a/package.json b/package.json index 6767fd92..b345ae1e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "7.1.6", + "version": "7.1.7", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" From df4598a75a8f5142d1fa2f50e66c686b7527ed7b Mon Sep 17 00:00:00 2001 From: mmkal Date: Wed, 18 Nov 2020 11:26:51 -0500 Subject: [PATCH 004/163] Add fs option to allow passing virtual filesystem PR-URL: https://github.com/isaacs/node-glob/pull/430 Credit: @mmkal Close: #430 Reviewed-by: @isaacs --- README.md | 3 + common.js | 2 + glob.js | 9 +- package-lock.json | 2204 +++++++++++++++++----------------- package.json | 1 + sync.js | 9 +- test/globstar-match-memfs.js | 30 + 7 files changed, 1119 insertions(+), 1139 deletions(-) create mode 100644 test/globstar-match-memfs.js diff --git a/README.md b/README.md index 2dde30a5..83f0c83a 100644 --- a/README.md +++ b/README.md @@ -276,6 +276,9 @@ the filesystem. * `absolute` Set to true to always receive absolute paths for matched files. Unlike `realpath`, this also affects the values returned in the `match` event. +* `fs` File-system object with Node's `fs` API. By default, the built-in + `fs` module will be used. Set to a volume provided by a library like + `memfs` to avoid using the "real" file-system. ## Comparisons to other fnmatch/glob implementations diff --git a/common.js b/common.js index d14157a0..8e363b6c 100644 --- a/common.js +++ b/common.js @@ -10,6 +10,7 @@ function ownProp (obj, field) { return Object.prototype.hasOwnProperty.call(obj, field) } +var fs = require("fs") var path = require("path") var minimatch = require("minimatch") var isAbsolute = require("path-is-absolute") @@ -75,6 +76,7 @@ function setopts (self, pattern, options) { self.stat = !!options.stat self.noprocess = !!options.noprocess self.absolute = !!options.absolute + self.fs = options.fs || fs self.maxLength = options.maxLength || Infinity self.cache = options.cache || Object.create(null) diff --git a/glob.js b/glob.js index dc27aef1..afcf8275 100644 --- a/glob.js +++ b/glob.js @@ -40,7 +40,6 @@ module.exports = glob -var fs = require('fs') var rp = require('fs.realpath') var minimatch = require('minimatch') var Minimatch = minimatch.Minimatch @@ -501,7 +500,7 @@ Glob.prototype._readdirInGlobStar = function (abs, cb) { var lstatcb = inflight(lstatkey, lstatcb_) if (lstatcb) - fs.lstat(abs, lstatcb) + self.fs.lstat(abs, lstatcb) function lstatcb_ (er, lstat) { if (er && er.code === 'ENOENT') @@ -542,7 +541,7 @@ Glob.prototype._readdir = function (abs, inGlobStar, cb) { } var self = this - fs.readdir(abs, readdirCb(this, abs, cb)) + self.fs.readdir(abs, readdirCb(this, abs, cb)) } function readdirCb (self, abs, cb) { @@ -746,13 +745,13 @@ Glob.prototype._stat = function (f, cb) { var self = this var statcb = inflight('stat\0' + abs, lstatcb_) if (statcb) - fs.lstat(abs, statcb) + self.fs.lstat(abs, statcb) function lstatcb_ (er, lstat) { if (lstat && lstat.isSymbolicLink()) { // If it's a symlink, then treat it as the target, unless // the target does not exist, then treat it as a file. - return fs.stat(abs, function (er, stat) { + return self.fs.stat(abs, function (er, stat) { if (er) self._stat2(f, abs, null, lstat, cb) else diff --git a/package-lock.json b/package-lock.json index 16543417..905061f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "glob", "version": "7.1.7", "license": "ISC", "dependencies": { @@ -16,6 +17,7 @@ "path-is-absolute": "^1.0.0" }, "devDependencies": { + "memfs": "^3.2.0", "mkdirp": "0", "rimraf": "^2.2.8", "tap": "^15.0.6", @@ -29,35 +31,41 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "dependencies": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz", - "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==", - "dev": true + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/core": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.0.tgz", - "integrity": "sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.0", - "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.14.0", - "@babel/helpers": "^7.14.0", - "@babel/parser": "^7.14.0", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.14.0", - "@babel/types": "^7.14.0", + "version": "7.15.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.5.tgz", + "integrity": "sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.5", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -73,181 +81,220 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@babel/generator": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", - "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz", + "integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==", "dev": true, "dependencies": { - "@babel/types": "^7.14.1", + "@babel/types": "^7.15.4", "jsesc": "^2.5.1", "source-map": "^0.5.0" - } - }, - "node_modules/@babel/generator/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, + }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", "semver": "^6.3.0" }, + "engines": { + "node": ">=6.9.0" + }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz", - "integrity": "sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw==", + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz", + "integrity": "sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.14.0", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.14.0", - "@babel/types": "^7.14.0" + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "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 + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helpers": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz", - "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", "dev": true, "dependencies": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.14.0", - "@babel/types": "^7.14.0" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", - "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz", + "integrity": "sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -256,50 +303,51 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/runtime": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", - "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.2" - } - }, "node_modules/@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz", - "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.0", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.0", - "@babel/types": "^7.14.0", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", - "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@istanbuljs/load-nyc-config": { @@ -387,9 +435,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "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", @@ -417,14 +465,6 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, - "node_modules/arg": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", - "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -453,9 +493,9 @@ } }, "node_modules/async-hook-domain": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.3.tgz", - "integrity": "sha512-MadiLLDEZRZzZwcm0dgS+K99qXZ4H2saAUwUgwzFulbAkXrKi3AX5FvWS3FFTQtLMwrqcGqAJe6o12KrObejQA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.4.tgz", + "integrity": "sha512-14LjCmlK1PK8eDtTezR6WX8TMaYNIzBIsd2D1sGoGjgx0BuNMMoSdk7i/drlbtamy0AWv9yv2tkB+ASdmeqFIw==", "dev": true, "engines": { "node": ">=10" @@ -483,9 +523,9 @@ "dev": true }, "node_modules/balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", @@ -497,9 +537,9 @@ } }, "node_modules/binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "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" @@ -515,11 +555,11 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", - "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dependencies": { - "balanced-match": "^0.4.1", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -536,16 +576,16 @@ } }, "node_modules/browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.1.tgz", + "integrity": "sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", + "caniuse-lite": "^1.0.30001259", + "electron-to-chromium": "^1.3.846", "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "nanocolors": "^0.1.5", + "node-releases": "^1.1.76" }, "bin": { "browserslist": "cli.js" @@ -559,9 +599,9 @@ } }, "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, "node_modules/byline": { @@ -598,10 +638,14 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001223", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz", - "integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==", - "dev": true + "version": "1.0.30001259", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001259.tgz", + "integrity": "sha512-V7mQTFhjITxuk9zBpI6nYsiTXhcPe05l+364nZjK7MFK/E7ibvYBSAXr4YcA6oPR8j3ZLM/LN+lUqUVAQEUZFg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } }, "node_modules/caseless": { "version": "0.12.0", @@ -624,24 +668,24 @@ } }, "node_modules/chokidar": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", - "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", "dev": true, "dependencies": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "glob-parent": "~5.1.0", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.3.0" + "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { - "fsevents": "~2.1.2" + "fsevents": "~2.3.2" } }, "node_modules/clean-stack": { @@ -697,12 +741,6 @@ "color-support": "bin.js" } }, - "node_modules/colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -727,9 +765,9 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "dependencies": { "safe-buffer": "~5.1.1" @@ -742,9 +780,9 @@ "dev": true }, "node_modules/coveralls": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz", - "integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", + "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", "dev": true, "dependencies": { "js-yaml": "^3.13.1", @@ -760,12 +798,6 @@ "node": ">=6" } }, - "node_modules/coveralls/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/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -793,12 +825,20 @@ } }, "node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/decamelize": { @@ -851,9 +891,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.3.727", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", - "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==", + "version": "1.3.846", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.846.tgz", + "integrity": "sha512-2jtSwgyiRzybHRxrc2nKI+39wH3AwQgn+sogQ+q814gv8hIFwrcZbV07Ea9f8AmK0ufPVZUvvAG1uZJ+obV4Jw==", "dev": true }, "node_modules/emoji-regex": { @@ -945,9 +985,9 @@ } }, "node_modules/find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "dependencies": { "commondir": "^1.0.1", @@ -980,37 +1020,6 @@ "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", "dev": true }, - "node_modules/flow-parser": { - "version": "0.117.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.117.0.tgz", - "integrity": "sha512-B9wlFfFtE9R9+lvhfShHIuE1eGLfTmMDUxIBU3NfbVynVzB2LNT38A5xBUURW5AYlkJveIlCcEsouOsro/DNWg==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/flow-remove-types": { - "version": "2.117.0", - "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.117.0.tgz", - "integrity": "sha512-qcHEALIeD7oDixDWK+yRiuC0wM/kc01p+lb1hcALb3cLfOrDIMTWHq2QisRqYWhSetfi7U3y2mwqVcsmumt3lw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "flow-parser": "^0.117.0", - "pirates": "^3.0.2", - "vlq": "^0.2.1" - }, - "bin": { - "flow-node": "flow-node", - "flow-remove-types": "flow-remove-types" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -1073,16 +1082,23 @@ "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", "dev": true }, + "node_modules/fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "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=" }, "node_modules/fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "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" @@ -1134,9 +1150,9 @@ } }, "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "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", @@ -1154,9 +1170,9 @@ } }, "node_modules/glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "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" @@ -1175,9 +1191,9 @@ } }, "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==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "node_modules/har-schema": { @@ -1277,9 +1293,9 @@ } }, "node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -1333,12 +1349,15 @@ } }, "node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-typedarray": { @@ -1486,6 +1505,15 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/istanbul-reports": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", @@ -1581,12 +1609,6 @@ "node": ">=6" } }, - "node_modules/json5/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/jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -1612,23 +1634,23 @@ } }, "node_modules/libtap": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.1.tgz", - "integrity": "sha512-Fye8fh1+G7E8qqmjQaY+pXGxy7HM0S6bqCCJFLa16+g2jODBByxbJFDpjbDNF69wfRVyvJ+foLZc1WTIv7dx+g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.3.tgz", + "integrity": "sha512-BfbhcSlcFngZWYvDt+gs4m1BkjP0LaFEg6+4FBAXD0E8Br95wpXCCvS5JZHW1a5QPWMrFD4LhsqBpTPRB3Em8g==", "dev": true, "dependencies": { - "async-hook-domain": "^2.0.1", + "async-hook-domain": "^2.0.4", "bind-obj-methods": "^3.0.0", "diff": "^4.0.2", "function-loop": "^2.0.1", - "minipass": "^3.1.1", + "minipass": "^3.1.5", "own-or": "^1.0.0", - "own-or-env": "^1.0.1", - "signal-exit": "^3.0.2", - "stack-utils": "^2.0.1", + "own-or-env": "^1.0.2", + "signal-exit": "^3.0.4", + "stack-utils": "^2.0.4", "tap-parser": "^10.0.1", "tap-yaml": "^1.0.0", - "tcompare": "^5.0.1", + "tcompare": "^5.0.6", "trivial-deferred": "^1.0.1", "yapool": "^1.0.0" }, @@ -1693,30 +1715,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "node_modules/memfs": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.3.0.tgz", + "integrity": "sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg==", "dev": true, - "optional": true, - "peer": true + "dependencies": { + "fs-monkey": "1.0.3" + }, + "engines": { + "node": ">= 4.0.0" + } }, "node_modules/mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", "dev": true, "dependencies": { - "mime-db": "1.47.0" + "mime-db": "1.49.0" }, "engines": { "node": ">= 0.6" @@ -1734,15 +1760,15 @@ } }, "node_modules/minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "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/minipass": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", - "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", + "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", "dev": true, "dependencies": { "yallist": "^4.0.0" @@ -1751,19 +1777,13 @@ "node": ">=8" } }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "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": "0.0.8" + "minimist": "^1.2.5" }, "bin": { "mkdirp": "bin/cmd.js" @@ -1775,15 +1795,13 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "node_modules/nanocolors": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.6.tgz", + "integrity": "sha512-2pvTw6vYRaBLGir2xR7MxaJtyWkrn+C53EpW8yPotG+pdAwBvt0Xwk4VJ6VHLY0aLthVZPvDfm9TdZvrvAm5UQ==", "dev": true, - "optional": true, - "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=8.0.0" } }, "node_modules/node-preload": { @@ -1799,9 +1817,9 @@ } }, "node_modules/node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "version": "1.1.76", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.76.tgz", + "integrity": "sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA==", "dev": true }, "node_modules/normalize-path": { @@ -1914,9 +1932,9 @@ } }, "node_modules/opener": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", - "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true, "bin": { "opener": "bin/opener-bin.js" @@ -1929,9 +1947,9 @@ "dev": true }, "node_modules/own-or-env": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", - "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.2.tgz", + "integrity": "sha512-NQ7v0fliWtK7Lkb+WdFqe6ky9XAzYmlkXthQrBbzlYbmFKoAYbDDcwmOm6q8kOuwSRXW8bdL5ORksploUJmWgw==", "dev": true, "dependencies": { "own-or": "^1.0.0" @@ -2033,26 +2051,15 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", + "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" - } - }, - "node_modules/pirates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", - "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "node-modules-regexp": "^1.0.0" }, - "engines": { - "node": ">= 4" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pkg-dir": { @@ -2115,9 +2122,9 @@ } }, "node_modules/react": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", - "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "dev": true, "dependencies": { "loose-envify": "^1.1.0", @@ -2129,29 +2136,23 @@ } }, "node_modules/react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "node_modules/readdirp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", - "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { - "picomatch": "^2.0.7" + "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", - "dev": true - }, "node_modules/release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -2212,12 +2213,12 @@ "dev": true }, "node_modules/rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "dependencies": { - "glob": "^7.0.5" + "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" @@ -2272,30 +2273,39 @@ } }, "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", + "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", "dev": true }, "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "dev": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/spawn-wrap": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", @@ -2360,9 +2370,9 @@ } }, "node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -2427,9 +2437,9 @@ } }, "node_modules/tap": { - "version": "15.0.6", - "resolved": "https://registry.npmjs.org/tap/-/tap-15.0.6.tgz", - "integrity": "sha512-f3LaBSGgXkwTh17Lj4H4DxKIl4BrDZlmxWHtLVGwl8vx+XxNKvf0qMbeFLVhsVTRVz9E5yTaSUweB00YcO+TMw==", + "version": "15.0.10", + "resolved": "https://registry.npmjs.org/tap/-/tap-15.0.10.tgz", + "integrity": "sha512-8aq4j+1JUOlXyffLX7ZJxhe9KAxV3s7PsdWAm3XwfoWc/OiFyAMcv4+T0/5/65gBxOVAPLpxH8ecfDkYTA2BCQ==", "bundleDependencies": [ "ink", "treport", @@ -2437,7 +2447,7 @@ ], "dev": true, "dependencies": { - "@types/react": "^16.9.23", + "@types/react": "*", "chokidar": "^3.3.0", "coveralls": "^3.0.11", "findit": "^2.0.0", @@ -2445,11 +2455,11 @@ "fs-exists-cached": "^1.0.0", "glob": "^7.1.6", "import-jsx": "^4.0.0", - "ink": "^2.7.1", + "ink": "*", "isexe": "^2.0.0", "istanbul-lib-processinfo": "^2.0.2", "jackspeak": "^1.4.0", - "libtap": "^1.1.1", + "libtap": "^1.1.3", "minipass": "^3.1.1", "mkdirp": "^1.0.4", "nyc": "^15.1.0", @@ -2461,8 +2471,8 @@ "tap-mocha-reporter": "^5.0.0", "tap-parser": "^10.0.1", "tap-yaml": "^1.0.0", - "tcompare": "^5.0.4", - "treport": "^2.0.1", + "tcompare": "^5.0.6", + "treport": "*", "which": "^2.0.2" }, "bin": { @@ -2523,9 +2533,9 @@ } }, "node_modules/tap-parser": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.0.1.tgz", - "integrity": "sha512-qdT15H0DoJIi7zOqVXDn9X0gSM68JjNy1w3VemwTJlDnETjbi6SutnqmBfjDJAwkFS79NJ97gZKqie00ZCGmzg==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.1.0.tgz", + "integrity": "sha512-FujQeciDaOiOvaIVGS1Rpb0v4R6XkOjvWCWowlz5oKuhPkEJ8U6pxgqt38xuzYhPt8dWEnfHn2jqpZdJEkW7pA==", "dev": true, "dependencies": { "events-to-array": "^1.0.1", @@ -2549,35 +2559,41 @@ } }, "node_modules/tap/node_modules/@babel/code-frame": { - "version": "7.12.13", + "version": "7.14.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/compat-data": { - "version": "7.13.12", + "version": "7.15.0", "dev": true, "inBundle": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, "node_modules/tap/node_modules/@babel/core": { - "version": "7.13.14", + "version": "7.15.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-compilation-targets": "^7.13.13", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.10", - "@babel/parser": "^7.13.13", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14", + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.5", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -2594,175 +2610,238 @@ } }, "node_modules/tap/node_modules/@babel/generator": { - "version": "7.13.9", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.13.0", + "@babel/types": "^7.15.4", "jsesc": "^2.5.1", "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.12.13", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-compilation-targets": { - "version": "7.13.13", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.13.12", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", "semver": "^6.3.0" }, + "engines": { + "node": ">=6.9.0" + }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/tap/node_modules/@babel/helper-function-name": { - "version": "7.12.13", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-get-function-arity": { - "version": "7.12.13", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/tap/node_modules/@babel/helper-hoist-variables": { + "version": "7.15.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.13.12", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-module-imports": { - "version": "7.13.12", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-module-transforms": { - "version": "7.13.14", + "version": "7.15.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.13", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-plugin-utils": { - "version": "7.13.0", + "version": "7.14.5", "dev": true, "inBundle": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, "node_modules/tap/node_modules/@babel/helper-replace-supers": { - "version": "7.13.12", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-simple-access": { - "version": "7.13.12", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.13", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", + "version": "7.15.7", "dev": true, "inBundle": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, "node_modules/tap/node_modules/@babel/helper-validator-option": { - "version": "7.12.17", + "version": "7.14.5", "dev": true, "inBundle": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, "node_modules/tap/node_modules/@babel/helpers": { - "version": "7.13.10", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/highlight": { - "version": "7.13.10", + "version": "7.14.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/parser": { - "version": "7.13.13", + "version": "7.15.7", "dev": true, "inBundle": true, "license": "MIT", @@ -2774,28 +2853,34 @@ } }, "node_modules/tap/node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.13.8", + "version": "7.15.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.13.8", - "@babel/helper-compilation-targets": "^7.13.8", - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/compat-data": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.13.0" + "@babel/plugin-transform-parameters": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/tap/node_modules/@babel/plugin-syntax-jsx": { - "version": "7.12.13", + "version": "7.14.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" @@ -2814,91 +2899,109 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-destructuring": { - "version": "7.13.0", + "version": "7.14.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/tap/node_modules/@babel/plugin-transform-parameters": { - "version": "7.13.0", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/tap/node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.13.12", + "version": "7.14.9", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-jsx": "^7.12.13", - "@babel/types": "^7.13.12" + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-jsx": "^7.14.5", + "@babel/types": "^7.14.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "node_modules/tap/node_modules/@babel/template": { - "version": "7.12.13", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/traverse": { - "version": "7.13.13", + "version": "7.15.4", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.13", - "@babel/types": "^7.13.13", + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/types": { - "version": "7.13.14", + "version": "7.15.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@types/prop-types": { - "version": "15.7.3", + "version": "15.7.4", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/tap/node_modules/@types/react": { - "version": "16.14.5", + "version": "16.14.15", "dev": true, "inBundle": true, "license": "MIT", @@ -2909,7 +3012,7 @@ } }, "node_modules/tap/node_modules/@types/scheduler": { - "version": "0.16.1", + "version": "0.16.2", "dev": true, "inBundle": true, "license": "MIT" @@ -2984,7 +3087,7 @@ } }, "node_modules/tap/node_modules/balanced-match": { - "version": "1.0.0", + "version": "1.0.2", "dev": true, "inBundle": true, "license": "MIT" @@ -3000,16 +3103,16 @@ } }, "node_modules/tap/node_modules/browserslist": { - "version": "4.16.3", + "version": "4.17.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001181", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.649", + "caniuse-lite": "^1.0.30001254", + "colorette": "^1.3.0", + "electron-to-chromium": "^1.3.830", "escalade": "^3.1.1", - "node-releases": "^1.1.70" + "node-releases": "^1.1.75" }, "bin": { "browserslist": "cli.js" @@ -3056,10 +3159,14 @@ } }, "node_modules/tap/node_modules/caniuse-lite": { - "version": "1.0.30001204", + "version": "1.0.30001258", "dev": true, "inBundle": true, - "license": "CC-BY-4.0" + "license": "CC-BY-4.0", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } }, "node_modules/tap/node_modules/cardinal": { "version": "2.1.1", @@ -3138,7 +3245,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/colorette": { - "version": "1.2.2", + "version": "1.4.0", "dev": true, "inBundle": true, "license": "MIT" @@ -3156,7 +3263,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/convert-source-map": { - "version": "1.7.0", + "version": "1.8.0", "dev": true, "inBundle": true, "license": "MIT", @@ -3165,13 +3272,13 @@ } }, "node_modules/tap/node_modules/csstype": { - "version": "3.0.7", + "version": "3.0.9", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/tap/node_modules/debug": { - "version": "4.3.1", + "version": "4.3.2", "dev": true, "inBundle": true, "license": "MIT", @@ -3188,7 +3295,7 @@ } }, "node_modules/tap/node_modules/electron-to-chromium": { - "version": "1.3.703", + "version": "1.3.844", "dev": true, "inBundle": true, "license": "ISC" @@ -3237,7 +3344,7 @@ "license": "ISC" }, "node_modules/tap/node_modules/find-cache-dir": { - "version": "3.3.1", + "version": "3.3.2", "dev": true, "inBundle": true, "license": "MIT", @@ -3282,7 +3389,7 @@ } }, "node_modules/tap/node_modules/glob": { - "version": "7.1.6", + "version": "7.1.7", "dev": true, "inBundle": true, "license": "ISC", @@ -3526,12 +3633,6 @@ "node": ">=8" } }, - "node_modules/tap/node_modules/lodash": { - "version": "4.17.21", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/tap/node_modules/lodash.throttle": { "version": "4.1.1", "dev": true, @@ -3729,7 +3830,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/minipass": { - "version": "3.1.3", + "version": "3.1.5", "dev": true, "inBundle": true, "license": "ISC", @@ -3759,7 +3860,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/node-releases": { - "version": "1.1.71", + "version": "1.1.76", "dev": true, "inBundle": true, "license": "MIT" @@ -3979,7 +4080,7 @@ } }, "node_modules/tap/node_modules/signal-exit": { - "version": "3.0.3", + "version": "3.0.4", "dev": true, "inBundle": true, "license": "ISC" @@ -4098,7 +4199,7 @@ } }, "node_modules/tap/node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.0", + "version": "5.0.1", "dev": true, "inBundle": true, "license": "MIT", @@ -4166,7 +4267,7 @@ } }, "node_modules/tap/node_modules/treport": { - "version": "2.0.1", + "version": "2.0.2", "dev": true, "inBundle": true, "license": "ISC", @@ -4321,7 +4422,7 @@ } }, "node_modules/tap/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.0", + "version": "5.0.1", "dev": true, "inBundle": true, "license": "MIT", @@ -4408,9 +4509,9 @@ } }, "node_modules/tcompare": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.4.tgz", - "integrity": "sha512-worXBcrmLoFu9oJYAKznjPE89APTEXk/XCazuDuSQfK1EqX3bpLPW3cY/RQucbcc7mW+yKW0duujsuFlU7dRCA==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.6.tgz", + "integrity": "sha512-OvO7omN/wkdsKzmOqr3sQFfLbghs/2X5mwSkcfgRiXZshfPnTsAs3IRf1RixR/Pff26qG/r9ogcZMpV0YdeGXg==", "dev": true, "dependencies": { "diff": "^4.0.2" @@ -4488,28 +4589,6 @@ "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", "dev": true }, - "node_modules/ts-node": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", - "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-script": "dist/script.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -4546,21 +4625,6 @@ "is-typedarray": "^1.0.0" } }, - "node_modules/typescript": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", - "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/unicode-length": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz", @@ -4605,6 +4669,7 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, "bin": { "uuid": "bin/uuid" @@ -4624,14 +4689,6 @@ "extsprintf": "^1.2.0" } }, - "node_modules/vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4736,14 +4793,17 @@ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/yaml": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", - "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, - "dependencies": { - "@babel/runtime": "^7.6.3" - }, "engines": { "node": ">= 6" } @@ -4790,9 +4850,9 @@ } }, "node_modules/yargs/node_modules/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, "engines": { "node": ">=8" @@ -4890,273 +4950,247 @@ "engines": { "node": ">=8" } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=6" - } } }, "dependencies": { "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.14.5" } }, "@babel/compat-data": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz", - "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", "dev": true }, "@babel/core": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.0.tgz", - "integrity": "sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw==", + "version": "7.15.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.5.tgz", + "integrity": "sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.0", - "@babel/helper-compilation-targets": "^7.13.16", - "@babel/helper-module-transforms": "^7.14.0", - "@babel/helpers": "^7.14.0", - "@babel/parser": "^7.14.0", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.14.0", - "@babel/types": "^7.14.0", + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.5", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", "semver": "^6.3.0", "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/generator": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", - "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz", + "integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==", "dev": true, "requires": { - "@babel/types": "^7.14.1", + "@babel/types": "^7.15.4", "jsesc": "^2.5.1", "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/helper-compilation-targets": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", - "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.13.15", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", "semver": "^6.3.0" } }, "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, "requires": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" } }, "@babel/helper-module-imports": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", - "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, "requires": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" } }, "@babel/helper-module-transforms": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz", - "integrity": "sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw==", + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz", + "integrity": "sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.14.0", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.14.0", - "@babel/types": "^7.14.0" + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" } }, "@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-simple-access": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", - "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, "requires": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" } }, "@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==", + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", "dev": true }, "@babel/helpers": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz", - "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", "dev": true, "requires": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.14.0", - "@babel/types": "^7.14.0" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", - "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz", + "integrity": "sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==", "dev": true }, - "@babel/runtime": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", - "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.2" - } - }, "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/traverse": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz", - "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.0", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.0", - "@babel/types": "^7.14.0", + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", - "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" } }, @@ -5225,9 +5259,9 @@ } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -5249,14 +5283,6 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, - "arg": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", - "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==", - "dev": true, - "optional": true, - "peer": true - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -5282,9 +5308,9 @@ "dev": true }, "async-hook-domain": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.3.tgz", - "integrity": "sha512-MadiLLDEZRZzZwcm0dgS+K99qXZ4H2saAUwUgwzFulbAkXrKi3AX5FvWS3FFTQtLMwrqcGqAJe6o12KrObejQA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.4.tgz", + "integrity": "sha512-14LjCmlK1PK8eDtTezR6WX8TMaYNIzBIsd2D1sGoGjgx0BuNMMoSdk7i/drlbtamy0AWv9yv2tkB+ASdmeqFIw==", "dev": true }, "asynckit": { @@ -5306,9 +5332,9 @@ "dev": true }, "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -5320,9 +5346,9 @@ } }, "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "bind-obj-methods": { @@ -5332,11 +5358,11 @@ "dev": true }, "brace-expansion": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", - "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { - "balanced-match": "^0.4.1", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -5350,22 +5376,22 @@ } }, "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.1.tgz", + "integrity": "sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", + "caniuse-lite": "^1.0.30001259", + "electron-to-chromium": "^1.3.846", "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "nanocolors": "^0.1.5", + "node-releases": "^1.1.76" } }, "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, "byline": { @@ -5393,9 +5419,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001223", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz", - "integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==", + "version": "1.0.30001259", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001259.tgz", + "integrity": "sha512-V7mQTFhjITxuk9zBpI6nYsiTXhcPe05l+364nZjK7MFK/E7ibvYBSAXr4YcA6oPR8j3ZLM/LN+lUqUVAQEUZFg==", "dev": true }, "caseless": { @@ -5416,19 +5442,19 @@ } }, "chokidar": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz", - "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", "dev": true, "requires": { - "anymatch": "~3.1.1", + "anymatch": "~3.1.2", "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.3.0" + "readdirp": "~3.6.0" } }, "clean-stack": { @@ -5475,12 +5501,6 @@ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5502,9 +5522,9 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -5517,9 +5537,9 @@ "dev": true }, "coveralls": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz", - "integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", + "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", "dev": true, "requires": { "js-yaml": "^3.13.1", @@ -5527,14 +5547,6 @@ "log-driver": "^1.2.7", "minimist": "^1.2.5", "request": "^2.88.2" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } } }, "cross-spawn": { @@ -5558,12 +5570,12 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "decamelize": { @@ -5604,9 +5616,9 @@ } }, "electron-to-chromium": { - "version": "1.3.727", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", - "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==", + "version": "1.3.846", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.846.tgz", + "integrity": "sha512-2jtSwgyiRzybHRxrc2nKI+39wH3AwQgn+sogQ+q814gv8hIFwrcZbV07Ea9f8AmK0ufPVZUvvAG1uZJ+obV4Jw==", "dev": true }, "emoji-regex": { @@ -5679,9 +5691,9 @@ } }, "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "requires": { "commondir": "^1.0.1", @@ -5705,27 +5717,6 @@ "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", "dev": true }, - "flow-parser": { - "version": "0.117.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.117.0.tgz", - "integrity": "sha512-B9wlFfFtE9R9+lvhfShHIuE1eGLfTmMDUxIBU3NfbVynVzB2LNT38A5xBUURW5AYlkJveIlCcEsouOsro/DNWg==", - "dev": true, - "optional": true, - "peer": true - }, - "flow-remove-types": { - "version": "2.117.0", - "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.117.0.tgz", - "integrity": "sha512-qcHEALIeD7oDixDWK+yRiuC0wM/kc01p+lb1hcALb3cLfOrDIMTWHq2QisRqYWhSetfi7U3y2mwqVcsmumt3lw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "flow-parser": "^0.117.0", - "pirates": "^3.0.2", - "vlq": "^0.2.1" - } - }, "foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -5765,15 +5756,21 @@ "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", "dev": true }, + "fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "dev": true + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, @@ -5811,9 +5808,9 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -5825,9 +5822,9 @@ } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -5840,9 +5837,9 @@ "dev": true }, "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "har-schema": { @@ -5916,9 +5913,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "is-binary-path": { "version": "2.1.0", @@ -5957,9 +5954,9 @@ "dev": true }, "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "is-typedarray": { @@ -6076,6 +6073,14 @@ "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "istanbul-reports": { @@ -6150,14 +6155,6 @@ "dev": true, "requires": { "minimist": "^1.2.5" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } } }, "jsprim": { @@ -6179,23 +6176,23 @@ "dev": true }, "libtap": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.1.tgz", - "integrity": "sha512-Fye8fh1+G7E8qqmjQaY+pXGxy7HM0S6bqCCJFLa16+g2jODBByxbJFDpjbDNF69wfRVyvJ+foLZc1WTIv7dx+g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.3.tgz", + "integrity": "sha512-BfbhcSlcFngZWYvDt+gs4m1BkjP0LaFEg6+4FBAXD0E8Br95wpXCCvS5JZHW1a5QPWMrFD4LhsqBpTPRB3Em8g==", "dev": true, "requires": { - "async-hook-domain": "^2.0.1", + "async-hook-domain": "^2.0.4", "bind-obj-methods": "^3.0.0", "diff": "^4.0.2", "function-loop": "^2.0.1", - "minipass": "^3.1.1", + "minipass": "^3.1.5", "own-or": "^1.0.0", - "own-or-env": "^1.0.1", - "signal-exit": "^3.0.2", - "stack-utils": "^2.0.1", + "own-or-env": "^1.0.2", + "signal-exit": "^3.0.4", + "stack-utils": "^2.0.4", "tap-parser": "^10.0.1", "tap-yaml": "^1.0.0", - "tcompare": "^5.0.1", + "tcompare": "^5.0.6", "trivial-deferred": "^1.0.1", "yapool": "^1.0.0" } @@ -6239,27 +6236,28 @@ "semver": "^6.0.0" } }, - "make-error": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", - "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "memfs": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.3.0.tgz", + "integrity": "sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg==", "dev": true, - "optional": true, - "peer": true + "requires": { + "fs-monkey": "1.0.3" + } }, "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", "dev": true }, "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", "dev": true, "requires": { - "mime-db": "1.47.0" + "mime-db": "1.49.0" } }, "minimatch": { @@ -6271,35 +6269,27 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "minipass": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", - "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", + "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", "dev": true, "requires": { "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "ms": { @@ -6308,13 +6298,11 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true, - "optional": true, - "peer": true + "nanocolors": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.6.tgz", + "integrity": "sha512-2pvTw6vYRaBLGir2xR7MxaJtyWkrn+C53EpW8yPotG+pdAwBvt0Xwk4VJ6VHLY0aLthVZPvDfm9TdZvrvAm5UQ==", + "dev": true }, "node-preload": { "version": "0.2.1", @@ -6326,9 +6314,9 @@ } }, "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "version": "1.1.76", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.76.tgz", + "integrity": "sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA==", "dev": true }, "normalize-path": { @@ -6416,9 +6404,9 @@ } }, "opener": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", - "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true }, "own-or": { @@ -6428,9 +6416,9 @@ "dev": true }, "own-or-env": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", - "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.2.tgz", + "integrity": "sha512-NQ7v0fliWtK7Lkb+WdFqe6ky9XAzYmlkXthQrBbzlYbmFKoAYbDDcwmOm6q8kOuwSRXW8bdL5ORksploUJmWgw==", "dev": true, "requires": { "own-or": "^1.0.0" @@ -6505,22 +6493,11 @@ "dev": true }, "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, - "pirates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", - "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -6569,9 +6546,9 @@ "dev": true }, "react": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz", - "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "dev": true, "requires": { "loose-envify": "^1.1.0", @@ -6580,26 +6557,20 @@ } }, "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "readdirp": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz", - "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { - "picomatch": "^2.0.7" + "picomatch": "^2.2.1" } }, - "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", - "dev": true - }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -6650,12 +6621,12 @@ "dev": true }, "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "safe-buffer": { @@ -6698,25 +6669,33 @@ "dev": true }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", + "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", "dev": true }, "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "spawn-wrap": { @@ -6768,9 +6747,9 @@ } }, "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -6819,12 +6798,12 @@ } }, "tap": { - "version": "15.0.6", - "resolved": "https://registry.npmjs.org/tap/-/tap-15.0.6.tgz", - "integrity": "sha512-f3LaBSGgXkwTh17Lj4H4DxKIl4BrDZlmxWHtLVGwl8vx+XxNKvf0qMbeFLVhsVTRVz9E5yTaSUweB00YcO+TMw==", + "version": "15.0.10", + "resolved": "https://registry.npmjs.org/tap/-/tap-15.0.10.tgz", + "integrity": "sha512-8aq4j+1JUOlXyffLX7ZJxhe9KAxV3s7PsdWAm3XwfoWc/OiFyAMcv4+T0/5/65gBxOVAPLpxH8ecfDkYTA2BCQ==", "dev": true, "requires": { - "@types/react": "^16.9.23", + "@types/react": "*", "chokidar": "^3.3.0", "coveralls": "^3.0.11", "findit": "^2.0.0", @@ -6832,11 +6811,11 @@ "fs-exists-cached": "^1.0.0", "glob": "^7.1.6", "import-jsx": "^4.0.0", - "ink": "^2.7.1", + "ink": "*", "isexe": "^2.0.0", "istanbul-lib-processinfo": "^2.0.2", "jackspeak": "^1.4.0", - "libtap": "^1.1.1", + "libtap": "^1.1.3", "minipass": "^3.1.1", "mkdirp": "^1.0.4", "nyc": "^15.1.0", @@ -6848,38 +6827,38 @@ "tap-mocha-reporter": "^5.0.0", "tap-parser": "^10.0.1", "tap-yaml": "^1.0.0", - "tcompare": "^5.0.4", - "treport": "^2.0.1", + "tcompare": "^5.0.6", + "treport": "*", "which": "^2.0.2" }, "dependencies": { "@babel/code-frame": { - "version": "7.12.13", + "version": "7.14.5", "bundled": true, "dev": true, "requires": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.14.5" } }, "@babel/compat-data": { - "version": "7.13.12", + "version": "7.15.0", "bundled": true, "dev": true }, "@babel/core": { - "version": "7.13.14", + "version": "7.15.5", "bundled": true, "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-compilation-targets": "^7.13.13", - "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.10", - "@babel/parser": "^7.13.13", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14", + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.4", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.5", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -6889,176 +6868,184 @@ } }, "@babel/generator": { - "version": "7.13.9", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.13.0", + "@babel/types": "^7.15.4", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-annotate-as-pure": { - "version": "7.12.13", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" } }, "@babel/helper-compilation-targets": { - "version": "7.13.13", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/compat-data": "^7.13.12", - "@babel/helper-validator-option": "^7.12.17", - "browserslist": "^4.14.5", + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", "semver": "^6.3.0" } }, "@babel/helper-function-name": { - "version": "7.12.13", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-get-function-arity": { - "version": "7.12.13", + "version": "7.15.4", + "bundled": true, + "dev": true, + "requires": { + "@babel/types": "^7.15.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" } }, "@babel/helper-module-imports": { - "version": "7.13.12", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" } }, "@babel/helper-module-transforms": { - "version": "7.13.14", + "version": "7.15.7", "bundled": true, "dev": true, "requires": { - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-replace-supers": "^7.13.12", - "@babel/helper-simple-access": "^7.13.12", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/helper-validator-identifier": "^7.12.11", - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.13", - "@babel/types": "^7.13.14" + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.13", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" } }, "@babel/helper-plugin-utils": { - "version": "7.13.0", + "version": "7.14.5", "bundled": true, "dev": true }, "@babel/helper-replace-supers": { - "version": "7.13.12", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-simple-access": { - "version": "7.13.12", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.15.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.13", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.15.4" } }, "@babel/helper-validator-identifier": { - "version": "7.12.11", + "version": "7.15.7", "bundled": true, "dev": true }, "@babel/helper-validator-option": { - "version": "7.12.17", + "version": "7.14.5", "bundled": true, "dev": true }, "@babel/helpers": { - "version": "7.13.10", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/highlight": { - "version": "7.13.10", + "version": "7.14.5", "bundled": true, "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.13.13", + "version": "7.15.7", "bundled": true, "dev": true }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.13.8", + "version": "7.15.6", "bundled": true, "dev": true, "requires": { - "@babel/compat-data": "^7.13.8", - "@babel/helper-compilation-targets": "^7.13.8", - "@babel/helper-plugin-utils": "^7.13.0", + "@babel/compat-data": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.13.0" + "@babel/plugin-transform-parameters": "^7.15.4" } }, "@babel/plugin-syntax-jsx": { - "version": "7.12.13", + "version": "7.14.5", "bundled": true, "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-syntax-object-rest-spread": { @@ -7070,75 +7057,75 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.13.0", + "version": "7.14.7", "bundled": true, "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-parameters": { - "version": "7.13.0", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.13.0" + "@babel/helper-plugin-utils": "^7.14.5" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.13.12", + "version": "7.14.9", "bundled": true, "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.12.13", - "@babel/helper-module-imports": "^7.13.12", - "@babel/helper-plugin-utils": "^7.13.0", - "@babel/plugin-syntax-jsx": "^7.12.13", - "@babel/types": "^7.13.12" + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-jsx": "^7.14.5", + "@babel/types": "^7.14.9" } }, "@babel/template": { - "version": "7.12.13", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/traverse": { - "version": "7.13.13", + "version": "7.15.4", "bundled": true, "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.13", - "@babel/types": "^7.13.13", + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.13.14", + "version": "7.15.6", "bundled": true, "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" } }, "@types/prop-types": { - "version": "15.7.3", + "version": "15.7.4", "bundled": true, "dev": true }, "@types/react": { - "version": "16.14.5", + "version": "16.14.15", "bundled": true, "dev": true, "requires": { @@ -7148,7 +7135,7 @@ } }, "@types/scheduler": { - "version": "0.16.1", + "version": "0.16.2", "bundled": true, "dev": true }, @@ -7194,7 +7181,7 @@ "dev": true }, "balanced-match": { - "version": "1.0.0", + "version": "1.0.2", "bundled": true, "dev": true }, @@ -7208,15 +7195,15 @@ } }, "browserslist": { - "version": "4.16.3", + "version": "4.17.0", "bundled": true, "dev": true, "requires": { - "caniuse-lite": "^1.0.30001181", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.649", + "caniuse-lite": "^1.0.30001254", + "colorette": "^1.3.0", + "electron-to-chromium": "^1.3.830", "escalade": "^3.1.1", - "node-releases": "^1.1.70" + "node-releases": "^1.1.75" } }, "caller-callsite": { @@ -7241,7 +7228,7 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001204", + "version": "1.0.30001258", "bundled": true, "dev": true }, @@ -7300,7 +7287,7 @@ "dev": true }, "colorette": { - "version": "1.2.2", + "version": "1.4.0", "bundled": true, "dev": true }, @@ -7315,7 +7302,7 @@ "dev": true }, "convert-source-map": { - "version": "1.7.0", + "version": "1.8.0", "bundled": true, "dev": true, "requires": { @@ -7323,12 +7310,12 @@ } }, "csstype": { - "version": "3.0.7", + "version": "3.0.9", "bundled": true, "dev": true }, "debug": { - "version": "4.3.1", + "version": "4.3.2", "bundled": true, "dev": true, "requires": { @@ -7336,7 +7323,7 @@ } }, "electron-to-chromium": { - "version": "1.3.703", + "version": "1.3.844", "bundled": true, "dev": true }, @@ -7366,7 +7353,7 @@ "dev": true }, "find-cache-dir": { - "version": "3.3.1", + "version": "3.3.2", "bundled": true, "dev": true, "requires": { @@ -7395,7 +7382,7 @@ "dev": true }, "glob": { - "version": "7.1.6", + "version": "7.1.7", "bundled": true, "dev": true, "requires": { @@ -7556,11 +7543,6 @@ "p-locate": "^4.1.0" } }, - "lodash": { - "version": "4.17.21", - "bundled": true, - "dev": true - }, "lodash.throttle": { "version": "4.1.1", "bundled": true, @@ -7691,7 +7673,7 @@ "dev": true }, "minipass": { - "version": "3.1.3", + "version": "3.1.5", "bundled": true, "dev": true, "requires": { @@ -7710,7 +7692,7 @@ "dev": true }, "node-releases": { - "version": "1.1.71", + "version": "1.1.76", "bundled": true, "dev": true }, @@ -7855,7 +7837,7 @@ "dev": true }, "signal-exit": { - "version": "3.0.3", + "version": "3.0.4", "bundled": true, "dev": true }, @@ -7937,7 +7919,7 @@ }, "dependencies": { "ansi-regex": { - "version": "5.0.0", + "version": "5.0.1", "bundled": true, "dev": true }, @@ -7983,7 +7965,7 @@ "dev": true }, "treport": { - "version": "2.0.1", + "version": "2.0.2", "bundled": true, "dev": true, "requires": { @@ -8090,7 +8072,7 @@ }, "dependencies": { "ansi-regex": { - "version": "5.0.0", + "version": "5.0.1", "bundled": true, "dev": true }, @@ -8175,9 +8157,9 @@ } }, "tap-parser": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.0.1.tgz", - "integrity": "sha512-qdT15H0DoJIi7zOqVXDn9X0gSM68JjNy1w3VemwTJlDnETjbi6SutnqmBfjDJAwkFS79NJ97gZKqie00ZCGmzg==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.1.0.tgz", + "integrity": "sha512-FujQeciDaOiOvaIVGS1Rpb0v4R6XkOjvWCWowlz5oKuhPkEJ8U6pxgqt38xuzYhPt8dWEnfHn2jqpZdJEkW7pA==", "dev": true, "requires": { "events-to-array": "^1.0.1", @@ -8195,9 +8177,9 @@ } }, "tcompare": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.4.tgz", - "integrity": "sha512-worXBcrmLoFu9oJYAKznjPE89APTEXk/XCazuDuSQfK1EqX3bpLPW3cY/RQucbcc7mW+yKW0duujsuFlU7dRCA==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.6.tgz", + "integrity": "sha512-OvO7omN/wkdsKzmOqr3sQFfLbghs/2X5mwSkcfgRiXZshfPnTsAs3IRf1RixR/Pff26qG/r9ogcZMpV0YdeGXg==", "dev": true, "requires": { "diff": "^4.0.2" @@ -8254,21 +8236,6 @@ "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", "dev": true }, - "ts-node": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", - "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "3.1.1" - } - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -8299,14 +8266,6 @@ "is-typedarray": "^1.0.0" } }, - "typescript": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", - "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", - "dev": true, - "optional": true, - "peer": true - }, "unicode-length": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz", @@ -8360,14 +8319,6 @@ "extsprintf": "^1.2.0" } }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true, - "optional": true, - "peer": true - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -8453,14 +8404,17 @@ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "yaml": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", - "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.6.3" - } + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true }, "yapool": { "version": "1.0.0", @@ -8488,9 +8442,9 @@ }, "dependencies": { "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": { @@ -8576,14 +8530,6 @@ "camelcase": "^5.0.0", "decamelize": "^1.2.0" } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "optional": true, - "peer": true } } } diff --git a/package.json b/package.json index b345ae1e..5b689085 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "path-is-absolute": "^1.0.0" }, "devDependencies": { + "memfs": "^3.2.0", "mkdirp": "0", "rimraf": "^2.2.8", "tap": "^15.0.6", diff --git a/sync.js b/sync.js index 10b0ed2c..4f46f905 100644 --- a/sync.js +++ b/sync.js @@ -1,7 +1,6 @@ module.exports = globSync globSync.GlobSync = GlobSync -var fs = require('fs') var rp = require('fs.realpath') var minimatch = require('minimatch') var Minimatch = minimatch.Minimatch @@ -246,7 +245,7 @@ GlobSync.prototype._readdirInGlobStar = function (abs) { var lstat var stat try { - lstat = fs.lstatSync(abs) + lstat = this.fs.lstatSync(abs) } catch (er) { if (er.code === 'ENOENT') { // lstat failed, doesn't exist @@ -283,7 +282,7 @@ GlobSync.prototype._readdir = function (abs, inGlobStar) { } try { - return this._readdirEntries(abs, fs.readdirSync(abs)) + return this._readdirEntries(abs, this.fs.readdirSync(abs)) } catch (er) { this._readdirError(abs, er) return null @@ -442,7 +441,7 @@ GlobSync.prototype._stat = function (f) { if (!stat) { var lstat try { - lstat = fs.lstatSync(abs) + lstat = this.fs.lstatSync(abs) } catch (er) { if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { this.statCache[abs] = false @@ -452,7 +451,7 @@ GlobSync.prototype._stat = function (f) { if (lstat && lstat.isSymbolicLink()) { try { - stat = fs.statSync(abs) + stat = this.fs.statSync(abs) } catch (er) { stat = lstat } diff --git a/test/globstar-match-memfs.js b/test/globstar-match-memfs.js new file mode 100644 index 00000000..319738f2 --- /dev/null +++ b/test/globstar-match-memfs.js @@ -0,0 +1,30 @@ +require("./global-leakage.js") +var memfs = require('memfs') +var test = require('tap').test +var glob = require("../glob.js") + +test('fs-compatible file system can be used', function (t) { + var volJson = { + './text1.txt': 'abc', + './javascript.js': 'abc', + './text2.txt': 'abc', + } + var vol = memfs.Volume.fromJSON(volJson, '/some/directory') + glob('*.txt', { cwd: '/some/directory', fs: vol }, function (e, f) { + t.equal(e, null, 'no error') + t.same(f, ['text1.txt', 'text2.txt'], 'matched txt files') + t.end() + }) +}) + +test('fs-compatible file system can be used with glob.sync', function (t) { + var volJson = { + './text1.txt': 'abc', + './javascript.js': 'abc', + './text2.txt': 'abc', + } + var vol = memfs.Volume.fromJSON(volJson, '/some/directory') + var f = glob.sync('*.txt', { cwd: '/some/directory', fs: vol }) + t.same(f, ['text1.txt', 'text2.txt'], 'matched txt files') + t.end() +}) From 3bfec21dd180ddf4672880176ad33af6296a167e Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 22 Sep 2021 16:36:05 -0700 Subject: [PATCH 005/163] 7.2.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 905061f9..c9baaf9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "glob", - "version": "7.1.7", + "version": "7.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "glob", - "version": "7.1.7", + "version": "7.2.0", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", diff --git a/package.json b/package.json index 5b689085..cc1a57a8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "7.1.7", + "version": "7.2.0", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" From 73feafd17f1c04633349652605e12fbbaef9b3cf Mon Sep 17 00:00:00 2001 From: isaacs Date: Sat, 12 Feb 2022 20:24:41 -0800 Subject: [PATCH 006/163] update minimatch, use allowWindowsEscape:true option --- common.js | 2 + glob.js | 5 +- package-lock.json | 2759 ++++++++++++++++++++------------------------- package.json | 2 +- sync.js | 5 +- 5 files changed, 1208 insertions(+), 1565 deletions(-) diff --git a/common.js b/common.js index 8e363b6c..fc193ee6 100644 --- a/common.js +++ b/common.js @@ -110,6 +110,8 @@ function setopts (self, pattern, options) { // Note that they are not supported in Glob itself anyway. options.nonegate = true options.nocomment = true + // always treat \ in patterns as escapes, not path separators + options.allowWindowsEscape = true self.minimatch = new Minimatch(pattern, options) self.options = self.minimatch.options diff --git a/glob.js b/glob.js index afcf8275..37a4d7e6 100644 --- a/glob.js +++ b/glob.js @@ -342,7 +342,10 @@ Glob.prototype._process = function (pattern, index, inGlobStar, cb) { var read if (prefix === null) read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + else if (isAbsolute(prefix) || + isAbsolute(pattern.map(function (p) { + return typeof p === 'string' ? p : '[*]' + }).join('/'))) { if (!prefix || !isAbsolute(prefix)) prefix = '/' + prefix read = prefix diff --git a/package-lock.json b/package-lock.json index c9baaf9e..40230c24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -30,48 +30,60 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@ampproject/remapping": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.1.tgz", + "integrity": "sha512-Aolwjd7HSC2PyY0fDj/wA/EimQT4HfEnFYNp5s9CQlrdhyvWTtvZ5YzrUPu6R6/1jKiUlxu8bUhkdSnKHNAHMA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "dependencies": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.15.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.5.tgz", - "integrity": "sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.5", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz", + "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.0.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.0", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -82,12 +94,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz", - "integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", + "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4", + "@babel/types": "^7.17.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -96,14 +108,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", "semver": "^6.3.0" }, "engines": { @@ -113,177 +125,150 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "node_modules/@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "node_modules/@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "node_modules/@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz", - "integrity": "sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", "dev": true, "dependencies": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -292,9 +277,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz", - "integrity": "sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -304,32 +289,33 @@ } }, "node_modules/@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", + "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.0", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.0", + "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -338,12 +324,12 @@ } }, "node_modules/@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -366,15 +352,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", @@ -384,6 +361,31 @@ "node": ">=8" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -414,12 +416,12 @@ } }, "node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "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": ">=4" + "node": ">=8" } }, "node_modules/ansi-styles": { @@ -475,9 +477,9 @@ } }, "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dev": true, "dependencies": { "safer-buffer": "~2.1.0" @@ -576,16 +578,16 @@ } }, "node_modules/browserslist": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.1.tgz", - "integrity": "sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001259", - "electron-to-chromium": "^1.3.846", + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", "escalade": "^3.1.1", - "nanocolors": "^0.1.5", - "node-releases": "^1.1.76" + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" }, "bin": { "browserslist": "cli.js" @@ -638,9 +640,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001259", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001259.tgz", - "integrity": "sha512-V7mQTFhjITxuk9zBpI6nYsiTXhcPe05l+364nZjK7MFK/E7ibvYBSAXr4YcA6oPR8j3ZLM/LN+lUqUVAQEUZFg==", + "version": "1.0.30001311", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001311.tgz", + "integrity": "sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==", "dev": true, "funding": { "type": "opencollective", @@ -668,10 +670,16 @@ } }, "node_modules/chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -698,23 +706,14 @@ } }, "node_modules/cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "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": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "engines": { - "node": ">=0.10.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, "node_modules/color-convert": { @@ -825,9 +824,9 @@ } }, "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -891,9 +890,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.3.846", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.846.tgz", - "integrity": "sha512-2jtSwgyiRzybHRxrc2nKI+39wH3AwQgn+sogQ+q814gv8hIFwrcZbV07Ea9f8AmK0ufPVZUvvAG1uZJ+obV4Jw==", + "version": "1.4.68", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", + "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==", "dev": true }, "node_modules/emoji-regex": { @@ -1150,9 +1149,9 @@ } }, "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -1191,9 +1190,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, "node_modules/har-schema": { @@ -1319,18 +1318,18 @@ } }, "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=", + "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": ">=4" + "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==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" @@ -1388,9 +1387,9 @@ "dev": true }, "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true, "engines": { "node": ">=8" @@ -1492,9 +1491,9 @@ } }, "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -1502,7 +1501,7 @@ "source-map": "^0.6.1" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { @@ -1515,9 +1514,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -1528,12 +1527,12 @@ } }, "node_modules/jackspeak": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.0.tgz", - "integrity": "sha512-VDcSunT+wcccoG46FtzuBAyQKlzhHjli4q31e1fIHGOsRspqNUFjVzGb+7eIFDlTvqLygxapDHPHS0ouT2o/tw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.1.tgz", + "integrity": "sha512-npN8f+M4+IQ8xD3CcWi3U62VQwKlT3Tj4GxbdT/fYTmeogD9eBF9OFdpoFG/VPNoshRjPUijdkp/p2XrzUHaVg==", "dev": true, "dependencies": { - "cliui": "^4.1.0" + "cliui": "^7.0.4" }, "engines": { "node": ">=8" @@ -1577,9 +1576,9 @@ } }, "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true }, "node_modules/json-schema-traverse": { @@ -1610,18 +1609,18 @@ } }, "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, - "engines": [ - "node >=0.6.0" - ], "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" } }, "node_modules/lcov-parse": { @@ -1634,9 +1633,9 @@ } }, "node_modules/libtap": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.3.tgz", - "integrity": "sha512-BfbhcSlcFngZWYvDt+gs4m1BkjP0LaFEg6+4FBAXD0E8Br95wpXCCvS5JZHW1a5QPWMrFD4LhsqBpTPRB3Em8g==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.4.tgz", + "integrity": "sha512-jM+QyAeRdVs1bJrNpjlu+l8gRdDkAehqls31AwSnqXghVLUP6nbYeU2Xfs2svYS7ZdksvnHvrxCKRBFEz/BCjA==", "dev": true, "dependencies": { "async-hook-domain": "^2.0.4", @@ -1688,18 +1687,6 @@ "node": ">=0.8.6" } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -1716,9 +1703,9 @@ } }, "node_modules/memfs": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.3.0.tgz", - "integrity": "sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", + "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", "dev": true, "dependencies": { "fs-monkey": "1.0.3" @@ -1728,30 +1715,30 @@ } }, "node_modules/mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, "dependencies": { - "mime-db": "1.49.0" + "mime-db": "1.51.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.1.tgz", + "integrity": "sha512-reLxBcKUPNBnc/sVtAbxgRVFSegoGeLaSjmphNhcwcolhYLRgtJscn5mRl6YRZNQv40Y7P6JM2YhSIsbL9OB5A==", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1766,9 +1753,9 @@ "dev": true }, "node_modules/minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", "dev": true, "dependencies": { "yallist": "^4.0.0" @@ -1795,15 +1782,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/nanocolors": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.6.tgz", - "integrity": "sha512-2pvTw6vYRaBLGir2xR7MxaJtyWkrn+C53EpW8yPotG+pdAwBvt0Xwk4VJ6VHLY0aLthVZPvDfm9TdZvrvAm5UQ==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -1817,9 +1795,9 @@ } }, "node_modules/node-releases": { - "version": "1.1.76", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.76.tgz", - "integrity": "sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", "dev": true }, "node_modules/normalize-path": { @@ -1831,15 +1809,6 @@ "node": ">=0.10.0" } }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/nyc": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", @@ -1881,15 +1850,6 @@ "node": ">=8.9" } }, - "node_modules/nyc/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/nyc/node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -1914,15 +1874,6 @@ "node": "*" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "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", @@ -2050,10 +2001,16 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "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==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" @@ -2086,17 +2043,6 @@ "node": ">=8" } }, - "node_modules/prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -2113,34 +2059,14 @@ } }, "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true, "engines": { "node": ">=0.6" } }, - "node_modules/react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -2212,6 +2138,15 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -2273,9 +2208,9 @@ } }, "node_modules/signal-exit": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", - "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "node_modules/source-map": { @@ -2288,9 +2223,9 @@ } }, "node_modules/source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "dependencies": { "buffer-from": "^1.0.0", @@ -2345,9 +2280,9 @@ "dev": true }, "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "dev": true, "dependencies": { "asn1": "~0.2.3", @@ -2391,28 +2326,29 @@ } }, "node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/strip-bom": { @@ -2437,16 +2373,19 @@ } }, "node_modules/tap": { - "version": "15.0.10", - "resolved": "https://registry.npmjs.org/tap/-/tap-15.0.10.tgz", - "integrity": "sha512-8aq4j+1JUOlXyffLX7ZJxhe9KAxV3s7PsdWAm3XwfoWc/OiFyAMcv4+T0/5/65gBxOVAPLpxH8ecfDkYTA2BCQ==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/tap/-/tap-15.1.6.tgz", + "integrity": "sha512-TN7xH6Q2tUPTd6qwmkhuFJcx1vUR8e4dDUpBKc61G0krOzne7Ia6aKIFb8O/0kVazachSSuVME1V8nQ2xwWL8w==", "bundleDependencies": [ "ink", "treport", - "@types/react" + "@types/react", + "@isaacs/import-jsx", + "react" ], "dev": true, "dependencies": { + "@isaacs/import-jsx": "*", "@types/react": "*", "chokidar": "^3.3.0", "coveralls": "^3.0.11", @@ -2454,24 +2393,23 @@ "foreground-child": "^2.0.0", "fs-exists-cached": "^1.0.0", "glob": "^7.1.6", - "import-jsx": "^4.0.0", "ink": "*", "isexe": "^2.0.0", "istanbul-lib-processinfo": "^2.0.2", - "jackspeak": "^1.4.0", - "libtap": "^1.1.3", + "jackspeak": "^1.4.1", + "libtap": "^1.1.4", "minipass": "^3.1.1", "mkdirp": "^1.0.4", "nyc": "^15.1.0", "opener": "^1.5.1", - "react": "^16.12.0", + "react": "*", "rimraf": "^3.0.0", - "signal-exit": "^3.0.0", + "signal-exit": "^3.0.6", "source-map-support": "^0.5.16", "tap-mocha-reporter": "^5.0.0", "tap-parser": "^10.0.1", "tap-yaml": "^1.0.0", - "tcompare": "^5.0.6", + "tcompare": "^5.0.7", "treport": "*", "which": "^2.0.2" }, @@ -2559,19 +2497,19 @@ } }, "node_modules/tap/node_modules/@babel/code-frame": { - "version": "7.14.5", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/compat-data": { - "version": "7.15.0", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", @@ -2580,20 +2518,20 @@ } }, "node_modules/tap/node_modules/@babel/core": { - "version": "7.15.5", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.5", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4", + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-compilation-targets": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.0", + "@babel/helpers": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -2610,12 +2548,12 @@ } }, "node_modules/tap/node_modules/@babel/generator": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4", + "@babel/types": "^7.16.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -2624,26 +2562,26 @@ } }, "node_modules/tap/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-compilation-targets": { - "version": "7.15.4", + "version": "7.16.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.15.0", + "@babel/compat-data": "^7.16.0", "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", + "browserslist": "^4.17.5", "semver": "^6.3.0" }, "engines": { @@ -2654,93 +2592,93 @@ } }, "node_modules/tap/node_modules/@babel/helper-function-name": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-get-function-arity": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-hoist-variables": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-module-imports": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-module-transforms": { - "version": "7.15.7", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-replace-supers": "^7.16.0", + "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-optimise-call-expression": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -2756,39 +2694,39 @@ } }, "node_modules/tap/node_modules/@babel/helper-replace-supers": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-member-expression-to-functions": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-simple-access": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-split-export-declaration": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -2813,26 +2751,26 @@ } }, "node_modules/tap/node_modules/@babel/helpers": { - "version": "7.15.4", + "version": "7.16.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.3", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/highlight": { - "version": "7.14.5", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.15.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -2841,7 +2779,7 @@ } }, "node_modules/tap/node_modules/@babel/parser": { - "version": "7.15.7", + "version": "7.16.3", "dev": true, "inBundle": true, "license": "MIT", @@ -2853,16 +2791,16 @@ } }, "node_modules/tap/node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.15.6", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", + "@babel/compat-data": "^7.16.0", + "@babel/helper-compilation-targets": "^7.16.0", "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.15.4" + "@babel/plugin-transform-parameters": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -2872,7 +2810,7 @@ } }, "node_modules/tap/node_modules/@babel/plugin-syntax-jsx": { - "version": "7.14.5", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", @@ -2899,7 +2837,7 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-destructuring": { - "version": "7.14.7", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", @@ -2914,7 +2852,7 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-parameters": { - "version": "7.15.4", + "version": "7.16.3", "dev": true, "inBundle": true, "license": "MIT", @@ -2929,16 +2867,16 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.14.9", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-jsx": "^7.14.5", - "@babel/types": "^7.14.9" + "@babel/plugin-syntax-jsx": "^7.16.0", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" @@ -2948,32 +2886,32 @@ } }, "node_modules/tap/node_modules/@babel/template": { - "version": "7.15.4", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/traverse": { - "version": "7.15.4", + "version": "7.16.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.3", + "@babel/types": "^7.16.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2982,18 +2920,71 @@ } }, "node_modules/tap/node_modules/@babel/types": { - "version": "7.15.6", + "version": "7.16.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-validator-identifier": "^7.15.7", "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/tap/node_modules/@isaacs/import-jsx": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.5.5", + "@babel/plugin-proposal-object-rest-spread": "^7.5.5", + "@babel/plugin-transform-destructuring": "^7.5.0", + "@babel/plugin-transform-react-jsx": "^7.3.0", + "caller-path": "^3.0.1", + "find-cache-dir": "^3.2.0", + "make-dir": "^3.0.2", + "resolve-from": "^3.0.0", + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tap/node_modules/@isaacs/import-jsx/node_modules/caller-callsite": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/@isaacs/import-jsx/node_modules/caller-path": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "caller-callsite": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/@isaacs/import-jsx/node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/tap/node_modules/@types/prop-types": { "version": "15.7.4", "dev": true, @@ -3001,7 +2992,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/@types/react": { - "version": "16.14.15", + "version": "17.0.34", "dev": true, "inBundle": true, "license": "MIT", @@ -3038,6 +3029,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/tap/node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "dev": true, + "inBundle": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tap/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/tap/node_modules/ansi-styles": { "version": "3.2.1", "dev": true, @@ -3056,15 +3068,6 @@ "inBundle": true, "license": "MIT" }, - "node_modules/tap/node_modules/arrify": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/tap/node_modules/astral-regex": { "version": "2.0.0", "dev": true, @@ -3103,16 +3106,16 @@ } }, "node_modules/tap/node_modules/browserslist": { - "version": "4.17.0", + "version": "4.17.6", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001254", - "colorette": "^1.3.0", - "electron-to-chromium": "^1.3.830", + "caniuse-lite": "^1.0.30001274", + "electron-to-chromium": "^1.3.886", "escalade": "^3.1.1", - "node-releases": "^1.1.75" + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" }, "bin": { "browserslist": "cli.js" @@ -3125,41 +3128,8 @@ "url": "https://opencollective.com/browserslist" } }, - "node_modules/tap/node_modules/caller-callsite": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tap/node_modules/caller-path": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tap/node_modules/callsites": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/tap/node_modules/caniuse-lite": { - "version": "1.0.30001258", + "version": "1.0.30001279", "dev": true, "inBundle": true, "license": "CC-BY-4.0", @@ -3201,6 +3171,18 @@ "inBundle": true, "license": "MIT" }, + "node_modules/tap/node_modules/cli-boxes": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tap/node_modules/cli-cursor": { "version": "3.1.0", "dev": true, @@ -3229,6 +3211,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/tap/node_modules/code-excerpt": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "convert-to-spaces": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/tap/node_modules/color-convert": { "version": "1.9.3", "dev": true, @@ -3244,12 +3238,6 @@ "inBundle": true, "license": "MIT" }, - "node_modules/tap/node_modules/colorette": { - "version": "1.4.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/tap/node_modules/commondir": { "version": "1.0.1", "dev": true, @@ -3271,6 +3259,15 @@ "safe-buffer": "~5.1.1" } }, + "node_modules/tap/node_modules/convert-to-spaces": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/tap/node_modules/csstype": { "version": "3.0.9", "dev": true, @@ -3295,7 +3292,7 @@ } }, "node_modules/tap/node_modules/electron-to-chromium": { - "version": "1.3.844", + "version": "1.3.893", "dev": true, "inBundle": true, "license": "ISC" @@ -3389,7 +3386,7 @@ } }, "node_modules/tap/node_modules/glob": { - "version": "7.1.7", + "version": "7.2.0", "dev": true, "inBundle": true, "license": "ISC", @@ -3426,24 +3423,13 @@ "node": ">=4" } }, - "node_modules/tap/node_modules/import-jsx": { + "node_modules/tap/node_modules/indent-string": { "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "@babel/core": "^7.5.5", - "@babel/plugin-proposal-object-rest-spread": "^7.5.5", - "@babel/plugin-transform-destructuring": "^7.5.0", - "@babel/plugin-transform-react-jsx": "^7.3.0", - "caller-path": "^2.0.0", - "find-cache-dir": "^3.2.0", - "make-dir": "^3.0.2", - "resolve-from": "^3.0.0", - "rimraf": "^3.0.0" - }, "engines": { - "node": ">=10" + "node": ">=8" } }, "node_modules/tap/node_modules/inflight": { @@ -3463,32 +3449,37 @@ "license": "ISC" }, "node_modules/tap/node_modules/ink": { - "version": "2.7.1", + "version": "3.2.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", - "arrify": "^2.0.1", - "auto-bind": "^4.0.0", - "chalk": "^3.0.0", + "auto-bind": "4.0.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.0", "cli-cursor": "^3.1.0", "cli-truncate": "^2.1.0", + "code-excerpt": "^3.0.0", + "indent-string": "^4.0.0", "is-ci": "^2.0.0", - "lodash.throttle": "^4.1.1", - "log-update": "^3.0.0", - "prop-types": "^15.6.2", - "react-reconciler": "^0.24.0", - "scheduler": "^0.18.0", + "lodash": "^4.17.20", + "patch-console": "^1.0.0", + "react-devtools-core": "^4.19.1", + "react-reconciler": "^0.26.2", + "scheduler": "^0.20.2", "signal-exit": "^3.0.2", "slice-ansi": "^3.0.0", - "string-length": "^3.1.0", + "stack-utils": "^2.0.2", + "string-width": "^4.2.2", + "type-fest": "^0.12.0", "widest-line": "^3.1.0", "wrap-ansi": "^6.2.0", - "yoga-layout-prebuilt": "^1.9.3" + "ws": "^7.5.5", + "yoga-layout-prebuilt": "^1.9.6" }, "engines": { - "node": ">=8" + "node": ">=10" }, "peerDependencies": { "@types/react": ">=16.8.0", @@ -3516,7 +3507,7 @@ } }, "node_modules/tap/node_modules/ink/node_modules/chalk": { - "version": "3.0.0", + "version": "4.1.2", "dev": true, "inBundle": true, "license": "MIT", @@ -3525,7 +3516,10 @@ "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/tap/node_modules/ink/node_modules/color-convert": { @@ -3633,148 +3627,12 @@ "node": ">=8" } }, - "node_modules/tap/node_modules/lodash.throttle": { - "version": "4.1.1", + "node_modules/tap/node_modules/lodash": { + "version": "4.17.21", "dev": true, "inBundle": true, "license": "MIT" }, - "node_modules/tap/node_modules/log-update": { - "version": "3.4.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^3.2.0", - "cli-cursor": "^2.1.0", - "wrap-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tap/node_modules/log-update/node_modules/ansi-escapes": { - "version": "3.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/tap/node_modules/log-update/node_modules/ansi-regex": { - "version": "4.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/tap/node_modules/log-update/node_modules/cli-cursor": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tap/node_modules/log-update/node_modules/emoji-regex": { - "version": "7.0.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/tap/node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/tap/node_modules/log-update/node_modules/mimic-fn": { - "version": "1.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/tap/node_modules/log-update/node_modules/onetime": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tap/node_modules/log-update/node_modules/restore-cursor": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tap/node_modules/log-update/node_modules/string-width": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tap/node_modules/log-update/node_modules/strip-ansi": { - "version": "5.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tap/node_modules/log-update/node_modules/wrap-ansi": { - "version": "5.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/tap/node_modules/loose-envify": { "version": "1.4.0", "dev": true, @@ -3860,7 +3718,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/node-releases": { - "version": "1.1.76", + "version": "2.0.1", "dev": true, "inBundle": true, "license": "MIT" @@ -3934,6 +3792,15 @@ "node": ">=6" } }, + "node_modules/tap/node_modules/patch-console": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/tap/node_modules/path-exists": { "version": "4.0.0", "dev": true, @@ -3952,6 +3819,12 @@ "node": ">=0.10.0" } }, + "node_modules/tap/node_modules/picocolors": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, "node_modules/tap/node_modules/pkg-dir": { "version": "4.2.0", "dev": true, @@ -3964,48 +3837,53 @@ "node": ">=8" } }, - "node_modules/tap/node_modules/prop-types": { - "version": "15.7.2", + "node_modules/tap/node_modules/punycode": { + "version": "2.1.1", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" + "engines": { + "node": ">=6" } }, - "node_modules/tap/node_modules/punycode": { - "version": "2.1.1", + "node_modules/tap/node_modules/react": { + "version": "17.0.2", "dev": true, "inBundle": true, "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/tap/node_modules/react-is": { - "version": "16.13.1", + "node_modules/tap/node_modules/react-devtools-core": { + "version": "4.21.0", "dev": true, "inBundle": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "shell-quote": "^1.6.1", + "ws": "^7" + } }, "node_modules/tap/node_modules/react-reconciler": { - "version": "0.24.0", + "version": "0.26.2", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.18.0" + "scheduler": "^0.20.2" }, "engines": { "node": ">=0.10.0" }, "peerDependencies": { - "react": "^16.0.0" + "react": "^17.0.2" } }, "node_modules/tap/node_modules/redeyed": { @@ -4061,7 +3939,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/scheduler": { - "version": "0.18.0", + "version": "0.20.2", "dev": true, "inBundle": true, "license": "MIT", @@ -4079,8 +3957,14 @@ "semver": "bin/semver.js" } }, + "node_modules/tap/node_modules/shell-quote": { + "version": "1.7.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, "node_modules/tap/node_modules/signal-exit": { - "version": "3.0.4", + "version": "3.0.6", "dev": true, "inBundle": true, "license": "ISC" @@ -4141,79 +4025,48 @@ "node": ">=0.10.0" } }, - "node_modules/tap/node_modules/string-length": { - "version": "3.1.0", + "node_modules/tap/node_modules/stack-utils": { + "version": "2.0.5", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "astral-regex": "^1.0.0", - "strip-ansi": "^5.2.0" + "escape-string-regexp": "^2.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/tap/node_modules/string-length/node_modules/ansi-regex": { - "version": "4.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/tap/node_modules/string-length/node_modules/astral-regex": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/tap/node_modules/string-length/node_modules/strip-ansi": { - "version": "5.2.0", + "node_modules/tap/node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^4.1.0" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/tap/node_modules/string-width": { - "version": "4.2.2", + "version": "4.2.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/tap/node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/tap/node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.0", + "node_modules/tap/node_modules/strip-ansi": { + "version": "6.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" @@ -4267,22 +4120,21 @@ } }, "node_modules/tap/node_modules/treport": { - "version": "2.0.2", + "version": "3.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@isaacs/import-jsx": "^4.0.1", "cardinal": "^2.1.1", "chalk": "^3.0.0", - "import-jsx": "^4.0.0", - "ink": "^2.6.0", + "ink": "^3.2.0", "ms": "^2.1.2", - "string-length": "^3.1.0", "tap-parser": "^10.0.1", "unicode-length": "^2.0.2" }, "peerDependencies": { - "react": "^16.8.6" + "react": "^17.0.2" } }, "node_modules/tap/node_modules/treport/node_modules/ansi-styles": { @@ -4353,7 +4205,7 @@ } }, "node_modules/tap/node_modules/type-fest": { - "version": "0.21.3", + "version": "0.12.0", "dev": true, "inBundle": true, "license": "(MIT OR CC0-1.0)", @@ -4421,15 +4273,6 @@ "node": ">=8" } }, - "node_modules/tap/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/tap/node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "dev": true, @@ -4463,24 +4306,33 @@ "inBundle": true, "license": "MIT" }, - "node_modules/tap/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.0", + "node_modules/tap/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/tap/node_modules/ws": { + "version": "7.5.5", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.0" - }, "engines": { - "node": ">=8" + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/tap/node_modules/wrappy": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/tap/node_modules/yallist": { "version": "4.0.0", "dev": true, @@ -4509,9 +4361,9 @@ } }, "node_modules/tcompare": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.6.tgz", - "integrity": "sha512-OvO7omN/wkdsKzmOqr3sQFfLbghs/2X5mwSkcfgRiXZshfPnTsAs3IRf1RixR/Pff26qG/r9ogcZMpV0YdeGXg==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.7.tgz", + "integrity": "sha512-d9iddt6YYGgyxJw5bjsN7UJUO1kGOtjSlNy/4PoGYAjQS5pAT/hzIoLf1bZCw+uUxRmZJh7Yy1aA7xKVRT9B4w==", "dev": true, "dependencies": { "diff": "^4.0.2" @@ -4711,65 +4563,55 @@ "dev": true }, "node_modules/wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "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": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "dependencies": { - "number-is-nan": "^1.0.0" + "node": ">=10" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "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": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "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": { - "ansi-regex": "^2.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=0.10.0" + "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", @@ -4849,15 +4691,6 @@ "node": ">=6" } }, - "node_modules/yargs/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/yargs/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4902,41 +4735,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/yargs/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/yargs/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/yargs/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/yargs/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -4953,244 +4751,233 @@ } }, "dependencies": { + "@ampproject/remapping": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.1.tgz", + "integrity": "sha512-Aolwjd7HSC2PyY0fDj/wA/EimQT4HfEnFYNp5s9CQlrdhyvWTtvZ5YzrUPu6R6/1jKiUlxu8bUhkdSnKHNAHMA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.0" + } + }, "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", "dev": true, "requires": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.16.7" } }, "@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", + "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", "dev": true }, "@babel/core": { - "version": "7.15.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.5.tgz", - "integrity": "sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz", + "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==", "dev": true, "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.5", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4", + "@ampproject/remapping": "^2.0.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.17.2", + "@babel/parser": "^7.17.0", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "semver": "^6.3.0" } }, "@babel/generator": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz", - "integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", + "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", "dev": true, "requires": { - "@babel/types": "^7.15.4", + "@babel/types": "^7.17.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", "dev": true, "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", "semver": "^6.3.0" } }, - "@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, - "@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" } }, - "@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, "@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, "@babel/helper-module-transforms": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz", - "integrity": "sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", "dev": true, "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, "@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.7" } }, "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", "dev": true }, "@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", + "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", "dev": true, "requires": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.0", + "@babel/types": "^7.17.0" } }, "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz", - "integrity": "sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==", "dev": true }, "@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", "dev": true, "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", + "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", "dev": true, "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.0", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.0", + "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } }, @@ -5205,14 +4992,6 @@ "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } } }, "@istanbuljs/schema": { @@ -5221,6 +5000,28 @@ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, + "@jridgewell/resolve-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", + "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", + "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", + "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -5244,9 +5045,9 @@ } }, "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "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": { @@ -5293,9 +5094,9 @@ } }, "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dev": true, "requires": { "safer-buffer": "~2.1.0" @@ -5376,16 +5177,16 @@ } }, "browserslist": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.1.tgz", - "integrity": "sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ==", + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001259", - "electron-to-chromium": "^1.3.846", + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", "escalade": "^3.1.1", - "nanocolors": "^0.1.5", - "node-releases": "^1.1.76" + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" } }, "buffer-from": { @@ -5419,9 +5220,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001259", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001259.tgz", - "integrity": "sha512-V7mQTFhjITxuk9zBpI6nYsiTXhcPe05l+364nZjK7MFK/E7ibvYBSAXr4YcA6oPR8j3ZLM/LN+lUqUVAQEUZFg==", + "version": "1.0.30001311", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001311.tgz", + "integrity": "sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==", "dev": true }, "caseless": { @@ -5442,9 +5243,9 @@ } }, "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { "anymatch": "~3.1.2", @@ -5464,22 +5265,16 @@ "dev": true }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -5570,9 +5365,9 @@ } }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -5616,9 +5411,9 @@ } }, "electron-to-chromium": { - "version": "1.3.846", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.846.tgz", - "integrity": "sha512-2jtSwgyiRzybHRxrc2nKI+39wH3AwQgn+sogQ+q814gv8hIFwrcZbV07Ea9f8AmK0ufPVZUvvAG1uZJ+obV4Jw==", + "version": "1.4.68", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", + "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==", "dev": true }, "emoji-regex": { @@ -5808,9 +5603,9 @@ } }, "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -5837,9 +5632,9 @@ "dev": true }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, "har-schema": { @@ -5933,15 +5728,15 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -5984,9 +5779,9 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true }, "istanbul-lib-hook": { @@ -6065,9 +5860,9 @@ } }, "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "requires": { "debug": "^4.1.1", @@ -6084,9 +5879,9 @@ } }, "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -6094,12 +5889,12 @@ } }, "jackspeak": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.0.tgz", - "integrity": "sha512-VDcSunT+wcccoG46FtzuBAyQKlzhHjli4q31e1fIHGOsRspqNUFjVzGb+7eIFDlTvqLygxapDHPHS0ouT2o/tw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.1.tgz", + "integrity": "sha512-npN8f+M4+IQ8xD3CcWi3U62VQwKlT3Tj4GxbdT/fYTmeogD9eBF9OFdpoFG/VPNoshRjPUijdkp/p2XrzUHaVg==", "dev": true, "requires": { - "cliui": "^4.1.0" + "cliui": "^7.0.4" } }, "js-tokens": { @@ -6131,9 +5926,9 @@ "dev": true }, "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "dev": true }, "json-schema-traverse": { @@ -6158,14 +5953,14 @@ } }, "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", - "json-schema": "0.2.3", + "json-schema": "0.4.0", "verror": "1.10.0" } }, @@ -6176,9 +5971,9 @@ "dev": true }, "libtap": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.3.tgz", - "integrity": "sha512-BfbhcSlcFngZWYvDt+gs4m1BkjP0LaFEg6+4FBAXD0E8Br95wpXCCvS5JZHW1a5QPWMrFD4LhsqBpTPRB3Em8g==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.4.tgz", + "integrity": "sha512-jM+QyAeRdVs1bJrNpjlu+l8gRdDkAehqls31AwSnqXghVLUP6nbYeU2Xfs2svYS7ZdksvnHvrxCKRBFEz/BCjA==", "dev": true, "requires": { "async-hook-domain": "^2.0.4", @@ -6218,15 +6013,6 @@ "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -6237,33 +6023,33 @@ } }, "memfs": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.3.0.tgz", - "integrity": "sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", + "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", "dev": true, "requires": { "fs-monkey": "1.0.3" } }, "mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", + "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true }, "mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "version": "2.1.34", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", + "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, "requires": { - "mime-db": "1.49.0" + "mime-db": "1.51.0" } }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.1.tgz", + "integrity": "sha512-reLxBcKUPNBnc/sVtAbxgRVFSegoGeLaSjmphNhcwcolhYLRgtJscn5mRl6YRZNQv40Y7P6JM2YhSIsbL9OB5A==", "requires": { "brace-expansion": "^1.1.7" } @@ -6275,9 +6061,9 @@ "dev": true }, "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -6298,12 +6084,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "nanocolors": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.1.6.tgz", - "integrity": "sha512-2pvTw6vYRaBLGir2xR7MxaJtyWkrn+C53EpW8yPotG+pdAwBvt0Xwk4VJ6VHLY0aLthVZPvDfm9TdZvrvAm5UQ==", - "dev": true - }, "node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -6314,9 +6094,9 @@ } }, "node-releases": { - "version": "1.1.76", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.76.tgz", - "integrity": "sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", + "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", "dev": true }, "normalize-path": { @@ -6325,12 +6105,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "nyc": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", @@ -6366,12 +6140,6 @@ "yargs": "^15.0.2" }, "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -6389,12 +6157,6 @@ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -6492,10 +6254,16 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pkg-dir": { @@ -6516,17 +6284,6 @@ "fromentries": "^1.2.0" } }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -6540,26 +6297,9 @@ "dev": true }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true }, "readdirp": { @@ -6620,6 +6360,12 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -6669,9 +6415,9 @@ "dev": true }, "signal-exit": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", - "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "source-map": { @@ -6681,9 +6427,9 @@ "dev": true }, "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -6730,9 +6476,9 @@ "dev": true }, "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", + "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -6764,22 +6510,23 @@ } }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { @@ -6798,11 +6545,12 @@ } }, "tap": { - "version": "15.0.10", - "resolved": "https://registry.npmjs.org/tap/-/tap-15.0.10.tgz", - "integrity": "sha512-8aq4j+1JUOlXyffLX7ZJxhe9KAxV3s7PsdWAm3XwfoWc/OiFyAMcv4+T0/5/65gBxOVAPLpxH8ecfDkYTA2BCQ==", + "version": "15.1.6", + "resolved": "https://registry.npmjs.org/tap/-/tap-15.1.6.tgz", + "integrity": "sha512-TN7xH6Q2tUPTd6qwmkhuFJcx1vUR8e4dDUpBKc61G0krOzne7Ia6aKIFb8O/0kVazachSSuVME1V8nQ2xwWL8w==", "dev": true, "requires": { + "@isaacs/import-jsx": "*", "@types/react": "*", "chokidar": "^3.3.0", "coveralls": "^3.0.11", @@ -6810,55 +6558,54 @@ "foreground-child": "^2.0.0", "fs-exists-cached": "^1.0.0", "glob": "^7.1.6", - "import-jsx": "^4.0.0", "ink": "*", "isexe": "^2.0.0", "istanbul-lib-processinfo": "^2.0.2", - "jackspeak": "^1.4.0", - "libtap": "^1.1.3", + "jackspeak": "^1.4.1", + "libtap": "^1.1.4", "minipass": "^3.1.1", "mkdirp": "^1.0.4", "nyc": "^15.1.0", "opener": "^1.5.1", - "react": "^16.12.0", + "react": "*", "rimraf": "^3.0.0", - "signal-exit": "^3.0.0", + "signal-exit": "^3.0.6", "source-map-support": "^0.5.16", "tap-mocha-reporter": "^5.0.0", "tap-parser": "^10.0.1", "tap-yaml": "^1.0.0", - "tcompare": "^5.0.6", + "tcompare": "^5.0.7", "treport": "*", "which": "^2.0.2" }, "dependencies": { "@babel/code-frame": { - "version": "7.14.5", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.16.0" } }, "@babel/compat-data": { - "version": "7.15.0", + "version": "7.16.0", "bundled": true, "dev": true }, "@babel/core": { - "version": "7.15.5", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.5", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4", + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-compilation-targets": "^7.16.0", + "@babel/helper-module-transforms": "^7.16.0", + "@babel/helpers": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -6868,97 +6615,97 @@ } }, "@babel/generator": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.15.4", + "@babel/types": "^7.16.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-annotate-as-pure": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-compilation-targets": { - "version": "7.15.4", + "version": "7.16.3", "bundled": true, "dev": true, "requires": { - "@babel/compat-data": "^7.15.0", + "@babel/compat-data": "^7.16.0", "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", + "browserslist": "^4.17.5", "semver": "^6.3.0" } }, "@babel/helper-function-name": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-get-function-arity": "^7.16.0", + "@babel/template": "^7.16.0", + "@babel/types": "^7.16.0" } }, "@babel/helper-get-function-arity": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-hoist-variables": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-module-imports": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-module-transforms": { - "version": "7.15.7", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-module-imports": "^7.16.0", + "@babel/helper-replace-supers": "^7.16.0", + "@babel/helper-simple-access": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" } }, "@babel/helper-optimise-call-expression": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-plugin-utils": { @@ -6967,30 +6714,30 @@ "dev": true }, "@babel/helper-replace-supers": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/helper-member-expression-to-functions": "^7.16.0", + "@babel/helper-optimise-call-expression": "^7.16.0", + "@babel/traverse": "^7.16.0", + "@babel/types": "^7.16.0" } }, "@babel/helper-simple-access": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-split-export-declaration": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.16.0" } }, "@babel/helper-validator-identifier": { @@ -7004,44 +6751,44 @@ "dev": true }, "@babel/helpers": { - "version": "7.15.4", + "version": "7.16.3", "bundled": true, "dev": true, "requires": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/template": "^7.16.0", + "@babel/traverse": "^7.16.3", + "@babel/types": "^7.16.0" } }, "@babel/highlight": { - "version": "7.14.5", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.15.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.15.7", + "version": "7.16.3", "bundled": true, "dev": true }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.15.6", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", + "@babel/compat-data": "^7.16.0", + "@babel/helper-compilation-targets": "^7.16.0", "@babel/helper-plugin-utils": "^7.14.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.15.4" + "@babel/plugin-transform-parameters": "^7.16.0" } }, "@babel/plugin-syntax-jsx": { - "version": "7.14.5", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { @@ -7057,7 +6804,7 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.14.7", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { @@ -7065,7 +6812,7 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.15.4", + "version": "7.16.3", "bundled": true, "dev": true, "requires": { @@ -7073,59 +6820,98 @@ } }, "@babel/plugin-transform-react-jsx": { - "version": "7.14.9", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-jsx": "^7.14.5", - "@babel/types": "^7.14.9" + "@babel/plugin-syntax-jsx": "^7.16.0", + "@babel/types": "^7.16.0" } }, "@babel/template": { - "version": "7.15.4", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/code-frame": "^7.16.0", + "@babel/parser": "^7.16.0", + "@babel/types": "^7.16.0" } }, "@babel/traverse": { - "version": "7.15.4", + "version": "7.16.3", "bundled": true, "dev": true, "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", + "@babel/code-frame": "^7.16.0", + "@babel/generator": "^7.16.0", + "@babel/helper-function-name": "^7.16.0", + "@babel/helper-hoist-variables": "^7.16.0", + "@babel/helper-split-export-declaration": "^7.16.0", + "@babel/parser": "^7.16.3", + "@babel/types": "^7.16.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.15.6", + "version": "7.16.0", "bundled": true, "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-validator-identifier": "^7.15.7", "to-fast-properties": "^2.0.0" } }, + "@isaacs/import-jsx": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "@babel/core": "^7.5.5", + "@babel/plugin-proposal-object-rest-spread": "^7.5.5", + "@babel/plugin-transform-destructuring": "^7.5.0", + "@babel/plugin-transform-react-jsx": "^7.3.0", + "caller-path": "^3.0.1", + "find-cache-dir": "^3.2.0", + "make-dir": "^3.0.2", + "resolve-from": "^3.0.0", + "rimraf": "^3.0.0" + }, + "dependencies": { + "caller-callsite": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "callsites": "^3.1.0" + } + }, + "caller-path": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "caller-callsite": "^4.1.0" + } + }, + "callsites": { + "version": "3.1.0", + "bundled": true, + "dev": true + } + } + }, "@types/prop-types": { "version": "15.7.4", "bundled": true, "dev": true }, "@types/react": { - "version": "16.14.15", + "version": "17.0.34", "bundled": true, "dev": true, "requires": { @@ -7150,8 +6936,20 @@ "dev": true, "requires": { "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "bundled": true, + "dev": true + } } }, + "ansi-regex": { + "version": "5.0.1", + "bundled": true, + "dev": true + }, "ansi-styles": { "version": "3.2.1", "bundled": true, @@ -7165,11 +6963,6 @@ "bundled": true, "dev": true }, - "arrify": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, "astral-regex": { "version": "2.0.0", "bundled": true, @@ -7195,40 +6988,19 @@ } }, "browserslist": { - "version": "4.17.0", + "version": "4.17.6", "bundled": true, "dev": true, "requires": { - "caniuse-lite": "^1.0.30001254", - "colorette": "^1.3.0", - "electron-to-chromium": "^1.3.830", + "caniuse-lite": "^1.0.30001274", + "electron-to-chromium": "^1.3.886", "escalade": "^3.1.1", - "node-releases": "^1.1.75" - } - }, - "caller-callsite": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "callsites": "^2.0.0" + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" } }, - "caller-path": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, "caniuse-lite": { - "version": "1.0.30001258", + "version": "1.0.30001279", "bundled": true, "dev": true }, @@ -7256,6 +7028,11 @@ "bundled": true, "dev": true }, + "cli-boxes": { + "version": "2.2.1", + "bundled": true, + "dev": true + }, "cli-cursor": { "version": "3.1.0", "bundled": true, @@ -7273,6 +7050,14 @@ "string-width": "^4.2.0" } }, + "code-excerpt": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "convert-to-spaces": "^1.0.1" + } + }, "color-convert": { "version": "1.9.3", "bundled": true, @@ -7286,11 +7071,6 @@ "bundled": true, "dev": true }, - "colorette": { - "version": "1.4.0", - "bundled": true, - "dev": true - }, "commondir": { "version": "1.0.1", "bundled": true, @@ -7309,6 +7089,11 @@ "safe-buffer": "~5.1.1" } }, + "convert-to-spaces": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, "csstype": { "version": "3.0.9", "bundled": true, @@ -7323,7 +7108,7 @@ } }, "electron-to-chromium": { - "version": "1.3.844", + "version": "1.3.893", "bundled": true, "dev": true }, @@ -7382,7 +7167,7 @@ "dev": true }, "glob": { - "version": "7.1.7", + "version": "7.2.0", "bundled": true, "dev": true, "requires": { @@ -7404,21 +7189,10 @@ "bundled": true, "dev": true }, - "import-jsx": { + "indent-string": { "version": "4.0.0", "bundled": true, - "dev": true, - "requires": { - "@babel/core": "^7.5.5", - "@babel/plugin-proposal-object-rest-spread": "^7.5.5", - "@babel/plugin-transform-destructuring": "^7.5.0", - "@babel/plugin-transform-react-jsx": "^7.3.0", - "caller-path": "^2.0.0", - "find-cache-dir": "^3.2.0", - "make-dir": "^3.0.2", - "resolve-from": "^3.0.0", - "rimraf": "^3.0.0" - } + "dev": true }, "inflight": { "version": "1.0.6", @@ -7435,28 +7209,33 @@ "dev": true }, "ink": { - "version": "2.7.1", + "version": "3.2.0", "bundled": true, "dev": true, "requires": { "ansi-escapes": "^4.2.1", - "arrify": "^2.0.1", - "auto-bind": "^4.0.0", - "chalk": "^3.0.0", + "auto-bind": "4.0.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.0", "cli-cursor": "^3.1.0", "cli-truncate": "^2.1.0", + "code-excerpt": "^3.0.0", + "indent-string": "^4.0.0", "is-ci": "^2.0.0", - "lodash.throttle": "^4.1.1", - "log-update": "^3.0.0", - "prop-types": "^15.6.2", - "react-reconciler": "^0.24.0", - "scheduler": "^0.18.0", + "lodash": "^4.17.20", + "patch-console": "^1.0.0", + "react-devtools-core": "^4.19.1", + "react-reconciler": "^0.26.2", + "scheduler": "^0.20.2", "signal-exit": "^3.0.2", "slice-ansi": "^3.0.0", - "string-length": "^3.1.0", + "stack-utils": "^2.0.2", + "string-width": "^4.2.2", + "type-fest": "^0.12.0", "widest-line": "^3.1.0", "wrap-ansi": "^6.2.0", - "yoga-layout-prebuilt": "^1.9.3" + "ws": "^7.5.5", + "yoga-layout-prebuilt": "^1.9.6" }, "dependencies": { "ansi-styles": { @@ -7468,7 +7247,7 @@ } }, "chalk": { - "version": "3.0.0", + "version": "4.1.2", "bundled": true, "dev": true, "requires": { @@ -7543,101 +7322,11 @@ "p-locate": "^4.1.0" } }, - "lodash.throttle": { - "version": "4.1.1", + "lodash": { + "version": "4.17.21", "bundled": true, "dev": true }, - "log-update": { - "version": "3.4.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "cli-cursor": "^2.1.0", - "wrap-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "bundled": true, - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "onetime": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "string-width": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - } - } - }, "loose-envify": { "version": "1.4.0", "bundled": true, @@ -7692,7 +7381,7 @@ "dev": true }, "node-releases": { - "version": "1.1.76", + "version": "2.0.1", "bundled": true, "dev": true }, @@ -7738,6 +7427,11 @@ "bundled": true, "dev": true }, + "patch-console": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, "path-exists": { "version": "4.0.0", "bundled": true, @@ -7748,6 +7442,11 @@ "bundled": true, "dev": true }, + "picocolors": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, "pkg-dir": { "version": "4.2.0", "bundled": true, @@ -7756,35 +7455,37 @@ "find-up": "^4.0.0" } }, - "prop-types": { - "version": "15.7.2", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, "punycode": { "version": "2.1.1", "bundled": true, "dev": true }, - "react-is": { - "version": "16.13.1", + "react": { + "version": "17.0.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-devtools-core": { + "version": "4.21.0", + "bundled": true, + "dev": true, + "requires": { + "shell-quote": "^1.6.1", + "ws": "^7" + } }, "react-reconciler": { - "version": "0.24.0", + "version": "0.26.2", "bundled": true, "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.18.0" + "scheduler": "^0.20.2" } }, "redeyed": { @@ -7823,7 +7524,7 @@ "dev": true }, "scheduler": { - "version": "0.18.0", + "version": "0.20.2", "bundled": true, "dev": true, "requires": { @@ -7836,8 +7537,13 @@ "bundled": true, "dev": true }, + "shell-quote": { + "version": "1.7.3", + "bundled": true, + "dev": true + }, "signal-exit": { - "version": "3.0.4", + "version": "3.0.6", "bundled": true, "dev": true }, @@ -7879,58 +7585,37 @@ "bundled": true, "dev": true }, - "string-length": { - "version": "3.1.0", + "stack-utils": { + "version": "2.0.5", "bundled": true, "dev": true, "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^5.2.0" + "escape-string-regexp": "^2.0.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "astral-regex": { - "version": "1.0.0", + "escape-string-regexp": { + "version": "2.0.0", "bundled": true, "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } } } }, "string-width": { - "version": "4.2.2", + "version": "4.2.3", "bundled": true, "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" } }, "supports-color": { @@ -7965,16 +7650,15 @@ "dev": true }, "treport": { - "version": "2.0.2", + "version": "3.0.2", "bundled": true, "dev": true, "requires": { + "@isaacs/import-jsx": "^4.0.1", "cardinal": "^2.1.1", "chalk": "^3.0.0", - "import-jsx": "^4.0.0", - "ink": "^2.6.0", + "ink": "^3.2.0", "ms": "^2.1.2", - "string-length": "^3.1.0", "tap-parser": "^10.0.1", "unicode-length": "^2.0.2" }, @@ -8025,7 +7709,7 @@ } }, "type-fest": { - "version": "0.21.3", + "version": "0.12.0", "bundled": true, "dev": true }, @@ -8071,11 +7755,6 @@ "strip-ansi": "^6.0.0" }, "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, "ansi-styles": { "version": "4.3.0", "bundled": true, @@ -8096,14 +7775,6 @@ "version": "1.1.4", "bundled": true, "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } } } }, @@ -8112,6 +7783,12 @@ "bundled": true, "dev": true }, + "ws": { + "version": "7.5.5", + "bundled": true, + "dev": true, + "requires": {} + }, "yallist": { "version": "4.0.0", "bundled": true, @@ -8177,9 +7854,9 @@ } }, "tcompare": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.6.tgz", - "integrity": "sha512-OvO7omN/wkdsKzmOqr3sQFfLbghs/2X5mwSkcfgRiXZshfPnTsAs3IRf1RixR/Pff26qG/r9ogcZMpV0YdeGXg==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.7.tgz", + "integrity": "sha512-d9iddt6YYGgyxJw5bjsN7UJUO1kGOtjSlNy/4PoGYAjQS5pAT/hzIoLf1bZCw+uUxRmZJh7Yy1aA7xKVRT9B4w==", "dev": true, "requires": { "diff": "^4.0.2" @@ -8335,49 +8012,39 @@ "dev": true }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "color-convert": "^2.0.1" } }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "color-name": "~1.1.4" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } + "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 } } }, @@ -8441,12 +8108,6 @@ "yargs-parser": "^18.1.2" }, "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -8482,32 +8143,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "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", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", diff --git a/package.json b/package.json index cc1a57a8..e6ab5e63 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, diff --git a/sync.js b/sync.js index 4f46f905..c705a9c0 100644 --- a/sync.js +++ b/sync.js @@ -109,7 +109,10 @@ GlobSync.prototype._process = function (pattern, index, inGlobStar) { var read if (prefix === null) read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + else if (isAbsolute(prefix) || + isAbsolute(pattern.map(function (p) { + return typeof p === 'string' ? p : '[*]' + }).join('/'))) { if (!prefix || !isAbsolute(prefix)) prefix = '/' + prefix read = prefix From 965f939a2871dbd207375d2e6e254bbd37740a33 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sat, 12 Feb 2022 20:25:12 -0800 Subject: [PATCH 007/163] 7.2.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40230c24..cb598bb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "glob", - "version": "7.2.0", + "version": "7.2.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "glob", - "version": "7.2.0", + "version": "7.2.1", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", diff --git a/package.json b/package.json index e6ab5e63..0c486d84 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "7.2.0", + "version": "7.2.1", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" From bd836b732c5f9b39bc09d8a9afd7e71358582a61 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sat, 26 Feb 2022 21:48:39 -0800 Subject: [PATCH 008/163] ci, update tests, pass with bash 5.2 --- .github/.github/FUNDING.yml | 3 -- .github/workflows/ci.yml | 39 ++++++++++++++++ .github/workflows/commit-if-modified.sh | 13 ++++++ .github/workflows/copyright-year.sh | 15 +++++++ .github/workflows/isaacs-makework.yml | 37 +++++++++++++++ .github/workflows/package-json-repo.js | 16 +++++++ .travis.yml | 14 ------ package.json | 4 ++ test/00-setup.js | 6 +-- test/bash-results.json | 60 ++++++++++++------------- 10 files changed, 157 insertions(+), 50 deletions(-) delete mode 100644 .github/.github/FUNDING.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/commit-if-modified.sh create mode 100644 .github/workflows/copyright-year.sh create mode 100644 .github/workflows/isaacs-makework.yml create mode 100644 .github/workflows/package-json-repo.js delete mode 100644 .travis.yml diff --git a/.github/.github/FUNDING.yml b/.github/.github/FUNDING.yml deleted file mode 100644 index 20d8c03a..00000000 --- a/.github/.github/FUNDING.yml +++ /dev/null @@ -1,3 +0,0 @@ -# These are supported funding model platforms - -github: [isaacs] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..13c3032f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,39 @@ +name: CI + +on: [push, pull_request] + +jobs: + build: + strategy: + matrix: + node-version: [12.x, 14.x, 16.x, 17.x] + platform: + - os: ubuntu-latest + shell: bash + - os: macos-latest + shell: bash + - os: windows-latest + shell: bash + - os: windows-latest + shell: powershell + fail-fast: false + + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + + steps: + - name: Checkout Repository + uses: actions/checkout@v1.1.0 + + - name: Use Nodejs ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: Install dependencies + run: npm install + + - name: Run Tests + run: npm test -- -c -t0 diff --git a/.github/workflows/commit-if-modified.sh b/.github/workflows/commit-if-modified.sh new file mode 100644 index 00000000..e951d3fb --- /dev/null +++ b/.github/workflows/commit-if-modified.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +git config --global user.email "$1" +shift +git config --global user.name "$1" +shift +message="$1" +shift +if [ $(git status --porcelain "$@" | egrep '^ M' | wc -l) -gt 0 ]; then + git add "$@" + git commit -m "$message" + git push || git pull --rebase + git push +fi diff --git a/.github/workflows/copyright-year.sh b/.github/workflows/copyright-year.sh new file mode 100644 index 00000000..92fdbe5f --- /dev/null +++ b/.github/workflows/copyright-year.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +dir=${1:-$PWD} +dates=($(git log --date=format:%Y --pretty=format:'%ad' --reverse | sort | uniq)) +if [ "${#dates[@]}" -eq 1 ]; then + datestr="${dates}" +else + datestr="${dates}-${dates[${#dates[@]}-1]}" +fi + +stripDate='s/^((.*)Copyright\b(.*?))((?:,\s*)?(([0-9]{4}\s*-\s*[0-9]{4})|(([0-9]{4},\s*)*[0-9]{4})))(?:,)?\s*(.*)\n$/$1$9\n/g' +addDate='s/^.*Copyright(?:\s*\(c\))? /Copyright \(c\) '$datestr' /g' +for l in $dir/LICENSE*; do + perl -pi -e "$stripDate" $l + perl -pi -e "$addDate" $l +done diff --git a/.github/workflows/isaacs-makework.yml b/.github/workflows/isaacs-makework.yml new file mode 100644 index 00000000..8eb5e855 --- /dev/null +++ b/.github/workflows/isaacs-makework.yml @@ -0,0 +1,37 @@ +name: "various tidying up tasks to silence nagging" + +on: + push: + branches: + - main + workflow_dispatch: + +jobs: + makework: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Use Node.js + uses: actions/setup-node@v2.1.4 + with: + node-version: 16.x + - name: put repo in package.json + run: node .github/workflows/package-json-repo.js + - name: check in package.json if modified + run: | + bash -x .github/workflows/commit-if-modified.sh \ + "package-json-repo-bot@example.com" \ + "package.json Repo Bot" \ + "chore: add repo to package.json" \ + package.json package-lock.json + - name: put all dates in license copyright line + run: bash .github/workflows/copyright-year.sh + - name: check in licenses if modified + run: | + bash .github/workflows/commit-if-modified.sh \ + "license-year-bot@example.com" \ + "License Year Bot" \ + "chore: add copyright year to license" \ + LICENSE* diff --git a/.github/workflows/package-json-repo.js b/.github/workflows/package-json-repo.js new file mode 100644 index 00000000..b28151b6 --- /dev/null +++ b/.github/workflows/package-json-repo.js @@ -0,0 +1,16 @@ +#!/usr/bin/env node + +const pf = require.resolve(`${process.cwd()}/package.json`) +const pj = require(pf) + +if (!pj.repository && process.env.GITHUB_REPOSITORY) { + const fs = require('fs') + const server = process.env.GITHUB_SERVER_URL || 'https://github.com' + const repo = `${server}/${process.env.GITHUB_REPOSITORY}` + pj.repository = repo + const json = fs.readFileSync(pf, 'utf8') + const match = json.match(/^\s*\{[\r\n]+([ \t]*)"/) + const indent = match[1] + const output = JSON.stringify(pj, null, indent || 2) + '\n' + fs.writeFileSync(pf, output) +} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 82f89217..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: node_js - -node_js: - - node - - 12 - - 10 - - 8 - -cache: - directories: - - $HOME/.npm - -notifications: - email: false diff --git a/package.json b/package.json index 0c486d84..26ba0f74 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,10 @@ "tap": { "before": "test/00-setup.js", "after": "test/zz-cleanup.js", + "statements": 90, + "branches": 90, + "functions": 90, + "lines": 90, "jobs": 1 }, "scripts": { diff --git a/test/00-setup.js b/test/00-setup.js index adb48a40..65ab0ca3 100644 --- a/test/00-setup.js +++ b/test/00-setup.js @@ -92,14 +92,14 @@ var globs = ,"a/**/[cg]/../[cg]" ,"a/{b,c,d,e,f}/**/g" ,"a/b/**" - ,"**/g" + ,"./**/g" ,"a/abc{fed,def}/g/h" ,"a/abc{fed/g,def}/**/" ,"a/abc{fed/g,def}/**///**/" - ,"**/a/**/" + ,"./**/a/**/" ,"+(a|b|c)/a{/,bc*}/**" ,"*/*/*/f" - ,"**/f" + ,"./**/f" ,"a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**" ,"{./*/*,/tmp/glob-test/*}" ,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me! diff --git a/test/bash-results.json b/test/bash-results.json index a833af76..42d9dd2b 100644 --- a/test/bash-results.json +++ b/test/bash-results.json @@ -16,9 +16,9 @@ "a/b/c", "a/b/c/d" ], - "**/g": [ - "a/abcdef/g", - "a/abcfed/g" + "./**/g": [ + "./a/abcdef/g", + "./a/abcfed/g" ], "a/abc{fed,def}/g/h": [ "a/abcdef/g/h", @@ -34,30 +34,30 @@ "a/abcdef/g", "a/abcfed/g" ], - "**/a/**/": [ - "a", - "a/abcdef", - "a/abcdef/g", - "a/abcfed", - "a/abcfed/g", - "a/b", - "a/b/c", - "a/bc", - "a/bc/e", - "a/c", - "a/c/d", - "a/c/d/c", - "a/cb", - "a/cb/e", - "a/symlink", - "a/symlink/a", - "a/symlink/a/b", - "a/symlink/a/b/c", - "a/symlink/a/b/c/a", - "a/symlink/a/b/c/a/b", - "a/symlink/a/b/c/a/b/c", - "a/x", - "a/z" + "./**/a/**/": [ + "./a", + "./a/abcdef", + "./a/abcdef/g", + "./a/abcfed", + "./a/abcfed/g", + "./a/b", + "./a/b/c", + "./a/bc", + "./a/bc/e", + "./a/c", + "./a/c/d", + "./a/c/d/c", + "./a/cb", + "./a/cb/e", + "./a/symlink", + "./a/symlink/a", + "./a/symlink/a/b", + "./a/symlink/a/b/c", + "./a/symlink/a/b/c/a", + "./a/symlink/a/b/c/a/b", + "./a/symlink/a/b/c/a/b/c", + "./a/x", + "./a/z" ], "+(a|b|c)/a{/,bc*}/**": [ "a/abcdef", @@ -71,9 +71,9 @@ "a/bc/e/f", "a/cb/e/f" ], - "**/f": [ - "a/bc/e/f", - "a/cb/e/f" + "./**/f": [ + "./a/bc/e/f", + "./a/cb/e/f" ], "a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [ "a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", From 6d021314c8b6d29f3704a75ca4a17874b2db7483 Mon Sep 17 00:00:00 2001 From: License Year Bot Date: Sun, 27 Feb 2022 05:49:04 +0000 Subject: [PATCH 009/163] chore: add copyright year to license --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 42ca266d..631b8062 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) Isaac Z. Schlueter and Contributors +Copyright (c) 2009-2022 Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above From 8b5eb93439ac60c6ea8cc8910dac6ea7553f31b0 Mon Sep 17 00:00:00 2001 From: kellertk Date: Fri, 18 Mar 2022 10:10:59 -0700 Subject: [PATCH 010/163] Update LICENSE to remove logo text Remove the glob logo licensing information from LICENSE as this information is already in README.md. See #459. PR-URL: https://github.com/isaacs/node-glob/pull/463 Credit: @kellertk Close: #463 Reviewed-by: @isaacs --- LICENSE | 6 ------ 1 file changed, 6 deletions(-) diff --git a/LICENSE b/LICENSE index 631b8062..39e8fe16 100644 --- a/LICENSE +++ b/LICENSE @@ -13,9 +13,3 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -## Glob Logo - -Glob's logo created by Tanya Brassie , licensed -under a Creative Commons Attribution-ShareAlike 4.0 International License -https://creativecommons.org/licenses/by-sa/4.0/ From 3d6c4cd2f3a6b7bdfdbf01fe9483badd5486fd71 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 21 Mar 2022 09:25:19 -0700 Subject: [PATCH 011/163] require node >= 12 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index cb598bb9..c4741b80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "tick": "0.0.6" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" diff --git a/package.json b/package.json index 26ba0f74..dc8ee232 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "common.js" ], "engines": { - "node": "*" + "node": ">=12" }, "dependencies": { "fs.realpath": "^1.0.0", From 6ad3bbf6c4b570b3569c07db96e2b8ddd5bc2ba8 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 21 Mar 2022 09:26:33 -0700 Subject: [PATCH 012/163] minimatch@5 Fix: #464 --- package-lock.json | 130 ++++++++++++++++++++++++++++++++++++++-------- package.json | 2 +- 2 files changed, 109 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index c4741b80..852e737a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", + "minimatch": "^5.0.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -557,12 +557,11 @@ } }, "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==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -761,7 +760,8 @@ "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=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "node_modules/convert-source-map": { "version": "1.8.0", @@ -1180,6 +1180,28 @@ "node": ">= 6" } }, + "node_modules/glob/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/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -1736,14 +1758,14 @@ } }, "node_modules/minimatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.1.tgz", - "integrity": "sha512-reLxBcKUPNBnc/sVtAbxgRVFSegoGeLaSjmphNhcwcolhYLRgtJscn5mRl6YRZNQv40Y7P6JM2YhSIsbL9OB5A==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=10" } }, "node_modules/minimist": { @@ -4386,6 +4408,28 @@ "node": ">=8" } }, + "node_modules/test-exclude/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/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/tick": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tick/-/tick-0.0.6.tgz", @@ -5159,12 +5203,11 @@ "dev": true }, "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "braces": { @@ -5314,7 +5357,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "convert-source-map": { "version": "1.8.0", @@ -5614,6 +5658,27 @@ "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "glob-parent": { @@ -6047,11 +6112,11 @@ } }, "minimatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.1.tgz", - "integrity": "sha512-reLxBcKUPNBnc/sVtAbxgRVFSegoGeLaSjmphNhcwcolhYLRgtJscn5mRl6YRZNQv40Y7P6JM2YhSIsbL9OB5A==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", + "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" } }, "minimist": { @@ -7871,6 +7936,27 @@ "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } } }, "tick": { diff --git a/package.json b/package.json index dc8ee232..f2320691 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.1.1", + "minimatch": "^5.0.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, From 0004d831a36e1259780ec62a2af97b9f6727ae0c Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 21 Mar 2022 09:27:00 -0700 Subject: [PATCH 013/163] 8.0.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 852e737a..8f96a083 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "glob", - "version": "7.2.1", + "version": "8.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "glob", - "version": "7.2.1", + "version": "8.0.0", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", diff --git a/package.json b/package.json index f2320691..862b3708 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "7.2.1", + "version": "8.0.0", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" From af3eb8a13fffee7f166562a2de99d4a9ed786c96 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 11 Apr 2022 10:24:28 -0700 Subject: [PATCH 014/163] update tap to pull in fixed minimist --- package-lock.json | 1073 ++++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 630 insertions(+), 445 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8f96a083..fd4d400b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "memfs": "^3.2.0", "mkdirp": "0", "rimraf": "^2.2.8", - "tap": "^15.0.6", + "tap": "^16.0.1", "tick": "0.0.6" }, "engines": { @@ -404,6 +404,8 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -481,6 +483,8 @@ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -490,6 +494,8 @@ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.8" } @@ -507,13 +513,17 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "*" } @@ -522,7 +532,9 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/balanced-match": { "version": "1.0.2", @@ -534,6 +546,8 @@ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "tweetnacl": "^0.14.3" } @@ -652,7 +666,9 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/chalk": { "version": "2.4.2", @@ -744,6 +760,8 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -776,13 +794,17 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/coveralls": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "js-yaml": "^3.13.1", "lcov-parse": "^1.0.0", @@ -816,6 +838,8 @@ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -866,6 +890,8 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.4.0" } @@ -884,6 +910,8 @@ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -948,7 +976,9 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/extsprintf": { "version": "1.3.0", @@ -957,19 +987,25 @@ "dev": true, "engines": [ "node >=0.6.0" - ] + ], + "optional": true, + "peer": true }, "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 + "dev": true, + "optional": true, + "peer": true }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/fill-range": { "version": "7.0.1", @@ -1037,6 +1073,8 @@ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "*" } @@ -1046,6 +1084,8 @@ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -1144,6 +1184,8 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "assert-plus": "^1.0.0" } @@ -1222,6 +1264,8 @@ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=4" } @@ -1232,6 +1276,8 @@ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "deprecated": "this library is no longer supported", "dev": true, + "optional": true, + "peer": true, "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -1276,6 +1322,8 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -1406,7 +1454,9 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", @@ -1583,7 +1633,9 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/jsesc": { "version": "2.5.2", @@ -1601,19 +1653,25 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "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 + "dev": true, + "optional": true, + "peer": true }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/json5": { "version": "2.2.0", @@ -1635,6 +1693,8 @@ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -1650,14 +1710,16 @@ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", "dev": true, + "optional": true, + "peer": true, "bin": { "lcov-parse": "bin/cli.js" } }, "node_modules/libtap": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.4.tgz", - "integrity": "sha512-jM+QyAeRdVs1bJrNpjlu+l8gRdDkAehqls31AwSnqXghVLUP6nbYeU2Xfs2svYS7ZdksvnHvrxCKRBFEz/BCjA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.3.0.tgz", + "integrity": "sha512-yU5uSY987sVwpWiR5h84ZM96bxvmCQFZ/bOEJ1M7+Us8oez25fLmmLNGFRFGWi2PzuLqAzqzESH7HCaZ/b9IZA==", "dev": true, "dependencies": { "async-hook-domain": "^2.0.4", @@ -1669,11 +1731,10 @@ "own-or-env": "^1.0.2", "signal-exit": "^3.0.4", "stack-utils": "^2.0.4", - "tap-parser": "^10.0.1", + "tap-parser": "^11.0.0", "tap-yaml": "^1.0.0", "tcompare": "^5.0.6", - "trivial-deferred": "^1.0.1", - "yapool": "^1.0.0" + "trivial-deferred": "^1.0.1" }, "engines": { "node": ">=10" @@ -1705,6 +1766,8 @@ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.8.6" } @@ -1741,6 +1804,8 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.6" } @@ -1750,6 +1815,8 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "mime-db": "1.51.0" }, @@ -1769,9 +1836,9 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "node_modules/minipass": { @@ -1892,6 +1959,8 @@ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": "*" } @@ -2021,7 +2090,9 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/picocolors": { "version": "1.0.0", @@ -2069,7 +2140,9 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/punycode": { "version": "2.1.1", @@ -2085,6 +2158,8 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.6" } @@ -2119,6 +2194,8 @@ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dev": true, + "optional": true, + "peer": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -2191,7 +2268,9 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/semver": { "version": "6.3.0", @@ -2306,6 +2385,8 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -2395,9 +2476,9 @@ } }, "node_modules/tap": { - "version": "15.1.6", - "resolved": "https://registry.npmjs.org/tap/-/tap-15.1.6.tgz", - "integrity": "sha512-TN7xH6Q2tUPTd6qwmkhuFJcx1vUR8e4dDUpBKc61G0krOzne7Ia6aKIFb8O/0kVazachSSuVME1V8nQ2xwWL8w==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/tap/-/tap-16.0.1.tgz", + "integrity": "sha512-y32sc4NFWzeOE1mrNvZoS1kRJADI8MCCSaatVBalCNVgusTf59h3t8mHZ3d0wSTQRs05JTOG52WC3KnWovhjPg==", "bundleDependencies": [ "ink", "treport", @@ -2410,7 +2491,6 @@ "@isaacs/import-jsx": "*", "@types/react": "*", "chokidar": "^3.3.0", - "coveralls": "^3.0.11", "findit": "^2.0.0", "foreground-child": "^2.0.0", "fs-exists-cached": "^1.0.0", @@ -2419,7 +2499,7 @@ "isexe": "^2.0.0", "istanbul-lib-processinfo": "^2.0.2", "jackspeak": "^1.4.1", - "libtap": "^1.1.4", + "libtap": "^1.3.0", "minipass": "^3.1.1", "mkdirp": "^1.0.4", "nyc": "^15.1.0", @@ -2428,8 +2508,8 @@ "rimraf": "^3.0.0", "signal-exit": "^3.0.6", "source-map-support": "^0.5.16", - "tap-mocha-reporter": "^5.0.0", - "tap-parser": "^10.0.1", + "tap-mocha-reporter": "^5.0.3", + "tap-parser": "^11.0.1", "tap-yaml": "^1.0.0", "tcompare": "^5.0.7", "treport": "*", @@ -2439,17 +2519,21 @@ "tap": "bin/run.js" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" }, "peerDependencies": { + "coveralls": "^3.1.1", "flow-remove-types": ">=2.112.0", "ts-node": ">=8.5.2", "typescript": ">=3.7.2" }, "peerDependenciesMeta": { + "coveralls": { + "optional": true + }, "flow-remove-types": { "optional": true }, @@ -2462,9 +2546,9 @@ } }, "node_modules/tap-mocha-reporter": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.1.tgz", - "integrity": "sha512-1knFWOwd4khx/7uSEnUeaP9IPW3w+sqTgJMhrwah6t46nZ8P25atOKAjSvVDsT67lOPu0nfdOqUwoyKn+3E5pA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.3.tgz", + "integrity": "sha512-6zlGkaV4J+XMRFkN0X+yuw6xHbE9jyCZ3WUKfw4KxMyRGOpYSRuuQTRJyWX88WWuLdVTuFbxzwXhXuS2XE6o0g==", "dev": true, "dependencies": { "color-support": "^1.1.0", @@ -2472,7 +2556,7 @@ "diff": "^4.0.1", "escape-string-regexp": "^2.0.0", "glob": "^7.0.5", - "tap-parser": "^10.0.0", + "tap-parser": "^11.0.0", "tap-yaml": "^1.0.0", "unicode-length": "^2.0.2" }, @@ -2493,13 +2577,13 @@ } }, "node_modules/tap-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.1.0.tgz", - "integrity": "sha512-FujQeciDaOiOvaIVGS1Rpb0v4R6XkOjvWCWowlz5oKuhPkEJ8U6pxgqt38xuzYhPt8dWEnfHn2jqpZdJEkW7pA==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-11.0.1.tgz", + "integrity": "sha512-5ow0oyFOnXVSALYdidMX94u0GEjIlgc/BPFYLx0yRh9hb8+cFGNJqJzDJlUqbLOwx8+NBrIbxCWkIQi7555c0w==", "dev": true, "dependencies": { "events-to-array": "^1.0.1", - "minipass": "^3.0.0", + "minipass": "^3.1.6", "tap-yaml": "^1.0.0" }, "bin": { @@ -2518,20 +2602,32 @@ "yaml": "^1.5.0" } }, + "node_modules/tap/node_modules/@ampproject/remapping": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/tap/node_modules/@babel/code-frame": { - "version": "7.16.0", + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.16.0" + "@babel/highlight": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/compat-data": { - "version": "7.16.0", + "version": "7.17.7", "dev": true, "inBundle": true, "license": "MIT", @@ -2540,26 +2636,26 @@ } }, "node_modules/tap/node_modules/@babel/core": { - "version": "7.16.0", + "version": "7.17.8", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.0", - "@babel/helper-compilation-targets": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.0", - "@babel/helpers": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.0", - "@babel/types": "^7.16.0", + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.7", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helpers": "^7.17.8", + "@babel/parser": "^7.17.8", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -2570,12 +2666,12 @@ } }, "node_modules/tap/node_modules/@babel/generator": { - "version": "7.16.0", + "version": "7.17.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.0", + "@babel/types": "^7.17.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -2584,25 +2680,25 @@ } }, "node_modules/tap/node_modules/@babel/helper-annotate-as-pure": { - "version": "7.16.0", + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-compilation-targets": { - "version": "7.16.3", + "version": "7.17.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-validator-option": "^7.14.5", + "@babel/compat-data": "^7.17.7", + "@babel/helper-validator-option": "^7.16.7", "browserslist": "^4.17.5", "semver": "^6.3.0" }, @@ -2613,149 +2709,122 @@ "@babel/core": "^7.0.0" } }, - "node_modules/tap/node_modules/@babel/helper-function-name": { - "version": "7.16.0", + "node_modules/tap/node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/tap/node_modules/@babel/helper-get-function-arity": { - "version": "7.16.0", + "node_modules/tap/node_modules/@babel/helper-function-name": { + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/tap/node_modules/@babel/helper-hoist-variables": { - "version": "7.16.0", + "node_modules/tap/node_modules/@babel/helper-get-function-arity": { + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/tap/node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.16.0", + "node_modules/tap/node_modules/@babel/helper-hoist-variables": { + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-module-imports": { - "version": "7.16.0", + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-module-transforms": { - "version": "7.16.0", + "version": "7.17.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-replace-supers": "^7.16.0", - "@babel/helper-simple-access": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.0", - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/tap/node_modules/@babel/helper-optimise-call-expression": { - "version": "7.16.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.16.0" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-plugin-utils": { - "version": "7.14.5", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/tap/node_modules/@babel/helper-replace-supers": { - "version": "7.16.0", + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/traverse": "^7.16.0", - "@babel/types": "^7.16.0" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-simple-access": { - "version": "7.16.0", + "version": "7.17.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.0", + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/helper-validator-identifier": { - "version": "7.15.7", + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", @@ -2764,7 +2833,7 @@ } }, "node_modules/tap/node_modules/@babel/helper-validator-option": { - "version": "7.14.5", + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", @@ -2773,26 +2842,26 @@ } }, "node_modules/tap/node_modules/@babel/helpers": { - "version": "7.16.3", + "version": "7.17.8", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.3", - "@babel/types": "^7.16.0" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/highlight": { - "version": "7.16.0", + "version": "7.16.10", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -2801,7 +2870,7 @@ } }, "node_modules/tap/node_modules/@babel/parser": { - "version": "7.16.3", + "version": "7.17.8", "dev": true, "inBundle": true, "license": "MIT", @@ -2813,16 +2882,16 @@ } }, "node_modules/tap/node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.16.0", + "version": "7.17.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-compilation-targets": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/compat-data": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.0" + "@babel/plugin-transform-parameters": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -2832,12 +2901,12 @@ } }, "node_modules/tap/node_modules/@babel/plugin-syntax-jsx": { - "version": "7.16.0", + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -2859,12 +2928,12 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-destructuring": { - "version": "7.16.0", + "version": "7.17.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -2874,12 +2943,12 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-parameters": { - "version": "7.16.3", + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" }, "engines": { "node": ">=6.9.0" @@ -2889,16 +2958,16 @@ } }, "node_modules/tap/node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.16.0", + "version": "7.17.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-jsx": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.16.7", + "@babel/types": "^7.17.0" }, "engines": { "node": ">=6.9.0" @@ -2908,32 +2977,33 @@ } }, "node_modules/tap/node_modules/@babel/template": { - "version": "7.16.0", + "version": "7.16.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/tap/node_modules/@babel/traverse": { - "version": "7.16.3", + "version": "7.17.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.0", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.3", - "@babel/types": "^7.16.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2942,12 +3012,12 @@ } }, "node_modules/tap/node_modules/@babel/types": { - "version": "7.16.0", + "version": "7.17.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2974,37 +3044,29 @@ "node": ">=10" } }, - "node_modules/tap/node_modules/@isaacs/import-jsx/node_modules/caller-callsite": { - "version": "4.1.0", + "node_modules/tap/node_modules/@jridgewell/resolve-uri": { + "version": "3.0.5", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "callsites": "^3.1.0" - }, "engines": { - "node": ">=8" + "node": ">=6.0.0" } }, - "node_modules/tap/node_modules/@isaacs/import-jsx/node_modules/caller-path": { - "version": "3.0.1", + "node_modules/tap/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.11", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "caller-callsite": "^4.1.0" - }, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/tap/node_modules/@isaacs/import-jsx/node_modules/callsites": { - "version": "3.1.0", + "node_modules/tap/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.4", "dev": true, "inBundle": true, "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, "node_modules/tap/node_modules/@types/prop-types": { @@ -3014,7 +3076,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/@types/react": { - "version": "17.0.34", + "version": "17.0.41", "dev": true, "inBundle": true, "license": "MIT", @@ -3128,15 +3190,25 @@ } }, "node_modules/tap/node_modules/browserslist": { - "version": "4.17.6", + "version": "4.20.2", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], "inBundle": true, "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001274", - "electron-to-chromium": "^1.3.886", + "caniuse-lite": "^1.0.30001317", + "electron-to-chromium": "^1.4.84", "escalade": "^3.1.1", - "node-releases": "^2.0.1", + "node-releases": "^2.0.2", "picocolors": "^1.0.0" }, "bin": { @@ -3144,22 +3216,57 @@ }, "engines": { "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/tap/node_modules/caller-callsite": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.1.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "engines": { + "node": ">=8" } }, - "node_modules/tap/node_modules/caniuse-lite": { - "version": "1.0.30001279", + "node_modules/tap/node_modules/caller-path": { + "version": "3.0.1", "dev": true, "inBundle": true, - "license": "CC-BY-4.0", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "license": "MIT", + "dependencies": { + "caller-callsite": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tap/node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" } }, + "node_modules/tap/node_modules/caniuse-lite": { + "version": "1.0.30001319", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ], + "inBundle": true, + "license": "CC-BY-4.0" + }, "node_modules/tap/node_modules/cardinal": { "version": "2.1.1", "dev": true, @@ -3291,13 +3398,13 @@ } }, "node_modules/tap/node_modules/csstype": { - "version": "3.0.9", + "version": "3.0.11", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/tap/node_modules/debug": { - "version": "4.3.2", + "version": "4.3.4", "dev": true, "inBundle": true, "license": "MIT", @@ -3314,7 +3421,7 @@ } }, "node_modules/tap/node_modules/electron-to-chromium": { - "version": "1.3.893", + "version": "1.4.89", "dev": true, "inBundle": true, "license": "ISC" @@ -3623,13 +3730,10 @@ } }, "node_modules/tap/node_modules/json5": { - "version": "2.2.0", + "version": "2.2.1", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "minimist": "^1.2.5" - }, "bin": { "json5": "lib/cli.js" }, @@ -3692,7 +3796,7 @@ } }, "node_modules/tap/node_modules/minimatch": { - "version": "3.0.4", + "version": "3.1.2", "dev": true, "inBundle": true, "license": "ISC", @@ -3703,14 +3807,8 @@ "node": "*" } }, - "node_modules/tap/node_modules/minimist": { - "version": "1.2.5", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/tap/node_modules/minipass": { - "version": "3.1.5", + "version": "3.1.6", "dev": true, "inBundle": true, "license": "ISC", @@ -3740,7 +3838,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/node-releases": { - "version": "2.0.1", + "version": "2.0.2", "dev": true, "inBundle": true, "license": "MIT" @@ -3882,7 +3980,7 @@ } }, "node_modules/tap/node_modules/react-devtools-core": { - "version": "4.21.0", + "version": "4.24.1", "dev": true, "inBundle": true, "license": "MIT", @@ -3986,7 +4084,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/signal-exit": { - "version": "3.0.6", + "version": "3.0.7", "dev": true, "inBundle": true, "license": "ISC" @@ -4107,13 +4205,13 @@ } }, "node_modules/tap/node_modules/tap-parser": { - "version": "10.1.0", + "version": "11.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "events-to-array": "^1.0.1", - "minipass": "^3.0.0", + "minipass": "^3.1.6", "tap-yaml": "^1.0.0" }, "bin": { @@ -4142,7 +4240,7 @@ } }, "node_modules/tap/node_modules/treport": { - "version": "3.0.2", + "version": "3.0.3", "dev": true, "inBundle": true, "license": "ISC", @@ -4152,7 +4250,7 @@ "chalk": "^3.0.0", "ink": "^3.2.0", "ms": "^2.1.2", - "tap-parser": "^10.0.1", + "tap-parser": "^11.0.0", "unicode-length": "^2.0.2" }, "peerDependencies": { @@ -4335,7 +4433,7 @@ "license": "ISC" }, "node_modules/tap/node_modules/ws": { - "version": "7.5.5", + "version": "7.5.7", "dev": true, "inBundle": true, "license": "MIT", @@ -4471,6 +4569,8 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -4490,6 +4590,8 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, + "optional": true, + "peer": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -4501,7 +4603,9 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/type-fest": { "version": "0.8.1", @@ -4557,6 +4661,8 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -4579,6 +4685,8 @@ "engines": [ "node >=0.6.0" ], + "optional": true, + "peer": true, "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -4694,12 +4802,6 @@ "node": ">= 6" } }, - "node_modules/yapool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", - "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", - "dev": true - }, "node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", @@ -5081,6 +5183,8 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "optional": true, + "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5142,6 +5246,8 @@ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "safer-buffer": "~2.1.0" } @@ -5150,7 +5256,9 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "async-hook-domain": { "version": "2.0.4", @@ -5162,19 +5270,25 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "aws4": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "balanced-match": { "version": "1.0.2", @@ -5186,6 +5300,8 @@ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, + "optional": true, + "peer": true, "requires": { "tweetnacl": "^0.14.3" } @@ -5272,7 +5388,9 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "chalk": { "version": "2.4.2", @@ -5344,6 +5462,8 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, + "optional": true, + "peer": true, "requires": { "delayed-stream": "~1.0.0" } @@ -5373,13 +5493,17 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "coveralls": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", "dev": true, + "optional": true, + "peer": true, "requires": { "js-yaml": "^3.13.1", "lcov-parse": "^1.0.0", @@ -5404,6 +5528,8 @@ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, + "optional": true, + "peer": true, "requires": { "assert-plus": "^1.0.0" } @@ -5436,7 +5562,9 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "diff": { "version": "4.0.2", @@ -5449,6 +5577,8 @@ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, + "optional": true, + "peer": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -5500,25 +5630,33 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "fill-range": { "version": "7.0.1", @@ -5570,13 +5708,17 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -5642,6 +5784,8 @@ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, + "optional": true, + "peer": true, "requires": { "assert-plus": "^1.0.0" } @@ -5706,13 +5850,17 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "har-validator": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, + "optional": true, + "peer": true, "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -5745,6 +5893,8 @@ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, + "optional": true, + "peer": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -5841,7 +5991,9 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "istanbul-lib-coverage": { "version": "3.2.0", @@ -5982,7 +6134,9 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "jsesc": { "version": "2.5.2", @@ -5994,19 +6148,25 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "json5": { "version": "2.2.0", @@ -6022,6 +6182,8 @@ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", "dev": true, + "optional": true, + "peer": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -6033,12 +6195,14 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "libtap": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.1.4.tgz", - "integrity": "sha512-jM+QyAeRdVs1bJrNpjlu+l8gRdDkAehqls31AwSnqXghVLUP6nbYeU2Xfs2svYS7ZdksvnHvrxCKRBFEz/BCjA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.3.0.tgz", + "integrity": "sha512-yU5uSY987sVwpWiR5h84ZM96bxvmCQFZ/bOEJ1M7+Us8oez25fLmmLNGFRFGWi2PzuLqAzqzESH7HCaZ/b9IZA==", "dev": true, "requires": { "async-hook-domain": "^2.0.4", @@ -6050,11 +6214,10 @@ "own-or-env": "^1.0.2", "signal-exit": "^3.0.4", "stack-utils": "^2.0.4", - "tap-parser": "^10.0.1", + "tap-parser": "^11.0.0", "tap-yaml": "^1.0.0", "tcompare": "^5.0.6", - "trivial-deferred": "^1.0.1", - "yapool": "^1.0.0" + "trivial-deferred": "^1.0.1" } }, "locate-path": { @@ -6076,7 +6239,9 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "make-dir": { "version": "3.1.0", @@ -6100,13 +6265,17 @@ "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "mime-types": { "version": "2.1.34", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", "dev": true, + "optional": true, + "peer": true, "requires": { "mime-db": "1.51.0" } @@ -6120,9 +6289,9 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "minipass": { @@ -6220,7 +6389,9 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "once": { "version": "1.4.0", @@ -6317,7 +6488,9 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "picocolors": { "version": "1.0.0", @@ -6353,7 +6526,9 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "punycode": { "version": "2.1.1", @@ -6365,7 +6540,9 @@ "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "readdirp": { "version": "3.6.0", @@ -6390,6 +6567,8 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "dev": true, + "optional": true, + "peer": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -6450,7 +6629,9 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "semver": { "version": "6.3.0", @@ -6545,6 +6726,8 @@ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", "dev": true, + "optional": true, + "peer": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -6610,15 +6793,14 @@ } }, "tap": { - "version": "15.1.6", - "resolved": "https://registry.npmjs.org/tap/-/tap-15.1.6.tgz", - "integrity": "sha512-TN7xH6Q2tUPTd6qwmkhuFJcx1vUR8e4dDUpBKc61G0krOzne7Ia6aKIFb8O/0kVazachSSuVME1V8nQ2xwWL8w==", + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/tap/-/tap-16.0.1.tgz", + "integrity": "sha512-y32sc4NFWzeOE1mrNvZoS1kRJADI8MCCSaatVBalCNVgusTf59h3t8mHZ3d0wSTQRs05JTOG52WC3KnWovhjPg==", "dev": true, "requires": { "@isaacs/import-jsx": "*", "@types/react": "*", "chokidar": "^3.3.0", - "coveralls": "^3.0.11", "findit": "^2.0.0", "foreground-child": "^2.0.0", "fs-exists-cached": "^1.0.0", @@ -6627,7 +6809,7 @@ "isexe": "^2.0.0", "istanbul-lib-processinfo": "^2.0.2", "jackspeak": "^1.4.1", - "libtap": "^1.1.4", + "libtap": "^1.3.0", "minipass": "^3.1.1", "mkdirp": "^1.0.4", "nyc": "^15.1.0", @@ -6636,228 +6818,217 @@ "rimraf": "^3.0.0", "signal-exit": "^3.0.6", "source-map-support": "^0.5.16", - "tap-mocha-reporter": "^5.0.0", - "tap-parser": "^10.0.1", + "tap-mocha-reporter": "^5.0.3", + "tap-parser": "^11.0.1", "tap-yaml": "^1.0.0", "tcompare": "^5.0.7", "treport": "*", "which": "^2.0.2" }, "dependencies": { + "@ampproject/remapping": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.0" + } + }, "@babel/code-frame": { - "version": "7.16.0", + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/highlight": "^7.16.0" + "@babel/highlight": "^7.16.7" } }, "@babel/compat-data": { - "version": "7.16.0", + "version": "7.17.7", "bundled": true, "dev": true }, "@babel/core": { - "version": "7.16.0", + "version": "7.17.8", "bundled": true, "dev": true, "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.0", - "@babel/helper-compilation-targets": "^7.16.0", - "@babel/helper-module-transforms": "^7.16.0", - "@babel/helpers": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.0", - "@babel/types": "^7.16.0", + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.7", + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-module-transforms": "^7.17.7", + "@babel/helpers": "^7.17.8", + "@babel/parser": "^7.17.8", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "semver": "^6.3.0" } }, "@babel/generator": { - "version": "7.16.0", + "version": "7.17.7", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.16.0", + "@babel/types": "^7.17.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-annotate-as-pure": { - "version": "7.16.0", + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-compilation-targets": { - "version": "7.16.3", + "version": "7.17.7", "bundled": true, "dev": true, "requires": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-validator-option": "^7.14.5", + "@babel/compat-data": "^7.17.7", + "@babel/helper-validator-option": "^7.16.7", "browserslist": "^4.17.5", "semver": "^6.3.0" } }, - "@babel/helper-function-name": { - "version": "7.16.0", + "@babel/helper-environment-visitor": { + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, - "@babel/helper-get-function-arity": { - "version": "7.16.0", + "@babel/helper-function-name": { + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" } }, - "@babel/helper-hoist-variables": { - "version": "7.16.0", + "@babel/helper-get-function-arity": { + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, - "@babel/helper-member-expression-to-functions": { - "version": "7.16.0", + "@babel/helper-hoist-variables": { + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-module-imports": { - "version": "7.16.0", + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-module-transforms": { - "version": "7.16.0", + "version": "7.17.7", "bundled": true, "dev": true, "requires": { - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-replace-supers": "^7.16.0", - "@babel/helper-simple-access": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.16.0", - "bundled": true, - "dev": true, - "requires": { - "@babel/types": "^7.16.0" + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" } }, "@babel/helper-plugin-utils": { - "version": "7.14.5", + "version": "7.16.7", "bundled": true, "dev": true }, - "@babel/helper-replace-supers": { - "version": "7.16.0", - "bundled": true, - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.16.0", - "@babel/helper-optimise-call-expression": "^7.16.0", - "@babel/traverse": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, "@babel/helper-simple-access": { - "version": "7.16.0", + "version": "7.17.7", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.17.0" } }, "@babel/helper-split-export-declaration": { - "version": "7.16.0", + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/types": "^7.16.0" + "@babel/types": "^7.16.7" } }, "@babel/helper-validator-identifier": { - "version": "7.15.7", + "version": "7.16.7", "bundled": true, "dev": true }, "@babel/helper-validator-option": { - "version": "7.14.5", + "version": "7.16.7", "bundled": true, "dev": true }, "@babel/helpers": { - "version": "7.16.3", + "version": "7.17.8", "bundled": true, "dev": true, "requires": { - "@babel/template": "^7.16.0", - "@babel/traverse": "^7.16.3", - "@babel/types": "^7.16.0" + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.3", + "@babel/types": "^7.17.0" } }, "@babel/highlight": { - "version": "7.16.0", + "version": "7.16.10", "bundled": true, "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.16.3", + "version": "7.17.8", "bundled": true, "dev": true }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.16.0", + "version": "7.17.3", "bundled": true, "dev": true, "requires": { - "@babel/compat-data": "^7.16.0", - "@babel/helper-compilation-targets": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", + "@babel/compat-data": "^7.17.0", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.16.0" + "@babel/plugin-transform-parameters": "^7.16.7" } }, "@babel/plugin-syntax-jsx": { - "version": "7.16.0", + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-syntax-object-rest-spread": { @@ -6869,65 +7040,66 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.16.0", + "version": "7.17.7", "bundled": true, "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-parameters": { - "version": "7.16.3", + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.16.7" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.16.0", + "version": "7.17.3", "bundled": true, "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-jsx": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/helper-annotate-as-pure": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-plugin-utils": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.16.7", + "@babel/types": "^7.17.0" } }, "@babel/template": { - "version": "7.16.0", + "version": "7.16.7", "bundled": true, "dev": true, "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" } }, "@babel/traverse": { - "version": "7.16.3", + "version": "7.17.3", "bundled": true, "dev": true, "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.0", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.3", - "@babel/types": "^7.16.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.16.0", + "version": "7.17.0", "bundled": true, "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.15.7", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } }, @@ -6945,29 +7117,25 @@ "make-dir": "^3.0.2", "resolve-from": "^3.0.0", "rimraf": "^3.0.0" - }, - "dependencies": { - "caller-callsite": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "callsites": "^3.1.0" - } - }, - "caller-path": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "caller-callsite": "^4.1.0" - } - }, - "callsites": { - "version": "3.1.0", - "bundled": true, - "dev": true - } + } + }, + "@jridgewell/resolve-uri": { + "version": "3.0.5", + "bundled": true, + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.11", + "bundled": true, + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.4", + "bundled": true, + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, "@types/prop-types": { @@ -6976,7 +7144,7 @@ "dev": true }, "@types/react": { - "version": "17.0.34", + "version": "17.0.41", "bundled": true, "dev": true, "requires": { @@ -7053,19 +7221,40 @@ } }, "browserslist": { - "version": "4.17.6", + "version": "4.20.2", "bundled": true, "dev": true, "requires": { - "caniuse-lite": "^1.0.30001274", - "electron-to-chromium": "^1.3.886", + "caniuse-lite": "^1.0.30001317", + "electron-to-chromium": "^1.4.84", "escalade": "^3.1.1", - "node-releases": "^2.0.1", + "node-releases": "^2.0.2", "picocolors": "^1.0.0" } }, + "caller-callsite": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "callsites": "^3.1.0" + } + }, + "caller-path": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "caller-callsite": "^4.1.0" + } + }, + "callsites": { + "version": "3.1.0", + "bundled": true, + "dev": true + }, "caniuse-lite": { - "version": "1.0.30001279", + "version": "1.0.30001319", "bundled": true, "dev": true }, @@ -7160,12 +7349,12 @@ "dev": true }, "csstype": { - "version": "3.0.9", + "version": "3.0.11", "bundled": true, "dev": true }, "debug": { - "version": "4.3.2", + "version": "4.3.4", "bundled": true, "dev": true, "requires": { @@ -7173,7 +7362,7 @@ } }, "electron-to-chromium": { - "version": "1.3.893", + "version": "1.4.89", "bundled": true, "dev": true }, @@ -7372,12 +7561,9 @@ "dev": true }, "json5": { - "version": "2.2.0", + "version": "2.2.1", "bundled": true, - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "dev": true }, "locate-path": { "version": "5.0.0", @@ -7414,20 +7600,15 @@ "dev": true }, "minimatch": { - "version": "3.0.4", + "version": "3.1.2", "bundled": true, "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.5", - "bundled": true, - "dev": true - }, "minipass": { - "version": "3.1.5", + "version": "3.1.6", "bundled": true, "dev": true, "requires": { @@ -7446,7 +7627,7 @@ "dev": true }, "node-releases": { - "version": "2.0.1", + "version": "2.0.2", "bundled": true, "dev": true }, @@ -7535,7 +7716,7 @@ } }, "react-devtools-core": { - "version": "4.21.0", + "version": "4.24.1", "bundled": true, "dev": true, "requires": { @@ -7608,7 +7789,7 @@ "dev": true }, "signal-exit": { - "version": "3.0.6", + "version": "3.0.7", "bundled": true, "dev": true }, @@ -7692,12 +7873,12 @@ } }, "tap-parser": { - "version": "10.1.0", + "version": "11.0.1", "bundled": true, "dev": true, "requires": { "events-to-array": "^1.0.1", - "minipass": "^3.0.0", + "minipass": "^3.1.6", "tap-yaml": "^1.0.0" } }, @@ -7715,7 +7896,7 @@ "dev": true }, "treport": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, "dev": true, "requires": { @@ -7724,7 +7905,7 @@ "chalk": "^3.0.0", "ink": "^3.2.0", "ms": "^2.1.2", - "tap-parser": "^10.0.1", + "tap-parser": "^11.0.0", "unicode-length": "^2.0.2" }, "dependencies": { @@ -7849,7 +8030,7 @@ "dev": true }, "ws": { - "version": "7.5.5", + "version": "7.5.7", "bundled": true, "dev": true, "requires": {} @@ -7875,9 +8056,9 @@ } }, "tap-mocha-reporter": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.1.tgz", - "integrity": "sha512-1knFWOwd4khx/7uSEnUeaP9IPW3w+sqTgJMhrwah6t46nZ8P25atOKAjSvVDsT67lOPu0nfdOqUwoyKn+3E5pA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.3.tgz", + "integrity": "sha512-6zlGkaV4J+XMRFkN0X+yuw6xHbE9jyCZ3WUKfw4KxMyRGOpYSRuuQTRJyWX88WWuLdVTuFbxzwXhXuS2XE6o0g==", "dev": true, "requires": { "color-support": "^1.1.0", @@ -7885,7 +8066,7 @@ "diff": "^4.0.1", "escape-string-regexp": "^2.0.0", "glob": "^7.0.5", - "tap-parser": "^10.0.0", + "tap-parser": "^11.0.0", "tap-yaml": "^1.0.0", "unicode-length": "^2.0.2" }, @@ -7899,13 +8080,13 @@ } }, "tap-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.1.0.tgz", - "integrity": "sha512-FujQeciDaOiOvaIVGS1Rpb0v4R6XkOjvWCWowlz5oKuhPkEJ8U6pxgqt38xuzYhPt8dWEnfHn2jqpZdJEkW7pA==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-11.0.1.tgz", + "integrity": "sha512-5ow0oyFOnXVSALYdidMX94u0GEjIlgc/BPFYLx0yRh9hb8+cFGNJqJzDJlUqbLOwx8+NBrIbxCWkIQi7555c0w==", "dev": true, "requires": { "events-to-array": "^1.0.1", - "minipass": "^3.0.0", + "minipass": "^3.1.6", "tap-yaml": "^1.0.0" } }, @@ -7988,6 +8169,8 @@ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, + "optional": true, + "peer": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -8004,6 +8187,8 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, + "optional": true, + "peer": true, "requires": { "safe-buffer": "^5.0.1" } @@ -8012,7 +8197,9 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "type-fest": { "version": "0.8.1", @@ -8061,6 +8248,8 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "optional": true, + "peer": true, "requires": { "punycode": "^2.1.0" } @@ -8076,6 +8265,8 @@ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, + "optional": true, + "peer": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -8169,12 +8360,6 @@ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true }, - "yapool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", - "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", - "dev": true - }, "yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", diff --git a/package.json b/package.json index 862b3708..a4d75544 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "memfs": "^3.2.0", "mkdirp": "0", "rimraf": "^2.2.8", - "tap": "^15.0.6", + "tap": "^16.0.1", "tick": "0.0.6" }, "tap": { From 55ebc0b473f250f698156060277390dbdb103e62 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 11 Apr 2022 10:24:44 -0700 Subject: [PATCH 015/163] 8.0.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index fd4d400b..e6b5f316 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "glob", - "version": "8.0.0", + "version": "8.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "glob", - "version": "8.0.0", + "version": "8.0.1", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", diff --git a/package.json b/package.json index a4d75544..54940cbe 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "8.0.0", + "version": "8.0.1", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" From 7eab927fb4fce8870dd8871cde9dc0aaf5409fbf Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 12 Apr 2022 09:17:56 -0700 Subject: [PATCH 016/163] changelog updates Fix: https://github.com/isaacs/node-glob/issues/467 --- changelog.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/changelog.md b/changelog.md index 41636771..f3632bbf 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,18 @@ +## 8.0 + +- Only support node v12 and higher + +## 7.2 + +- Add fs option to allow passing virtual filesystem + +## 7.1 + +- Ignore stat errors that are not `ENOENT` to work around Windows issues. +- Support using root and absolute options together +- Bring back lumpy space princess +- force 'en' locale in string sorting + ## 7.0 - Raise error if `options.cwd` is specified, and not a directory From 563019768fe6de7b3240dd8fcdf8db4d7990680a Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 6 May 2022 09:30:47 -0700 Subject: [PATCH 017/163] ci: test on node 18 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 13c3032f..f9797acb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ jobs: build: strategy: matrix: - node-version: [12.x, 14.x, 16.x, 17.x] + node-version: [12.x, 14.x, 16.x, 18.x] platform: - os: ubuntu-latest shell: bash From a8a3682527640e5356e0448330c5955081efa85f Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 6 May 2022 09:34:15 -0700 Subject: [PATCH 018/163] remove path-is-absolute --- common.js | 2 +- glob.js | 2 +- package-lock.json | 7 ++++--- package.json | 3 +-- sync.js | 2 +- test/absolute.js | 2 +- test/bash-comparison.js | 2 +- test/cwd-test.js | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/common.js b/common.js index fc193ee6..896f1c3d 100644 --- a/common.js +++ b/common.js @@ -13,7 +13,7 @@ function ownProp (obj, field) { var fs = require("fs") var path = require("path") var minimatch = require("minimatch") -var isAbsolute = require("path-is-absolute") +var isAbsolute = require("path").isAbsolute var Minimatch = minimatch.Minimatch function alphasort (a, b) { diff --git a/glob.js b/glob.js index 37a4d7e6..2112a957 100644 --- a/glob.js +++ b/glob.js @@ -47,7 +47,7 @@ var inherits = require('inherits') var EE = require('events').EventEmitter var path = require('path') var assert = require('assert') -var isAbsolute = require('path-is-absolute') +var isAbsolute = require('path').isAbsolute var globSync = require('./sync.js') var common = require('./common.js') var setopts = common.setopts diff --git a/package-lock.json b/package-lock.json index e6b5f316..acd5c613 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,8 +13,7 @@ "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "once": "^1.3.0" }, "devDependencies": { "memfs": "^3.2.0", @@ -2073,6 +2072,7 @@ "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" } @@ -6476,7 +6476,8 @@ "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=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-key": { "version": "3.1.1", diff --git a/package.json b/package.json index 54940cbe..99a7483f 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,7 @@ "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "once": "^1.3.0" }, "devDependencies": { "memfs": "^3.2.0", diff --git a/sync.js b/sync.js index c705a9c0..f9185494 100644 --- a/sync.js +++ b/sync.js @@ -8,7 +8,7 @@ var Glob = require('./glob.js').Glob var util = require('util') var path = require('path') var assert = require('assert') -var isAbsolute = require('path-is-absolute') +var isAbsolute = require('path').isAbsolute var common = require('./common.js') var setopts = common.setopts var ownProp = common.ownProp diff --git a/test/absolute.js b/test/absolute.js index 704caa90..68c81191 100644 --- a/test/absolute.js +++ b/test/absolute.js @@ -4,7 +4,7 @@ var glob = require('../') var common = require('../common.js') var pattern = 'a/b/**'; var bashResults = require('./bash-results.json') -var isAbsolute = require('path-is-absolute') +var isAbsolute = require('path').isAbsolute process.chdir(__dirname + '/fixtures') t.Test.prototype.addAssert('isAbsolute', 1, function (file, message, extra) { diff --git a/test/bash-comparison.js b/test/bash-comparison.js index 25304bec..01a52452 100644 --- a/test/bash-comparison.js +++ b/test/bash-comparison.js @@ -7,7 +7,7 @@ var bashResults = require("./bash-results.json") var globs = Object.keys(bashResults) var glob = require("../") var path = require("path") -var isAbsolute = require("path-is-absolute") +var isAbsolute = require("path").isAbsolute // run from the root of the project // this is usually where you're at anyway, but be sure. diff --git a/test/cwd-test.js b/test/cwd-test.js index 8f81a6ed..6528a47e 100644 --- a/test/cwd-test.js +++ b/test/cwd-test.js @@ -4,7 +4,7 @@ var tap = require("tap") var origCwd = process.cwd() process.chdir(__dirname + '/fixtures') var path = require('path') -var isAbsolute = require('path-is-absolute') +var isAbsolute = require('path').isAbsolute var glob = require('../') function cacheCheck(g, t) { From 0049e9a1df29ccbed7df7eab0e196666aee0a686 Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 6 May 2022 09:29:39 -0700 Subject: [PATCH 019/163] always coerce cwd, root to '/' separated paths Re: https://github.com/isaacs/node-glob/issues/467 PR-URL: https://github.com/isaacs/node-glob/pull/469 Credit: @isaacs Close: #469 Reviewed-by: @isaacs --- .github/workflows/ci.yml | 2 +- common.js | 12 +++++++----- test/cwd-test.js | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f9797acb..7090c3fe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,4 +36,4 @@ jobs: run: npm install - name: Run Tests - run: npm test -- -c -t0 + run: npm test -- -c -t0 --statements=80 --branches=80 --functions=80 --lines=80 diff --git a/common.js b/common.js index 896f1c3d..e094f750 100644 --- a/common.js +++ b/common.js @@ -88,7 +88,7 @@ function setopts (self, pattern, options) { self.changedCwd = false var cwd = process.cwd() if (!ownProp(options, "cwd")) - self.cwd = cwd + self.cwd = path.resolve(cwd) else { self.cwd = path.resolve(options.cwd) self.changedCwd = self.cwd !== cwd @@ -96,16 +96,18 @@ function setopts (self, pattern, options) { self.root = options.root || path.resolve(self.cwd, "/") self.root = path.resolve(self.root) - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/") // TODO: is an absolute `cwd` supposed to be resolved against `root`? // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) - if (process.platform === "win32") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") self.nomount = !!options.nomount + if (process.platform === "win32") { + self.root = self.root.replace(/\\/g, "/") + self.cwd = self.cwd.replace(/\\/g, "/") + self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") + } + // disable comments and negation in Minimatch. // Note that they are not supported in Glob itself anyway. options.nonegate = true diff --git a/test/cwd-test.js b/test/cwd-test.js index 6528a47e..0f31df88 100644 --- a/test/cwd-test.js +++ b/test/cwd-test.js @@ -69,7 +69,7 @@ tap.test("changing cwd and searching for **/d", function (t) { tap.test('non-dir cwd should raise error', function (t) { var notdir = 'a/b/c/d' var notdirRE = /a[\\\/]b[\\\/]c[\\\/]d/ - var abs = path.resolve(notdir) + var abs = path.resolve(notdir).split('\\').join('/') var expect = new Error('ENOTDIR invalid cwd ' + abs) expect.code = 'ENOTDIR' expect.path = notdirRE From af4207ba7325203b12b9009d6c0b18ed34f49f20 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 12 May 2022 11:49:58 -0700 Subject: [PATCH 020/163] changelog updates re path separator handling --- changelog.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/changelog.md b/changelog.md index f3632bbf..e3dd7354 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,18 @@ ## 8.0 - Only support node v12 and higher +- `\` is now **only** used as an escape character, and never as a + path separator in glob patterns, so that Windows users have a + way to match against filenames containing literal glob pattern + characters. +- Glob pattern paths **must** use forward-slashes as path + separators, since `\` is an escape character to match literal + glob pattern characters. +- (8.0.2) `cwd` and `root` will always be automatically coerced + to use `/` as path separators on Windows, as they cannot + contain glob patterns anyway, and are often supplied by + `path.resolve()` and other methods that will use `\` path + separators by default. ## 7.2 From d13cb0692910fa2b9b16a1c8393cb9d687c83722 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 12 May 2022 11:51:36 -0700 Subject: [PATCH 021/163] 8.0.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index acd5c613..987d7a96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "glob", - "version": "8.0.1", + "version": "8.0.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "glob", - "version": "8.0.1", + "version": "8.0.2", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", diff --git a/package.json b/package.json index 99a7483f..b63edcf0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "8.0.1", + "version": "8.0.2", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" From fc717ba2d4c511c16a96a8d0ca32563eed68bf73 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Wed, 5 Jan 2022 12:23:59 -0800 Subject: [PATCH 022/163] [Refactor] use more explicit `assert.ok` PR-URL: https://github.com/isaacs/node-glob/pull/451 Credit: @ljharb Close: #451 Reviewed-by: @nicolas377 --- sync.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sync.js b/sync.js index f9185494..af4600dd 100644 --- a/sync.js +++ b/sync.js @@ -48,7 +48,7 @@ function GlobSync (pattern, options) { } GlobSync.prototype._finish = function () { - assert(this instanceof GlobSync) + assert.ok(this instanceof GlobSync) if (this.realpath) { var self = this this.matches.forEach(function (matchset, index) { @@ -72,7 +72,7 @@ GlobSync.prototype._finish = function () { GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert(this instanceof GlobSync) + assert.ok(this instanceof GlobSync) // Get the first [n] parts of pattern that are all strings. var n = 0 From d844b2c1debfb7a408a8a219aea6cd5c66cfdea4 Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 13 May 2022 10:08:12 -0700 Subject: [PATCH 023/163] 8.0.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 987d7a96..a30d953c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "glob", - "version": "8.0.2", + "version": "8.0.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "glob", - "version": "8.0.2", + "version": "8.0.3", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", diff --git a/package.json b/package.json index b63edcf0..5134253e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "8.0.2", + "version": "8.0.3", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" From e19db65d233c8e5bb36ecdffbb558dd3ecada26f Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Mon, 16 May 2022 11:22:07 -0700 Subject: [PATCH 024/163] Remove dependency on path-is-absolute Per https://www.npmjs.com/package/path-is-absolute: > This package is no longer relevant as Node.js 0.12 is unmaintained. PR-URL: https://github.com/isaacs/node-glob/pull/477 Credit: @jsha Close: #477 Reviewed-by: @isaacs --- test/nodir.js | 3 +-- test/root-nomount.js | 3 +-- test/root.js | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/test/nodir.js b/test/nodir.js index 1f095694..01cc8b01 100644 --- a/test/nodir.js +++ b/test/nodir.js @@ -2,7 +2,6 @@ require("./global-leakage.js") var test = require("tap").test var glob = require('../') var path = require('path') -var isAbsolute = require('path-is-absolute') process.chdir(__dirname + '/fixtures') function cacheCheck(g, t) { @@ -10,7 +9,7 @@ function cacheCheck(g, t) { var caches = [ 'cache', 'statCache', 'symlinks' ] caches.forEach(function (c) { Object.keys(g[c]).forEach(function (p) { - t.ok(isAbsolute(p), p + ' should be absolute') + t.ok(path.isAbsolute(p), p + ' should be absolute') }) }) } diff --git a/test/root-nomount.js b/test/root-nomount.js index 1417d4d4..98943095 100644 --- a/test/root-nomount.js +++ b/test/root-nomount.js @@ -2,14 +2,13 @@ require("./global-leakage.js") var tap = require("tap") var glob = require('../') var path = require('path') -var isAbsolute = require('path-is-absolute') function cacheCheck(g, t) { // verify that path cache keys are all absolute var caches = [ 'cache', 'statCache', 'symlinks' ] caches.forEach(function (c) { Object.keys(g[c]).forEach(function (p) { - t.ok(isAbsolute(p), p + ' should be absolute') + t.ok(path.isAbsolute(p), p + ' should be absolute') }) }) } diff --git a/test/root.js b/test/root.js index eb87e3c2..1e4e75b9 100644 --- a/test/root.js +++ b/test/root.js @@ -5,14 +5,13 @@ process.chdir(__dirname + '/fixtures') var glob = require('../') var path = require('path') -var isAbsolute = require('path-is-absolute') function cacheCheck(g, t) { // verify that path cache keys are all absolute var caches = [ 'cache', 'statCache', 'symlinks' ] caches.forEach(function (c) { Object.keys(g[c]).forEach(function (p) { - t.ok(isAbsolute(p), p + ' should be absolute') + t.ok(path.isAbsolute(p), p + ' should be absolute') }) }) } From af57da21c7722bb6edb687ccd4ad3b99d3e7a333 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 16 May 2022 09:42:32 -0700 Subject: [PATCH 025/163] update tap, libtap --- package-lock.json | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index a30d953c..ec337ddf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1716,9 +1716,9 @@ } }, "node_modules/libtap": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.3.0.tgz", - "integrity": "sha512-yU5uSY987sVwpWiR5h84ZM96bxvmCQFZ/bOEJ1M7+Us8oez25fLmmLNGFRFGWi2PzuLqAzqzESH7HCaZ/b9IZA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.4.0.tgz", + "integrity": "sha512-STLFynswQ2A6W14JkabgGetBNk6INL1REgJ9UeNKw5llXroC2cGLgKTqavv0sl8OLVztLLipVKMcQ7yeUcqpmg==", "dev": true, "dependencies": { "async-hook-domain": "^2.0.4", @@ -2476,9 +2476,9 @@ } }, "node_modules/tap": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/tap/-/tap-16.0.1.tgz", - "integrity": "sha512-y32sc4NFWzeOE1mrNvZoS1kRJADI8MCCSaatVBalCNVgusTf59h3t8mHZ3d0wSTQRs05JTOG52WC3KnWovhjPg==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/tap/-/tap-16.2.0.tgz", + "integrity": "sha512-ikfNLy701p2+sH3R0pAXQ/Aen6ZByaguUY7UsoTLL4AXa2c9gYQL+pI21p13lq54R7/CEoLaViC1sexcWG32ig==", "bundleDependencies": [ "ink", "treport", @@ -2488,23 +2488,23 @@ ], "dev": true, "dependencies": { - "@isaacs/import-jsx": "*", - "@types/react": "*", + "@isaacs/import-jsx": "^4.0.1", + "@types/react": "^17", "chokidar": "^3.3.0", "findit": "^2.0.0", "foreground-child": "^2.0.0", "fs-exists-cached": "^1.0.0", "glob": "^7.1.6", - "ink": "*", + "ink": "^3.2.0", "isexe": "^2.0.0", "istanbul-lib-processinfo": "^2.0.2", "jackspeak": "^1.4.1", - "libtap": "^1.3.0", + "libtap": "^1.4.0", "minipass": "^3.1.1", "mkdirp": "^1.0.4", "nyc": "^15.1.0", "opener": "^1.5.1", - "react": "*", + "react": "^17.0.2", "rimraf": "^3.0.0", "signal-exit": "^3.0.6", "source-map-support": "^0.5.16", @@ -2512,7 +2512,7 @@ "tap-parser": "^11.0.1", "tap-yaml": "^1.0.0", "tcompare": "^5.0.7", - "treport": "*", + "treport": "^3.0.3", "which": "^2.0.2" }, "bin": { @@ -6200,9 +6200,9 @@ "peer": true }, "libtap": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.3.0.tgz", - "integrity": "sha512-yU5uSY987sVwpWiR5h84ZM96bxvmCQFZ/bOEJ1M7+Us8oez25fLmmLNGFRFGWi2PzuLqAzqzESH7HCaZ/b9IZA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.4.0.tgz", + "integrity": "sha512-STLFynswQ2A6W14JkabgGetBNk6INL1REgJ9UeNKw5llXroC2cGLgKTqavv0sl8OLVztLLipVKMcQ7yeUcqpmg==", "dev": true, "requires": { "async-hook-domain": "^2.0.4", @@ -6794,28 +6794,28 @@ } }, "tap": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/tap/-/tap-16.0.1.tgz", - "integrity": "sha512-y32sc4NFWzeOE1mrNvZoS1kRJADI8MCCSaatVBalCNVgusTf59h3t8mHZ3d0wSTQRs05JTOG52WC3KnWovhjPg==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/tap/-/tap-16.2.0.tgz", + "integrity": "sha512-ikfNLy701p2+sH3R0pAXQ/Aen6ZByaguUY7UsoTLL4AXa2c9gYQL+pI21p13lq54R7/CEoLaViC1sexcWG32ig==", "dev": true, "requires": { - "@isaacs/import-jsx": "*", - "@types/react": "*", + "@isaacs/import-jsx": "^4.0.1", + "@types/react": "^17", "chokidar": "^3.3.0", "findit": "^2.0.0", "foreground-child": "^2.0.0", "fs-exists-cached": "^1.0.0", "glob": "^7.1.6", - "ink": "*", + "ink": "^3.2.0", "isexe": "^2.0.0", "istanbul-lib-processinfo": "^2.0.2", "jackspeak": "^1.4.1", - "libtap": "^1.3.0", + "libtap": "^1.4.0", "minipass": "^3.1.1", "mkdirp": "^1.0.4", "nyc": "^15.1.0", "opener": "^1.5.1", - "react": "*", + "react": "^17.0.2", "rimraf": "^3.0.0", "signal-exit": "^3.0.6", "source-map-support": "^0.5.16", @@ -6823,7 +6823,7 @@ "tap-parser": "^11.0.1", "tap-yaml": "^1.0.0", "tcompare": "^5.0.7", - "treport": "*", + "treport": "^3.0.3", "which": "^2.0.2" }, "dependencies": { From 1756fccfe713a2d83bfe6ac6e4d93e2d5dc0e69e Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 12 May 2022 12:04:38 -0700 Subject: [PATCH 026/163] add windowsPathsNoEscape option Fix: #468 PR-URL: https://github.com/isaacs/node-glob/pull/470 Credit: @isaacs Close: #470 Reviewed-by: @isaacs --- README.md | 25 +++++++++++- changelog.md | 4 ++ common.js | 8 +++- test/windows-paths-fs.js | 70 +++++++++++++++++++++++++++++++++ test/windows-paths-no-escape.js | 45 +++++++++++++++++++++ 5 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 test/windows-paths-fs.js create mode 100644 test/windows-paths-no-escape.js diff --git a/README.md b/README.md index 83f0c83a..62939110 100644 --- a/README.md +++ b/README.md @@ -210,10 +210,26 @@ parallel glob operations will be sped up by sharing information about the filesystem. * `cwd` The current working directory in which to search. Defaults - to `process.cwd()`. + to `process.cwd()`. This option is always coerced to use + forward-slashes as a path separator, because it is not tested + as a glob pattern, so there is no need to escape anything. * `root` The place where patterns starting with `/` will be mounted onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix - systems, and `C:\` or some such on Windows.) + systems, and `C:\` or some such on Windows.) This option is + always coerced to use forward-slashes as a path separator, + because it is not tested as a glob pattern, so there is no need + to escape anything. +* `windowsPathsNoEscape` Use `\\` as a path separator _only_, and + _never_ as an escape character. If set, all `\\` characters + are replaced with `/` in the pattern. Note that this makes it + **impossible** to match against paths containing literal glob + pattern characters, but allows matching with patterns constructed + using `path.join()` and `path.resolve()` on Windows platforms, + mimicking the (buggy!) behavior of Glob v7 and before on + Windows. Please use with caution, and be mindful of [the caveat + below about Windows paths](#windows). (For legacy reasons, + this is also set if `allowWindowsEscape` is set to the exact + value `false`.) * `dot` Include `.dot` files in normal matches and `globstar` matches. Note that an explicit dot in a portion of the pattern will always match dot files. @@ -332,6 +348,11 @@ Results from absolute patterns such as `/foo/*` are mounted onto the root setting using `path.join`. On windows, this will by default result in `/foo/*` matching `C:\foo\bar.txt`. +To automatically coerce all `\` characters to `/` in pattern +strings, **thus making it impossible to escape literal glob +characters**, you may set the `windowsPathsNoEscape` option to +`true`. + ## Race Conditions Glob searching, by its very nature, is susceptible to race conditions, diff --git a/changelog.md b/changelog.md index e3dd7354..80e2e5b2 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,7 @@ +## 8.1 + +- Add `windowsPathsNoEscape` option + ## 8.0 - Only support node v12 and higher diff --git a/common.js b/common.js index e094f750..61a4452f 100644 --- a/common.js +++ b/common.js @@ -57,6 +57,12 @@ function setopts (self, pattern, options) { pattern = "**/" + pattern } + self.windowsPathsNoEscape = !!options.windowsPathsNoEscape || + options.allowWindowsEscape === false + if (self.windowsPathsNoEscape) { + pattern = pattern.replace(/\\/g, '/') + } + self.silent = !!options.silent self.pattern = pattern self.strict = options.strict !== false @@ -112,8 +118,6 @@ function setopts (self, pattern, options) { // Note that they are not supported in Glob itself anyway. options.nonegate = true options.nocomment = true - // always treat \ in patterns as escapes, not path separators - options.allowWindowsEscape = true self.minimatch = new Minimatch(pattern, options) self.options = self.minimatch.options diff --git a/test/windows-paths-fs.js b/test/windows-paths-fs.js new file mode 100644 index 00000000..85ff9ab8 --- /dev/null +++ b/test/windows-paths-fs.js @@ -0,0 +1,70 @@ +// test that escape chars are handled properly according to configs +// when found in patterns and paths containing glob magic. + +const t = require('tap') +const dir = t.testdir({ + // treat escapes as path separators + a: { + '[x': { + ']b': { + y: '', + }, + }, + }, + // escape parent dir name only, not filename + 'a[x]b': { + y: '', + }, + // no path separators, all escaped + 'a[x]by': '', +}) + +const glob = require('../') +t.test('treat backslash as escape', async t => { + const cases = { + 'a[x]b/y': [], + 'a\\[x\\]b/y': ['a[x]b/y'], + 'a\\[x\\]b\\y': ['a[x]by'], + } + for (const [pattern, expect] of Object.entries(cases)) { + t.test(pattern, t => { + const s = glob.sync(pattern, { cwd: dir }) + .map(s => s.replace(/\\/g, '/')) + t.strictSame(s, expect, 'sync') + glob(pattern, {cwd: dir}, (er, s) => { + if (er) { + throw er + } + s = s.map(s => s.replace(/\\/g, '/')) + t.strictSame(s, expect, 'async') + t.end() + }) + }) + } +}) + +t.test('treat backslash as separator', async t => { + Object.defineProperty(process, 'platform', { + value: 'win32' + }) + const cases = { + 'a[x]b/y': [], + 'a\\[x\\]b/y': ['a/[x/]b/y'], + 'a\\[x\\]b\\y': ['a/[x/]b/y'], + } + for (const [pattern, expect] of Object.entries(cases)) { + t.test(pattern, t => { + const s = glob.sync(pattern, { cwd: dir, windowsPathsNoEscape: true }) + .map(s => s.replace(/\\/g, '/')) + t.strictSame(s, expect, 'sync') + glob(pattern, {cwd: dir, windowsPathsNoEscape: true}, (er, s) => { + if (er) { + throw er + } + s = s.map(s => s.replace(/\\/g, '/')) + t.strictSame(s, expect, 'async') + t.end() + }) + }) + } +}) diff --git a/test/windows-paths-no-escape.js b/test/windows-paths-no-escape.js new file mode 100644 index 00000000..6a1bf1d9 --- /dev/null +++ b/test/windows-paths-no-escape.js @@ -0,0 +1,45 @@ +const t = require('tap') +const g = require('../') + +const platforms = ['win32', 'posix'] +const originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform') +for (const p of platforms) { + t.test(p, t => { + Object.defineProperty(process, 'platform', { + value: p, + enumerable: true, + configurable: true, + writable: true, + }) + t.equal(process.platform, p, 'gut check: actually set platform') + const pattern = '/a/b/c/x\\[a-b\\]y\\*' + const def = new g.Glob(pattern, { noprocess: true }) + const winpath = new g.Glob(pattern, { + windowsPathsNoEscape: true, + noprocess: true, + }) + const winpathLegacy = new g.Glob(pattern, { + allowWindowsEscape: false, + noprocess: true, + }) + const nowinpath = new g.Glob(pattern, { + windowsPathsNoEscape: false, + noprocess: true, + }) + + t.strictSame([ + def.pattern, + nowinpath.pattern, + winpath.pattern, + winpathLegacy.pattern, + ], [ + '/a/b/c/x\\[a-b\\]y\\*', + '/a/b/c/x\\[a-b\\]y\\*', + '/a/b/c/x/[a-b/]y/*', + '/a/b/c/x/[a-b/]y/*', + ]) + t.end() + }) +} + +Object.defineProperty(process, 'platform', originalPlatform) From 1b6bf20239a4c3bd73cacc82daa86bb7cf409398 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sat, 14 Jan 2023 14:35:13 -0800 Subject: [PATCH 027/163] 8.1.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ec337ddf..0a0192e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "glob", - "version": "8.0.3", + "version": "8.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "glob", - "version": "8.0.3", + "version": "8.1.0", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", diff --git a/package.json b/package.json index 5134253e..ca0fd916 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "8.0.3", + "version": "8.1.0", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" From 3a5a70af353b163712ee1c142d293d7bf2a661cf Mon Sep 17 00:00:00 2001 From: License Year Bot Date: Sat, 14 Jan 2023 22:35:38 +0000 Subject: [PATCH 028/163] chore: add copyright year to license --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 39e8fe16..ec7df933 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The ISC License -Copyright (c) 2009-2022 Isaac Z. Schlueter and Contributors +Copyright (c) 2009-2023 Isaac Z. Schlueter and Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above From 187305f2c48ddeccf3a8b4f465bb70e56c1aa9e2 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sun, 15 Jan 2023 18:25:15 -0800 Subject: [PATCH 029/163] v9 rewrite (tests not updated, all failing) --- .github/workflows/ci.yml | 2 +- .gitignore | 14 +- .prettierignore | 9 + CONTRIBUTING.md | 6 +- README.md | 581 ++++---- changelog.md | 26 + common.js | 244 ---- fixup.sh | 13 + glob.js | 790 ---------- package-lock.json | 2991 ++++++++++++++++++++++++++++++++++---- package.json | 90 +- src/glob.ts | 135 ++ src/has-magic.ts | 17 + src/ignore.ts | 34 + src/index.ts | 24 + src/readdir.ts | 87 ++ src/walker.ts | 298 ++++ sync.js | 486 ------- tsconfig-base.json | 17 + tsconfig-cjs.json | 7 + tsconfig-esm.json | 7 + 21 files changed, 3753 insertions(+), 2125 deletions(-) create mode 100644 .prettierignore delete mode 100644 common.js create mode 100644 fixup.sh delete mode 100644 glob.js create mode 100644 src/glob.ts create mode 100644 src/has-magic.ts create mode 100644 src/ignore.ts create mode 100644 src/index.ts create mode 100644 src/readdir.ts create mode 100644 src/walker.ts delete mode 100644 sync.js create mode 100644 tsconfig-base.json create mode 100644 tsconfig-cjs.json create mode 100644 tsconfig-esm.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7090c3fe..cac0372b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ jobs: build: strategy: matrix: - node-version: [12.x, 14.x, 16.x, 18.x] + node-version: [16.x, 18.x, 19.x] platform: - os: ubuntu-latest shell: bash diff --git a/.gitignore b/.gitignore index 06cc0e0b..e50a7792 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,10 @@ .*.swp +/old /*.tap -node_modules/* -v8.log -profile.txt -nyc_output/ -.nyc_output/ -coverage/ +/dist +/node_modules +/v8.log +/profile.txt +/nyc_output +/.nyc_output +/coverage diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..9fdb805a --- /dev/null +++ b/.prettierignore @@ -0,0 +1,9 @@ +/node_modules +/example +/.github +/dist +.env +/tap-snapshots +/.nyc_output +/coverage +/benchmark diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb90985c..85e4a81b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,12 +1,8 @@ -Please consider signing [the neveragain.tech pledge](http://neveragain.tech/) - -## Contributing - Any change to behavior (including bugfixes) must come with a test. Patches that fail tests or reduce performance will be rejected. -``` +```sh # to run tests npm test diff --git a/README.md b/README.md index 62939110..b4a1449b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ # Glob -Match files using the patterns the shell uses, like stars and stuff. +Match files using the patterns the shell uses. -[![Build Status](https://travis-ci.org/isaacs/node-glob.svg?branch=master)](https://travis-ci.org/isaacs/node-glob/) [![Build Status](https://ci.appveyor.com/api/projects/status/kd7f3yftf7unxlsx?svg=true)](https://ci.appveyor.com/project/isaacs/node-glob) [![Coverage Status](https://coveralls.io/repos/isaacs/node-glob/badge.svg?branch=master&service=github)](https://coveralls.io/github/isaacs/node-glob?branch=master) - -This is a glob implementation in JavaScript. It uses the `minimatch` -library to do its matching. +This is a glob implementation in JavaScript. It uses the +[`minimatch`](http://npm.im/minimatch) library to do its +matching. ![a fun cartoon logo made of glob characters](logo/glob.png) @@ -17,321 +16,278 @@ Install with npm npm i glob ``` -```javascript -var glob = require("glob") +```js +// load using import +import { glob } from 'glob' +// or using commonjs +const { glob } = require('glob') -// options is optional -glob("**/*.js", options, function (er, files) { - // files is an array of filenames. - // If the `nonull` option is set, and nothing - // was found, then files is ["**/*.js"] - // er is an error object or null. -}) -``` +// these all return arrays of filenames -## Glob Primer +// all js files, but don't look in node_modules +const jsfiles = await glob('**/*.js', { ignore: 'node_modules/**' }) -"Globs" are the patterns you type when you do stuff like `ls *.js` on -the command line, or put `build/*` in a `.gitignore` file. - -Before parsing the path part patterns, braced sections are expanded -into a set. Braced sections start with `{` and end with `}`, with any -number of comma-delimited sections within. Braced sections may contain -slash characters, so `a{/b/c,bcd}` would expand into `a/b/c` and `abcd`. - -The following characters have special magic meaning when used in a -path portion: - -* `*` Matches 0 or more characters in a single path portion -* `?` Matches 1 character -* `[...]` Matches a range of characters, similar to a RegExp range. - If the first character of the range is `!` or `^` then it matches - any character not in the range. -* `!(pattern|pattern|pattern)` Matches anything that does not match - any of the patterns provided. -* `?(pattern|pattern|pattern)` Matches zero or one occurrence of the - patterns provided. -* `+(pattern|pattern|pattern)` Matches one or more occurrences of the - patterns provided. -* `*(a|b|c)` Matches zero or more occurrences of the patterns provided -* `@(pattern|pat*|pat?erN)` Matches exactly one of the patterns - provided -* `**` If a "globstar" is alone in a path portion, then it matches - zero or more directories and subdirectories searching for matches. - It does not crawl symlinked directories. +// multiple patterns supported as well +const images = await glob(['css/*.{png,jpeg}', 'public/*.{png,jpeg}']) -### Dots +// but of course you can do that with the glob pattern also +const imagesAlt = await glob('{css,public}/*.{png,jpeg}') +``` -If a file or directory path portion has a `.` as the first character, -then it will not match any glob pattern unless that pattern's -corresponding path part also has a `.` as its first character. +## `glob(pattern: string | string[], options?: GlobOptions) => Promise` -For example, the pattern `a/.*/c` would match the file at `a/.b/c`. -However the pattern `a/*/c` would not, because `*` does not start with -a dot character. +Perform an asynchronous glob search for the pattern(s) specified. +See below for options field desciptions. -You can make glob treat dots as normal characters by setting -`dot:true` in the options. +## `globSync(pattern: string, options?: GlobOptions) => string[]` -### Basename Matching +Synchronous form of `glob()`. -If you set `matchBase:true` in the options, and the pattern has no -slashes in it, then it will seek for any file anywhere in the tree -with a matching basename. For example, `*.js` would match -`test/simple/basic.js`. +## Options -### Empty Sets +Exported as `GlobOptions` TypeScript interface. -If no matching files are found, then an empty array is returned. This -differs from the shell, where the pattern itself is returned. For -example: +All options that can be passed to +[`minimatch`](http://npm.im/minimatch) can also be passed to Glob +to affect pattern matching behavior. - $ echo a*s*d*f - a*s*d*f +All options are optional, and false by default, unless otherwise +noted. -To get the bash-style behavior, set the `nonull:true` in the options. +All options are added to the Glob object, as well. -### See Also: +If you are running many `glob` operations, you can pass a Glob +object as the `options` argument to a subsequent operation to +shortcut some `readdir` calls. At the very least, you may pass in +a shared `cache` option, so that parallel glob operations will be +sped up by sharing information about the filesystem. + +- `cwd` The current working directory in which to search. + Defaults to `process.cwd()`. This option is always coerced to + use forward-slashes as a path separator, because it is not + tested as a glob pattern, so there is no need to escape + anything. +- `windowsPathsNoEscape` Use `\\` as a path separator _only_, and + _never_ as an escape character. If set, all `\\` characters are + replaced with `/` in the pattern. Note that this makes it + **impossible** to match against paths containing literal glob + pattern characters, but allows matching with patterns + constructed using `path.join()` and `path.resolve()` on Windows + platforms, mimicking the (buggy!) behavior of Glob v7 and + before on Windows. Please use with caution, and be mindful of + [the caveat below about Windows paths](#windows). (For legacy + reasons, this is also set if `allowWindowsEscape` is set to the + exact value `false`.) +- `dot` Include `.dot` files in normal matches and `globstar` + matches. Note that an explicit dot in a portion of the pattern + will always match dot files. +- `mark` Add a `/` character to directory matches. Note that this + requires additional stat calls. +- `nosort` Don't sort the results. +- `cache` See `cache` property above. Pass in a previously + generated cache object to save some fs calls. +- `nounique` In some cases, brace-expanded patterns or symlinks + resolved with `{realpath: true}` can result in the same path + showing up multiple times in the result set. By default, this + implementation prevents duplicates in the result set. Set this + flag to disable that behavior. +- `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets. +- `noglobstar` Do not match `**` against multiple filenames. (Ie, + treat it as a normal `*` instead.) +- `noext` Do not match `+(a|b)` "extglob" patterns. +- `nocase` Perform a case-insensitive match. Note: on + case-insensitive filesystems, non-magic patterns may match + case-insensitively by default, since `stat` and `readdir` will + not raise errors. +- `matchBase` Perform a basename-only match if the pattern does + not contain any slash characters. That is, `*.js` would be + treated as equivalent to `**/*.js`, matching all js files in + all directories. +- `nodir` Do not match directories, only files. (Note: to match + _only_ directories, simply put a `/` at the end of the + pattern.) +- `ignore` A glob pattern or array of glob patterns to exclude + from matches. To ignore all children within a directory, as + well as the entry itself, append `/**'` to the ignore pattern. + Note: `ignore` patterns are _always_ in `dot:true` mode, + regardless of any other settings. +- `follow` Follow symlinked directories when expanding `**` + patterns. Note that this can result in a lot of duplicate + references in the presence of cyclic links, and make + performance quite bad. +- `realpath` Set to true to call `fs.realpath` on all of the + results. In the case of an entry that cannot be resolved, the + path-resolved absolute path to the matched entry is returned + (though it will usually be a broken symlink). +- `absolute` Set to true to always receive absolute paths for + matched files. Note that this does _not_ make an extra system + call to get the realpath, it only does string path resolution. +- `nonull` When a brace-expanded portion of the pattern does not + have find matches, setting `{nonull:true}` will cause glob to + return the pattern itself instead of the empty set. + +`nocomment` and `nonegate` are always set to `false`. + +## `hasMagic(pattern: string, options?: GlobOptions) => boolean` + +Returns `true` if there are any special characters in the +pattern, and `false` otherwise. + +Note that the options affect the results. If `noext:true` is set +in the options object, then `+(a|b)` will not be considered a +magic pattern. If the pattern has a brace expansion, like +`a/{b/c,x/y}` then that is considered magical, unless +`{nobrace:true}` is set in the options. + +## Class: `Glob` + +The implementation called by the `glob()` method. + +```js +import { Glob } from 'glob' +const ohMyGlob = new Glob(pattern, options) + +// sync traversal +const results = ohMyGlob.processSync() + +// async traversal +const results = await ohMyGlob.process() +``` -* `man sh` -* `man bash` (Search for "Pattern Matching") -* `man 3 fnmatch` -* `man 5 gitignore` -* [minimatch documentation](https://github.com/isaacs/minimatch) +### `new Glob(pattern: string, options?: GlobOptions | Glob)` -## glob.hasMagic(pattern, [options]) +Constructs a new `Glob` object. -Returns `true` if there are any special characters in the pattern, and -`false` otherwise. +### `glob.process() => Promise` -Note that the options affect the results. If `noext:true` is set in -the options object, then `+(a|b)` will not be considered a magic -pattern. If the pattern has a brace expansion, like `a/{b/c,x/y}` -then that is considered magical, unless `nobrace:true` is set in the -options. +Performs a directory walk and returns the matching entries. -## glob(pattern, [options], cb) +### `glob.processSync() => string[]` -* `pattern` `{String}` Pattern to be matched -* `options` `{Object}` -* `cb` `{Function}` - * `err` `{Error | null}` - * `matches` `{Array}` filenames found matching the pattern +Synchronous form of `glob.process()` -Perform an asynchronous glob search. +## Glob Primer -## glob.sync(pattern, [options]) +Much more information about glob pattern expansion can be found +by running `man bash` and searching for `Pattern Matching`. + +"Globs" are the patterns you type when you do stuff like `ls +*.js` on the command line, or put `build/*` in a `.gitignore` +file. + +Before parsing the path part patterns, braced sections are +expanded into a set. Braced sections start with `{` and end with +`}`, with 2 or more comma-delimited sections within. Braced +sections may contain slash characters, so `a{/b/c,bcd}` would +expand into `a/b/c` and `abcd`. + +The following characters have special magic meaning when used in +a path portion: + +- `*` Matches 0 or more characters in a single path portion +- `?` Matches 1 character +- `[...]` Matches a range of characters, similar to a RegExp + range. If the first character of the range is `!` or `^` then + it matches any character not in the range. +- `!(pattern|pattern|pattern)` Matches anything that does not + match any of the patterns provided. May _not_ contain `/` + characters. +- `?(pattern|pattern|pattern)` Matches zero or one occurrence of + the patterns provided. May _not_ contain `/` characters. +- `+(pattern|pattern|pattern)` Matches one or more occurrences of + the patterns provided. May _not_ contain `/` characters. +- `*(a|b|c)` Matches zero or more occurrences of the patterns + provided. May _not_ contain `/` characters. +- `@(pattern|pat*|pat?erN)` Matches exactly one of the patterns + provided. May _not_ contain `/` characters. +- `**` If a "globstar" is alone in a path portion, then it + matches zero or more directories and subdirectories searching + for matches. It does not crawl symlinked directories, unless + `{follow:true}` is passed in the options object. + +Note that `[:class:]`, `[=c=]`, and `[.symbol.]` style class +patterns are _not_ supported by this implementation. -* `pattern` `{String}` Pattern to be matched -* `options` `{Object}` -* return: `{Array}` filenames found matching the pattern +### Dots -Perform a synchronous glob search. +If a file or directory path portion has a `.` as the first +character, then it will not match any glob pattern unless that +pattern's corresponding path part also has a `.` as its first +character. -## Class: glob.Glob +For example, the pattern `a/.*/c` would match the file at +`a/.b/c`. However the pattern `a/*/c` would not, because `*` does +not start with a dot character. -Create a Glob object by instantiating the `glob.Glob` class. +You can make glob treat dots as normal characters by setting +`dot:true` in the options. -```javascript -var Glob = require("glob").Glob -var mg = new Glob(pattern, options, cb) -``` +### Basename Matching -It's an EventEmitter, and starts walking the filesystem to find matches -immediately. - -### new glob.Glob(pattern, [options], [cb]) - -* `pattern` `{String}` pattern to search for -* `options` `{Object}` -* `cb` `{Function}` Called when an error occurs, or matches are found - * `err` `{Error | null}` - * `matches` `{Array}` filenames found matching the pattern - -Note that if the `sync` flag is set in the options, then matches will -be immediately available on the `g.found` member. - -### Properties - -* `minimatch` The minimatch object that the glob uses. -* `options` The options object passed in. -* `aborted` Boolean which is set to true when calling `abort()`. There - is no way at this time to continue a glob search after aborting, but - you can re-use the statCache to avoid having to duplicate syscalls. -* `cache` Convenience object. Each field has the following possible - values: - * `false` - Path does not exist - * `true` - Path exists - * `'FILE'` - Path exists, and is not a directory - * `'DIR'` - Path exists, and is a directory - * `[file, entries, ...]` - Path exists, is a directory, and the - array value is the results of `fs.readdir` -* `statCache` Cache of `fs.stat` results, to prevent statting the same - path multiple times. -* `symlinks` A record of which paths are symbolic links, which is - relevant in resolving `**` patterns. -* `realpathCache` An optional object which is passed to `fs.realpath` - to minimize unnecessary syscalls. It is stored on the instantiated - Glob object, and may be re-used. - -### Events - -* `end` When the matching is finished, this is emitted with all the - matches found. If the `nonull` option is set, and no match was found, - then the `matches` list contains the original pattern. The matches - are sorted, unless the `nosort` flag is set. -* `match` Every time a match is found, this is emitted with the specific - thing that matched. It is not deduplicated or resolved to a realpath. -* `error` Emitted when an unexpected error is encountered, or whenever - any fs error occurs if `options.strict` is set. -* `abort` When `abort()` is called, this event is raised. - -### Methods - -* `pause` Temporarily stop the search -* `resume` Resume the search -* `abort` Stop the search forever - -### Options - -All the options that can be passed to Minimatch can also be passed to -Glob to change pattern matching behavior. Also, some have been added, -or have glob-specific ramifications. - -All options are false by default, unless otherwise noted. +If you set `matchBase:true` in the options, and the pattern has +no slashes in it, then it will seek for any file anywhere in the +tree with a matching basename. For example, `*.js` would match +`test/simple/basic.js`. -All options are added to the Glob object, as well. +### Empty Sets -If you are running many `glob` operations, you can pass a Glob object -as the `options` argument to a subsequent operation to shortcut some -`stat` and `readdir` calls. At the very least, you may pass in shared -`symlinks`, `statCache`, `realpathCache`, and `cache` options, so that -parallel glob operations will be sped up by sharing information about -the filesystem. - -* `cwd` The current working directory in which to search. Defaults - to `process.cwd()`. This option is always coerced to use - forward-slashes as a path separator, because it is not tested - as a glob pattern, so there is no need to escape anything. -* `root` The place where patterns starting with `/` will be mounted - onto. Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix - systems, and `C:\` or some such on Windows.) This option is - always coerced to use forward-slashes as a path separator, - because it is not tested as a glob pattern, so there is no need - to escape anything. -* `windowsPathsNoEscape` Use `\\` as a path separator _only_, and - _never_ as an escape character. If set, all `\\` characters - are replaced with `/` in the pattern. Note that this makes it - **impossible** to match against paths containing literal glob - pattern characters, but allows matching with patterns constructed - using `path.join()` and `path.resolve()` on Windows platforms, - mimicking the (buggy!) behavior of Glob v7 and before on - Windows. Please use with caution, and be mindful of [the caveat - below about Windows paths](#windows). (For legacy reasons, - this is also set if `allowWindowsEscape` is set to the exact - value `false`.) -* `dot` Include `.dot` files in normal matches and `globstar` matches. - Note that an explicit dot in a portion of the pattern will always - match dot files. -* `nomount` By default, a pattern starting with a forward-slash will be - "mounted" onto the root setting, so that a valid filesystem path is - returned. Set this flag to disable that behavior. -* `mark` Add a `/` character to directory matches. Note that this - requires additional stat calls. -* `nosort` Don't sort the results. -* `stat` Set to true to stat *all* results. This reduces performance - somewhat, and is completely unnecessary, unless `readdir` is presumed - to be an untrustworthy indicator of file existence. -* `silent` When an unusual error is encountered when attempting to - read a directory, a warning will be printed to stderr. Set the - `silent` option to true to suppress these warnings. -* `strict` When an unusual error is encountered when attempting to - read a directory, the process will just continue on in search of - other matches. Set the `strict` option to raise an error in these - cases. -* `cache` See `cache` property above. Pass in a previously generated - cache object to save some fs calls. -* `statCache` A cache of results of filesystem information, to prevent - unnecessary stat calls. While it should not normally be necessary - to set this, you may pass the statCache from one glob() call to the - options object of another, if you know that the filesystem will not - change between calls. (See "Race Conditions" below.) -* `symlinks` A cache of known symbolic links. You may pass in a - previously generated `symlinks` object to save `lstat` calls when - resolving `**` matches. -* `sync` DEPRECATED: use `glob.sync(pattern, opts)` instead. -* `nounique` In some cases, brace-expanded patterns can result in the - same file showing up multiple times in the result set. By default, - this implementation prevents duplicates in the result set. Set this - flag to disable that behavior. -* `nonull` Set to never return an empty set, instead returning a set - containing the pattern itself. This is the default in glob(3). -* `debug` Set to enable debug logging in minimatch and glob. -* `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets. -* `noglobstar` Do not match `**` against multiple filenames. (Ie, - treat it as a normal `*` instead.) -* `noext` Do not match `+(a|b)` "extglob" patterns. -* `nocase` Perform a case-insensitive match. Note: on - case-insensitive filesystems, non-magic patterns will match by - default, since `stat` and `readdir` will not raise errors. -* `matchBase` Perform a basename-only match if the pattern does not - contain any slash characters. That is, `*.js` would be treated as - equivalent to `**/*.js`, matching all js files in all directories. -* `nodir` Do not match directories, only files. (Note: to match - *only* directories, simply put a `/` at the end of the pattern.) -* `ignore` Add a pattern or an array of glob patterns to exclude matches. - Note: `ignore` patterns are *always* in `dot:true` mode, regardless - of any other settings. -* `follow` Follow symlinked directories when expanding `**` patterns. - Note that this can result in a lot of duplicate references in the - presence of cyclic links. -* `realpath` Set to true to call `fs.realpath` on all of the results. - In the case of a symlink that cannot be resolved, the full absolute - path to the matched entry is returned (though it will usually be a - broken symlink) -* `absolute` Set to true to always receive absolute paths for matched - files. Unlike `realpath`, this also affects the values returned in - the `match` event. -* `fs` File-system object with Node's `fs` API. By default, the built-in - `fs` module will be used. Set to a volume provided by a library like - `memfs` to avoid using the "real" file-system. +If no matching files are found, then an empty array is returned. +This differs from the shell, where the pattern itself is +returned. For example: + +```sh +$ echo a*s*d*f +a*s*d*f +``` + +To return the pattern when there are no matches, use the +`{nonull:true}` option. ## Comparisons to other fnmatch/glob implementations -While strict compliance with the existing standards is a worthwhile -goal, some discrepancies exist between node-glob and other -implementations, and are intentional. - -The double-star character `**` is supported by default, unless the -`noglobstar` flag is set. This is supported in the manner of bsdglob -and bash 4.3, where `**` only has special significance if it is the only -thing in a path part. That is, `a/**/b` will match `a/x/y/b`, but -`a/**b` will not. - -Note that symlinked directories are not crawled as part of a `**`, -though their contents may match against subsequent portions of the -pattern. This prevents infinite loops and duplicates and the like. - -If an escaped pattern has no matches, and the `nonull` flag is set, -then glob returns the pattern as-provided, rather than -interpreting the character escapes. For example, -`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than -`"*a?"`. This is akin to setting the `nullglob` option in bash, except -that it does not resolve escaped pattern characters. - -If brace expansion is not disabled, then it is performed before any -other interpretation of the glob pattern. Thus, a pattern like -`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded -**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are -checked for validity. Since those two are valid, matching proceeds. +While strict compliance with the existing standards is a +worthwhile goal, some discrepancies exist between node-glob and +other implementations, and are intentional. + +The double-star character `**` is supported by default, unless +the `noglobstar` flag is set. This is supported in the manner of +bsdglob and bash 5, where `**` only has special significance if +it is the only thing in a path part. That is, `a/**/b` will match +`a/x/y/b`, but `a/**b` will not. + +Note that symlinked directories are not traversed as part of a +`**`, though their contents may match against subsequent portions +of the pattern. This prevents infinite loops and duplicates and +the like. You can force glob to traverse symlinks with `**` by +setting `{follow:true}` in the options. + +If an escaped pattern has no matches, and the `nonull` flag is +set, then glob returns the pattern as-provided, rather than +interpreting the character escapes. For example, `glob.match([], +"\\*a\\?")` will return `"\\*a\\?"` rather than `"*a?"`. This is +akin to setting the `nullglob` option in bash, except that it +does not resolve escaped pattern characters. + +If brace expansion is not disabled, then it is performed before +any other interpretation of the glob pattern. Thus, a pattern +like `+(a|{b),c)}`, which would not be valid in bash or zsh, is +expanded **first** into the set of `+(a|b)` and `+(a|c)`, and +those patterns are checked for validity. Since those two are +valid, matching proceeds. + +The character class patterns `[:class:]` (POSIX standard named +classes), `[=c=]` (locale-specific character collation weight), +and `[.symbol.]` (collating symbol) style class patterns are +_not_ supported by this implementation. ### Comments and Negation -Previously, this module let you mark a pattern as a "comment" if it -started with a `#` character, or a "negated" pattern if it started -with a `!` character. +Previously, this module let you mark a pattern as a "comment" if +it started with a `#` character, or a "negated" pattern if it +started with a `!` character. -These options were deprecated in version 5, and removed in version 6. +These options were deprecated in version 5, and removed in +version 6. To specify things that should not match, use the `ignore` option. @@ -339,14 +295,14 @@ To specify things that should not match, use the `ignore` option. **Please only use forward-slashes in glob expressions.** -Though windows uses either `/` or `\` as its path separator, only `/` -characters are used by this glob implementation. You must use -forward-slashes **only** in glob expressions. Back-slashes will always -be interpreted as escape characters, not path separators. +Though windows uses either `/` or `\` as its path separator, only +`/` characters are used by this glob implementation. You must use +forward-slashes **only** in glob expressions. Back-slashes will +always be interpreted as escape characters, not path separators. -Results from absolute patterns such as `/foo/*` are mounted onto the -root setting using `path.join`. On windows, this will by default result -in `/foo/*` matching `C:\foo\bar.txt`. +Results from absolute patterns such as `/foo/*` are mounted onto +the root setting using `path.join`. On windows, this will by +default result in `/foo/*` matching `C:\foo\bar.txt`. To automatically coerce all `\` characters to `/` in pattern strings, **thus making it impossible to escape literal glob @@ -355,34 +311,48 @@ characters**, you may set the `windowsPathsNoEscape` option to ## Race Conditions -Glob searching, by its very nature, is susceptible to race conditions, -since it relies on directory walking and such. +Glob searching, by its very nature, is susceptible to race +conditions, since it relies on directory walking. -As a result, it is possible that a file that exists when glob looks for -it may have been deleted or modified by the time it returns the result. +As a result, it is possible that a file that exists when glob +looks for it may have been deleted or modified by the time it +returns the result. -As part of its internal implementation, this program caches all stat -and readdir calls that it makes, in order to cut down on system -overhead. However, this also makes it even more susceptible to races, -especially if the cache or statCache objects are reused between glob -calls. +By design, this implementation caches all readdir calls that it +makes, in order to cut down on system overhead. However, this +also makes it even more susceptible to races, especially if the +cache object is reused between glob calls. Users are thus advised not to use a glob result as a guarantee of -filesystem state in the face of rapid changes. For the vast majority -of operations, this is never a problem. +filesystem state in the face of rapid changes. For the vast +majority of operations, this is never a problem. + +### See Also: + +- `man sh` +- `man bash` (Search for "Pattern Matching") +- `man 3 fnmatch` +- `man 5 gitignore` +- [minimatch documentation](https://github.com/isaacs/minimatch) ## Glob Logo -Glob's logo was created by [Tanya Brassie](http://tanyabrassie.com/). Logo files can be found [here](https://github.com/isaacs/node-glob/tree/master/logo). -The logo is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/). +Glob's logo was created by [Tanya +Brassie](http://tanyabrassie.com/). Logo files can be found +[here](https://github.com/isaacs/node-glob/tree/master/logo). + +The logo is licensed under a [Creative Commons +Attribution-ShareAlike 4.0 International +License](https://creativecommons.org/licenses/by-sa/4.0/). ## Contributing -Any change to behavior (including bugfixes) must come with a test. +Any change to behavior (including bugfixes) must come with a +test. Patches that fail tests or reduce performance will be rejected. -``` +```sh # to run tests npm test @@ -395,5 +365,4 @@ npm run bench # to profile javascript npm run prof ``` - ![](oh-my-glob.gif) diff --git a/changelog.md b/changelog.md index 80e2e5b2..764fc09d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,29 @@ +## 9.0 + +This is a full rewrite. + +- Promise API instead of callbacks. +- Accept pattern as string or array of strings. +- Hybrid module distribution. +- Full TypeScript support. +- Removed `root` option and mounting behavior. +- Removed `stat` option. +- Simplified `cwd` behavior. Now it simply serves as the initial + argument to `fs.readdir`. +- Removed all stat calls, in favor of using `withFileTypes:true` + with `fs.readdir()`. +- Consolidated all caching to a single object that only caches + directory entries and `readdir` errors. +- Removed EventEmitter behavior from exported `Glob` class. +- Consolidated sync and async `Glob` class behavior into a single + class with `process()` and `processSync()` methods. +- Removed `silent` option. Any readdir errors are simply treated as + "the directory could not be read", and it is treated as a + normal file entry instead, like shells do. +- Removed `fs` option. This module only operates on the real + filesystem. +- Only support node 16 and higher. + ## 8.1 - Add `windowsPathsNoEscape` option diff --git a/common.js b/common.js deleted file mode 100644 index 61a4452f..00000000 --- a/common.js +++ /dev/null @@ -1,244 +0,0 @@ -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored - -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var fs = require("fs") -var path = require("path") -var minimatch = require("minimatch") -var isAbsolute = require("path").isAbsolute -var Minimatch = minimatch.Minimatch - -function alphasort (a, b) { - return a.localeCompare(b, 'en') -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || [] - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} - -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern, { dot: true }) - } - - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher - } -} - -function setopts (self, pattern, options) { - if (!options) - options = {} - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - self.windowsPathsNoEscape = !!options.windowsPathsNoEscape || - options.allowWindowsEscape === false - if (self.windowsPathsNoEscape) { - pattern = pattern.replace(/\\/g, '/') - } - - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - self.absolute = !!options.absolute - self.fs = options.fs || fs - - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) - - setupIgnores(self, options) - - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = path.resolve(cwd) - else { - self.cwd = path.resolve(options.cwd) - self.changedCwd = self.cwd !== cwd - } - - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) - self.nomount = !!options.nomount - - if (process.platform === "win32") { - self.root = self.root.replace(/\\/g, "/") - self.cwd = self.cwd.replace(/\\/g, "/") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") - } - - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true - options.nocomment = true - - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options -} - -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) - } - } - - if (!nou) - all = Object.keys(all) - - if (!self.nosort) - all = all.sort(alphasort) - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) - } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)) - var c = self.cache[e] || self.cache[makeAbs(self, e)] - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c) - return notDir - }) - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) - - self.found = all -} - -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' - - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) - - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] - } - } - - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) - } - - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/') - - return abs -} - - -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} diff --git a/fixup.sh b/fixup.sh new file mode 100644 index 00000000..dba4325c --- /dev/null +++ b/fixup.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +cat >dist/cjs/package.json <dist/mjs/package.json < 1) - return true - - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } - - return false -} - -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options) - this._didRealPath = false - - // process each pattern in the minimatch set - var n = this.minimatch.set.length - - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) - - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) - } - - var self = this - this._processing = 0 - - this._emitQueue = [] - this._processQueue = [] - this.paused = false - - if (this.noprocess) - return this - - if (n === 0) - return done() - - var sync = true - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) - } - sync = false - - function done () { - --self._processing - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish() - }) - } else { - self._finish() - } - } - } -} - -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return - - if (this.realpath && !this._didRealpath) - return this._realpath() - - common.finish(this) - this.emit('end', this.found) -} - -Glob.prototype._realpath = function () { - if (this._didRealpath) - return - - this._didRealpath = true - - var n = this.matches.length - if (n === 0) - return this._finish() - - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) - - function next () { - if (--n === 0) - self._finish() - } -} - -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() - - var found = Object.keys(matchset) - var self = this - var n = found.length - - if (n === 0) - return cb() - - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here - - if (--n === 0) { - self.matches[index] = set - cb() - } - }) - }) -} - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} - -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} - -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') -} - -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } -} - -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } - } - } -} - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') - - if (this.aborted) - return - - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return - } - - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) -} - -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return cb() - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - this._process([e].concat(remain), index, inGlobStar, cb) - } - cb() -} - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]) - return - } - - var abs = isAbsolute(e) ? e : this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) - e = abs - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) - - this.emit('match', e) -} - -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return - - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) - - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) - - if (lstatcb) - self.fs.lstat(abs, lstatcb) - - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() - - var isSym = lstat && lstat.isSymbolicLink() - self.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } -} - -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return - - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() - - if (Array.isArray(c)) - return cb(null, c) - } - - var self = this - self.fs.readdir(abs, readdirCb(this, abs, cb)) -} - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) - } -} - -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return - - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - return cb(null, entries) -} - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - this.emit('error', error) - this.abort() - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() - } - if (!this.silent) - console.error('glob error', er) - break - } - - return cb() -} - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} - - -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) - - var isSym = this.symlinks[abs] - var len = entries.length - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) - } - - cb() -} - -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) -} -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} - -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return cb() - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) - - if (needDir && c === 'FILE') - return cb() - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } - - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - self.fs.lstat(abs, statcb) - - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return self.fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) - } - } -} - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return cb() - } - - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return cb() - - return cb(null, c, stat) -} diff --git a/package-lock.json b/package-lock.json index 0a0192e4..909afbbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,29 +1,30 @@ { "name": "glob", - "version": "8.1.0", + "version": "9.0.0-0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "glob", - "version": "8.1.0", + "version": "9.0.0-0", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "minimatch": "^6.0.4" }, "devDependencies": { + "@types/node": "^18.11.18", + "@types/tap": "^15.0.7", + "c8": "^7.12.0", + "eslint-config-prettier": "^8.6.0", "memfs": "^3.2.0", "mkdirp": "0", + "prettier": "^2.8.3", "rimraf": "^2.2.8", - "tap": "^16.0.1", - "tick": "0.0.6" - }, - "engines": { - "node": ">=12" + "tap": "^16.3.3", + "ts-node": "^10.9.1", + "typedoc": "^0.23.24", + "typescript": "^4.9.4" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -335,6 +336,181 @@ "node": ">=6.9.0" } }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "dev": true, + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/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, + "peer": true + }, + "node_modules/@eslint/eslintrc/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, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "peer": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/eslintrc/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, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "peer": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/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, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true, + "peer": true + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -361,30 +537,144 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true + }, + "node_modules/@types/tap": { + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/@types/tap/-/tap-15.0.7.tgz", + "integrity": "sha512-TTMajw4gxQfFgYbhXhy/Tb2OiNcwS+4oP/9yp1/GdU0pFJo3wtnkYhRgmQy39ksh+rnoa0VrPHJ4Tuv2cLNQ5A==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peer": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -403,7 +693,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "optional": true, "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -468,6 +757,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -618,70 +913,209 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/byline": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/byline/-/byline-2.0.3.tgz", - "integrity": "sha1-gRskuHScHN0dJrWbd/zBnT4Nhsk=", + "node_modules/c8": { + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz", + "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==", "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^2.0.0", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-reports": "^3.1.4", + "rimraf": "^3.0.2", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9" + }, + "bin": { + "c8": "bin/c8.js" + }, "engines": { - "node": "*" + "node": ">=10.12.0" } }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "node_modules/c8/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": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/c8/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": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001311", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001311.tgz", - "integrity": "sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==", + "node_modules/c8/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": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true, - "optional": true, - "peer": true - }, - "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==", + "node_modules/c8/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": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=4" - } + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c8/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/c8/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/c8/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/c8/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001311", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001311.tgz", + "integrity": "sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true, + "optional": true, + "peer": true + }, + "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/chokidar": { "version": "3.5.3", @@ -818,6 +1252,12 @@ "node": ">=6" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -872,6 +1312,13 @@ "node": ">=0.10.0" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "peer": true + }, "node_modules/default-require-extensions": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", @@ -904,6 +1351,19 @@ "node": ">=0.3.1" } }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "peer": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -949,20 +1409,446 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true, "engines": { - "node": ">=0.8.0" + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz", + "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz", + "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "peer": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/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, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/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, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/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, + "peer": true + }, + "node_modules/eslint/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, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": 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/eslint/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, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/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, + "peer": true + }, + "node_modules/eslint/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, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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, + "peer": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "peer": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "peer": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/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, + "peer": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/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, + "peer": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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, + "peer": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/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, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/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, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "peer": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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, + "peer": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "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, + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0" } }, - "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==", + "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, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, + "peer": true, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, "node_modules/events-to-array": { @@ -995,7 +1881,6 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, - "optional": true, "peer": true }, "node_modules/fast-json-stable-stringify": { @@ -1003,9 +1888,38 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "optional": true, "peer": true }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "peer": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "peer": 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, + "peer": 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", @@ -1054,6 +1968,43 @@ "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", "dev": true }, + "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, + "peer": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/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, + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true, + "peer": true + }, "node_modules/foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -1190,15 +2141,15 @@ } }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -1258,6 +2209,13 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true, + "peer": true + }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -1333,6 +2291,43 @@ "npm": ">=1.3.7" } }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "peer": 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, + "peer": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -1355,6 +2350,7 @@ "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" @@ -1363,7 +2359,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -1416,6 +2413,16 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -1494,18 +2501,17 @@ } }, "node_modules/istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", "dev": true, "dependencies": { "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", "p-map": "^3.0.0", "rimraf": "^3.0.0", - "uuid": "^3.3.3" + "uuid": "^8.3.2" }, "engines": { "node": ">=8" @@ -1526,6 +2532,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/istanbul-lib-processinfo/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", @@ -1598,9 +2613,9 @@ } }, "node_modules/jackspeak": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.1.tgz", - "integrity": "sha512-npN8f+M4+IQ8xD3CcWi3U62VQwKlT3Tj4GxbdT/fYTmeogD9eBF9OFdpoFG/VPNoshRjPUijdkp/p2XrzUHaVg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.2.tgz", + "integrity": "sha512-GHeGTmnuaHnvS+ZctRB01bfxARuu9wW83ENbuiweu07SFcVlZrJpcshSre/keGT7YGBhLHg/+rXCNSrsEHKU4Q==", "dev": true, "dependencies": { "cliui": "^7.0.4" @@ -1609,6 +2624,17 @@ "node": ">=8" } }, + "node_modules/js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "dev": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -1661,7 +2687,13 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "optional": true, + "peer": 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": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, "peer": true }, "node_modules/json-stringify-safe": { @@ -1673,13 +2705,10 @@ "peer": true }, "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, "bin": { "json5": "lib/cli.js" }, @@ -1687,6 +2716,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "node_modules/jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -1715,6 +2750,20 @@ "lcov-parse": "bin/cli.js" } }, + "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, + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/libtap": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.4.0.tgz", @@ -1742,6 +2791,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/libtap/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -1760,6 +2821,13 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "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, + "peer": true + }, "node_modules/log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", @@ -1771,6 +2839,12 @@ "node": ">=0.8.6" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -1786,6 +2860,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/marked": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz", + "integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/memfs": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", @@ -1824,14 +2916,17 @@ } }, "node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.0.4.tgz", + "integrity": "sha512-9SQupyyavjdAc1VFjJS/5kdtFtlLAhKSWt7HocG0h/npy626jYrGegSslcM7Xxet5z0U9GOx9YbcpyIjBzn7tA==", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minimist": { @@ -1840,18 +2935,6 @@ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, - "node_modules/minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", @@ -1870,6 +2953,13 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "peer": true + }, "node_modules/node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -1968,6 +3058,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "dependencies": { "wrappy": "1" } @@ -1981,6 +3072,24 @@ "opener": "bin/opener-bin.js" } }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "peer": 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/own-or": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", @@ -2059,6 +3168,19 @@ "node": ">=8" } }, + "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, + "peer": 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", @@ -2124,6 +3246,31 @@ "node": ">=8" } }, + "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, + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -2164,6 +3311,27 @@ "node": ">=0.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" + } + ], + "peer": true + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -2176,6 +3344,19 @@ "node": ">=8.10.0" } }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, "node_modules/release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -2246,16 +3427,51 @@ "node": ">=8" } }, + "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, + "peer": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "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" + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "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" + } + ], + "peer": true, + "dependencies": { + "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { @@ -2308,6 +3524,17 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.12.1.tgz", + "integrity": "sha512-aieaV1m349rZINEBkjxh2QbBvFFQOlgqYTNtCal82hHj4dDZ76oMlQIX+C7ryerBTDiga3e5NfH6smjdJ02BbQ==", + "dev": true, + "dependencies": { + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -2463,6 +3690,19 @@ "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, + "peer": 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", @@ -2476,9 +3716,9 @@ } }, "node_modules/tap": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/tap/-/tap-16.2.0.tgz", - "integrity": "sha512-ikfNLy701p2+sH3R0pAXQ/Aen6ZByaguUY7UsoTLL4AXa2c9gYQL+pI21p13lq54R7/CEoLaViC1sexcWG32ig==", + "version": "16.3.3", + "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.3.tgz", + "integrity": "sha512-E6Ti4FaH3zUvOtl13GA60n8aodRj44S8Vu5efM84U5NmquJo4+y21+2VM9r9jR5iiEcce5dqvlrrwAhZ6r11xg==", "bundleDependencies": [ "ink", "treport", @@ -2489,18 +3729,18 @@ "dev": true, "dependencies": { "@isaacs/import-jsx": "^4.0.1", - "@types/react": "^17", + "@types/react": "^17.0.52", "chokidar": "^3.3.0", "findit": "^2.0.0", "foreground-child": "^2.0.0", "fs-exists-cached": "^1.0.0", - "glob": "^7.1.6", + "glob": "^7.2.3", "ink": "^3.2.0", "isexe": "^2.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "jackspeak": "^1.4.1", + "istanbul-lib-processinfo": "^2.0.3", + "jackspeak": "^1.4.2", "libtap": "^1.4.0", - "minipass": "^3.1.1", + "minipass": "^3.3.4", "mkdirp": "^1.0.4", "nyc": "^15.1.0", "opener": "^1.5.1", @@ -2509,10 +3749,10 @@ "signal-exit": "^3.0.6", "source-map-support": "^0.5.16", "tap-mocha-reporter": "^5.0.3", - "tap-parser": "^11.0.1", - "tap-yaml": "^1.0.0", + "tap-parser": "^11.0.2", + "tap-yaml": "^1.0.2", "tcompare": "^5.0.7", - "treport": "^3.0.3", + "treport": "^3.0.4", "which": "^2.0.2" }, "bin": { @@ -2577,9 +3817,9 @@ } }, "node_modules/tap-parser": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-11.0.1.tgz", - "integrity": "sha512-5ow0oyFOnXVSALYdidMX94u0GEjIlgc/BPFYLx0yRh9hb8+cFGNJqJzDJlUqbLOwx8+NBrIbxCWkIQi7555c0w==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-11.0.2.tgz", + "integrity": "sha512-6qGlC956rcORw+fg7Fv1iCRAY8/bU9UabUAhs3mXRH6eRmVZcNPLheSXCYaVaYeSwx5xa/1HXZb1537YSvwDZg==", "dev": true, "dependencies": { "events-to-array": "^1.0.1", @@ -2593,13 +3833,25 @@ "node": ">= 8" } }, + "node_modules/tap-parser/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/tap-yaml": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", - "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.2.tgz", + "integrity": "sha512-GegASpuqBnRNdT1U+yuUPZ8rEU64pL35WPBpCISWwff4dErS2/438barz7WFJl4Nzh3Y05tfPidZnH+GaV1wMg==", "dev": true, "dependencies": { - "yaml": "^1.5.0" + "yaml": "^1.10.2" } }, "node_modules/tap/node_modules/@ampproject/remapping": { @@ -3076,7 +4328,7 @@ "license": "MIT" }, "node_modules/tap/node_modules/@types/react": { - "version": "17.0.41", + "version": "17.0.52", "dev": true, "inBundle": true, "license": "MIT", @@ -3515,7 +4767,7 @@ } }, "node_modules/tap/node_modules/glob": { - "version": "7.2.0", + "version": "7.2.3", "dev": true, "inBundle": true, "license": "ISC", @@ -3523,7 +4775,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -3730,7 +4982,7 @@ } }, "node_modules/tap/node_modules/json5": { - "version": "2.2.1", + "version": "2.2.3", "dev": true, "inBundle": true, "license": "MIT", @@ -3808,7 +5060,7 @@ } }, "node_modules/tap/node_modules/minipass": { - "version": "3.1.6", + "version": "3.3.4", "dev": true, "inBundle": true, "license": "ISC", @@ -4205,7 +5457,7 @@ } }, "node_modules/tap/node_modules/tap-parser": { - "version": "11.0.1", + "version": "11.0.2", "dev": true, "inBundle": true, "license": "MIT", @@ -4222,12 +5474,12 @@ } }, "node_modules/tap/node_modules/tap-yaml": { - "version": "1.0.0", + "version": "1.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "yaml": "^1.5.0" + "yaml": "^1.10.2" } }, "node_modules/tap/node_modules/to-fast-properties": { @@ -4240,7 +5492,7 @@ } }, "node_modules/tap/node_modules/treport": { - "version": "3.0.3", + "version": "3.0.4", "dev": true, "inBundle": true, "license": "ISC", @@ -4251,6 +5503,7 @@ "ink": "^3.2.0", "ms": "^2.1.2", "tap-parser": "^11.0.0", + "tap-yaml": "^1.0.0", "unicode-length": "^2.0.2" }, "peerDependencies": { @@ -4528,20 +5781,12 @@ "node": "*" } }, - "node_modules/tick": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tick/-/tick-0.0.6.tgz", - "integrity": "sha1-XvgPPRHheef+gRDMintvfF2hycQ=", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true, - "dependencies": { - "byline": "~2.0.3" - }, - "bin": { - "node-tick-processor": "bin/tickprocessor-driver.js" - }, - "engines": { - "node": ">=0.4.0" - } + "peer": true }, "node_modules/to-fast-properties": { "version": "2.0.0", @@ -4585,6 +5830,49 @@ "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", "dev": true }, + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -4607,6 +5895,19 @@ "optional": true, "peer": true }, + "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, + "peer": 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", @@ -4625,6 +5926,52 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/typedoc": { + "version": "0.23.24", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.24.tgz", + "integrity": "sha512-bfmy8lNQh+WrPYcJbtjQ6JEEsVl/ce1ZIXyXhyW+a1vFrjO39t6J8sL/d6FfAGrJTc7McCXgk9AanYBSNvLdIA==", + "dev": true, + "dependencies": { + "lunr": "^2.3.9", + "marked": "^4.2.5", + "minimatch": "^5.1.2", + "shiki": "^0.12.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 14.14" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x" + } + }, + "node_modules/typedoc/node_modules/minimatch": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.4.tgz", + "integrity": "sha512-U0iNYXt9wALljzfnGkhFSy5sAC6/SCR3JrHrlsdJz4kF8MvhTRQNiC59iUi1iqsitV7abrNAJWElVL9pdnoUgw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/unicode-length": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz", @@ -4661,7 +6008,6 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "optional": true, "peer": true, "dependencies": { "punycode": "^2.1.0" @@ -4673,10 +6019,42 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, + "optional": true, + "peer": true, "bin": { "uuid": "bin/uuid" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -4693,6 +6071,18 @@ "extsprintf": "^1.2.0" } }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4714,6 +6104,16 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "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, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -4767,7 +6167,8 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "node_modules/write-file-atomic": { "version": "3.0.3", @@ -4894,6 +6295,27 @@ "engines": { "node": ">=8" } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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": { @@ -5127,6 +6549,145 @@ "to-fast-properties": "^2.0.0" } }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + } + }, + "@eslint/eslintrc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "dev": true, + "peer": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "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, + "peer": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "peer": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "peer": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "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, + "peer": true + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "peer": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "dependencies": { + "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, + "peer": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "peer": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true, + "peer": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -5147,27 +6708,121 @@ "dev": true }, "@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "peer": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "peer": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "peer": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", + "@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", "dev": true }, - "@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "@types/tap": { + "version": "15.0.7", + "resolved": "https://registry.npmjs.org/@types/tap/-/tap-15.0.7.tgz", + "integrity": "sha512-TTMajw4gxQfFgYbhXhy/Tb2OiNcwS+4oP/9yp1/GdU0pFJo3wtnkYhRgmQy39ksh+rnoa0VrPHJ4Tuv2cLNQ5A==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@types/node": "*" } }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peer": true, + "requires": {} + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -5183,7 +6838,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "optional": true, "peer": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -5232,6 +6886,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -5354,11 +7014,100 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "byline": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/byline/-/byline-2.0.3.tgz", - "integrity": "sha1-gRskuHScHN0dJrWbd/zBnT4Nhsk=", - "dev": true + "c8": { + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz", + "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^2.0.0", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-reports": "^3.1.4", + "rimraf": "^3.0.2", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9" + }, + "dependencies": { + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } }, "caching-transform": { "version": "4.0.0", @@ -5372,6 +7121,13 @@ "write-file-atomic": "^3.0.0" } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "peer": true + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -5512,6 +7268,12 @@ "request": "^2.88.2" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -5549,6 +7311,13 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "peer": true + }, "default-require-extensions": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", @@ -5572,6 +7341,16 @@ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "peer": true, + "requires": { + "esutils": "^2.0.2" + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -5608,17 +7387,325 @@ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "8.31.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz", + "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==", + "dev": true, + "peer": true, + "requires": { + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "dependencies": { + "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, + "peer": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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, + "peer": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "peer": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "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, + "peer": true + }, + "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, + "peer": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "peer": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "peer": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "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, + "peer": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "peer": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "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, + "peer": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "peer": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "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, + "peer": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "peer": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "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, + "peer": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "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, + "peer": true + } + } + }, + "eslint-config-prettier": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz", + "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==", + "dev": true, + "requires": {} + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "peer": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "peer": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "peer": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "peer": true + }, + "espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "peer": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "peer": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "peer": true, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "peer": true }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "peer": true }, "events-to-array": { "version": "1.1.2", @@ -5647,7 +7734,6 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, - "optional": true, "peer": true }, "fast-json-stable-stringify": { @@ -5655,9 +7741,35 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, - "optional": true, "peer": true }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "peer": true + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "peer": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "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, + "peer": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -5694,6 +7806,36 @@ "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", "dev": true }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "peer": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "dependencies": { + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "peer": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true, + "peer": true + }, "foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -5791,15 +7933,15 @@ } }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -5846,6 +7988,13 @@ "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "dev": true }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true, + "peer": true + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -5901,6 +8050,33 @@ "sshpk": "^1.7.0" } }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "peer": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "peer": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "peer": true + } + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -5917,6 +8093,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -5925,7 +8102,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "is-binary-path": { "version": "2.1.0", @@ -5963,6 +8141,13 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "peer": true + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -6023,18 +8208,17 @@ } }, "istanbul-lib-processinfo": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", "dev": true, "requires": { "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", "p-map": "^3.0.0", "rimraf": "^3.0.0", - "uuid": "^3.3.3" + "uuid": "^8.3.2" }, "dependencies": { "rimraf": { @@ -6045,6 +8229,12 @@ "requires": { "glob": "^7.1.3" } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true } } }, @@ -6106,14 +8296,21 @@ } }, "jackspeak": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.1.tgz", - "integrity": "sha512-npN8f+M4+IQ8xD3CcWi3U62VQwKlT3Tj4GxbdT/fYTmeogD9eBF9OFdpoFG/VPNoshRjPUijdkp/p2XrzUHaVg==", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.2.tgz", + "integrity": "sha512-GHeGTmnuaHnvS+ZctRB01bfxARuu9wW83ENbuiweu07SFcVlZrJpcshSre/keGT7YGBhLHg/+rXCNSrsEHKU4Q==", "dev": true, "requires": { "cliui": "^7.0.4" } }, + "js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "dev": true, + "peer": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6157,7 +8354,13 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "optional": true, + "peer": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, "peer": true }, "json-stringify-safe": { @@ -6169,13 +8372,16 @@ "peer": true }, "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true }, "jsprim": { "version": "1.4.2", @@ -6199,6 +8405,17 @@ "optional": true, "peer": true }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "peer": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, "libtap": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.4.0.tgz", @@ -6218,6 +8435,17 @@ "tap-yaml": "^1.0.0", "tcompare": "^5.0.6", "trivial-deferred": "^1.0.1" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } } }, "locate-path": { @@ -6235,6 +8463,13 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "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, + "peer": true + }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", @@ -6243,6 +8478,12 @@ "optional": true, "peer": true }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -6252,6 +8493,18 @@ "semver": "^6.0.0" } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "marked": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz", + "integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==", + "dev": true + }, "memfs": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", @@ -6281,9 +8534,9 @@ } }, "minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.0.4.tgz", + "integrity": "sha512-9SQupyyavjdAc1VFjJS/5kdtFtlLAhKSWt7HocG0h/npy626jYrGegSslcM7Xxet5z0U9GOx9YbcpyIjBzn7tA==", "requires": { "brace-expansion": "^2.0.1" } @@ -6294,15 +8547,6 @@ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, - "minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", @@ -6318,6 +8562,13 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "peer": true + }, "node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -6397,6 +8648,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -6407,6 +8659,21 @@ "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "peer": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, "own-or": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", @@ -6467,6 +8734,16 @@ "release-zalgo": "^1.0.0" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "peer": true, + "requires": { + "callsites": "^3.0.0" + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -6514,6 +8791,19 @@ "find-up": "^4.0.0" } }, + "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, + "peer": true + }, + "prettier": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "dev": true + }, "process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -6545,6 +8835,13 @@ "optional": true, "peer": true }, + "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, + "peer": true + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -6554,6 +8851,13 @@ "picomatch": "^2.2.1" } }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "peer": true + }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -6611,6 +8915,13 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "peer": true + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -6620,6 +8931,16 @@ "glob": "^7.1.3" } }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "peer": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -6661,6 +8982,17 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, + "shiki": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.12.1.tgz", + "integrity": "sha512-aieaV1m349rZINEBkjxh2QbBvFFQOlgqYTNtCal82hHj4dDZ76oMlQIX+C7ryerBTDiga3e5NfH6smjdJ02BbQ==", + "dev": true, + "requires": { + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -6784,6 +9116,13 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, + "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, + "peer": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -6794,24 +9133,24 @@ } }, "tap": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/tap/-/tap-16.2.0.tgz", - "integrity": "sha512-ikfNLy701p2+sH3R0pAXQ/Aen6ZByaguUY7UsoTLL4AXa2c9gYQL+pI21p13lq54R7/CEoLaViC1sexcWG32ig==", + "version": "16.3.3", + "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.3.tgz", + "integrity": "sha512-E6Ti4FaH3zUvOtl13GA60n8aodRj44S8Vu5efM84U5NmquJo4+y21+2VM9r9jR5iiEcce5dqvlrrwAhZ6r11xg==", "dev": true, "requires": { "@isaacs/import-jsx": "^4.0.1", - "@types/react": "^17", + "@types/react": "^17.0.52", "chokidar": "^3.3.0", "findit": "^2.0.0", "foreground-child": "^2.0.0", "fs-exists-cached": "^1.0.0", - "glob": "^7.1.6", + "glob": "^7.2.3", "ink": "^3.2.0", "isexe": "^2.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "jackspeak": "^1.4.1", + "istanbul-lib-processinfo": "^2.0.3", + "jackspeak": "^1.4.2", "libtap": "^1.4.0", - "minipass": "^3.1.1", + "minipass": "^3.3.4", "mkdirp": "^1.0.4", "nyc": "^15.1.0", "opener": "^1.5.1", @@ -6820,10 +9159,10 @@ "signal-exit": "^3.0.6", "source-map-support": "^0.5.16", "tap-mocha-reporter": "^5.0.3", - "tap-parser": "^11.0.1", - "tap-yaml": "^1.0.0", + "tap-parser": "^11.0.2", + "tap-yaml": "^1.0.2", "tcompare": "^5.0.7", - "treport": "^3.0.3", + "treport": "^3.0.4", "which": "^2.0.2" }, "dependencies": { @@ -7145,7 +9484,7 @@ "dev": true }, "@types/react": { - "version": "17.0.41", + "version": "17.0.52", "bundled": true, "dev": true, "requires": { @@ -7422,14 +9761,14 @@ "dev": true }, "glob": { - "version": "7.2.0", + "version": "7.2.3", "bundled": true, "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -7562,7 +9901,7 @@ "dev": true }, "json5": { - "version": "2.2.1", + "version": "2.2.3", "bundled": true, "dev": true }, @@ -7609,7 +9948,7 @@ } }, "minipass": { - "version": "3.1.6", + "version": "3.3.4", "bundled": true, "dev": true, "requires": { @@ -7874,7 +10213,7 @@ } }, "tap-parser": { - "version": "11.0.1", + "version": "11.0.2", "bundled": true, "dev": true, "requires": { @@ -7884,11 +10223,11 @@ } }, "tap-yaml": { - "version": "1.0.0", + "version": "1.0.2", "bundled": true, "dev": true, "requires": { - "yaml": "^1.5.0" + "yaml": "^1.10.2" } }, "to-fast-properties": { @@ -7897,7 +10236,7 @@ "dev": true }, "treport": { - "version": "3.0.3", + "version": "3.0.4", "bundled": true, "dev": true, "requires": { @@ -7907,6 +10246,7 @@ "ink": "^3.2.0", "ms": "^2.1.2", "tap-parser": "^11.0.0", + "tap-yaml": "^1.0.0", "unicode-length": "^2.0.2" }, "dependencies": { @@ -8081,23 +10421,34 @@ } }, "tap-parser": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-11.0.1.tgz", - "integrity": "sha512-5ow0oyFOnXVSALYdidMX94u0GEjIlgc/BPFYLx0yRh9hb8+cFGNJqJzDJlUqbLOwx8+NBrIbxCWkIQi7555c0w==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-11.0.2.tgz", + "integrity": "sha512-6qGlC956rcORw+fg7Fv1iCRAY8/bU9UabUAhs3mXRH6eRmVZcNPLheSXCYaVaYeSwx5xa/1HXZb1537YSvwDZg==", "dev": true, "requires": { "events-to-array": "^1.0.1", "minipass": "^3.1.6", "tap-yaml": "^1.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + } } }, "tap-yaml": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", - "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.2.tgz", + "integrity": "sha512-GegASpuqBnRNdT1U+yuUPZ8rEU64pL35WPBpCISWwff4dErS2/438barz7WFJl4Nzh3Y05tfPidZnH+GaV1wMg==", "dev": true, "requires": { - "yaml": "^1.5.0" + "yaml": "^1.10.2" } }, "tcompare": { @@ -8141,14 +10492,12 @@ } } }, - "tick": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tick/-/tick-0.0.6.tgz", - "integrity": "sha1-XvgPPRHheef+gRDMintvfF2hycQ=", + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true, - "requires": { - "byline": "~2.0.3" - } + "peer": true }, "to-fast-properties": { "version": "2.0.0", @@ -8183,6 +10532,27 @@ "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", "dev": true }, + "ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -8202,6 +10572,16 @@ "optional": true, "peer": true }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "peer": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -8217,6 +10597,35 @@ "is-typedarray": "^1.0.0" } }, + "typedoc": { + "version": "0.23.24", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.24.tgz", + "integrity": "sha512-bfmy8lNQh+WrPYcJbtjQ6JEEsVl/ce1ZIXyXhyW+a1vFrjO39t6J8sL/d6FfAGrJTc7McCXgk9AanYBSNvLdIA==", + "dev": true, + "requires": { + "lunr": "^2.3.9", + "marked": "^4.2.5", + "minimatch": "^5.1.2", + "shiki": "^0.12.1" + }, + "dependencies": { + "minimatch": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.4.tgz", + "integrity": "sha512-U0iNYXt9wALljzfnGkhFSy5sAC6/SCR3JrHrlsdJz4kF8MvhTRQNiC59iUi1iqsitV7abrNAJWElVL9pdnoUgw==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true + }, "unicode-length": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz", @@ -8249,7 +10658,6 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "optional": true, "peer": true, "requires": { "punycode": "^2.1.0" @@ -8259,8 +10667,39 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true, + "optional": true, + "peer": true + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, + "v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + } + } + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -8274,6 +10713,18 @@ "extsprintf": "^1.2.0" } }, + "vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -8289,6 +10740,13 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "peer": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -8329,7 +10787,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "write-file-atomic": { "version": "3.0.3", @@ -8437,6 +10896,18 @@ "camelcase": "^5.0.0", "decamelize": "^1.2.0" } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index ca0fd916..da09b9fb 100644 --- a/package.json +++ b/package.json @@ -2,54 +2,90 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "glob", "description": "a little globber", - "version": "8.1.0", + "version": "9.0.0-0", "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" }, - "main": "glob.js", + "main": "./dist/cjs/index.js", + "module": "./dist/mjs/index.js", + "types": "./dist/cjs/index.d.ts", + "exports": { + ".": { + "types": "./dist/cjs/index.d.ts", + "import": "./dist/mjs/index.js", + "require": "./dist/cjs/index.js" + } + }, "files": [ - "glob.js", - "sync.js", - "common.js" + "dist" ], - "engines": { - "node": ">=12" + "scripts": { + "preversion": "npm test", + "postversion": "npm publish", + "prepublishOnly": "git push origin --follow-tags", + "preprepare": "rm -rf dist", + "prepare": "tsc -p tsconfig-cjs.json && tsc -p tsconfig-esm.json", + "postprepare": "bash fixup.sh", + "pretest": "npm run prepare", + "presnap": "npm run prepare", + "test": "c8 tap", + "snap": "c8 tap", + "format": "prettier --write . --loglevel warn", + "benchmark": "node benchmark/index.js", + "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts", + "prepublish": "npm run benchclean", + "profclean": "rm -f v8.log profile.txt", + "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", + "bench": "bash benchmark.sh", + "prof": "bash prof.sh && cat profile.txt", + "benchclean": "node benchclean.js" + }, + "prettier": { + "semi": false, + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "jsxSingleQuote": false, + "bracketSameLine": true, + "arrowParens": "avoid", + "endOfLine": "lf" }, "dependencies": { "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "minimatch": "^6.0.4" }, "devDependencies": { + "@types/node": "^18.11.18", + "@types/tap": "^15.0.7", + "c8": "^7.12.0", + "eslint-config-prettier": "^8.6.0", "memfs": "^3.2.0", "mkdirp": "0", + "prettier": "^2.8.3", "rimraf": "^2.2.8", - "tap": "^16.0.1", - "tick": "0.0.6" + "tap": "^16.3.3", + "ts-node": "^10.9.1", + "typedoc": "^0.23.24", + "typescript": "^4.9.4" }, "tap": { "before": "test/00-setup.js", "after": "test/zz-cleanup.js", - "statements": 90, - "branches": 90, - "functions": 90, - "lines": 90, - "jobs": 1 - }, - "scripts": { - "prepublish": "npm run benchclean", - "profclean": "rm -f v8.log profile.txt", - "test": "tap", - "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", - "bench": "bash benchmark.sh", - "prof": "bash prof.sh && cat profile.txt", - "benchclean": "node benchclean.js" + "coverage": false, + "node-arg": [ + "--no-warnings", + "--loader", + "ts-node/esm" + ], + "ts": false }, "license": "ISC", "funding": { "url": "https://github.com/sponsors/isaacs" + }, + "engines": { + "node": ">=16" } } diff --git a/src/glob.ts b/src/glob.ts new file mode 100644 index 00000000..ee3d0b58 --- /dev/null +++ b/src/glob.ts @@ -0,0 +1,135 @@ +import { Minimatch, MinimatchOptions } from 'minimatch' +import { GlobCache } from './readdir.js' +import { GlobWalker, Pattern } from './walker.js' + +type MatchSet = Minimatch['set'] +type GlobSet = Exclude + +export interface GlobOptions extends MinimatchOptions { + ignore?: string | string[] + follow?: boolean + mark?: boolean + nodir?: boolean + nounique?: boolean + nosort?: boolean + cwd?: string + realpath?: boolean + absolute?: boolean + cache?: GlobCache +} + +export class Glob { + pattern: string[] + ignore?: string | string[] + follow: boolean + dot: boolean + mark: boolean + nodir: boolean + nounique: boolean + nosort: boolean + cwd: string + matchSet: MatchSet + globSet: GlobSet + realpath: boolean + nonull: boolean + absolute: boolean + matchBase: boolean + windowsPathsNoEscape: boolean + noglobstar: boolean + cache: GlobCache + + constructor(pattern: string | string[], options: GlobOptions | Glob = {}) { + this.ignore = options.ignore + this.follow = !!options.follow + this.dot = !!options.dot + this.nodir = !!options.nodir + this.mark = !!options.mark + this.nounique = !!options.nounique + this.nosort = !!options.nosort + this.cwd = options.cwd || '' + if (process.platform === 'win32') { + this.cwd = this.cwd.replace(/\\/g, '/') + } + this.realpath = !!options.realpath + this.nonull = !!options.nonull + this.absolute = !!options.absolute + this.cache = options.cache || Object.create(null) + + this.noglobstar = !!options.noglobstar + this.matchBase = !!options.matchBase + + if (typeof pattern === 'string') { + pattern = [pattern] + } + + this.windowsPathsNoEscape = + !!options.windowsPathsNoEscape || + (options as GlobOptions).allowWindowsEscape === false + + if (this.windowsPathsNoEscape) { + pattern = pattern.map(p => p.replace(/\\/g, '/')) + } + + if (this.matchBase) { + if (options.noglobstar) { + throw new TypeError('base matching requires globstar') + } + pattern = pattern.map(p => (p.includes('/') ? p : `**/${p}`)) + } + + this.pattern = pattern + + const mmo = { ...options, nonegate: true, nocomment: true } + const mms = this.pattern.map(p => new Minimatch(p, mmo)) + this.matchSet = mms.reduce((set: MatchSet, m) => set.concat(m.set), []) + this.globSet = mms.reduce((set: GlobSet, m) => set.concat(m.globSet), []) + } + + doNonull(matches: string[], i: number) { + console.log('doNonull', matches, i, this.globSet[i]) + if (!matches.length && this.nonull) { + const gs: string | undefined = this.globSet[i] + if (gs) { + return [gs] + } else { + return [] + } + } + return matches + } + + async process() { + return this.finish( + await Promise.all( + this.matchSet.map(async (set, i) => { + if (!set.length) { + return [] + } + const matches = await this.getWalker(set as Pattern).walk() + return this.doNonull(matches, i) + }) + ) + ) + } + + finish(matches: string[][]): string[] { + const raw = matches.reduce((set, m) => set.concat(m), []) + const flat = this.nounique ? raw : [...new Set(raw)] + return this.nosort ? flat : flat.sort((a, b) => a.localeCompare(b, 'en')) + } + + getWalker(set: Pattern) { + return new GlobWalker(set, this.cwd, this) + } + + processSync() { + return this.finish( + this.matchSet.map((set, i) => { + if (!set.length) { + return [] + } + return this.doNonull(this.getWalker(set as Pattern).walkSync(), i) + }) + ) + } +} diff --git a/src/has-magic.ts b/src/has-magic.ts new file mode 100644 index 00000000..775ca38a --- /dev/null +++ b/src/has-magic.ts @@ -0,0 +1,17 @@ +import { Glob, GlobOptions } from './glob.js' + +export const hasMagic = ( + pattern: string | string[], + options?: Glob | GlobOptions +): boolean => { + if (!Array.isArray(pattern)) { + pattern = [pattern] + } + return pattern.some(p => { + const g = new Glob(p, options) + if (g.matchSet.length > 1) { + return true + } + return g.matchSet[0].some(p => typeof p !== 'string') + }) +} diff --git a/src/ignore.ts b/src/ignore.ts new file mode 100644 index 00000000..17069620 --- /dev/null +++ b/src/ignore.ts @@ -0,0 +1,34 @@ +// give it a pattern, and it'll be able to tell you if +// a given path should be ignored. +// Ignoring a path ignores its children if the pattern ends in /** +// Ignores are always parsed in dot:true mode + +import { Minimatch } from 'minimatch' + +export class Ignore { + matchers: Minimatch[] + gmatchers: Minimatch[] + + constructor(patterns: string[]) { + this.matchers = [] + this.gmatchers = [] + for (const pattern of patterns) { + this.matchers.push(new Minimatch(pattern, { dot: true })) + if (pattern.substring(pattern.length - 3) === '/**') { + const gp = pattern.slice(0, pattern.length - 3) + this.gmatchers.push(new Minimatch(gp, { dot: true })) + } + } + } + + ignored(p: string): boolean { + return ( + this.matchers.some(m => m.match(p)) || + this.gmatchers.some(m => m.match(p)) + ) + } + + childrenIgnored(p: string): boolean { + return this.gmatchers.some(m => m.match(p)) + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000..f500cc1e --- /dev/null +++ b/src/index.ts @@ -0,0 +1,24 @@ +import { Glob, GlobOptions } from './glob.js' +import { hasMagic } from './has-magic.js' + +export const globSync = ( + pattern: string | string[], + options?: Glob | GlobOptions +): string[] => new Glob(pattern, options).processSync() + +export const glob = Object.assign( + async ( + pattern: string | string[], + options?: Glob | GlobOptions + ): Promise => new Glob(pattern, options).process(), + { + sync: globSync, + Glob, + hasMagic, + } +) + +export { Glob } from './glob.js' +export type { GlobOptions } from './glob.js' +export { hasMagic } from './has-magic.js' +export default glob diff --git a/src/readdir.ts b/src/readdir.ts new file mode 100644 index 00000000..101fe879 --- /dev/null +++ b/src/readdir.ts @@ -0,0 +1,87 @@ +// this is a caching readdir that cuts down on excess syscalls, +// if the same directory needs to be read multiple times. + +import { Dirent } from 'fs' + +import { readdir as origReaddir, readdirSync as origReaddirSync } from 'fs' +import { basename, dirname, resolve } from 'path' + +// when we read a directory, put its entries in here as well +export interface GlobCache { + [path: string]: Dirent[] | NodeJS.ErrnoException +} + +export class Readdir { + cache: GlobCache + + constructor(cache: GlobCache = Object.create(null)) { + this.cache = cache + } + + // alias cached lookup from p to realpath rp, if not already set + alias(rp: string, p: string): void { + if (!this.cache[rp]) { + this.cache[rp] = this.cache[p] + } + } + + // look up the Dirent for the path, if it exists + lookup(path: string): Dirent | undefined { + const resolved = resolve(path) + const dir = dirname(resolved) + const entities = this.cache[dir] + if (entities && Array.isArray(entities)) { + return entities.find(e => e.name === basename(resolved)) + } + } + + isDirectory(path: string): boolean { + const resolved = resolve(path) + return this.cache[resolved] + ? Array.isArray(this.cache[resolved]) + : !!this.lookup(path)?.isDirectory() + } + + async readdir(path: string): Promise { + const resolved = resolve(path) + const cacheEntry = this.cache[resolved] + if (cacheEntry) { + if (Array.isArray(cacheEntry)) { + return cacheEntry + } else { + throw cacheEntry + } + } + + return new Promise((res, rej) => { + origReaddir(resolved, { withFileTypes: true }, (er, entities) => { + this.cache[resolved] = er || entities + if (er) { + rej(er) + } else { + res(entities) + } + }) + }) + } + + readdirSync(path: string): Dirent[] { + const resolved = resolve(path) + const cacheEntry = this.cache[resolved] + if (cacheEntry) { + if (Array.isArray(cacheEntry)) { + return cacheEntry + } else { + throw cacheEntry + } + } + try { + const entities = origReaddirSync(resolved, { withFileTypes: true }) + this.cache[resolved] = entities + return entities + } catch (er) { + this.cache[resolved] = er as NodeJS.ErrnoException + throw er + } + } +} diff --git a/src/walker.ts b/src/walker.ts new file mode 100644 index 00000000..b54ae031 --- /dev/null +++ b/src/walker.ts @@ -0,0 +1,298 @@ +// glob walker +// The simplest first pass at finding a bunch of paths matching a glob +// Takes a single pattern entry from the minimatch (string|re|globstar)[] +// and operate on a single path, fanning out to child entries as appropriate. +// +// - if pattern is empty, return [path] +// - readdir path +// - if ENOTDIR, return [] +// - if pattern[0] is string (including '.' or '..') and pattern[0] in +// entries, or pattern[0] is . or .. +// - return walk(dir+pattern[0], pattern.slice(1)) +// - if pattern[0] is globstar: +// - return walk all entries with pattern AND pattern.slice(1) if len>1 +// - discard any entries that don't match pattern[0] +// - child walk remaining entries with pattern.slice(1) +// - return all matching child walks + +import { Dirent, realpath, realpathSync } from 'fs' +import { GLOBSTAR } from 'minimatch' +import { resolve } from 'path' +import { Ignore } from './ignore.js' +import { GlobCache, Readdir } from './readdir.js' + +// a single minimatch set entry with 1 or more parts +type ParseReturnFiltered = string | RegExp | typeof GLOBSTAR +export type Pattern = [p: ParseReturnFiltered, ...rest: ParseReturnFiltered[]] + +type Children = (GlobWalker | string)[] + +export interface GlobWalkerOptions { + follow?: boolean + rd?: Readdir + cache?: GlobCache + realpath?: boolean + mark?: boolean + nodir?: boolean + ignore?: string | string[] | Ignore + dot?: boolean + absolute?: boolean +} + +export class GlobWalker { + pattern: Pattern + path: string + follow: boolean + rd: Readdir + realpath: boolean + absolute: boolean + mark: boolean + nodir: boolean + dot: boolean + ignore?: Ignore + cache: GlobCache + + constructor( + pattern: Pattern, + path: string, + options: GlobWalkerOptions | GlobWalker = {} + ) { + const { + follow = false, + realpath = false, + absolute = false, + mark = false, + nodir = false, + dot = false, + rd, + cache, + ignore, + } = options + + // if the pattern starts with a bunch of strings, then skip ahead + this.pattern = [...pattern] + this.path = path + while (this.pattern.length > 1 && typeof this.pattern[0] === 'string') { + this.path = this.join(this.pattern[0]) + this.pattern.shift() + } + this.follow = follow + this.realpath = realpath + this.absolute = absolute + this.mark = mark + this.nodir = nodir + this.rd = rd ? rd : new Readdir(cache) + this.cache = this.rd.cache + this.dot = dot + if (typeof ignore === 'string') { + this.ignore = new Ignore([ignore]) + } else if (Array.isArray(ignore)) { + this.ignore = new Ignore(ignore) + } else if (ignore instanceof Ignore) { + this.ignore = ignore + } + } + + child(pattern: Pattern, path: string) { + return new GlobWalker(pattern, path, this) + } + + async walk(): Promise { + if (this.ignore && this.ignore.childrenIgnored(this.path)) { + return [] + } + let entries: Dirent[] + // if it's not a directory, or we can't read it, then + // that means no match, because we still have pattern to consume + try { + entries = await this.rd.readdir(this.path || '.') + } catch (_) { + return [] + } + const children = this.getChildren(entries) + const matches: (string | string[])[] = await Promise.all( + children.map(async c => + typeof c === 'string' ? this.finish(await this.doRealpath(c)) : c.walk() + ) + ) + const flat = matches.reduce((set: string[], m) => set.concat(m), []) + return this.ignore ? flat.filter(f => !this.ignore?.ignored(f)) : flat + } + + finish(p: string | undefined): string | [] { + if (!p) { + return [] + } + if (this.nodir || this.mark) { + const isDir = this.rd.isDirectory(p) + if (isDir) { + if (this.nodir) { + return [] + } + if (p.substring(p.length - 1) !== '/') { + return p + '/' + } + } + } + return p + } + + async doRealpath(p: string): Promise { + if (!this.realpath && !this.absolute) { + return p + } + if (!this.realpath) { + return resolve(p) + } + const rp: string = await new Promise(res => + realpath(p, (er, rp) => (er ? res(resolve(p)) : res(rp))) + ) + this.rd.alias(rp, p) + return rp + } + + doRealpathSync(p: string): string | undefined { + if (!this.realpath && !this.absolute) { + return p + } + if (!this.realpath) { + return resolve(p) + } + let rp: string + try { + rp = realpathSync(p) + } catch (_) { + rp = resolve(p) + } + this.rd.alias(rp, p) + return rp + } + + walkSync(): string[] { + if (this.ignore?.childrenIgnored(this.path)) { + return [] + } + let entries: Dirent[] + // if it's not a directory, or we can't read it, then + // that means no match, because we still have pattern to consume + try { + entries = this.rd.readdirSync(this.path || '.') + } catch (e) { + return [] + } + const children = this.getChildren(entries) + const matches: (string | string[])[] = children.map(c => { + return typeof c === 'string' + ? this.finish(this.doRealpathSync(c)) + : c.walkSync() + }) + const flat = matches.reduce((set: string[], m) => set.concat(m), []) + return this.ignore ? flat.filter(f => !this.ignore?.ignored(f)) : flat + } + + join(p: string) { + return this.path ? `${this.path}/${p}` : p + } + + getChildrenString( + entries: Dirent[], + p: string, + rest: Pattern | null + ): Children { + console.log('CS', this.path, entries, p, rest) + const children: Children = [] + const e = entries.find(e => e.name === p) + const traverse = + p === '..' || + p === '.' || + p === '' || + (e && (e.isDirectory() || e.isSymbolicLink())) + if (p === '.' || p === '' || p === '..' || e) { + if (rest) { + if (traverse) { + children.push(this.child(rest, this.join(p))) + } + } else { + children.push(this.join(p)) + } + } + return children + } + + getChildrenGlobstar(entries: Dirent[], rest: Pattern | null): Children { + console.log('CGS', this.path, entries, rest) + const children: Children = [] + + // eg, p=**/a/b + if (rest) { + console.log('> 1', rest, this.path) + // it can match a/b against this path, without the ** + children.push(this.child(rest, this.path)) + } else { + // but if ** is at the end, then this path definitely matches + console.log('> 2', null, this.path) + children.push(this.path) + } + + for (const e of entries) { + if (!this.dot && e.name.startsWith('.')) { + continue + } + const path = this.join(e.name) + // ** does not traverse symlinks, unless follow:true is set. + const traverse = e.isDirectory() || (this.follow && e.isSymbolicLink()) + if (traverse) { + console.log('t1>', this.pattern, path) + children.push(this.child(this.pattern, path)) + } + if (rest) { + // can match a/b against child path + if (traverse) { + console.log('t2>', rest, path) + children.push(this.child(rest, path)) + } + } else { + // ** at the end, will match all children + console.log('t3>', path) + children.push(path) + } + } + + return children + } + + getChildrenRegexp( + entries: Dirent[], + p: RegExp, + rest: Pattern | null + ): Children { + const children: Children = [] + for (const e of entries) { + if (!p.test(e.name)) { + continue + } + const traverse = e.isDirectory() || e.isSymbolicLink() + if (rest) { + if (traverse) { + children.push(this.child(rest, this.join(e.name))) + } + } else { + children.push(this.join(e.name)) + } + } + + return children + } + + getChildren(entries: Dirent[]): Children { + const [p, ...tail] = this.pattern + const rest = tail.length ? (tail as Pattern) : null + if (typeof p === 'string') { + return this.getChildrenString(entries, p, rest) + } else if (p === GLOBSTAR) { + return this.getChildrenGlobstar(entries, rest) + } else { + return this.getChildrenRegexp(entries, p, rest) + } + } +} diff --git a/sync.js b/sync.js deleted file mode 100644 index af4600dd..00000000 --- a/sync.js +++ /dev/null @@ -1,486 +0,0 @@ -module.exports = globSync -globSync.GlobSync = GlobSync - -var rp = require('fs.realpath') -var minimatch = require('minimatch') -var Minimatch = minimatch.Minimatch -var Glob = require('./glob.js').Glob -var util = require('util') -var path = require('path') -var assert = require('assert') -var isAbsolute = require('path').isAbsolute -var common = require('./common.js') -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - return new GlobSync(pattern, options).found -} - -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') - - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) - - setopts(this, pattern, options) - - if (this.noprocess) - return this - - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) - } - this._finish() -} - -GlobSync.prototype._finish = function () { - assert.ok(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = rp.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er - } - } - }) - } - common.finish(this) -} - - -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert.ok(this instanceof GlobSync) - - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. - - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } - - var remain = pattern.slice(n) - - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || - isAbsolute(pattern.map(function (p) { - return typeof p === 'string' ? p : '[*]' - }).join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - - var abs = this._makeAbs(read) - - //if ignored, skip processing - if (childrenIgnored(this, read)) - return - - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) -} - - -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' - - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } - - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) - } -} - - -GlobSync.prototype._emitMatch = function (index, e) { - if (isIgnored(this, e)) - return - - var abs = this._makeAbs(e) - - if (this.mark) - e = this._mark(e) - - if (this.absolute) { - e = abs - } - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true - - if (this.stat) - this._stat(e) -} - - -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries - var lstat - var stat - try { - lstat = this.fs.lstatSync(abs) - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null - } - } - - var isSym = lstat && lstat.isSymbolicLink() - this.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) - - return entries -} - -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries - - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null - - if (Array.isArray(c)) - return c - } - - try { - return this._readdirEntries(abs, this.fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null - } -} - -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } - } - - this.cache[abs] = entries - - // mark and cache dir-ness - return entries -} - -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - throw error - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} - -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - - var entries = this._readdir(abs, inGlobStar) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) - - var len = entries.length - var isSym = this.symlinks[abs] - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return - - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) - - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) - } -} - -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) - - if (!this.matches[index]) - this.matches[index] = Object.create(null) - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) -} - -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] - - if (Array.isArray(c)) - c = 'DIR' - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c - - if (needDir && c === 'FILE') - return false - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat - try { - lstat = this.fs.lstatSync(abs) - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return false - } - } - - if (lstat && lstat.isSymbolicLink()) { - try { - stat = this.fs.statSync(abs) - } catch (er) { - stat = lstat - } - } else { - stat = lstat - } - } - - this.statCache[abs] = stat - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return false - - return c -} - -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} - -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} diff --git a/tsconfig-base.json b/tsconfig-base.json new file mode 100644 index 00000000..b72747bb --- /dev/null +++ b/tsconfig-base.json @@ -0,0 +1,17 @@ +{ + "exclude": ["./test", "./tap-snapshots"], + "include": ["src/**/*.ts"], + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "declaration": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "target": "es2022" + } +} diff --git a/tsconfig-cjs.json b/tsconfig-cjs.json new file mode 100644 index 00000000..7aae8118 --- /dev/null +++ b/tsconfig-cjs.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig-base.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "dist/cjs" + } +} diff --git a/tsconfig-esm.json b/tsconfig-esm.json new file mode 100644 index 00000000..9a571575 --- /dev/null +++ b/tsconfig-esm.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig-base.json", + "compilerOptions": { + "module": "esnext", + "outDir": "dist/mjs" + } +} From c8a000f8827dd00c685729c15e2da81aee840478 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sun, 15 Jan 2023 21:49:13 -0800 Subject: [PATCH 030/163] two tests passing! --- package-lock.json | 104 ++++++---- package.json | 13 +- src/glob.ts | 14 +- src/index.ts | 3 + src/walker.ts | 17 +- test/00-setup.js | 182 ------------------ test/00-setup.ts | 153 +++++++++++++++ test/abort.js | 19 -- test/absolute.js | 49 ----- test/absolute.ts | 45 +++++ test/bash-comparison.js | 79 -------- test/bash-comparison.ts | 56 ++++++ test/{bash-results.json => bash-results.ts} | 7 +- test/{broken-symlink.js => broken-symlink.ts} | 0 test/{cwd-test.js => cwd-test.ts} | 0 test/{empty-set.js => empty-set.ts} | 0 test/{enotsup.js => enotsup.ts} | 0 test/{eperm-stat.js => eperm-stat.ts} | 0 test/{error-callback.js => error-callback.ts} | 0 test/{follow.js => follow.ts} | 0 test/global-leakage.js | 20 -- ...match-memfs.js => globstar-match-memfs.ts} | 0 test/{globstar-match.js => globstar-match.ts} | 0 test/{has-magic.js => has-magic.ts} | 0 test/{ignore.js => ignore.ts} | 0 test/{mark.js => mark.ts} | 0 test/{match-base.js => match-base.ts} | 0 ...weird-error.js => multiple-weird-error.ts} | 0 ...ptions.js => new-glob-optional-options.ts} | 0 test/{nocase-nomagic.js => nocase-nomagic.ts} | 0 test/{nodir.js => nodir.ts} | 0 test/{nonull.js => nonull.ts} | 0 test/{pause-resume.js => pause-resume.ts} | 0 test/{readme-issue.js => readme-issue.ts} | 0 test/{realpath.js => realpath.ts} | 0 test/{root-nomount.js => root-nomount.ts} | 0 test/{root.js => root.ts} | 0 test/{slash-cwd.js => slash-cwd.ts} | 0 test/{stat.js => stat.ts} | 0 test/{sync-cb-throw.js => sync-cb-throw.ts} | 0 ...indows-paths-fs.js => windows-paths-fs.ts} | 0 ...o-escape.js => windows-paths-no-escape.ts} | 0 test/zz-cleanup.js | 16 -- test/zz-cleanup.ts | 13 ++ 44 files changed, 366 insertions(+), 424 deletions(-) delete mode 100644 test/00-setup.js create mode 100644 test/00-setup.ts delete mode 100644 test/abort.js delete mode 100644 test/absolute.js create mode 100644 test/absolute.ts delete mode 100644 test/bash-comparison.js create mode 100644 test/bash-comparison.ts rename test/{bash-results.json => bash-results.ts} (93%) rename test/{broken-symlink.js => broken-symlink.ts} (100%) rename test/{cwd-test.js => cwd-test.ts} (100%) rename test/{empty-set.js => empty-set.ts} (100%) rename test/{enotsup.js => enotsup.ts} (100%) rename test/{eperm-stat.js => eperm-stat.ts} (100%) rename test/{error-callback.js => error-callback.ts} (100%) rename test/{follow.js => follow.ts} (100%) delete mode 100644 test/global-leakage.js rename test/{globstar-match-memfs.js => globstar-match-memfs.ts} (100%) rename test/{globstar-match.js => globstar-match.ts} (100%) rename test/{has-magic.js => has-magic.ts} (100%) rename test/{ignore.js => ignore.ts} (100%) rename test/{mark.js => mark.ts} (100%) rename test/{match-base.js => match-base.ts} (100%) rename test/{multiple-weird-error.js => multiple-weird-error.ts} (100%) rename test/{new-glob-optional-options.js => new-glob-optional-options.ts} (100%) rename test/{nocase-nomagic.js => nocase-nomagic.ts} (100%) rename test/{nodir.js => nodir.ts} (100%) rename test/{nonull.js => nonull.ts} (100%) rename test/{pause-resume.js => pause-resume.ts} (100%) rename test/{readme-issue.js => readme-issue.ts} (100%) rename test/{realpath.js => realpath.ts} (100%) rename test/{root-nomount.js => root-nomount.ts} (100%) rename test/{root.js => root.ts} (100%) rename test/{slash-cwd.js => slash-cwd.ts} (100%) rename test/{stat.js => stat.ts} (100%) rename test/{sync-cb-throw.js => sync-cb-throw.ts} (100%) rename test/{windows-paths-fs.js => windows-paths-fs.ts} (100%) rename test/{windows-paths-no-escape.js => windows-paths-no-escape.ts} (100%) delete mode 100644 test/zz-cleanup.js create mode 100644 test/zz-cleanup.ts diff --git a/package-lock.json b/package-lock.json index 909afbbc..67d8ba79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,19 +13,23 @@ "minimatch": "^6.0.4" }, "devDependencies": { + "@types/mkdirp": "^1.0.2", "@types/node": "^18.11.18", "@types/tap": "^15.0.7", "c8": "^7.12.0", "eslint-config-prettier": "^8.6.0", "memfs": "^3.2.0", - "mkdirp": "0", + "mkdirp": "^2.0.0", "prettier": "^2.8.3", - "rimraf": "^2.2.8", - "tap": "^16.3.3", + "rimraf": "^4.0.7", + "tap": "^16.3.4", "ts-node": "^10.9.1", "typedoc": "^0.23.24", "typescript": "^4.9.4" }, + "engines": { + "node": ">=16" + }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -629,6 +633,15 @@ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, + "node_modules/@types/mkdirp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.2.tgz", + "integrity": "sha512-o0K1tSO0Dx5X6xlU5F1D6625FawhC3dU3iqr25lluNv/+/QIVH8RLNEiVokgIZo+mz+87w/3Mkg/VvQS+J51fQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", @@ -2933,18 +2946,23 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "dev": true, + "optional": true, + "peer": 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==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.0.0.tgz", + "integrity": "sha512-M9ecBPkCu6jZ+H19zruhjw/JB97qqVhyi1H2Lxxo2XAoIMdpHKQ8MfQiMzXk9SH/oJXIbM3oSAfLB8qSWJdCLA==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, "bin": { - "mkdirp": "bin/cmd.js" + "mkdirp": "dist/cjs/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/ms": { @@ -3439,15 +3457,18 @@ } }, "node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.0.7.tgz", + "integrity": "sha512-CUEDDrZvc0swDgVdXGiv3FcYYQMpJxjvSGt85Amj6yU+MCVWurrLCeLiJDdJPHCzNJnwuebBEdcO//eP11Xa7w==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/run-parallel": { @@ -3716,9 +3737,9 @@ } }, "node_modules/tap": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.3.tgz", - "integrity": "sha512-E6Ti4FaH3zUvOtl13GA60n8aodRj44S8Vu5efM84U5NmquJo4+y21+2VM9r9jR5iiEcce5dqvlrrwAhZ6r11xg==", + "version": "16.3.4", + "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.4.tgz", + "integrity": "sha512-SAexdt2ZF4XBgye6TPucFI2y7VE0qeFXlXucJIV1XDPCs+iJodk0MYacr1zR6Ycltzz7PYg8zrblDXKbAZM2LQ==", "bundleDependencies": [ "ink", "treport", @@ -6788,6 +6809,15 @@ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, + "@types/mkdirp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.2.tgz", + "integrity": "sha512-o0K1tSO0Dx5X6xlU5F1D6625FawhC3dU3iqr25lluNv/+/QIVH8RLNEiVokgIZo+mz+87w/3Mkg/VvQS+J51fQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/node": { "version": "18.11.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", @@ -8545,16 +8575,15 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.0.0.tgz", + "integrity": "sha512-M9ecBPkCu6jZ+H19zruhjw/JB97qqVhyi1H2Lxxo2XAoIMdpHKQ8MfQiMzXk9SH/oJXIbM3oSAfLB8qSWJdCLA==", + "dev": true }, "ms": { "version": "2.1.2", @@ -8923,13 +8952,10 @@ "peer": true }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.0.7.tgz", + "integrity": "sha512-CUEDDrZvc0swDgVdXGiv3FcYYQMpJxjvSGt85Amj6yU+MCVWurrLCeLiJDdJPHCzNJnwuebBEdcO//eP11Xa7w==", + "dev": true }, "run-parallel": { "version": "1.2.0", @@ -9133,9 +9159,9 @@ } }, "tap": { - "version": "16.3.3", - "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.3.tgz", - "integrity": "sha512-E6Ti4FaH3zUvOtl13GA60n8aodRj44S8Vu5efM84U5NmquJo4+y21+2VM9r9jR5iiEcce5dqvlrrwAhZ6r11xg==", + "version": "16.3.4", + "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.4.tgz", + "integrity": "sha512-SAexdt2ZF4XBgye6TPucFI2y7VE0qeFXlXucJIV1XDPCs+iJodk0MYacr1zR6Ycltzz7PYg8zrblDXKbAZM2LQ==", "dev": true, "requires": { "@isaacs/import-jsx": "^4.0.1", diff --git a/package.json b/package.json index da09b9fb..b18e4fe5 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts", "prepublish": "npm run benchclean", "profclean": "rm -f v8.log profile.txt", - "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js", + "test-regen": "npm run profclean && TEST_REGEN=1 node --no-warnings --loader ts-node/esm test/00-setup.js", "bench": "bash benchmark.sh", "prof": "bash prof.sh && cat profile.txt", "benchclean": "node benchclean.js" @@ -57,22 +57,23 @@ "minimatch": "^6.0.4" }, "devDependencies": { + "@types/mkdirp": "^1.0.2", "@types/node": "^18.11.18", "@types/tap": "^15.0.7", "c8": "^7.12.0", "eslint-config-prettier": "^8.6.0", "memfs": "^3.2.0", - "mkdirp": "0", + "mkdirp": "^2.0.0", "prettier": "^2.8.3", - "rimraf": "^2.2.8", - "tap": "^16.3.3", + "rimraf": "^4.0.7", + "tap": "^16.3.4", "ts-node": "^10.9.1", "typedoc": "^0.23.24", "typescript": "^4.9.4" }, "tap": { - "before": "test/00-setup.js", - "after": "test/zz-cleanup.js", + "before": "test/00-setup.ts", + "after": "test/zz-cleanup.ts", "coverage": false, "node-arg": [ "--no-warnings", diff --git a/src/glob.ts b/src/glob.ts index ee3d0b58..181d236e 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -1,4 +1,5 @@ import { Minimatch, MinimatchOptions } from 'minimatch' +import {resolve} from 'path' import { GlobCache } from './readdir.js' import { GlobWalker, Pattern } from './walker.js' @@ -86,7 +87,6 @@ export class Glob { } doNonull(matches: string[], i: number) { - console.log('doNonull', matches, i, this.globSet[i]) if (!matches.length && this.nonull) { const gs: string | undefined = this.globSet[i] if (gs) { @@ -119,7 +119,17 @@ export class Glob { } getWalker(set: Pattern) { - return new GlobWalker(set, this.cwd, this) + // if the set starts with an absolute path, then start there + const first = set[0] + const setAbs = + typeof first === 'string' && + (first === '' || + (process.platform === 'win32' && /^[a-z]:$/i.test(first))) + if (setAbs) { + set.shift() + } + const start = setAbs ? first + '/' : this.cwd + return new GlobWalker(set, start, this) } processSync() { diff --git a/src/index.ts b/src/index.ts index f500cc1e..d019bd3f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,12 +13,15 @@ export const glob = Object.assign( ): Promise => new Glob(pattern, options).process(), { sync: globSync, + globSync, Glob, hasMagic, } ) +/* c8 ignore start */ export { Glob } from './glob.js' export type { GlobOptions } from './glob.js' export { hasMagic } from './has-magic.js' export default glob +/* c8 ignore stop */ diff --git a/src/walker.ts b/src/walker.ts index b54ae031..d7657c86 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -191,7 +191,11 @@ export class GlobWalker { } join(p: string) { - return this.path ? `${this.path}/${p}` : p + return this.path === '' + ? p + : this.path === '/' + ? `${this.path}${p}` + : `${this.path}/${p}` } getChildrenString( @@ -199,7 +203,6 @@ export class GlobWalker { p: string, rest: Pattern | null ): Children { - console.log('CS', this.path, entries, p, rest) const children: Children = [] const e = entries.find(e => e.name === p) const traverse = @@ -220,17 +223,14 @@ export class GlobWalker { } getChildrenGlobstar(entries: Dirent[], rest: Pattern | null): Children { - console.log('CGS', this.path, entries, rest) const children: Children = [] // eg, p=**/a/b if (rest) { - console.log('> 1', rest, this.path) // it can match a/b against this path, without the ** children.push(this.child(rest, this.path)) } else { // but if ** is at the end, then this path definitely matches - console.log('> 2', null, this.path) children.push(this.path) } @@ -242,18 +242,13 @@ export class GlobWalker { // ** does not traverse symlinks, unless follow:true is set. const traverse = e.isDirectory() || (this.follow && e.isSymbolicLink()) if (traverse) { - console.log('t1>', this.pattern, path) children.push(this.child(this.pattern, path)) } if (rest) { // can match a/b against child path - if (traverse) { - console.log('t2>', rest, path) - children.push(this.child(rest, path)) - } + children.push(this.child(rest, path)) } else { // ** at the end, will match all children - console.log('t3>', path) children.push(path) } } diff --git a/test/00-setup.js b/test/00-setup.js deleted file mode 100644 index 65ab0ca3..00000000 --- a/test/00-setup.js +++ /dev/null @@ -1,182 +0,0 @@ -// just a little pre-run script to set up the fixtures. -// zz-finish cleans it up - -require("./global-leakage.js") -var mkdirp = require("mkdirp") -var path = require("path") -var i = 0 -process.env.TAP_BAIL = '1' -var tap = require("tap") -var fs = require("fs") -tap.pipe(fs.createWriteStream(path.resolve(__dirname, '../00-setup.tap'))) -var rimraf = require("rimraf") - -var fixtureDir = path.resolve(__dirname, 'fixtures') - -var files = -[ "a/.abcdef/x/y/z/a" -, "a/abcdef/g/h" -, "a/abcfed/g/h" -, "a/b/c/d" -, "a/bc/e/f" -, "a/c/d/c/b" -, "a/cb/e/f" -, "a/x/.y/b" -, "a/z/.y/b" -] - -var symlinkTo = path.resolve(fixtureDir, "a/symlink/a/b/c") -var symlinkFrom = "../.." - -files = files.map(function (f) { - return path.resolve(fixtureDir, f) -}) - -tap.test("remove fixtures", function (t) { - rimraf.sync(fixtureDir) - t.end() -}) - -files.forEach(function (f) { - tap.test(f, function (t) { - f = path.resolve(fixtureDir, f) - var d = path.dirname(f) - mkdirp(d, '0755', function (er) { - if (er) { - t.fail(er) - return t.bailout() - } - fs.writeFile(f, "i like tests", function (er) { - t.error(er, "make file") - t.end() - }) - }) - }) -}) - -if (process.platform !== "win32") { - tap.test("symlinky", function (t) { - var d = path.dirname(symlinkTo) - mkdirp(d, '0755', function (er) { - if (er) - throw er - fs.symlinkSync(symlinkFrom, symlinkTo, "dir") - t.end() - }) - }) -} - -;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) { - w = "/tmp/glob-test/" + w - tap.test("create " + w, function (t) { - mkdirp(w, function (er) { - if (er) - throw er - t.pass(w) - t.end() - }) - }) -}) - -// generate the bash pattern test-fixtures if possible -if (process.platform === "win32" || !process.env.TEST_REGEN) { - console.error("Windows, or TEST_REGEN unset. Using cached fixtures.") - return -} - -var spawn = require("child_process").spawn; -var globs = - // put more patterns here. - // anything that would be directly in / should be in /tmp/glob-test - ["a/*/+(c|g)/./d" - ,"a/**/[cg]/../[cg]" - ,"a/{b,c,d,e,f}/**/g" - ,"a/b/**" - ,"./**/g" - ,"a/abc{fed,def}/g/h" - ,"a/abc{fed/g,def}/**/" - ,"a/abc{fed/g,def}/**///**/" - ,"./**/a/**/" - ,"+(a|b|c)/a{/,bc*}/**" - ,"*/*/*/f" - ,"./**/f" - ,"a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**" - ,"{./*/*,/tmp/glob-test/*}" - ,"{/tmp/glob-test/*,*}" // evil owl face! how you taunt me! - ,"a/!(symlink)/**" - ,"a/symlink/a/**/*" - ] -var bashOutput = {} -var fs = require("fs") - -globs.forEach(function (pattern) { - tap.test("generate fixture " + pattern, function (t) { - var opts = [ - "-O", "globstar", - "-O", "extglob", - "-O", "nullglob", - "-c", - "for i in " + pattern + "; do echo $i; done" - ] - var cp = spawn("bash", opts, { cwd: fixtureDir }) - var out = [] - cp.stdout.on("data", function (c) { - out.push(c) - }) - cp.stderr.pipe(process.stderr) - cp.on("close", function (code) { - out = flatten(out) - if (!out) - out = [] - else - out = cleanResults(out.split(/\r*\n/)) - - bashOutput[pattern] = out - t.notOk(code, "bash test should finish nicely") - t.end() - }) - }) -}) - -tap.test("save fixtures", function (t) { - var fname = path.resolve(__dirname, "bash-results.json") - var data = JSON.stringify(bashOutput, null, 2) + "\n" - fs.writeFile(fname, data, function (er) { - t.error(er) - t.end() - }) -}) - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') - }) -} - -function flatten (chunks) { - var s = 0 - chunks.forEach(function (c) { s += c.length }) - var out = new Buffer(s) - s = 0 - chunks.forEach(function (c) { - c.copy(out, s) - s += c.length - }) - - return out.toString().trim() -} - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} diff --git a/test/00-setup.ts b/test/00-setup.ts new file mode 100644 index 00000000..39334680 --- /dev/null +++ b/test/00-setup.ts @@ -0,0 +1,153 @@ +// just a little pre-run script to set up the fixtures. +// zz-finish cleans it up + +import { spawn } from 'child_process' +import { createWriteStream, promises } from 'fs' +import mkdirp from 'mkdirp' +import { dirname, resolve } from 'path' +import { rimraf } from 'rimraf' +import t from 'tap' + +const { writeFile, symlink } = promises +//@ts-ignore +t.pipe(createWriteStream('00-setup.tap')) +process.env.TAP_BAIL = '1' + +const fixtureDir = resolve(__dirname, 'fixtures') + +const filesUnresolved = [ + 'a/.abcdef/x/y/z/a', + 'a/abcdef/g/h', + 'a/abcfed/g/h', + 'a/b/c/d', + 'a/bc/e/f', + 'a/c/d/c/b', + 'a/cb/e/f', + 'a/x/.y/b', + 'a/z/.y/b', +] + +const symlinkTo = resolve(fixtureDir, 'a/symlink/a/b/c') +const symlinkFrom = '../..' + +const files = filesUnresolved.map(f => resolve(fixtureDir, f)) + +t.test('remove fixtures', async () => await rimraf(fixtureDir)) + +for (const file of files) { + t.test(file, { bail: true }, async () => { + const f = resolve(fixtureDir, file) + const d = dirname(f) + await mkdirp(d) + await writeFile(f, 'i like tests') + }) +} + +if (process.platform !== 'win32') { + t.test('symlinky', async () => { + const d = dirname(symlinkTo) + await mkdirp(d) + await symlink(symlinkFrom, symlinkTo, 'dir') + }) +} + +;['foo', 'bar', 'baz', 'asdf', 'quux', 'qwer', 'rewq'].forEach(function (w) { + w = '/tmp/glob-test/' + w + t.test('create ' + w, async t => { + await mkdirp(w) + t.pass(w) + }) +}) + +// generate the bash pattern test-fixtures if possible +if (process.platform === 'win32' || !process.env.TEST_REGEN) { + console.error('Windows, or TEST_REGEN unset. Using cached fixtures.') +} else { + const globs = + // put more patterns here. + // anything that would be directly in / should be in /tmp/glob-test + [ + 'a/*/+(c|g)/./d', + 'a/**/[cg]/../[cg]', + 'a/{b,c,d,e,f}/**/g', + 'a/b/**', + './**/g', + 'a/abc{fed,def}/g/h', + 'a/abc{fed/g,def}/**/', + 'a/abc{fed/g,def}/**///**/', + './**/a/**/', + '+(a|b|c)/a{/,bc*}/**', + '*/*/*/f', + './**/f', + 'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**', + '{./*/*,/tmp/glob-test/*}', + '{/tmp/glob-test/*,*}', // evil owl face! how you taunt me! + 'a/!(symlink)/**', + 'a/symlink/a/**/*', + ] + const bashOutput: { [k: string]: string[] } = {} + + for (const pattern of globs) { + t.test('generate fixture ' + pattern, t => { + const opts = [ + '-O', + 'globstar', + '-O', + 'extglob', + '-O', + 'nullglob', + '-c', + 'for i in ' + pattern + '; do echo $i; done', + ] + const cp = spawn('bash', opts, { cwd: fixtureDir }) + const out: Buffer[] = [] + cp.stdout.on('data', c => out.push(c)) + cp.stderr.pipe(process.stderr) + cp.on('close', function (code) { + const o = flatten(out) + bashOutput[pattern] = !o ? [] : cleanResults(o.split(/\r*\n/)) + t.notOk(code, 'bash test should finish nicely') + t.end() + }) + }) + } + + t.test('save fixtures', async () => { + const fname = resolve(__dirname, 'bash-results.ts') + const data = `// generated via 'npm run test-regen' +if (module === require.main) { + console.log('TAP version 13\\n1..1\\nok\\n') +} +export const bashResults:{ [path: string]: string[] } = ${ + JSON.stringify(bashOutput, null, 2) + '\n' + } +` + await writeFile(fname, data) + }) + + function cleanResults(m: string[]) { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m + .map(function (m) { + return m.replace(/\/+/g, '/').replace(/\/$/, '') + }) + .sort(alphasort) + .reduce(function (set: string[], f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []) + .sort(alphasort) + .map(function (f) { + // de-windows + return process.platform !== 'win32' + ? f + : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') + }) + } + + const flatten = (chunks: Buffer[]) => Buffer.concat(chunks).toString().trim() + + const alphasort = (a: string, b: string) => + a.toLowerCase().localeCompare(b.toLowerCase(), 'en') +} diff --git a/test/abort.js b/test/abort.js deleted file mode 100644 index 1aeb58f4..00000000 --- a/test/abort.js +++ /dev/null @@ -1,19 +0,0 @@ -require("./global-leakage.js") -var test = require("tap").test -var glob = require('../') -var assert = require("assert") -var fs = require("fs") -process.chdir(__dirname) - -test("abort prevents any action", function (t) { - glob("a/**").abort() - glob("a/").abort() - glob("a/b/*").abort() - - glob.Glob.prototype.emit = fs.readdir = fs.stat = fs.lstat = assert.fail - - setTimeout(function () { - t.pass("if it gets here then it worked") - t.end() - }, 100) -}) diff --git a/test/absolute.js b/test/absolute.js deleted file mode 100644 index 68c81191..00000000 --- a/test/absolute.js +++ /dev/null @@ -1,49 +0,0 @@ -require('./global-leakage.js') -var t = require('tap') -var glob = require('../') -var common = require('../common.js') -var pattern = 'a/b/**'; -var bashResults = require('./bash-results.json') -var isAbsolute = require('path').isAbsolute -process.chdir(__dirname + '/fixtures') - -t.Test.prototype.addAssert('isAbsolute', 1, function (file, message, extra) { - extra.found = file - return this.ok(isAbsolute(file), message || 'must be absolute', extra) -}) - -var marks = [ true, false ] -marks.forEach(function (mark) { - t.test('mark=' + mark, function (t) { - t.plan(2) - - t.test('Emits absolute matches if option set', function (t) { - var g = new glob.Glob(pattern, { absolute: true }) - - var matchCount = 0 - g.on('match', function (m) { - t.isAbsolute(m) - matchCount++ - }) - - g.on('end', function (results) { - t.equal(matchCount, bashResults[pattern].length, 'must match all files') - t.equal(results.length, bashResults[pattern].length, 'must match all files') - results.forEach(function (m) { - t.isAbsolute(m) - }) - t.end() - }) - }) - - t.test('returns absolute results synchronously', function (t) { - var results = glob.sync(pattern, { absolute: true }) - - t.equal(results.length, bashResults[pattern].length, 'must match all files') - results.forEach(function (m) { - t.ok(isAbsolute(m), 'must be absolute', { found: m }) - }) - t.end() - }) - }) -}) diff --git a/test/absolute.ts b/test/absolute.ts new file mode 100644 index 00000000..5ff92d21 --- /dev/null +++ b/test/absolute.ts @@ -0,0 +1,45 @@ +import { isAbsolute } from 'path' +import t from 'tap' +import { Glob } from '../' +import { bashResults } from './bash-results' + +const pattern = 'a/b/**' +process.chdir(__dirname + '/fixtures') + +const ok = (t: Tap.Test, file: string) => + t.ok(isAbsolute(file), 'must be absolute', { found: file }) + +var marks = [true, false] +for (const mark of marks) { + t.test('mark=' + mark, t => { + t.plan(2) + + t.test('Emits absolute matches if option set', async t => { + var g = new Glob(pattern, { absolute: true }) + const results = await g.process() + + t.equal( + results.length, + bashResults[pattern].length, + 'must match all files' + ) + for (const m of results) { + ok(t, m) + } + }) + + t.test('returns absolute results synchronously', async t => { + var g = new Glob(pattern, { absolute: true }) + const results = g.processSync() + + t.equal( + results.length, + bashResults[pattern].length, + 'must match all files' + ) + for (const m of results) { + ok(t, m) + } + }) + }) +} diff --git a/test/bash-comparison.js b/test/bash-comparison.js deleted file mode 100644 index 01a52452..00000000 --- a/test/bash-comparison.js +++ /dev/null @@ -1,79 +0,0 @@ -// basic test -// show that it does the same thing by default as the shell. -require("./global-leakage.js") -var tap = require("tap") -var child_process = require("child_process") -var bashResults = require("./bash-results.json") -var globs = Object.keys(bashResults) -var glob = require("../") -var path = require("path") -var isAbsolute = require("path").isAbsolute - -// run from the root of the project -// this is usually where you're at anyway, but be sure. -var root = path.dirname(__dirname) -var fixtures = path.resolve(__dirname, 'fixtures') -process.chdir(fixtures) - -function cacheCheck(g, t) { - // verify that path cache keys are all absolute - var caches = [ 'cache', 'statCache', 'symlinks' ] - caches.forEach(function (c) { - Object.keys(g[c]).forEach(function (p) { - t.ok(isAbsolute(p), p + ' should be absolute') - }) - }) -} - -function alphasort (a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} - -globs.forEach(function (pattern) { - var expect = bashResults[pattern] - // anything regarding the symlink thing will fail on windows, so just skip it - if (process.platform === "win32" && - expect.some(function (m) { - return /\bsymlink\b/.test(m) - })) - return - - tap.test(pattern, function (t) { - var g = glob(pattern, function (er, matches) { - if (er) - throw er - - // sort and unmark, just to match the shell results - matches = cleanResults(matches) - t.same(matches, expect, pattern) - - // verify that path cache keys are all absolute - cacheCheck(g, t) - t.end() - }) - }) - - tap.test(pattern + " sync", function (t) { - var matches = cleanResults(glob.sync(pattern)) - - t.same(matches, expect, "should match shell (sync)") - t.end() - }) -}) - -function cleanResults (m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/') - }).sort(alphasort) -} diff --git a/test/bash-comparison.ts b/test/bash-comparison.ts new file mode 100644 index 00000000..5495e7b0 --- /dev/null +++ b/test/bash-comparison.ts @@ -0,0 +1,56 @@ +// basic test +// show that it does the same thing by default as the shell. +import { resolve } from 'path' +import t from 'tap' +import glob from '../' +import { bashResults } from './bash-results' +const globs = Object.keys(bashResults) + +// run from the root of the project +// this is usually where you're at anyway, but be sure. +const fixtures = resolve(__dirname, 'fixtures') +process.chdir(fixtures) + +const alphasort = (a: string, b: string) => + a.toLowerCase().localeCompare(b.toLowerCase(), 'en') + +const cleanResults = (m: string[]) => { + // normalize discrepancies in ordering, duplication, + // and ending slashes. + return m + .map(m => m.replace(/\/+/g, '/').replace(/\/$/, '')) + .sort(alphasort) + .reduce((set: string[], f) => { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []) + .map(f => { + // de-windows + return process.platform !== 'win32' + ? f + : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/') + }) + .sort(alphasort) +} + +globs.forEach(function (pattern) { + var expect = bashResults[pattern] + // anything regarding the symlink thing will fail on windows, so just skip it + if ( + process.platform === 'win32' && + expect.some((m: string) => /\bsymlink\b/.test(m)) + ) { + return + } + + t.test(pattern, async t => { + // sort and unmark, just to match the shell results + const matches = cleanResults(await glob(pattern)) + t.same(matches, expect, pattern) + }) + + t.test(pattern + ' sync', async t => { + const matches = cleanResults(glob.sync(pattern)) + t.same(matches, expect, 'should match shell (sync)') + }) +}) diff --git a/test/bash-results.json b/test/bash-results.ts similarity index 93% rename from test/bash-results.json rename to test/bash-results.ts index 42d9dd2b..f1bdded4 100644 --- a/test/bash-results.json +++ b/test/bash-results.ts @@ -1,4 +1,8 @@ -{ +// generated via 'npm run test-regen' +if (module === require.main) { + console.log('TAP version 13\n1..1\nok\n') +} +export const bashResults:{ [path: string]: string[] } = { "a/*/+(c|g)/./d": [ "a/b/c/./d" ], @@ -138,3 +142,4 @@ "a/symlink/a/b/c/a" ] } + diff --git a/test/broken-symlink.js b/test/broken-symlink.ts similarity index 100% rename from test/broken-symlink.js rename to test/broken-symlink.ts diff --git a/test/cwd-test.js b/test/cwd-test.ts similarity index 100% rename from test/cwd-test.js rename to test/cwd-test.ts diff --git a/test/empty-set.js b/test/empty-set.ts similarity index 100% rename from test/empty-set.js rename to test/empty-set.ts diff --git a/test/enotsup.js b/test/enotsup.ts similarity index 100% rename from test/enotsup.js rename to test/enotsup.ts diff --git a/test/eperm-stat.js b/test/eperm-stat.ts similarity index 100% rename from test/eperm-stat.js rename to test/eperm-stat.ts diff --git a/test/error-callback.js b/test/error-callback.ts similarity index 100% rename from test/error-callback.js rename to test/error-callback.ts diff --git a/test/follow.js b/test/follow.ts similarity index 100% rename from test/follow.js rename to test/follow.ts diff --git a/test/global-leakage.js b/test/global-leakage.js deleted file mode 100644 index 8cd3a5c8..00000000 --- a/test/global-leakage.js +++ /dev/null @@ -1,20 +0,0 @@ -if (require.main === module) - return require('tap').pass('ok') - -var before = Object.keys(global).sort().filter(function (t) { - return t !== '__coverage__' && t !== '__core-js_shared__' -}).join(':') -var assert = require('assert') -var glob = require('../') - -process.on('exit', function() { - delete global.TAP_Global_Harness - var after = Object.keys(global).sort().filter(function (t) { - return t !== '__coverage__' && t !== '__core-js_shared__' - }).join(':') - if (after !== before) { - console.log('- ' + before) - console.log('+ ' + after) - } - assert.equal(before, after) -}) diff --git a/test/globstar-match-memfs.js b/test/globstar-match-memfs.ts similarity index 100% rename from test/globstar-match-memfs.js rename to test/globstar-match-memfs.ts diff --git a/test/globstar-match.js b/test/globstar-match.ts similarity index 100% rename from test/globstar-match.js rename to test/globstar-match.ts diff --git a/test/has-magic.js b/test/has-magic.ts similarity index 100% rename from test/has-magic.js rename to test/has-magic.ts diff --git a/test/ignore.js b/test/ignore.ts similarity index 100% rename from test/ignore.js rename to test/ignore.ts diff --git a/test/mark.js b/test/mark.ts similarity index 100% rename from test/mark.js rename to test/mark.ts diff --git a/test/match-base.js b/test/match-base.ts similarity index 100% rename from test/match-base.js rename to test/match-base.ts diff --git a/test/multiple-weird-error.js b/test/multiple-weird-error.ts similarity index 100% rename from test/multiple-weird-error.js rename to test/multiple-weird-error.ts diff --git a/test/new-glob-optional-options.js b/test/new-glob-optional-options.ts similarity index 100% rename from test/new-glob-optional-options.js rename to test/new-glob-optional-options.ts diff --git a/test/nocase-nomagic.js b/test/nocase-nomagic.ts similarity index 100% rename from test/nocase-nomagic.js rename to test/nocase-nomagic.ts diff --git a/test/nodir.js b/test/nodir.ts similarity index 100% rename from test/nodir.js rename to test/nodir.ts diff --git a/test/nonull.js b/test/nonull.ts similarity index 100% rename from test/nonull.js rename to test/nonull.ts diff --git a/test/pause-resume.js b/test/pause-resume.ts similarity index 100% rename from test/pause-resume.js rename to test/pause-resume.ts diff --git a/test/readme-issue.js b/test/readme-issue.ts similarity index 100% rename from test/readme-issue.js rename to test/readme-issue.ts diff --git a/test/realpath.js b/test/realpath.ts similarity index 100% rename from test/realpath.js rename to test/realpath.ts diff --git a/test/root-nomount.js b/test/root-nomount.ts similarity index 100% rename from test/root-nomount.js rename to test/root-nomount.ts diff --git a/test/root.js b/test/root.ts similarity index 100% rename from test/root.js rename to test/root.ts diff --git a/test/slash-cwd.js b/test/slash-cwd.ts similarity index 100% rename from test/slash-cwd.js rename to test/slash-cwd.ts diff --git a/test/stat.js b/test/stat.ts similarity index 100% rename from test/stat.js rename to test/stat.ts diff --git a/test/sync-cb-throw.js b/test/sync-cb-throw.ts similarity index 100% rename from test/sync-cb-throw.js rename to test/sync-cb-throw.ts diff --git a/test/windows-paths-fs.js b/test/windows-paths-fs.ts similarity index 100% rename from test/windows-paths-fs.js rename to test/windows-paths-fs.ts diff --git a/test/windows-paths-no-escape.js b/test/windows-paths-no-escape.ts similarity index 100% rename from test/windows-paths-no-escape.js rename to test/windows-paths-no-escape.ts diff --git a/test/zz-cleanup.js b/test/zz-cleanup.js deleted file mode 100644 index 62db2429..00000000 --- a/test/zz-cleanup.js +++ /dev/null @@ -1,16 +0,0 @@ -require("./global-leakage.js") -// remove the fixtures -process.env.TAP_BAIL = '1' -var tap = require("tap") -var fs = require('fs') -var rimraf = require("rimraf") -var path = require("path") -tap.pipe(fs.createWriteStream(path.resolve(__dirname, '../zz-cleanup.tap'))) - - -tap.test("cleanup fixtures", function (t) { - rimraf(path.resolve(__dirname, "fixtures"), function (er) { - t.error(er, "removed") - t.end() - }) -}) diff --git a/test/zz-cleanup.ts b/test/zz-cleanup.ts new file mode 100644 index 00000000..c6b1b818 --- /dev/null +++ b/test/zz-cleanup.ts @@ -0,0 +1,13 @@ +// remove the fixtures +process.env.TAP_BAIL = '1' +import { createWriteStream } from 'fs' +import { resolve } from 'path' +import { rimraf } from 'rimraf' +import t from 'tap' +//@ts-ignore +t.pipe(createWriteStream('zz-cleanup.tap')) + +t.test( + 'cleanup fixtures', + async () => await rimraf(resolve(__dirname, 'fixtures')) +) From e294d2a3d9699f5b34d22417178451057a564a8f Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 16 Jan 2023 00:21:13 -0800 Subject: [PATCH 031/163] make more tests pass, format everything, fix cwd behavior --- README.md | 1 + benchclean.js | 3 +- changelog.md | 18 +- package.json | 2 +- src/glob.ts | 27 ++- src/walker.ts | 60 ++++-- test/00-setup.ts | 7 +- test/bash-results.ts | 237 +++++++++------------ test/broken-symlink.ts | 106 ++++------ test/cwd-test.ts | 112 +++------- test/empty-set.ts | 23 +- test/enotsup.ts | 65 ------ test/eperm-stat.ts | 112 ---------- test/error-callback.ts | 19 +- test/follow.ts | 18 +- test/globstar-match-memfs.ts | 4 +- test/globstar-match.ts | 10 +- test/has-magic.ts | 47 ++-- test/ignore.ts | 341 ++++++++++++++++++++++++++---- test/mark.ts | 207 +++++++++--------- test/match-base.ts | 21 +- test/multiple-weird-error.ts | 12 +- test/new-glob-optional-options.ts | 18 +- test/nocase-nomagic.ts | 141 ++++++------ test/nodir.ts | 50 ++--- test/nonull.ts | 15 +- test/pause-resume.ts | 71 ++++--- test/readme-issue.ts | 37 ++-- test/realpath.ts | 66 +++--- test/root-nomount.ts | 70 ++++-- test/root.ts | 117 ++++++---- test/slash-cwd.ts | 5 +- test/stat.ts | 23 +- test/sync-cb-throw.ts | 16 +- test/windows-paths-fs.ts | 12 +- test/windows-paths-no-escape.ts | 30 +-- 36 files changed, 1129 insertions(+), 994 deletions(-) delete mode 100644 test/enotsup.ts delete mode 100644 test/eperm-stat.ts diff --git a/README.md b/README.md index b4a1449b..3cc84508 100644 --- a/README.md +++ b/README.md @@ -365,4 +365,5 @@ npm run bench # to profile javascript npm run prof ``` + ![](oh-my-glob.gif) diff --git a/benchclean.js b/benchclean.js index de90d8a7..462ccbb1 100644 --- a/benchclean.js +++ b/benchclean.js @@ -1,6 +1,5 @@ var rimraf = require('rimraf') var bf = (process.env.TMPDIR || '/tmp') + '/benchmark-fixture' rimraf('{' + [bf, 'v8.log', 'profile.txt'].join(',') + '}', function (er) { - if (er) - throw er + if (er) throw er }) diff --git a/changelog.md b/changelog.md index 764fc09d..cd2f9d2b 100644 --- a/changelog.md +++ b/changelog.md @@ -7,21 +7,23 @@ This is a full rewrite. - Hybrid module distribution. - Full TypeScript support. - Removed `root` option and mounting behavior. -- Removed `stat` option. -- Simplified `cwd` behavior. Now it simply serves as the initial +- Removed `stat` option. It's slow and pointless. (Could bring + back easily if there's demand.) +- Simplified `cwd` behavior. Now it just serves as the initial argument to `fs.readdir`. - Removed all stat calls, in favor of using `withFileTypes:true` with `fs.readdir()`. - Consolidated all caching to a single object that only caches - directory entries and `readdir` errors. + directory entries and `readdir` errors. We can actually get + everything we need from just that. - Removed EventEmitter behavior from exported `Glob` class. - Consolidated sync and async `Glob` class behavior into a single class with `process()` and `processSync()` methods. -- Removed `silent` option. Any readdir errors are simply treated as - "the directory could not be read", and it is treated as a - normal file entry instead, like shells do. -- Removed `fs` option. This module only operates on the real - filesystem. +- Removed `silent` and `strict` options. Any readdir errors are + simply treated as "the directory could not be read", and it is + treated as a normal file entry instead, like shells do. +- Removed `fs` option. This module only operates on the real + filesystem. (Could bring back if there's demand for it.) - Only support node 16 and higher. ## 8.1 diff --git a/package.json b/package.json index b18e4fe5..addcfc72 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ }, "prettier": { "semi": false, - "printWidth": 80, + "printWidth": 75, "tabWidth": 2, "useTabs": false, "singleQuote": true, diff --git a/src/glob.ts b/src/glob.ts index 181d236e..56160e0f 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -1,5 +1,4 @@ import { Minimatch, MinimatchOptions } from 'minimatch' -import {resolve} from 'path' import { GlobCache } from './readdir.js' import { GlobWalker, Pattern } from './walker.js' @@ -39,7 +38,10 @@ export class Glob { noglobstar: boolean cache: GlobCache - constructor(pattern: string | string[], options: GlobOptions | Glob = {}) { + constructor( + pattern: string | string[], + options: GlobOptions | Glob = {} + ) { this.ignore = options.ignore this.follow = !!options.follow this.dot = !!options.dot @@ -83,7 +85,10 @@ export class Glob { const mmo = { ...options, nonegate: true, nocomment: true } const mms = this.pattern.map(p => new Minimatch(p, mmo)) this.matchSet = mms.reduce((set: MatchSet, m) => set.concat(m.set), []) - this.globSet = mms.reduce((set: GlobSet, m) => set.concat(m.globSet), []) + this.globSet = mms.reduce( + (set: GlobSet, m) => set.concat(m.globSet), + [] + ) } doNonull(matches: string[], i: number) { @@ -115,21 +120,13 @@ export class Glob { finish(matches: string[][]): string[] { const raw = matches.reduce((set, m) => set.concat(m), []) const flat = this.nounique ? raw : [...new Set(raw)] - return this.nosort ? flat : flat.sort((a, b) => a.localeCompare(b, 'en')) + return this.nosort + ? flat + : flat.sort((a, b) => a.localeCompare(b, 'en')) } getWalker(set: Pattern) { - // if the set starts with an absolute path, then start there - const first = set[0] - const setAbs = - typeof first === 'string' && - (first === '' || - (process.platform === 'win32' && /^[a-z]:$/i.test(first))) - if (setAbs) { - set.shift() - } - const start = setAbs ? first + '/' : this.cwd - return new GlobWalker(set, start, this) + return new GlobWalker(set, '', this) } processSync() { diff --git a/src/walker.ts b/src/walker.ts index d7657c86..a884fb09 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -21,9 +21,14 @@ import { resolve } from 'path' import { Ignore } from './ignore.js' import { GlobCache, Readdir } from './readdir.js' +import { join } from 'path' + // a single minimatch set entry with 1 or more parts type ParseReturnFiltered = string | RegExp | typeof GLOBSTAR -export type Pattern = [p: ParseReturnFiltered, ...rest: ParseReturnFiltered[]] +export type Pattern = [ + p: ParseReturnFiltered, + ...rest: ParseReturnFiltered[] +] type Children = (GlobWalker | string)[] @@ -37,6 +42,7 @@ export interface GlobWalkerOptions { ignore?: string | string[] | Ignore dot?: boolean absolute?: boolean + cwd?: string } export class GlobWalker { @@ -51,6 +57,8 @@ export class GlobWalker { dot: boolean ignore?: Ignore cache: GlobCache + cwd: string + start: string constructor( pattern: Pattern, @@ -67,15 +75,14 @@ export class GlobWalker { rd, cache, ignore, + cwd = '', } = options // if the pattern starts with a bunch of strings, then skip ahead this.pattern = [...pattern] this.path = path - while (this.pattern.length > 1 && typeof this.pattern[0] === 'string') { - this.path = this.join(this.pattern[0]) - this.pattern.shift() - } + this.cwd = cwd + this.start = this.setStart() this.follow = follow this.realpath = realpath this.absolute = absolute @@ -93,26 +100,51 @@ export class GlobWalker { } } + setStart() { + const [first, ...rest] = this.pattern + // a pattern like /a/s/d/f discards the cwd + // a pattern like / (or c:/ on windows) can only match the root + const setAbs = + typeof first === 'string' && + (first === '' || + (process.platform === 'win32' && /^[a-z]:$/i.test(first))) + if (setAbs) { + this.pattern = rest as Pattern + this.cwd = '/' + this.path = '/' + } + while ( + this.pattern.length > 1 && + typeof this.pattern[0] === 'string' + ) { + this.path = this.join(this.pattern[0]) + this.pattern.shift() + } + return join(this.cwd, this.path) || '.' + } + child(pattern: Pattern, path: string) { return new GlobWalker(pattern, path, this) } async walk(): Promise { - if (this.ignore && this.ignore.childrenIgnored(this.path)) { + if (this.ignore?.childrenIgnored(this.path)) { return [] } let entries: Dirent[] // if it's not a directory, or we can't read it, then // that means no match, because we still have pattern to consume try { - entries = await this.rd.readdir(this.path || '.') - } catch (_) { + entries = await this.rd.readdir(this.start) + } catch (er) { return [] } const children = this.getChildren(entries) const matches: (string | string[])[] = await Promise.all( children.map(async c => - typeof c === 'string' ? this.finish(await this.doRealpath(c)) : c.walk() + typeof c === 'string' + ? this.finish(await this.doRealpath(c)) + : c.walk() ) ) const flat = matches.reduce((set: string[], m) => set.concat(m), []) @@ -176,8 +208,8 @@ export class GlobWalker { // if it's not a directory, or we can't read it, then // that means no match, because we still have pattern to consume try { - entries = this.rd.readdirSync(this.path || '.') - } catch (e) { + entries = this.rd.readdirSync(this.start) + } catch (er) { return [] } const children = this.getChildren(entries) @@ -235,12 +267,16 @@ export class GlobWalker { } for (const e of entries) { + if (!e.name) { + console.error('wat?', this.start, e) + } if (!this.dot && e.name.startsWith('.')) { continue } const path = this.join(e.name) // ** does not traverse symlinks, unless follow:true is set. - const traverse = e.isDirectory() || (this.follow && e.isSymbolicLink()) + const traverse = + e.isDirectory() || (this.follow && e.isSymbolicLink()) if (traverse) { children.push(this.child(this.pattern, path)) } diff --git a/test/00-setup.ts b/test/00-setup.ts index 39334680..6a9228d9 100644 --- a/test/00-setup.ts +++ b/test/00-setup.ts @@ -51,7 +51,9 @@ if (process.platform !== 'win32') { }) } -;['foo', 'bar', 'baz', 'asdf', 'quux', 'qwer', 'rewq'].forEach(function (w) { +;['foo', 'bar', 'baz', 'asdf', 'quux', 'qwer', 'rewq'].forEach(function ( + w +) { w = '/tmp/glob-test/' + w t.test('create ' + w, async t => { await mkdirp(w) @@ -146,7 +148,8 @@ export const bashResults:{ [path: string]: string[] } = ${ }) } - const flatten = (chunks: Buffer[]) => Buffer.concat(chunks).toString().trim() + const flatten = (chunks: Buffer[]) => + Buffer.concat(chunks).toString().trim() const alphasort = (a: string, b: string) => a.toLowerCase().localeCompare(b.toLowerCase(), 'en') diff --git a/test/bash-results.ts b/test/bash-results.ts index f1bdded4..90a783ba 100644 --- a/test/bash-results.ts +++ b/test/bash-results.ts @@ -2,144 +2,117 @@ if (module === require.main) { console.log('TAP version 13\n1..1\nok\n') } -export const bashResults:{ [path: string]: string[] } = { - "a/*/+(c|g)/./d": [ - "a/b/c/./d" +export const bashResults: { [path: string]: string[] } = { + 'a/*/+(c|g)/./d': ['a/b/c/./d'], + 'a/**/[cg]/../[cg]': [ + 'a/abcdef/g/../g', + 'a/abcfed/g/../g', + 'a/b/c/../c', + 'a/c/../c', + 'a/c/d/c/../c', + 'a/symlink/a/b/c/../c', ], - "a/**/[cg]/../[cg]": [ - "a/abcdef/g/../g", - "a/abcfed/g/../g", - "a/b/c/../c", - "a/c/../c", - "a/c/d/c/../c", - "a/symlink/a/b/c/../c" + 'a/{b,c,d,e,f}/**/g': [], + 'a/b/**': ['a/b', 'a/b/c', 'a/b/c/d'], + './**/g': ['./a/abcdef/g', './a/abcfed/g'], + 'a/abc{fed,def}/g/h': ['a/abcdef/g/h', 'a/abcfed/g/h'], + 'a/abc{fed/g,def}/**/': ['a/abcdef', 'a/abcdef/g', 'a/abcfed/g'], + 'a/abc{fed/g,def}/**///**/': ['a/abcdef', 'a/abcdef/g', 'a/abcfed/g'], + './**/a/**/': [ + './a', + './a/abcdef', + './a/abcdef/g', + './a/abcfed', + './a/abcfed/g', + './a/b', + './a/b/c', + './a/bc', + './a/bc/e', + './a/c', + './a/c/d', + './a/c/d/c', + './a/cb', + './a/cb/e', + './a/symlink', + './a/symlink/a', + './a/symlink/a/b', + './a/symlink/a/b/c', + './a/symlink/a/b/c/a', + './a/symlink/a/b/c/a/b', + './a/symlink/a/b/c/a/b/c', + './a/x', + './a/z', ], - "a/{b,c,d,e,f}/**/g": [], - "a/b/**": [ - "a/b", - "a/b/c", - "a/b/c/d" + '+(a|b|c)/a{/,bc*}/**': [ + 'a/abcdef', + 'a/abcdef/g', + 'a/abcdef/g/h', + 'a/abcfed', + 'a/abcfed/g', + 'a/abcfed/g/h', ], - "./**/g": [ - "./a/abcdef/g", - "./a/abcfed/g" + '*/*/*/f': ['a/bc/e/f', 'a/cb/e/f'], + './**/f': ['./a/bc/e/f', './a/cb/e/f'], + 'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**': [ + 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c', + 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a', + 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b', + 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c', ], - "a/abc{fed,def}/g/h": [ - "a/abcdef/g/h", - "a/abcfed/g/h" + '{./*/*,/tmp/glob-test/*}': [ + './a/abcdef', + './a/abcfed', + './a/b', + './a/bc', + './a/c', + './a/cb', + './a/symlink', + './a/x', + './a/z', + '/tmp/glob-test/asdf', + '/tmp/glob-test/bar', + '/tmp/glob-test/baz', + '/tmp/glob-test/foo', + '/tmp/glob-test/quux', + '/tmp/glob-test/qwer', + '/tmp/glob-test/rewq', ], - "a/abc{fed/g,def}/**/": [ - "a/abcdef", - "a/abcdef/g", - "a/abcfed/g" + '{/tmp/glob-test/*,*}': [ + '/tmp/glob-test/asdf', + '/tmp/glob-test/bar', + '/tmp/glob-test/baz', + '/tmp/glob-test/foo', + '/tmp/glob-test/quux', + '/tmp/glob-test/qwer', + '/tmp/glob-test/rewq', + 'a', ], - "a/abc{fed/g,def}/**///**/": [ - "a/abcdef", - "a/abcdef/g", - "a/abcfed/g" + 'a/!(symlink)/**': [ + 'a/abcdef', + 'a/abcdef/g', + 'a/abcdef/g/h', + 'a/abcfed', + 'a/abcfed/g', + 'a/abcfed/g/h', + 'a/b', + 'a/b/c', + 'a/b/c/d', + 'a/bc', + 'a/bc/e', + 'a/bc/e/f', + 'a/c', + 'a/c/d', + 'a/c/d/c', + 'a/c/d/c/b', + 'a/cb', + 'a/cb/e', + 'a/cb/e/f', + 'a/x', + 'a/z', ], - "./**/a/**/": [ - "./a", - "./a/abcdef", - "./a/abcdef/g", - "./a/abcfed", - "./a/abcfed/g", - "./a/b", - "./a/b/c", - "./a/bc", - "./a/bc/e", - "./a/c", - "./a/c/d", - "./a/c/d/c", - "./a/cb", - "./a/cb/e", - "./a/symlink", - "./a/symlink/a", - "./a/symlink/a/b", - "./a/symlink/a/b/c", - "./a/symlink/a/b/c/a", - "./a/symlink/a/b/c/a/b", - "./a/symlink/a/b/c/a/b/c", - "./a/x", - "./a/z" + 'a/symlink/a/**/*': [ + 'a/symlink/a/b', + 'a/symlink/a/b/c', + 'a/symlink/a/b/c/a', ], - "+(a|b|c)/a{/,bc*}/**": [ - "a/abcdef", - "a/abcdef/g", - "a/abcdef/g/h", - "a/abcfed", - "a/abcfed/g", - "a/abcfed/g/h" - ], - "*/*/*/f": [ - "a/bc/e/f", - "a/cb/e/f" - ], - "./**/f": [ - "./a/bc/e/f", - "./a/cb/e/f" - ], - "a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [ - "a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c", - "a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a", - "a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b", - "a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c" - ], - "{./*/*,/tmp/glob-test/*}": [ - "./a/abcdef", - "./a/abcfed", - "./a/b", - "./a/bc", - "./a/c", - "./a/cb", - "./a/symlink", - "./a/x", - "./a/z", - "/tmp/glob-test/asdf", - "/tmp/glob-test/bar", - "/tmp/glob-test/baz", - "/tmp/glob-test/foo", - "/tmp/glob-test/quux", - "/tmp/glob-test/qwer", - "/tmp/glob-test/rewq" - ], - "{/tmp/glob-test/*,*}": [ - "/tmp/glob-test/asdf", - "/tmp/glob-test/bar", - "/tmp/glob-test/baz", - "/tmp/glob-test/foo", - "/tmp/glob-test/quux", - "/tmp/glob-test/qwer", - "/tmp/glob-test/rewq", - "a" - ], - "a/!(symlink)/**": [ - "a/abcdef", - "a/abcdef/g", - "a/abcdef/g/h", - "a/abcfed", - "a/abcfed/g", - "a/abcfed/g/h", - "a/b", - "a/b/c", - "a/b/c/d", - "a/bc", - "a/bc/e", - "a/bc/e/f", - "a/c", - "a/c/d", - "a/c/d/c", - "a/c/d/c/b", - "a/cb", - "a/cb/e", - "a/cb/e/f", - "a/x", - "a/z" - ], - "a/symlink/a/**/*": [ - "a/symlink/a/b", - "a/symlink/a/b/c", - "a/symlink/a/b/c/a" - ] } - diff --git a/test/broken-symlink.ts b/test/broken-symlink.ts index dbf276cf..3cd7c2b9 100644 --- a/test/broken-symlink.ts +++ b/test/broken-symlink.ts @@ -1,82 +1,66 @@ -var fs = require('fs') -var test = require('tap').test -var glob = require('../') -var mkdirp = require('mkdirp') +import { relative } from 'path' +import t from 'tap' +import glob, { GlobOptions } from '../' -if (process.platform === 'win32') - return require('tap').plan(0, 'skip on windows') +if (process.platform === 'win32') { + t.plan(0, 'skip on windows') + process.exit(0) +} -process.chdir(__dirname) +const dir = relative( + process.cwd(), + t.testdir({ + a: { + 'broken-link': { + link: t.fixture('symlink', 'this-does-not-exist'), + }, + }, + }) +) -var link = 'fixtures/a/broken-link/link' +const link = `${dir}/a/broken-link/link` -var patterns = [ - 'fixtures/a/broken-link/*', - 'fixtures/a/broken-link/**', - 'fixtures/a/broken-link/**/link', - 'fixtures/a/broken-link/**/*', - 'fixtures/a/broken-link/link', - 'fixtures/a/broken-link/{link,asdf}', - 'fixtures/a/broken-link/+(link|asdf)', - 'fixtures/a/broken-link/!(asdf)' +const patterns = [ + `${dir}/a/broken-link/*`, + `${dir}/a/broken-link/**`, + `${dir}/a/broken-link/**/link`, + `${dir}/a/broken-link/**/*`, + `${dir}/a/broken-link/link`, + `${dir}/a/broken-link/{link,asdf}`, + `${dir}/a/broken-link/+(link|asdf)`, + `${dir}/a/broken-link/!(asdf)`, ] -var opts = [ - null, +const opts: (GlobOptions | undefined)[] = [ + undefined, { nonull: true }, { mark: true }, - { stat: true }, - { follow: true } + { follow: true }, ] -test('set up broken symlink', function (t) { - cleanup() - mkdirp.sync('fixtures/a/broken-link') - fs.symlinkSync('this-does-not-exist', 'fixtures/a/broken-link/link') - t.end() -}) - -test('async test', function (t) { - var count = patterns.length * opts.length +t.test('async test', t => { t.plan(patterns.length) - patterns.forEach(function (pattern) { - t.test(pattern, function (t) { + for (const pattern of patterns) { + t.test(pattern, async t => { t.plan(opts.length) - - opts.forEach(function (opt) { - glob(pattern, opt, cb(opt)) - }) - - function cb (opt) { return function (er, res) { - if (er) - throw er - var msg = pattern + ' ' + JSON.stringify(opt) + for (const opt of opts) { + const res = await glob(pattern, opt) + const msg = pattern + ' ' + JSON.stringify(opt) t.not(res.indexOf(link), -1, msg) - }} + } }) - }) + } }) -test('sync test', function (t) { +t.test('sync test', t => { t.plan(patterns.length) - patterns.forEach(function (pattern) { - t.test(pattern, function (t) { + for (const pattern of patterns) { + t.test(pattern, t => { t.plan(opts.length) - - opts.forEach(function (opt) { - var res = glob.sync(pattern, opt) + for (const opt of opts) { + const res = glob.sync(pattern, opt) t.not(res.indexOf(link), -1, 'opt=' + JSON.stringify(opt)) - }) + } }) - }) -}) - -test('cleanup', function (t) { - cleanup() - t.end() + } }) - -function cleanup () { - try { fs.unlinkSync('fixtures/a/broken-link/link') } catch (e) {} - try { fs.rmdirSync('fixtures/a/broken-link') } catch (e) {} -} diff --git a/test/cwd-test.ts b/test/cwd-test.ts index 0f31df88..695a10ea 100644 --- a/test/cwd-test.ts +++ b/test/cwd-test.ts @@ -1,91 +1,33 @@ -require("./global-leakage.js") -var tap = require("tap") +import { join, resolve } from 'path' +import t from 'tap' +import glob from '../' -var origCwd = process.cwd() +const origCwd = process.cwd() process.chdir(__dirname + '/fixtures') -var path = require('path') -var isAbsolute = require('path').isAbsolute -var glob = require('../') +t.teardown(() => process.chdir(origCwd)) -function cacheCheck(g, t) { - // verify that path cache keys are all absolute - var caches = [ 'cache', 'statCache', 'symlinks' ] - caches.forEach(function (c) { - Object.keys(g[c]).forEach(function (p) { - t.ok(isAbsolute(p), p + ' should be absolute') - }) - }) -} - -tap.test("changing cwd and searching for **/d", function (t) { - t.test('.', function (t) { - var g = glob('**/d', function (er, matches) { - t.error(er) - t.match(matches, [ 'a/b/c/d', 'a/c/d' ]) - cacheCheck(g, t) - t.end() - }) - }) - - t.test('a', function (t) { - var g = glob('**/d', {cwd:path.resolve('a')}, function (er, matches) { - t.error(er) - t.match(matches, [ 'b/c/d', 'c/d' ]) - cacheCheck(g, t) - t.end() - }) - }) - - t.test('a/b', function (t) { - var g = glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) { - t.error(er) - t.match(matches, [ 'c/d' ]) - cacheCheck(g, t) - t.end() - }) - }) - - t.test('a/b/', function (t) { - var g = glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) { - t.error(er) - t.match(matches, [ 'c/d' ]) - cacheCheck(g, t) - t.end() - }) +t.test('changing cwd and searching for **/d', t => { + const expect = Object.entries({ + a: ['b/c/d', 'c/d'], + 'a/b': ['c/d'], + '': ['a/b/c/d', 'a/c/d'], }) - - t.test('.', function (t) { - var g = glob('**/d', {cwd: process.cwd()}, function (er, matches) { - t.error(er) - t.match(matches, [ 'a/b/c/d', 'a/c/d' ]) - cacheCheck(g, t) - t.end() + t.plan(expect.length) + for (const [cwd, matches] of expect) { + t.test(cwd || '(empty string)', async t => { + t.same(await glob('**/d', { cwd }), matches) + if (cwd) { + t.same(await glob('**/d', { cwd: cwd + '/' }), matches) + t.same(await glob('**/d', { cwd: cwd + '/.' }), matches) + t.same(await glob('**/d', { cwd: cwd + '/./' }), matches) + } else { + t.same(await glob('**/d', { cwd: '.' }), matches) + t.same(await glob('**/d', { cwd: './' }), matches) + } + t.same(await glob('**/d', { cwd: resolve(cwd) }), matches) + t.same(await glob('**/d', { cwd: resolve(cwd) + '/' }), matches) + t.same(await glob('**/d', { cwd: resolve(cwd) + '/.' }), matches) + t.same(await glob('**/d', { cwd: resolve(cwd) + '/./' }), matches) }) - }) - - t.end() -}) - -tap.test('non-dir cwd should raise error', function (t) { - var notdir = 'a/b/c/d' - var notdirRE = /a[\\\/]b[\\\/]c[\\\/]d/ - var abs = path.resolve(notdir).split('\\').join('/') - var expect = new Error('ENOTDIR invalid cwd ' + abs) - expect.code = 'ENOTDIR' - expect.path = notdirRE - expect.stack = undefined - var msg = 'raise error when cwd is not a dir' - - t.throws(function () { - glob.sync('*', { cwd: notdir }) - }, expect) - glob('*', { cwd: notdir }, function (er, results) { - t.match(er, expect) - t.end() - }) -}) - -tap.test('cd -', function (t) { - process.chdir(origCwd) - t.end() + } }) diff --git a/test/empty-set.ts b/test/empty-set.ts index 75956fb6..822a16e2 100644 --- a/test/empty-set.ts +++ b/test/empty-set.ts @@ -1,21 +1,18 @@ -require("./global-leakage.js") -var test = require('tap').test -var glob = require("../glob.js") +import t from 'tap' +import glob from '../' // Patterns that cannot match anything -var patterns = [ +const patterns = [ '# comment', ' ', '\n', - 'just doesnt happen to match anything so this is a control' + 'just doesnt happen to match anything so this is a control', ] -patterns.forEach(function (p) { - test(JSON.stringify(p), function (t) { - glob(p, function (e, f) { - t.equal(e, null, 'no error') - t.same(f, [], 'no returned values') - t.end() - }) +t.plan(patterns.length) +for (const p of patterns) { + t.test(JSON.stringify(p), async t => { + const f = await glob(p) + t.same(f, [], 'no returned values') }) -}) +} diff --git a/test/enotsup.ts b/test/enotsup.ts deleted file mode 100644 index 5de3b625..00000000 --- a/test/enotsup.ts +++ /dev/null @@ -1,65 +0,0 @@ -var fs = require('fs') -var readdir = fs.readdir -var readdirSync = fs.readdirSync -var sawAsyncENOTSUP = false -var sawSyncENOTSUP = false - -var path = require('path') -var fixtureDir = path.resolve(__dirname, 'fixtures') -var allowedDirs = [ - path.resolve(fixtureDir, 'a'), - path.resolve(fixtureDir, 'a', 'abcdef'), - path.resolve(fixtureDir, 'a', 'abcfed') -] - -fs.readdirSync = function (p) { - if (allowedDirs.indexOf(path.resolve(p)) === -1 && - !p.match(/[\\\/]node_modules[\\\/]/)) { - sawSyncENOTSUP = true - var er = new Error('ENOTSUP: Operation not supported') - er.path = path - er.code = 'ENOTSUP' - throw er - } - return readdirSync.call(fs, p) -} - -fs.readdir = function (p, cb) { - if (allowedDirs.indexOf(path.resolve(p)) === -1 && - !p.match(/[\\\/]node_modules[\\\/]/)) { - setTimeout(function () { - sawAsyncENOTSUP = true - er = new Error('ENOTSUP: Operation not supported') - er.path = path - er.code = 'ENOTSUP' - return cb(er) - }) - } else { - readdir.call(fs, p, cb) - } -} - -var glob = require('../') -var test = require('tap').test -var common = require('../common.js') -process.chdir(__dirname + '/fixtures') - -var pattern = 'a/**/h' -var expect = [ 'a/abcdef/g/h', 'a/abcfed/g/h' ] - -var options = { strict: true, silent: false } - -test(pattern + ' ' + JSON.stringify(options), function (t) { - var res = glob.sync(pattern, options).sort() - t.same(res, expect, 'sync results') - t.ok(sawSyncENOTSUP, 'saw sync ENOTSUP') - - var g = glob(pattern, options, function (er, res) { - if (er) - throw er - t.ok(sawAsyncENOTSUP, 'saw async ENOTSUP') - res = res.sort() - t.same(res, expect, 'async results') - t.end() - }) -}) diff --git a/test/eperm-stat.ts b/test/eperm-stat.ts deleted file mode 100644 index 5eecd6bc..00000000 --- a/test/eperm-stat.ts +++ /dev/null @@ -1,112 +0,0 @@ -require("./global-leakage.js") -var dir = __dirname + '/fixtures' - -var fs = require('fs') -var expect = [ - 'a/abcdef', - 'a/abcdef/g', - 'a/abcdef/g/h', - 'a/abcfed', - 'a/abcfed/g', - 'a/abcfed/g/h' -] - -var lstat = fs.lstat -var lstatSync = fs.lstatSync -var badPaths = /\ba[\\\/]?$|\babcdef\b/ - -fs.lstat = function (path, cb) { - // synthetically generate a non-ENOENT error - if (badPaths.test(path)) { - var er = new Error('synthetic') - er.code = 'EPERM' - return process.nextTick(cb.bind(null, er)) - } - - return lstat.call(fs, path, cb) -} - -fs.lstatSync = function (path) { - // synthetically generate a non-ENOENT error - if (badPaths.test(path)) { - var er = new Error('synthetic') - er.code = 'EPERM' - throw er - } - - return lstatSync.call(fs, path) -} - -var glob = require('../') -var t = require('tap') - -t.test('stat errors other than ENOENT are ok', function (t) { - t.plan(2) - t.test('async', function (t) { - glob('a/*abc*/**', { stat: true, cwd: dir }, function (er, matches) { - if (er) - throw er - t.same(matches, expect) - t.end() - }) - }) - - t.test('sync', function (t) { - var matches = glob.sync('a/*abc*/**', { stat: true, cwd: dir }) - t.same(matches, expect) - t.end() - }) -}) - -t.test('globstar with error in root', function (t) { - var expect = [ - 'a', - 'a/abcdef', - 'a/abcdef/g', - 'a/abcdef/g/h', - 'a/abcfed', - 'a/abcfed/g', - 'a/abcfed/g/h', - 'a/b', - 'a/b/c', - 'a/b/c/d', - 'a/bc', - 'a/bc/e', - 'a/bc/e/f', - 'a/c', - 'a/c/d', - 'a/c/d/c', - 'a/c/d/c/b', - 'a/cb', - 'a/cb/e', - 'a/cb/e/f', - 'a/symlink', - 'a/symlink/a', - 'a/symlink/a/b', - 'a/symlink/a/b/c', - 'a/x', - 'a/z' - ] - if (process.platform === 'win32') { - expect = expect.filter(function(path) { - return path.indexOf('/symlink') === -1 - }) - } - - var pattern = 'a/**' - t.plan(2) - t.test('async', function (t) { - glob(pattern, { cwd: dir }, function (er, matches) { - if (er) - throw er - t.same(matches, expect) - t.end() - }) - }) - - t.test('sync', function (t) { - var matches = glob.sync(pattern, { cwd: dir }) - t.same(matches, expect) - t.end() - }) -}) diff --git a/test/error-callback.ts b/test/error-callback.ts index b60c2956..dcedea00 100644 --- a/test/error-callback.ts +++ b/test/error-callback.ts @@ -1,4 +1,4 @@ -require("./global-leakage.js") +require('./global-leakage.js') var logCalled var console_error = console.error console.error = function () { @@ -10,9 +10,9 @@ var fs = require('fs') var test = require('tap').test var glob = require('../') -test('mock fs', function(t) { - fs.readdir = function(path, cb) { - process.nextTick(function() { +test('mock fs', function (t) { + fs.readdir = function (path, cb) { + process.nextTick(function () { cb(new Error('mock fs.readdir error')) }) } @@ -20,8 +20,8 @@ test('mock fs', function(t) { t.end() }) -test('error callback', function(t) { - glob('*', function(err, res) { +test('error callback', function (t) { + glob('*', function (err, res) { t.ok(err, 'expecting mock error') t.end() }) @@ -31,8 +31,11 @@ test('called console.error for weird error', function (t) { // Need a setTimeout, since the console.error happens directly AFTER // the emit('error') with the error. setTimeout(function () { - t.has(logCalled, [ 'glob error', { message: 'mock fs.readdir error' } ], - 'got expected error printed to console.error') + t.has( + logCalled, + ['glob error', { message: 'mock fs.readdir error' }], + 'got expected error printed to console.error' + ) t.end() }) }) diff --git a/test/follow.ts b/test/follow.ts index 79df94dd..56e1c7e5 100644 --- a/test/follow.ts +++ b/test/follow.ts @@ -13,19 +13,25 @@ test('follow symlinks', function (t) { var syncNoFollow = glob.sync(pattern).sort() var syncFollow = glob.sync(pattern, { follow: true }).sort() glob(pattern, function (er, res) { - if (er) - throw er + if (er) throw er var noFollow = res.sort() glob(pattern, { follow: true }, function (er, res) { - if (er) - throw er + if (er) throw er var follow = res.sort() t.same(follow, syncFollow, 'sync and async follow should match') - t.same(noFollow, syncNoFollow, 'sync and async noFollow should match') + t.same( + noFollow, + syncNoFollow, + 'sync and async noFollow should match' + ) var long = 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c' t.not(follow.indexOf(long), -1, 'follow should have long entry') - t.not(syncFollow.indexOf(long), -1, 'syncFollow should have long entry') + t.not( + syncFollow.indexOf(long), + -1, + 'syncFollow should have long entry' + ) t.end() }) }) diff --git a/test/globstar-match-memfs.ts b/test/globstar-match-memfs.ts index 319738f2..3598fb2c 100644 --- a/test/globstar-match-memfs.ts +++ b/test/globstar-match-memfs.ts @@ -1,7 +1,7 @@ -require("./global-leakage.js") +require('./global-leakage.js') var memfs = require('memfs') var test = require('tap').test -var glob = require("../glob.js") +var glob = require('../glob.js') test('fs-compatible file system can be used', function (t) { var volJson = { diff --git a/test/globstar-match.ts b/test/globstar-match.ts index 68f391be..b3b517fb 100644 --- a/test/globstar-match.ts +++ b/test/globstar-match.ts @@ -1,15 +1,15 @@ -require("./global-leakage.js") -var Glob = require("../glob.js").Glob +require('./global-leakage.js') +var Glob = require('../glob.js').Glob var test = require('tap').test -test('globstar should not have dupe matches', function(t) { +test('globstar should not have dupe matches', function (t) { var pattern = 'a/**/[gh]' var g = new Glob(pattern, { cwd: __dirname }) var matches = [] - g.on('match', function(m) { + g.on('match', function (m) { matches.push(m) }) - g.on('end', function(set) { + g.on('end', function (set) { matches = matches.sort() set = set.sort() t.same(matches, set, 'should have same set of matches') diff --git a/test/has-magic.ts b/test/has-magic.ts index 45650901..78e0d13e 100644 --- a/test/has-magic.ts +++ b/test/has-magic.ts @@ -1,34 +1,43 @@ -require("./global-leakage.js") -var test = require("tap").test +require('./global-leakage.js') +var test = require('tap').test var glob = require('../') process.chdir(__dirname) -glob.GlobSync.prototype._process = glob.Glob.prototype._process = function () { - throw new Error('should not call _process() in these tests') -} +glob.GlobSync.prototype._process = glob.Glob.prototype._process = + function () { + throw new Error('should not call _process() in these tests') + } -test("create glob object without processing", function (t) { - t.ok(glob('a', {noprocess:true}) instanceof glob.Glob) - t.ok(glob.GlobSync('a', {noprocess:true}) instanceof glob.GlobSync) +test('create glob object without processing', function (t) { + t.ok(glob('a', { noprocess: true }) instanceof glob.Glob) + t.ok(glob.GlobSync('a', { noprocess: true }) instanceof glob.GlobSync) t.end() }) -test("non-string pattern is evil magic", function (t) { - var patterns = [ 0, null, 12, {x:1}, undefined, /x/, NaN ] +test('non-string pattern is evil magic', function (t) { + var patterns = [0, null, 12, { x: 1 }, undefined, /x/, NaN] patterns.forEach(function (p) { - t.throws('' + p, function () { glob.hasMagic(p) }) + t.throws('' + p, function () { + glob.hasMagic(p) + }) }) t.end() }) -test("detect magic in glob patterns", function (t) { - t.notOk(glob.hasMagic(""), "no magic in ''") - t.notOk(glob.hasMagic("a/b/c/"), "no magic a/b/c/") - t.ok(glob.hasMagic("a/b/**/"), "magic in a/b/**/") - t.ok(glob.hasMagic("a/b/?/"), "magic in a/b/?/") - t.ok(glob.hasMagic("a/b/+(x|y)"), "magic in a/b/+(x|y)") - t.notOk(glob.hasMagic("a/b/+(x|y)", {noext:true}), "no magic in a/b/+(x|y) noext") +test('detect magic in glob patterns', function (t) { + t.notOk(glob.hasMagic(''), "no magic in ''") + t.notOk(glob.hasMagic('a/b/c/'), 'no magic a/b/c/') + t.ok(glob.hasMagic('a/b/**/'), 'magic in a/b/**/') + t.ok(glob.hasMagic('a/b/?/'), 'magic in a/b/?/') + t.ok(glob.hasMagic('a/b/+(x|y)'), 'magic in a/b/+(x|y)') + t.notOk( + glob.hasMagic('a/b/+(x|y)', { noext: true }), + 'no magic in a/b/+(x|y) noext' + ) t.ok(glob.hasMagic('{a,b}'), 'magic in {a,b}') - t.notOk(glob.hasMagic('{a,b}', {nobrace:true}), 'magic in {a,b} nobrace:true') + t.notOk( + glob.hasMagic('{a,b}', { nobrace: true }), + 'magic in {a,b} nobrace:true' + ) t.end() }) diff --git a/test/ignore.ts b/test/ignore.ts index d391753b..0f265591 100644 --- a/test/ignore.ts +++ b/test/ignore.ts @@ -7,36 +7,300 @@ var test = require('tap').test // [pattern, ignore, expect, opt (object) or cwd (string)] var cases = [ - [ '*', null, ['abcdef', 'abcfed', 'b', 'bc', 'c', 'cb', 'symlink', 'x', 'z'], 'a'], - [ '*', 'b', ['abcdef', 'abcfed', 'bc', 'c', 'cb', 'symlink', 'x', 'z'], 'a'], - [ '*', 'b*', ['abcdef', 'abcfed', 'c', 'cb', 'symlink', 'x', 'z'], 'a'], - [ 'b/**', 'b/c/d', ['b', 'b/c'], 'a'], - [ 'b/**', 'd', ['b', 'b/c', 'b/c/d'], 'a'], - [ 'b/**', 'b/c/**', ['b'], 'a'], - [ '**/d', 'b/c/d', ['c/d'], 'a'], - [ 'a/**/[gh]', ['a/abcfed/g/h'], ['a/abcdef/g', 'a/abcdef/g/h', 'a/abcfed/g']], - [ '*', ['c', 'bc', 'symlink', 'abcdef'], ['abcfed', 'b', 'cb', 'x', 'z'], 'a'], - [ '**', ['c/**', 'bc/**', 'symlink/**', 'abcdef/**'], ['abcfed', 'abcfed/g', 'abcfed/g/h', 'b', 'b/c', 'b/c/d', 'cb', 'cb/e', 'cb/e/f', 'x', 'z'], 'a'], - [ 'a/**', ['a/**'], []], - [ 'a/**', ['a/**/**'], []], - [ 'a/b/**', ['a/b'], ['a/b/c', 'a/b/c/d']], - [ '**', ['b'], ['abcdef', 'abcdef/g', 'abcdef/g/h', 'abcfed', 'abcfed/g', 'abcfed/g/h', 'b/c', 'b/c/d', 'bc', 'bc/e', 'bc/e/f', 'c', 'c/d', 'c/d/c', 'c/d/c/b', 'cb', 'cb/e', 'cb/e/f', 'symlink', 'symlink/a', 'symlink/a/b', 'symlink/a/b/c', 'x', 'z'], 'a'], - [ '**', ['b', 'c'], ['abcdef', 'abcdef/g', 'abcdef/g/h', 'abcfed', 'abcfed/g', 'abcfed/g/h', 'b/c', 'b/c/d', 'bc', 'bc/e', 'bc/e/f', 'c/d', 'c/d/c', 'c/d/c/b', 'cb', 'cb/e', 'cb/e/f', 'symlink', 'symlink/a', 'symlink/a/b', 'symlink/a/b/c', 'x', 'z'], 'a'], - [ '**', ['b**'], ['abcdef', 'abcdef/g', 'abcdef/g/h', 'abcfed', 'abcfed/g', 'abcfed/g/h', 'b/c', 'b/c/d', 'bc/e', 'bc/e/f', 'c', 'c/d', 'c/d/c', 'c/d/c/b', 'cb', 'cb/e', 'cb/e/f', 'symlink', 'symlink/a', 'symlink/a/b', 'symlink/a/b/c', 'x', 'z'], 'a'], - [ '**', ['b/**'], ['abcdef', 'abcdef/g', 'abcdef/g/h', 'abcfed', 'abcfed/g', 'abcfed/g/h', 'bc', 'bc/e', 'bc/e/f', 'c', 'c/d', 'c/d/c', 'c/d/c/b', 'cb', 'cb/e', 'cb/e/f', 'symlink', 'symlink/a', 'symlink/a/b', 'symlink/a/b/c', 'x', 'z'], 'a'], - [ '**', ['b**/**'], ['abcdef', 'abcdef/g', 'abcdef/g/h', 'abcfed', 'abcfed/g', 'abcfed/g/h', 'c', 'c/d', 'c/d/c', 'c/d/c/b', 'cb', 'cb/e', 'cb/e/f', 'symlink', 'symlink/a', 'symlink/a/b', 'symlink/a/b/c', 'x', 'z'], 'a'], - [ '**', ['ab**ef/**'], ['abcfed', 'abcfed/g', 'abcfed/g/h', 'b', 'b/c', 'b/c/d', 'bc', 'bc/e', 'bc/e/f', 'c', 'c/d', 'c/d/c', 'c/d/c/b', 'cb', 'cb/e', 'cb/e/f', 'symlink', 'symlink/a', 'symlink/a/b', 'symlink/a/b/c', 'x', 'z'], 'a'], - [ '**', ['abc{def,fed}/**'], ['b', 'b/c', 'b/c/d', 'bc', 'bc/e', 'bc/e/f', 'c', 'c/d', 'c/d/c', 'c/d/c/b', 'cb', 'cb/e', 'cb/e/f', 'symlink', 'symlink/a', 'symlink/a/b', 'symlink/a/b/c', 'x', 'z'], 'a'], - [ '**', ['abc{def,fed}/*'], ['abcdef', 'abcdef/g/h', 'abcfed', 'abcfed/g/h', 'b', 'b/c', 'b/c/d', 'bc', 'bc/e', 'bc/e/f', 'c', 'c/d', 'c/d/c', 'c/d/c/b', 'cb', 'cb/e', 'cb/e/f', 'symlink', 'symlink/a', 'symlink/a/b', 'symlink/a/b/c', 'x', 'z'], 'a'], - [ 'c/**', ['c/*'], ['c', 'c/d/c', 'c/d/c/b'], 'a'], - [ 'a/c/**', ['a/c/*'], ['a/c', 'a/c/d/c', 'a/c/d/c/b']], - [ 'a/c/**', ['a/c/**', 'a/c/*', 'a/c/*/c'], []], - [ 'a/**/.y', ['a/x/**'], ['a/z/.y']], - [ 'a/**/.y', ['a/x/**'], ['a/z/.y'], { dot: true }], - [ 'a/**/b', ['a/x/**'], ['a/b', 'a/c/d/c/b', 'a/symlink/a/b']], - [ 'a/**/b', ['a/x/**'], ['a/b', 'a/c/d/c/b', 'a/symlink/a/b', 'a/z/.y/b'], { dot: true }], - [ '*/.abcdef', 'a/**', [] ], - [ 'a/*/.y/b', 'a/x/**', [ 'a/z/.y/b' ] ] + [ + '*', + null, + ['abcdef', 'abcfed', 'b', 'bc', 'c', 'cb', 'symlink', 'x', 'z'], + 'a', + ], + [ + '*', + 'b', + ['abcdef', 'abcfed', 'bc', 'c', 'cb', 'symlink', 'x', 'z'], + 'a', + ], + ['*', 'b*', ['abcdef', 'abcfed', 'c', 'cb', 'symlink', 'x', 'z'], 'a'], + ['b/**', 'b/c/d', ['b', 'b/c'], 'a'], + ['b/**', 'd', ['b', 'b/c', 'b/c/d'], 'a'], + ['b/**', 'b/c/**', ['b'], 'a'], + ['**/d', 'b/c/d', ['c/d'], 'a'], + [ + 'a/**/[gh]', + ['a/abcfed/g/h'], + ['a/abcdef/g', 'a/abcdef/g/h', 'a/abcfed/g'], + ], + [ + '*', + ['c', 'bc', 'symlink', 'abcdef'], + ['abcfed', 'b', 'cb', 'x', 'z'], + 'a', + ], + [ + '**', + ['c/**', 'bc/**', 'symlink/**', 'abcdef/**'], + [ + 'abcfed', + 'abcfed/g', + 'abcfed/g/h', + 'b', + 'b/c', + 'b/c/d', + 'cb', + 'cb/e', + 'cb/e/f', + 'x', + 'z', + ], + 'a', + ], + ['a/**', ['a/**'], []], + ['a/**', ['a/**/**'], []], + ['a/b/**', ['a/b'], ['a/b/c', 'a/b/c/d']], + [ + '**', + ['b'], + [ + 'abcdef', + 'abcdef/g', + 'abcdef/g/h', + 'abcfed', + 'abcfed/g', + 'abcfed/g/h', + 'b/c', + 'b/c/d', + 'bc', + 'bc/e', + 'bc/e/f', + 'c', + 'c/d', + 'c/d/c', + 'c/d/c/b', + 'cb', + 'cb/e', + 'cb/e/f', + 'symlink', + 'symlink/a', + 'symlink/a/b', + 'symlink/a/b/c', + 'x', + 'z', + ], + 'a', + ], + [ + '**', + ['b', 'c'], + [ + 'abcdef', + 'abcdef/g', + 'abcdef/g/h', + 'abcfed', + 'abcfed/g', + 'abcfed/g/h', + 'b/c', + 'b/c/d', + 'bc', + 'bc/e', + 'bc/e/f', + 'c/d', + 'c/d/c', + 'c/d/c/b', + 'cb', + 'cb/e', + 'cb/e/f', + 'symlink', + 'symlink/a', + 'symlink/a/b', + 'symlink/a/b/c', + 'x', + 'z', + ], + 'a', + ], + [ + '**', + ['b**'], + [ + 'abcdef', + 'abcdef/g', + 'abcdef/g/h', + 'abcfed', + 'abcfed/g', + 'abcfed/g/h', + 'b/c', + 'b/c/d', + 'bc/e', + 'bc/e/f', + 'c', + 'c/d', + 'c/d/c', + 'c/d/c/b', + 'cb', + 'cb/e', + 'cb/e/f', + 'symlink', + 'symlink/a', + 'symlink/a/b', + 'symlink/a/b/c', + 'x', + 'z', + ], + 'a', + ], + [ + '**', + ['b/**'], + [ + 'abcdef', + 'abcdef/g', + 'abcdef/g/h', + 'abcfed', + 'abcfed/g', + 'abcfed/g/h', + 'bc', + 'bc/e', + 'bc/e/f', + 'c', + 'c/d', + 'c/d/c', + 'c/d/c/b', + 'cb', + 'cb/e', + 'cb/e/f', + 'symlink', + 'symlink/a', + 'symlink/a/b', + 'symlink/a/b/c', + 'x', + 'z', + ], + 'a', + ], + [ + '**', + ['b**/**'], + [ + 'abcdef', + 'abcdef/g', + 'abcdef/g/h', + 'abcfed', + 'abcfed/g', + 'abcfed/g/h', + 'c', + 'c/d', + 'c/d/c', + 'c/d/c/b', + 'cb', + 'cb/e', + 'cb/e/f', + 'symlink', + 'symlink/a', + 'symlink/a/b', + 'symlink/a/b/c', + 'x', + 'z', + ], + 'a', + ], + [ + '**', + ['ab**ef/**'], + [ + 'abcfed', + 'abcfed/g', + 'abcfed/g/h', + 'b', + 'b/c', + 'b/c/d', + 'bc', + 'bc/e', + 'bc/e/f', + 'c', + 'c/d', + 'c/d/c', + 'c/d/c/b', + 'cb', + 'cb/e', + 'cb/e/f', + 'symlink', + 'symlink/a', + 'symlink/a/b', + 'symlink/a/b/c', + 'x', + 'z', + ], + 'a', + ], + [ + '**', + ['abc{def,fed}/**'], + [ + 'b', + 'b/c', + 'b/c/d', + 'bc', + 'bc/e', + 'bc/e/f', + 'c', + 'c/d', + 'c/d/c', + 'c/d/c/b', + 'cb', + 'cb/e', + 'cb/e/f', + 'symlink', + 'symlink/a', + 'symlink/a/b', + 'symlink/a/b/c', + 'x', + 'z', + ], + 'a', + ], + [ + '**', + ['abc{def,fed}/*'], + [ + 'abcdef', + 'abcdef/g/h', + 'abcfed', + 'abcfed/g/h', + 'b', + 'b/c', + 'b/c/d', + 'bc', + 'bc/e', + 'bc/e/f', + 'c', + 'c/d', + 'c/d/c', + 'c/d/c/b', + 'cb', + 'cb/e', + 'cb/e/f', + 'symlink', + 'symlink/a', + 'symlink/a/b', + 'symlink/a/b/c', + 'x', + 'z', + ], + 'a', + ], + ['c/**', ['c/*'], ['c', 'c/d/c', 'c/d/c/b'], 'a'], + ['a/c/**', ['a/c/*'], ['a/c', 'a/c/d/c', 'a/c/d/c/b']], + ['a/c/**', ['a/c/**', 'a/c/*', 'a/c/*/c'], []], + ['a/**/.y', ['a/x/**'], ['a/z/.y']], + ['a/**/.y', ['a/x/**'], ['a/z/.y'], { dot: true }], + ['a/**/b', ['a/x/**'], ['a/b', 'a/c/d/c/b', 'a/symlink/a/b']], + [ + 'a/**/b', + ['a/x/**'], + ['a/b', 'a/c/d/c/b', 'a/symlink/a/b', 'a/z/.y/b'], + { dot: true }, + ], + ['*/.abcdef', 'a/**', []], + ['a/*/.y/b', 'a/x/**', ['a/z/.y/b']], ] process.chdir(__dirname + '/fixtures') @@ -47,13 +311,10 @@ cases.forEach(function (c, i) { var expect = c[2].sort() var opt = c[3] var name = i + ' ' + pattern + ' ' + JSON.stringify(ignore) - if (typeof opt === 'string') - opt = { cwd: opt } + if (typeof opt === 'string') opt = { cwd: opt } - if (opt) - name += ' ' + JSON.stringify(opt) - else - opt = {} + if (opt) name += ' ' + JSON.stringify(opt) + else opt = {} var matches = [] @@ -61,8 +322,7 @@ cases.forEach(function (c, i) { test(name, function (t) { glob(pattern, opt, function (er, res) { - if (er) - throw er + if (er) throw er if (process.platform === 'win32') { expect = expect.filter(function (f) { @@ -93,9 +353,8 @@ test('race condition', function (t) { ignore: ignore, nonull: nonull, } - if (cwd) - opt.cwd = cwd - var expect = ignore ? [] : [ 'fixtures/a' ] + if (cwd) opt.cwd = cwd + var expect = ignore ? [] : ['fixtures/a'] t.test(JSON.stringify(opt), function (t) { t.plan(2) t.same(glob.sync(pattern, opt), expect) diff --git a/test/mark.ts b/test/mark.ts index e10564fd..0dbb2775 100644 --- a/test/mark.ts +++ b/test/mark.ts @@ -1,23 +1,27 @@ -require("./global-leakage.js") -var test = require("tap").test +require('./global-leakage.js') +var test = require('tap').test var glob = require('../') process.chdir(__dirname + '/fixtures') // expose timing issues var lag = 5 -glob.Glob.prototype._stat = function(o) { return function(f, cb) { - var args = arguments - setTimeout(function() { - o.call(this, f, cb) - }.bind(this), lag += 5) -}}(glob.Glob.prototype._stat) +glob.Glob.prototype._stat = (function (o) { + return function (f, cb) { + var args = arguments + setTimeout( + function () { + o.call(this, f, cb) + }.bind(this), + (lag += 5) + ) + } +})(glob.Glob.prototype._stat) test('mark with cwd', function (t) { var pattern = '*/*' var opt = { mark: true, cwd: 'a' } glob(pattern, opt, function (er, res) { - if (er) - throw er + if (er) throw er var expect = [ 'abcdef/g/', @@ -28,8 +32,7 @@ test('mark with cwd', function (t) { 'cb/e/', ].sort() - if (process.platform !== 'win32') - expect.push('symlink/a/') + if (process.platform !== 'win32') expect.push('symlink/a/') t.same(res.sort(), expect) t.same(glob.sync(pattern, opt).sort(), expect) @@ -37,28 +40,28 @@ test('mark with cwd', function (t) { }) }) -test("mark, with **", function (t) { +test('mark, with **', function (t) { var pattern = 'a/*b*/**' var opt = { mark: true } glob(pattern, opt, function (er, results) { - if (er) - throw er - var expect = - [ 'a/abcdef/', - 'a/abcdef/g/', - 'a/abcdef/g/h', - 'a/abcfed/', - 'a/abcfed/g/', - 'a/abcfed/g/h', - 'a/b/', - 'a/b/c/', - 'a/b/c/d', - 'a/bc/', - 'a/bc/e/', - 'a/bc/e/f', - 'a/cb/', - 'a/cb/e/', - 'a/cb/e/f' ] + if (er) throw er + var expect = [ + 'a/abcdef/', + 'a/abcdef/g/', + 'a/abcdef/g/h', + 'a/abcfed/', + 'a/abcfed/g/', + 'a/abcfed/g/h', + 'a/b/', + 'a/b/c/', + 'a/b/c/d', + 'a/bc/', + 'a/bc/e/', + 'a/bc/e/f', + 'a/cb/', + 'a/cb/e/', + 'a/cb/e/f', + ] t.same(results, expect) t.same(glob.sync(pattern, opt), expect) @@ -66,135 +69,135 @@ test("mark, with **", function (t) { }) }) -test("mark, no / on pattern", function (t) { +test('mark, no / on pattern', function (t) { var pattern = 'a/*' var opt = { mark: true } glob(pattern, opt, function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/', - 'a/x/', - 'a/z/' ] - - if (process.platform !== "win32") - expect.push('a/symlink/') + if (er) throw er + var expect = [ + 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/', + 'a/x/', + 'a/z/', + ] + + if (process.platform !== 'win32') expect.push('a/symlink/') expect = expect.sort() t.same(results, expect) t.same(glob.sync(pattern, opt), expect) t.end() - }).on('match', function(m) { + }).on('match', function (m) { t.match(m, /\/$/) }) }) -test("mark=false, no / on pattern", function (t) { +test('mark=false, no / on pattern', function (t) { var pattern = 'a/*' var opt = null glob(pattern, opt, function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef', - 'a/abcfed', - 'a/b', - 'a/bc', - 'a/c', - 'a/cb', - 'a/x', - 'a/z' ] - - if (process.platform !== "win32") - expect.push('a/symlink') + if (er) throw er + var expect = [ + 'a/abcdef', + 'a/abcfed', + 'a/b', + 'a/bc', + 'a/c', + 'a/cb', + 'a/x', + 'a/z', + ] + + if (process.platform !== 'win32') expect.push('a/symlink') expect = expect.sort() t.same(results, expect) t.same(glob.sync(pattern, opt), expect) t.end() - }).on('match', function(m) { + }).on('match', function (m) { t.match(m, /[^\/]$/) }) }) -test("mark=true, / on pattern", function (t) { +test('mark=true, / on pattern', function (t) { var pattern = 'a/*/' var opt = { mark: true } glob(pattern, opt, function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/', - 'a/x/', - 'a/z/' ] - - if (process.platform !== "win32") - expect.push('a/symlink/') + if (er) throw er + var expect = [ + 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/', + 'a/x/', + 'a/z/', + ] + + if (process.platform !== 'win32') expect.push('a/symlink/') expect = expect.sort() t.same(results, expect) t.same(glob.sync(pattern, opt), expect) t.end() - }).on('match', function(m) { + }).on('match', function (m) { t.match(m, /\/$/) }) }) -test("mark=false, / on pattern", function (t) { - var pattern = "a/*/" +test('mark=false, / on pattern', function (t) { + var pattern = 'a/*/' var opt = null glob(pattern, opt, function (er, results) { - if (er) - throw er - var expect = [ 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/', - 'a/x/', - 'a/z/' ] - if (process.platform !== "win32") - expect.push('a/symlink/') + if (er) throw er + var expect = [ + 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/', + 'a/x/', + 'a/z/', + ] + if (process.platform !== 'win32') expect.push('a/symlink/') expect = expect.sort() t.same(results, expect) t.same(glob.sync(pattern, opt), expect) t.end() - }).on('match', function(m) { + }).on('match', function (m) { t.match(m, /\/$/) }) }) -var cwd = process.cwd().replace(/[\/\\]+$/, '').replace(/\\/g, '/') -;[true,false].forEach(function (mark) { - ;[true,false].forEach(function (slash) { - test("cwd mark:" + mark + " slash:" + slash, function (t) { +var cwd = process + .cwd() + .replace(/[\/\\]+$/, '') + .replace(/\\/g, '/') +;[true, false].forEach(function (mark) { + ;[true, false].forEach(function (slash) { + test('cwd mark:' + mark + ' slash:' + slash, function (t) { var pattern = cwd + (slash ? '/' : '') - glob(pattern, {mark:mark}, function (er, results) { + glob(pattern, { mark: mark }, function (er, results) { t.equal(results.length, 1) var res = results[0].replace(/\\/g, '/') - var syncRes = glob.sync(pattern, {mark:mark}) + var syncRes = glob.sync(pattern, { mark: mark }) syncRes = syncRes[0].replace(/\\/g, '/') - if (slash || mark) - t.equal(res, cwd + '/') - else - t.equal(res.indexOf(cwd), 0) + if (slash || mark) t.equal(res, cwd + '/') + else t.equal(res.indexOf(cwd), 0) t.equal(syncRes, res, 'sync should match async') t.end() }) }) }) }) - diff --git a/test/match-base.ts b/test/match-base.ts index 051b5847..8291ad2a 100644 --- a/test/match-base.ts +++ b/test/match-base.ts @@ -4,11 +4,7 @@ var path = require('path') var fixtureDir = path.resolve(__dirname, 'fixtures') var pattern = 'a*' -var expect = [ - 'a', - 'a/abcdef', - 'a/abcfed', -] +var expect = ['a', 'a/abcdef', 'a/abcfed'] if (process.platform !== 'win32') expect.push('a/symlink/a', 'a/symlink/a/b/c/a') @@ -19,8 +15,7 @@ t.test('chdir', function (t) { t.same(glob.sync(pattern, { matchBase: true }), expect) t.same(glob(pattern, { matchBase: true, sync: true }), expect) glob(pattern, { matchBase: true }, function (er, res) { - if (er) - throw er + if (er) throw er t.same(res, expect) process.chdir(origCwd) t.end() @@ -29,10 +24,12 @@ t.test('chdir', function (t) { t.test('cwd', function (t) { t.same(glob.sync(pattern, { matchBase: true, cwd: fixtureDir }), expect) - t.same(glob(pattern, { matchBase: true, sync: true, cwd: fixtureDir }), expect) + t.same( + glob(pattern, { matchBase: true, sync: true, cwd: fixtureDir }), + expect + ) glob(pattern, { matchBase: true, cwd: fixtureDir }, function (er, res) { - if (er) - throw er + if (er) throw er t.same(res, expect) t.end() }) @@ -40,10 +37,10 @@ t.test('cwd', function (t) { t.test('noglobstar', function (t) { t.throws(function () { - glob(pattern, { matchBase:true, noglobstar: true }) + glob(pattern, { matchBase: true, noglobstar: true }) }) t.throws(function () { - glob.sync(pattern, { matchBase:true, noglobstar: true }) + glob.sync(pattern, { matchBase: true, noglobstar: true }) }) t.end() }) diff --git a/test/multiple-weird-error.ts b/test/multiple-weird-error.ts index 4a9e45ea..f53552b5 100644 --- a/test/multiple-weird-error.ts +++ b/test/multiple-weird-error.ts @@ -1,15 +1,19 @@ var t = require('tap') var fs = require('fs') -fs.readdir = function(path, cb) { cb(new Error('expected')) } +fs.readdir = function (path, cb) { + cb(new Error('expected')) +} var glob = require('../') // also test that silent:true is actually silent! -console.error = function () { throw 'SILENCE, INSECT!' } +console.error = function () { + throw 'SILENCE, INSECT!' +} t.plan(2) -glob('*', { silent: true }, function(err, files) { +glob('*', { silent: true }, function (err, files) { t.ok(err, 'got first error') }) -glob('*', { silent: true }, function(err, files) { +glob('*', { silent: true }, function (err, files) { t.ok(err, 'got second error') }) diff --git a/test/new-glob-optional-options.ts b/test/new-glob-optional-options.ts index 9dc29f54..a51786af 100644 --- a/test/new-glob-optional-options.ts +++ b/test/new-glob-optional-options.ts @@ -1,12 +1,12 @@ -require("./global-leakage.js") -var Glob = require('../glob.js').Glob; -var test = require('tap').test; +require('./global-leakage.js') +var Glob = require('../glob.js').Glob +var test = require('tap').test var f = __filename.replace(/\\/g, '/') test('new glob, with cb, and no options', function (t) { - new Glob(f, function(er, results) { - if (er) throw er; - t.same(results, [f]); - t.end(); - }); -}); + new Glob(f, function (er, results) { + if (er) throw er + t.same(results, [f]) + t.end() + }) +}) diff --git a/test/nocase-nomagic.ts b/test/nocase-nomagic.ts index 6bd46c60..7f99ecb9 100644 --- a/test/nocase-nomagic.ts +++ b/test/nocase-nomagic.ts @@ -1,7 +1,7 @@ -require("./global-leakage.js") +require('./global-leakage.js') var fs = require('fs') -var test = require('tap').test; -var glob = require('../'); +var test = require('tap').test +var glob = require('../') var cwd = process.cwd() var drive = 'c' @@ -9,7 +9,7 @@ if (/^[a-zA-Z]:[\\\/]/.test(cwd)) { drive = cwd.charAt(0).toLowerCase() } -test('mock fs', function(t) { +test('mock fs', function (t) { var stat = fs.stat var statSync = fs.statSync var readdir = fs.readdir @@ -18,20 +18,32 @@ test('mock fs', function(t) { function fakeStat(path) { var ret switch (path.toLowerCase().replace(/\\/g, '/')) { - case '/tmp': case '/tmp/': case drive+':\\tmp': case drive+':\\tmp\\': - ret = { isDirectory: function() { return true } } + case '/tmp': + case '/tmp/': + case drive + ':\\tmp': + case drive + ':\\tmp\\': + ret = { + isDirectory: function () { + return true + }, + } break - case '/tmp/a': case drive+':/tmp/a': - ret = { isDirectory: function() { return false } } + case '/tmp/a': + case drive + ':/tmp/a': + ret = { + isDirectory: function () { + return false + }, + } break } return ret } - fs.stat = function(path, cb) { - var f = fakeStat(path); + fs.stat = function (path, cb) { + var f = fakeStat(path) if (f) { - process.nextTick(function() { + process.nextTick(function () { cb(null, f) }) } else { @@ -39,33 +51,36 @@ test('mock fs', function(t) { } } - fs.statSync = function(path) { + fs.statSync = function (path) { return fakeStat(path) || statSync.call(fs, path) } function fakeReaddir(path) { var ret switch (path.toLowerCase().replace(/\\/g, '/')) { - case '/tmp': case '/tmp/': case drive+':/tmp': case drive+':/tmp/': - ret = [ 'a', 'A' ] + case '/tmp': + case '/tmp/': + case drive + ':/tmp': + case drive + ':/tmp/': + ret = ['a', 'A'] break - case '/': case drive+':/': + case '/': + case drive + ':/': ret = ['tmp', 'tMp', 'tMP', 'TMP'] } return ret } - fs.readdir = function(path, cb) { + fs.readdir = function (path, cb) { var f = fakeReaddir(path) if (f) - process.nextTick(function() { + process.nextTick(function () { cb(null, f) }) - else - readdir.call(fs, path, cb) + else readdir.call(fs, path, cb) } - fs.readdirSync = function(path) { + fs.readdirSync = function (path) { return fakeReaddir(path) || readdirSync.call(fs, path) } @@ -73,75 +88,83 @@ test('mock fs', function(t) { t.end() }) -test('nocase, nomagic', function(t) { +test('nocase, nomagic', function (t) { var n = 2 - var want = [ '/TMP/A', - '/TMP/a', - '/tMP/A', - '/tMP/a', - '/tMp/A', - '/tMp/a', - '/tmp/A', - '/tmp/a' ] - if(process.platform.match(/^win/)) { - want = want.map(function(p) { - return drive+':' + p + var want = [ + '/TMP/A', + '/TMP/a', + '/tMP/A', + '/tMP/a', + '/tMp/A', + '/tMp/a', + '/tmp/A', + '/tmp/a', + ] + if (process.platform.match(/^win/)) { + want = want.map(function (p) { + return drive + ':' + p }) } - glob('/tmp/a', { nocase: true }, function(er, res) { - if (er) - throw er + glob('/tmp/a', { nocase: true }, function (er, res) { + if (er) throw er if (process.platform.match(/^win/)) res = res.map(function (r) { - return r.replace(/\\/g, '/').replace(new RegExp('^' + drive + ':', 'i'), drive+':') + return r + .replace(/\\/g, '/') + .replace(new RegExp('^' + drive + ':', 'i'), drive + ':') }) t.same(res.sort(), want) if (--n === 0) t.end() }) - glob('/tmp/A', { nocase: true }, function(er, res) { - if (er) - throw er + glob('/tmp/A', { nocase: true }, function (er, res) { + if (er) throw er if (process.platform.match(/^win/)) res = res.map(function (r) { - return r.replace(/\\/g, '/').replace(new RegExp('^' + drive + ':', 'i'), drive+':') + return r + .replace(/\\/g, '/') + .replace(new RegExp('^' + drive + ':', 'i'), drive + ':') }) t.same(res.sort(), want) if (--n === 0) t.end() }) }) -test('nocase, with some magic', function(t) { +test('nocase, with some magic', function (t) { t.plan(2) - var want = [ '/TMP/A', - '/TMP/a', - '/tMP/A', - '/tMP/a', - '/tMp/A', - '/tMp/a', - '/tmp/A', - '/tmp/a' ] - if(process.platform.match(/^win/)) { - want = want.map(function(p) { + var want = [ + '/TMP/A', + '/TMP/a', + '/tMP/A', + '/tMP/a', + '/tMp/A', + '/tMp/a', + '/tmp/A', + '/tmp/a', + ] + if (process.platform.match(/^win/)) { + want = want.map(function (p) { return drive + ':' + p }) } - glob('/tmp/*', { nocase: true }, function(er, res) { - if (er) - throw er + glob('/tmp/*', { nocase: true }, function (er, res) { + if (er) throw er if (process.platform.match(/^win/)) { res = res.map(function (r) { - return r.replace(/\\/g, '/').replace(new RegExp('^' + drive + ':', 'i'), drive+':') + return r + .replace(/\\/g, '/') + .replace(new RegExp('^' + drive + ':', 'i'), drive + ':') }) } t.same(res.sort(), want) }) - glob('/tmp/*', { nocase: true }, function(er, res) { - if (er) - throw er + glob('/tmp/*', { nocase: true }, function (er, res) { + if (er) throw er if (process.platform.match(/^win/)) { res = res.map(function (r) { - return r.replace(/\\/g, '/').replace(new RegExp('^' + drive + ':', 'i'), drive+':') + return r + .replace(/\\/g, '/') + .replace(new RegExp('^' + drive + ':', 'i'), drive + ':') }) } t.same(res.sort(), want) diff --git a/test/nodir.ts b/test/nodir.ts index 01cc8b01..0f147ad5 100644 --- a/test/nodir.ts +++ b/test/nodir.ts @@ -1,12 +1,12 @@ -require("./global-leakage.js") -var test = require("tap").test +require('./global-leakage.js') +var test = require('tap').test var glob = require('../') var path = require('path') process.chdir(__dirname + '/fixtures') function cacheCheck(g, t) { // verify that path cache keys are all absolute - var caches = [ 'cache', 'statCache', 'symlinks' ] + var caches = ['cache', 'statCache', 'symlinks'] caches.forEach(function (c) { Object.keys(g[c]).forEach(function (p) { t.ok(path.isAbsolute(p), p + ' should be absolute') @@ -17,33 +17,26 @@ function cacheCheck(g, t) { // [pattern, options, expect] var root = path.resolve('a') var cases = [ - [ '*/**', { cwd: 'a' }, [ - 'abcdef/g/h', - 'abcfed/g/h', - 'b/c/d', - 'bc/e/f', - 'c/d/c/b', - 'cb/e/f' - ] + [ + '*/**', + { cwd: 'a' }, + ['abcdef/g/h', 'abcfed/g/h', 'b/c/d', 'bc/e/f', 'c/d/c/b', 'cb/e/f'], ], - [ 'a/*b*/**', {}, [ - 'a/abcdef/g/h', - 'a/abcfed/g/h', - 'a/b/c/d', - 'a/bc/e/f', - 'a/cb/e/f' - ] + [ + 'a/*b*/**', + {}, + ['a/abcdef/g/h', 'a/abcfed/g/h', 'a/b/c/d', 'a/bc/e/f', 'a/cb/e/f'], ], - [ 'a/*b*/**/', {}, [] ], - [ '*/*', { cwd: 'a' }, [] ], - [ '/*/*', { root: root }, [] ], - [ '/b*/**', { root: root }, [ - '/b/c/d', - '/bc/e/f' - ].map(function (m) { + ['a/*b*/**/', {}, []], + ['*/*', { cwd: 'a' }, []], + ['/*/*', { root: root }, []], + [ + '/b*/**', + { root: root }, + ['/b/c/d', '/bc/e/f'].map(function (m) { return path.join(root, m).replace(/\\/g, '/') - }) - ] + }), + ], ] cases.forEach(function (c) { @@ -55,8 +48,7 @@ cases.forEach(function (c) { var res = glob.sync(pattern, options).sort() t.same(res, expect, 'sync results') var g = glob(pattern, options, function (er, res) { - if (er) - throw er + if (er) throw er res = res.sort() t.same(res, expect, 'async results') cacheCheck(g, t) diff --git a/test/nonull.ts b/test/nonull.ts index 5f744e36..b09a2400 100644 --- a/test/nonull.ts +++ b/test/nonull.ts @@ -1,15 +1,15 @@ -require("./global-leakage.js") -var test = require("tap").test +require('./global-leakage.js') +var test = require('tap').test var glob = require('../') var common = require('../common.js') process.chdir(__dirname) // [pattern, options, expect] var cases = [ - [ 'a/*NOFILE*/**/', {}, [ 'a/*NOFILE*/**/' ] ], - [ '*/*', { cwd: 'NODIR' }, [ '*/*' ] ], - [ 'NOFILE', {}, [ 'NOFILE' ] ], - [ 'NOFILE', { cwd: 'NODIR' }, [ 'NOFILE' ] ] + ['a/*NOFILE*/**/', {}, ['a/*NOFILE*/**/']], + ['*/*', { cwd: 'NODIR' }, ['*/*']], + ['NOFILE', {}, ['NOFILE']], + ['NOFILE', { cwd: 'NODIR' }, ['NOFILE']], ] cases.forEach(function (c) { @@ -21,8 +21,7 @@ cases.forEach(function (c) { var res = glob.sync(pattern, options).sort() t.same(res, expect, 'sync results') var g = glob(pattern, options, function (er, res) { - if (er) - throw er + if (er) throw er res = res.sort() t.same(res, expect, 'async results') t.end() diff --git a/test/pause-resume.ts b/test/pause-resume.ts index 49f07f6f..eb2df0b1 100644 --- a/test/pause-resume.ts +++ b/test/pause-resume.ts @@ -1,63 +1,74 @@ -require("./global-leakage.js") +require('./global-leakage.js') // show that no match events happen while paused. -var tap = require("tap") -var child_process = require("child_process") +var tap = require('tap') +var child_process = require('child_process') // just some gnarly pattern with lots of matches -var pattern = "a/!(symlink)/**" -var bashResults = require("./bash-results.json") -var glob = require("../") +var pattern = 'a/!(symlink)/**' +var bashResults = require('./bash-results.json') +var glob = require('../') var Glob = glob.Glob -var path = require("path") +var path = require('path') process.chdir(__dirname + '/fixtures') -function alphasort (a, b) { +function alphasort(a, b) { a = a.toLowerCase() b = b.toLowerCase() return a > b ? 1 : a < b ? -1 : 0 } -function cleanResults (m) { +function cleanResults(m) { // normalize discrepancies in ordering, duplication, // and ending slashes. - return m.map(function (m) { - return m.replace(/\/+/g, "/").replace(/\/$/, "") - }).sort(alphasort).reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []).sort(alphasort).map(function (f) { - // de-windows - return (process.platform !== 'win32') ? f - : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') - }) + return m + .map(function (m) { + return m.replace(/\/+/g, '/').replace(/\/$/, '') + }) + .sort(alphasort) + .reduce(function (set, f) { + if (f !== set[set.length - 1]) set.push(f) + return set + }, []) + .sort(alphasort) + .map(function (f) { + // de-windows + return process.platform !== 'win32' + ? f + : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') + }) } var globResults = [] -tap.test("use a Glob object, and pause/resume it", function (t) { +tap.test('use a Glob object, and pause/resume it', function (t) { var g = new Glob(pattern) var paused = false var res = [] var expect = bashResults[pattern] - g.on("match", function (m) { - t.notOk(g.paused, "must not be paused") + g.on('match', function (m) { + t.notOk(g.paused, 'must not be paused') globResults.push(m) g.pause() - t.ok(g.paused, "must be paused") + t.ok(g.paused, 'must be paused') setTimeout(g.resume.bind(g), 10) }) - g.on("end", function (matches) { - t.pass("reached glob end") + g.on('end', function (matches) { + t.pass('reached glob end') globResults = cleanResults(globResults) matches = cleanResults(matches) - t.same(matches, globResults, - "end event matches should be the same as match events") + t.same( + matches, + globResults, + 'end event matches should be the same as match events' + ) - t.same(matches, expect, - "glob matches should be the same as bash results") + t.same( + matches, + expect, + 'glob matches should be the same as bash results' + ) t.end() }) }) - diff --git a/test/readme-issue.ts b/test/readme-issue.ts index 1c35ecb9..7f44f626 100644 --- a/test/readme-issue.ts +++ b/test/readme-issue.ts @@ -1,37 +1,36 @@ -require("./global-leakage.js") -var test = require("tap").test -var glob = require("../") +require('./global-leakage.js') +var test = require('tap').test +var glob = require('../') -var mkdirp = require("mkdirp") -var fs = require("fs") -var rimraf = require("rimraf") -var dir = __dirname + "/package" +var mkdirp = require('mkdirp') +var fs = require('fs') +var rimraf = require('rimraf') +var dir = __dirname + '/package' -test("setup", function (t) { +test('setup', function (t) { mkdirp.sync(dir) - fs.writeFileSync(dir + "/package.json", "{}", "ascii") - fs.writeFileSync(dir + "/README", "x", "ascii") - t.pass("setup done") + fs.writeFileSync(dir + '/package.json', '{}', 'ascii') + fs.writeFileSync(dir + '/README', 'x', 'ascii') + t.pass('setup done') t.end() }) -test("glob", function (t) { +test('glob', function (t) { var opt = { cwd: dir, nocase: true, - mark: true + mark: true, } - glob("README?(.*)", opt, function (er, files) { - if (er) - throw er - t.same(files, ["README"]) + glob('README?(.*)', opt, function (er, files) { + if (er) throw er + t.same(files, ['README']) t.end() }) }) -test("cleanup", function (t) { +test('cleanup', function (t) { rimraf.sync(dir) - t.pass("clean") + t.pass('clean') t.end() }) diff --git a/test/realpath.ts b/test/realpath.ts index 3be55569..09264d2e 100644 --- a/test/realpath.ts +++ b/test/realpath.ts @@ -12,58 +12,67 @@ if (process.platform === 'win32') // options, results // realpath:true set on each option var cases = [ - [ {}, - [ 'a/symlink', 'a/symlink/a', 'a/symlink/a/b' ] ], + [{}, ['a/symlink', 'a/symlink/a', 'a/symlink/a/b']], - [ { mark: true }, - [ 'a/symlink/', 'a/symlink/a/', 'a/symlink/a/b/' ] ], + [{ mark: true }, ['a/symlink/', 'a/symlink/a/', 'a/symlink/a/b/']], - [ { stat: true }, - [ 'a/symlink', 'a/symlink/a', 'a/symlink/a/b' ] ], + [{ stat: true }, ['a/symlink', 'a/symlink/a', 'a/symlink/a/b']], - [ { follow: true }, - [ 'a/symlink', 'a/symlink/a', 'a/symlink/a/b' ] ], + [{ follow: true }, ['a/symlink', 'a/symlink/a', 'a/symlink/a/b']], - [ { cwd: 'a' }, - [ 'symlink', 'symlink/a', 'symlink/a/b' ], - pattern.substr(2) ], + [ + { cwd: 'a' }, + ['symlink', 'symlink/a', 'symlink/a/b'], + pattern.substr(2), + ], - [ { cwd: 'a' }, - [], - 'no one here but us chickens' ], + [{ cwd: 'a' }, [], 'no one here but us chickens'], - [ { nonull: true }, - [ 'no one here but us chickens', - 'no one here but us sheep' ], - 'no one here but us {chickens,sheep}' ], + [ + { nonull: true }, + ['no one here but us chickens', 'no one here but us sheep'], + 'no one here but us {chickens,sheep}', + ], - [ { nounique: true }, - [ 'a/symlink', + [ + { nounique: true }, + [ + 'a/symlink', 'a/symlink', 'a/symlink', 'a/symlink/a', 'a/symlink/a', 'a/symlink/a/b', - 'a/symlink/a/b' ] ], + 'a/symlink/a/b', + ], + ], - [ { nounique: true, mark: true }, - [ 'a/symlink/', + [ + { nounique: true, mark: true }, + [ + 'a/symlink/', 'a/symlink/', 'a/symlink/', 'a/symlink/a/', 'a/symlink/a/', 'a/symlink/a/b/', - 'a/symlink/a/b/' ] ], + 'a/symlink/a/b/', + ], + ], - [ { nounique: true, mark: true, follow: true }, - [ 'a/symlink/', + [ + { nounique: true, mark: true, follow: true }, + [ + 'a/symlink/', 'a/symlink/', 'a/symlink/', 'a/symlink/a/', 'a/symlink/a/', 'a/symlink/a/', 'a/symlink/a/b/', - 'a/symlink/a/b/' ] ], + 'a/symlink/a/b/', + ], + ], ] cases.forEach(function (c) { @@ -84,8 +93,7 @@ cases.forEach(function (c) { var sync = glob.sync(p, opt) t.same(sync, expect, 'sync') glob(p, opt, function (er, async) { - if (er) - throw er + if (er) throw er t.same(async, expect, 'async') t.end() }) diff --git a/test/root-nomount.ts b/test/root-nomount.ts index 98943095..75d121e9 100644 --- a/test/root-nomount.ts +++ b/test/root-nomount.ts @@ -1,11 +1,11 @@ -require("./global-leakage.js") -var tap = require("tap") +require('./global-leakage.js') +var tap = require('tap') var glob = require('../') var path = require('path') function cacheCheck(g, t) { // verify that path cache keys are all absolute - var caches = [ 'cache', 'statCache', 'symlinks' ] + var caches = ['cache', 'statCache', 'symlinks'] caches.forEach(function (c) { Object.keys(g[c]).forEach(function (p) { t.ok(path.isAbsolute(p), p + ' should be absolute') @@ -15,32 +15,58 @@ function cacheCheck(g, t) { process.chdir(__dirname + '/fixtures') -tap.test("changing root and searching for /b*/**", function (t) { +tap.test('changing root and searching for /b*/**', function (t) { t.test('.', function (t) { - var g = glob('/b*/**', { root: '.', nomount: true }, function (er, matches) { - t.error(er) - t.same(matches, []) - cacheCheck(g, t) - t.end() - }) + var g = glob( + '/b*/**', + { root: '.', nomount: true }, + function (er, matches) { + t.error(er) + t.same(matches, []) + cacheCheck(g, t) + t.end() + } + ) }) t.test('a', function (t) { - var g = glob('/b*/**', { root: path.resolve('a'), nomount: true }, function (er, matches) { - t.error(er) - t.same(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) - cacheCheck(g, t) - t.end() - }) + var g = glob( + '/b*/**', + { root: path.resolve('a'), nomount: true }, + function (er, matches) { + t.error(er) + t.same(matches, [ + '/b', + '/b/c', + '/b/c/d', + '/bc', + '/bc/e', + '/bc/e/f', + ]) + cacheCheck(g, t) + t.end() + } + ) }) t.test('root=a, cwd=a/b', function (t) { - var g = glob('/b*/**', { root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) { - t.error(er) - t.same(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ]) - cacheCheck(g, t) - t.end() - }) + var g = glob( + '/b*/**', + { root: 'a', cwd: path.resolve('a/b'), nomount: true }, + function (er, matches) { + t.error(er) + t.same(matches, [ + '/b', + '/b/c', + '/b/c/d', + '/bc', + '/bc/e', + '/bc/e/f', + ]) + cacheCheck(g, t) + t.end() + } + ) }) t.end() diff --git a/test/root.ts b/test/root.ts index 1e4e75b9..60153537 100644 --- a/test/root.ts +++ b/test/root.ts @@ -1,5 +1,5 @@ -require("./global-leakage.js") -var t = require("tap") +require('./global-leakage.js') +var t = require('tap') process.chdir(__dirname + '/fixtures') @@ -8,7 +8,7 @@ var path = require('path') function cacheCheck(g, t) { // verify that path cache keys are all absolute - var caches = [ 'cache', 'statCache', 'symlinks' ] + var caches = ['cache', 'statCache', 'symlinks'] caches.forEach(function (c) { Object.keys(g[c]).forEach(function (p) { t.ok(path.isAbsolute(p), p + ' should be absolute') @@ -25,56 +25,85 @@ t.test('.', function (t) { }) }) - t.test('a', function (t) { - var g = glob('/b*/**', { root: path.resolve('a') }, function (er, matches) { - t.error(er) - var wanted = [ - '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' - ].map(function (m) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - }) + var g = glob( + '/b*/**', + { root: path.resolve('a') }, + function (er, matches) { + t.error(er) + var wanted = ['/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'].map( + function (m) { + return path.join(path.resolve('a'), m).replace(/\\/g, '/') + } + ) - t.same(matches, wanted) - cacheCheck(g, t) - t.end() - }) + t.same(matches, wanted) + cacheCheck(g, t) + t.end() + } + ) }) t.test('root=a, cwd=a/b', function (t) { - var g = glob('/b*/**', { root: 'a', cwd: path.resolve('a/b') }, function (er, matches) { - t.error(er) - t.same(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - })) - cacheCheck(g, t) - t.end() - }) + var g = glob( + '/b*/**', + { root: 'a', cwd: path.resolve('a/b') }, + function (er, matches) { + t.error(er) + t.same( + matches, + ['/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'].map(function ( + m + ) { + return path.join(path.resolve('a'), m).replace(/\\/g, '/') + }) + ) + cacheCheck(g, t) + t.end() + } + ) }) -t.test('combined with absolute option', function(t) { - var g = glob('/b*/**', { root: path.resolve('a'), absolute: true }, function (er, matches) { - t.error(er) - t.same(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - })) - cacheCheck(g, t) - t.end() - }) +t.test('combined with absolute option', function (t) { + var g = glob( + '/b*/**', + { root: path.resolve('a'), absolute: true }, + function (er, matches) { + t.error(er) + t.same( + matches, + ['/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'].map(function ( + m + ) { + return path.join(path.resolve('a'), m).replace(/\\/g, '/') + }) + ) + cacheCheck(g, t) + t.end() + } + ) }) -t.test('cwdAbs when root=a, absolute=true', function(t) { - var g = glob('/b*/**', { root: path.resolve('a'), absolute: true }, function (er, matches) { - t.error(er) - t.same(g.cwdAbs, process.cwd().replace(/\\/g, '/')) - t.end() - }) +t.test('cwdAbs when root=a, absolute=true', function (t) { + var g = glob( + '/b*/**', + { root: path.resolve('a'), absolute: true }, + function (er, matches) { + t.error(er) + t.same(g.cwdAbs, process.cwd().replace(/\\/g, '/')) + t.end() + } + ) }) -t.test('cwdAbs when root=a, absolute=true, cwd=__dirname', function(t) { - var g = glob('/b*/**', { root: path.resolve('a'), absolute: true, cwd: __dirname }, function (er, matches) { - t.error(er) - t.same(g.cwdAbs, __dirname.replace(/\\/g, '/')) - t.end() - }) +t.test('cwdAbs when root=a, absolute=true, cwd=__dirname', function (t) { + var g = glob( + '/b*/**', + { root: path.resolve('a'), absolute: true, cwd: __dirname }, + function (er, matches) { + t.error(er) + t.same(g.cwdAbs, __dirname.replace(/\\/g, '/')) + t.end() + } + ) }) diff --git a/test/slash-cwd.ts b/test/slash-cwd.ts index fc1f1b0e..f1771e09 100644 --- a/test/slash-cwd.ts +++ b/test/slash-cwd.ts @@ -3,7 +3,7 @@ var glob = require('../') var test = require('tap').test var pattern = '../{*.md,test}/' -var expect = [ '../test/' ] +var expect = ['../test/'] var cwd = __dirname var opt = { cwd: cwd } process.chdir(__dirname + '/..') @@ -12,8 +12,7 @@ test('slashes only match directories', function (t) { var sync = glob.sync(pattern, { cwd: cwd }) t.same(sync, expect, 'sync test') glob(pattern, { cwd: cwd }, function (er, async) { - if (er) - throw er + if (er) throw er t.same(async, expect, 'async test') t.end() }) diff --git a/test/stat.ts b/test/stat.ts index 3e5862a9..857a7315 100644 --- a/test/stat.ts +++ b/test/stat.ts @@ -1,33 +1,38 @@ -require("./global-leakage.js") +require('./global-leakage.js') var glob = require('../') var test = require('tap').test var path = require('path') var Stats = require('fs').Stats var dir = __dirname + '/fixtures' -test('stat all the things', function(t) { +test('stat all the things', function (t) { var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: dir }) var matches = [] - g.on('match', function(m) { + g.on('match', function (m) { matches.push(m) }) var stats = [] - g.on('stat', function(m, st) { + g.on('stat', function (m, st) { stats.push(m) t.ok(st instanceof Stats) }) - g.on('end', function(eof) { + g.on('end', function (eof) { stats = stats.sort() matches = matches.sort() eof = eof.sort() t.same(stats, matches) t.same(eof, matches) var cache = Object.keys(this.statCache) - t.same(cache.map(function (f) { - return path.relative(dir, f).replace(/\\/g, '/') - }).sort(), matches) + t.same( + cache + .map(function (f) { + return path.relative(dir, f).replace(/\\/g, '/') + }) + .sort(), + matches + ) - cache.forEach(function(c) { + cache.forEach(function (c) { t.equal(typeof this.statCache[c], 'object') }, this) diff --git a/test/sync-cb-throw.ts b/test/sync-cb-throw.ts index 911eedcc..007afc29 100644 --- a/test/sync-cb-throw.ts +++ b/test/sync-cb-throw.ts @@ -1,27 +1,27 @@ -require("./global-leakage.js") +require('./global-leakage.js') var test = require('tap').test var g = require('../') test('sync throws if provided callback', function (t) { t.throws(function () { - g('*', {sync:true}, function() {}) + g('*', { sync: true }, function () {}) }) t.throws(function () { - g.sync('*', function() {}) + g.sync('*', function () {}) }) t.throws(function () { - g.sync('*', {}, function() {}) + g.sync('*', {}, function () {}) }) t.throws(function () { - g.Glob('*', {sync:true}, function() {}) + g.Glob('*', { sync: true }, function () {}) }) t.throws(function () { - g.GlobSync('*', {}, function() {}) + g.GlobSync('*', {}, function () {}) }) t.throws(function () { - g.GlobSync('*', function() {}) + g.GlobSync('*', function () {}) }) t.throws(function () { @@ -42,5 +42,3 @@ test('sync throws if provided callback', function (t) { t.end() }) - - diff --git a/test/windows-paths-fs.ts b/test/windows-paths-fs.ts index 85ff9ab8..61bea54b 100644 --- a/test/windows-paths-fs.ts +++ b/test/windows-paths-fs.ts @@ -28,10 +28,11 @@ t.test('treat backslash as escape', async t => { } for (const [pattern, expect] of Object.entries(cases)) { t.test(pattern, t => { - const s = glob.sync(pattern, { cwd: dir }) + const s = glob + .sync(pattern, { cwd: dir }) .map(s => s.replace(/\\/g, '/')) t.strictSame(s, expect, 'sync') - glob(pattern, {cwd: dir}, (er, s) => { + glob(pattern, { cwd: dir }, (er, s) => { if (er) { throw er } @@ -45,7 +46,7 @@ t.test('treat backslash as escape', async t => { t.test('treat backslash as separator', async t => { Object.defineProperty(process, 'platform', { - value: 'win32' + value: 'win32', }) const cases = { 'a[x]b/y': [], @@ -54,10 +55,11 @@ t.test('treat backslash as separator', async t => { } for (const [pattern, expect] of Object.entries(cases)) { t.test(pattern, t => { - const s = glob.sync(pattern, { cwd: dir, windowsPathsNoEscape: true }) + const s = glob + .sync(pattern, { cwd: dir, windowsPathsNoEscape: true }) .map(s => s.replace(/\\/g, '/')) t.strictSame(s, expect, 'sync') - glob(pattern, {cwd: dir, windowsPathsNoEscape: true}, (er, s) => { + glob(pattern, { cwd: dir, windowsPathsNoEscape: true }, (er, s) => { if (er) { throw er } diff --git a/test/windows-paths-no-escape.ts b/test/windows-paths-no-escape.ts index 6a1bf1d9..dcff9645 100644 --- a/test/windows-paths-no-escape.ts +++ b/test/windows-paths-no-escape.ts @@ -2,7 +2,10 @@ const t = require('tap') const g = require('../') const platforms = ['win32', 'posix'] -const originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform') +const originalPlatform = Object.getOwnPropertyDescriptor( + process, + 'platform' +) for (const p of platforms) { t.test(p, t => { Object.defineProperty(process, 'platform', { @@ -27,17 +30,20 @@ for (const p of platforms) { noprocess: true, }) - t.strictSame([ - def.pattern, - nowinpath.pattern, - winpath.pattern, - winpathLegacy.pattern, - ], [ - '/a/b/c/x\\[a-b\\]y\\*', - '/a/b/c/x\\[a-b\\]y\\*', - '/a/b/c/x/[a-b/]y/*', - '/a/b/c/x/[a-b/]y/*', - ]) + t.strictSame( + [ + def.pattern, + nowinpath.pattern, + winpath.pattern, + winpathLegacy.pattern, + ], + [ + '/a/b/c/x\\[a-b\\]y\\*', + '/a/b/c/x\\[a-b\\]y\\*', + '/a/b/c/x/[a-b/]y/*', + '/a/b/c/x/[a-b/]y/*', + ] + ) t.end() }) } From edd85fa47bea2b2f394122b07a09b4966d6b42ae Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 16 Jan 2023 09:55:19 -0800 Subject: [PATCH 032/163] formatting, and more cwd and test cleanup --- .gitignore | 1 + examples/g.js | 13 +++++---- examples/usr-local.js | 10 +++---- package-lock.json | 34 ------------------------ package.json | 1 - src/has-magic.ts | 3 +++ src/walker.ts | 11 +++----- test/00-setup.ts | 13 +++++++++ test/error-callback.ts | 41 ----------------------------- test/follow.ts | 51 ++++++++++++++---------------------- test/globstar-match-memfs.ts | 30 --------------------- test/globstar-match.ts | 18 ------------- test/has-magic.ts | 27 +++++-------------- 13 files changed, 60 insertions(+), 193 deletions(-) delete mode 100644 test/error-callback.ts delete mode 100644 test/globstar-match-memfs.ts delete mode 100644 test/globstar-match.ts diff --git a/.gitignore b/.gitignore index e50a7792..f8dfd121 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /nyc_output /.nyc_output /coverage +/test/fixtures diff --git a/examples/g.js b/examples/g.js index be122df0..c8537166 100644 --- a/examples/g.js +++ b/examples/g.js @@ -1,9 +1,12 @@ -var Glob = require("../").Glob +var Glob = require('../').Glob -var pattern = "test/a/**/[cg]/../[cg]" +var pattern = 'test/a/**/[cg]/../[cg]' console.log(pattern) -var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) { - console.log("matches", matches) +var mg = new Glob(pattern, { mark: true, sync: true }, function ( + er, + matches +) { + console.log('matches', matches) }) -console.log("after") +console.log('after') diff --git a/examples/usr-local.js b/examples/usr-local.js index 327a425e..1e99c6d1 100644 --- a/examples/usr-local.js +++ b/examples/usr-local.js @@ -1,9 +1,9 @@ -var Glob = require("../").Glob +var Glob = require('../').Glob -var pattern = "{./*/*,/*,/usr/local/*}" +var pattern = '{./*/*,/*,/usr/local/*}' console.log(pattern) -var mg = new Glob(pattern, {mark: true}, function (er, matches) { - console.log("matches", matches) +var mg = new Glob(pattern, { mark: true }, function (er, matches) { + console.log('matches', matches) }) -console.log("after") +console.log('after') diff --git a/package-lock.json b/package-lock.json index 67d8ba79..e9dfca7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,6 @@ "@types/tap": "^15.0.7", "c8": "^7.12.0", "eslint-config-prettier": "^8.6.0", - "memfs": "^3.2.0", "mkdirp": "^2.0.0", "prettier": "^2.8.3", "rimraf": "^4.0.7", @@ -2084,12 +2083,6 @@ "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", "dev": true }, - "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", - "dev": true - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2891,18 +2884,6 @@ "node": ">= 12" } }, - "node_modules/memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", - "dev": true, - "dependencies": { - "fs-monkey": "1.0.3" - }, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/mime-db": { "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", @@ -7909,12 +7890,6 @@ "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", "dev": true }, - "fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", - "dev": true - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -8535,15 +8510,6 @@ "integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==", "dev": true }, - "memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", - "dev": true, - "requires": { - "fs-monkey": "1.0.3" - } - }, "mime-db": { "version": "1.51.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", diff --git a/package.json b/package.json index addcfc72..9fb3a1a8 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ "@types/tap": "^15.0.7", "c8": "^7.12.0", "eslint-config-prettier": "^8.6.0", - "memfs": "^3.2.0", "mkdirp": "^2.0.0", "prettier": "^2.8.3", "rimraf": "^4.0.7", diff --git a/src/has-magic.ts b/src/has-magic.ts index 775ca38a..aa39aec7 100644 --- a/src/has-magic.ts +++ b/src/has-magic.ts @@ -9,6 +9,9 @@ export const hasMagic = ( } return pattern.some(p => { const g = new Glob(p, options) + if (g.matchSet.length === 0) { + return false + } if (g.matchSet.length > 1) { return true } diff --git a/src/walker.ts b/src/walker.ts index a884fb09..8381ece3 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -106,12 +106,12 @@ export class GlobWalker { // a pattern like / (or c:/ on windows) can only match the root const setAbs = typeof first === 'string' && - (first === '' || + ((first === '' && rest.length) || (process.platform === 'win32' && /^[a-z]:$/i.test(first))) if (setAbs) { - this.pattern = rest as Pattern - this.cwd = '/' - this.path = '/' + this.pattern = rest.length ? (rest as Pattern) : [''] + this.cwd = first || '/' + this.path = first || '/' } while ( this.pattern.length > 1 && @@ -267,9 +267,6 @@ export class GlobWalker { } for (const e of entries) { - if (!e.name) { - console.error('wat?', this.start, e) - } if (!this.dot && e.name.startsWith('.')) { continue } diff --git a/test/00-setup.ts b/test/00-setup.ts index 6a9228d9..b4aee586 100644 --- a/test/00-setup.ts +++ b/test/00-setup.ts @@ -127,6 +127,19 @@ export const bashResults:{ [path: string]: string[] } = ${ await writeFile(fname, data) }) + t.test('formatting', t => { + const c = spawn( + 'prettier', + ['--write', resolve(__dirname, 'bash-results.ts')], + { stdio: ['ignore', 2, 2] } + ) + c.on('close', (code, signal) => { + t.equal(code, 0, 'code') + t.equal(signal, null, 'signal') + t.end() + }) + }) + function cleanResults(m: string[]) { // normalize discrepancies in ordering, duplication, // and ending slashes. diff --git a/test/error-callback.ts b/test/error-callback.ts deleted file mode 100644 index dcedea00..00000000 --- a/test/error-callback.ts +++ /dev/null @@ -1,41 +0,0 @@ -require('./global-leakage.js') -var logCalled -var console_error = console.error -console.error = function () { - logCalled = [].slice.call(arguments, 0) - console.error = console_error -} - -var fs = require('fs') -var test = require('tap').test -var glob = require('../') - -test('mock fs', function (t) { - fs.readdir = function (path, cb) { - process.nextTick(function () { - cb(new Error('mock fs.readdir error')) - }) - } - t.pass('mocked') - t.end() -}) - -test('error callback', function (t) { - glob('*', function (err, res) { - t.ok(err, 'expecting mock error') - t.end() - }) -}) - -test('called console.error for weird error', function (t) { - // Need a setTimeout, since the console.error happens directly AFTER - // the emit('error') with the error. - setTimeout(function () { - t.has( - logCalled, - ['glob error', { message: 'mock fs.readdir error' }], - 'got expected error printed to console.error' - ) - t.end() - }) -}) diff --git a/test/follow.ts b/test/follow.ts index 56e1c7e5..bdc18d58 100644 --- a/test/follow.ts +++ b/test/follow.ts @@ -1,38 +1,25 @@ -var glob = require('../') -var test = require('tap').test - -process.chdir(__dirname + '/fixtures') +import t from 'tap' +import glob from '../' if (process.platform === 'win32') { - require('tap').plan(0, 'skip on windows') - return + t.plan(0, 'skip on windows') + process.exit(0) } -test('follow symlinks', function (t) { - var pattern = 'a/symlink/**' - var syncNoFollow = glob.sync(pattern).sort() - var syncFollow = glob.sync(pattern, { follow: true }).sort() - glob(pattern, function (er, res) { - if (er) throw er - var noFollow = res.sort() - glob(pattern, { follow: true }, function (er, res) { - if (er) throw er - var follow = res.sort() +process.chdir(__dirname + '/fixtures') - t.same(follow, syncFollow, 'sync and async follow should match') - t.same( - noFollow, - syncNoFollow, - 'sync and async noFollow should match' - ) - var long = 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c' - t.not(follow.indexOf(long), -1, 'follow should have long entry') - t.not( - syncFollow.indexOf(long), - -1, - 'syncFollow should have long entry' - ) - t.end() - }) - }) +t.test('follow symlinks', async t => { + const pattern = 'a/symlink/**' + const syncNoFollow = glob.sync(pattern) + const syncFollow = glob.sync(pattern, { follow: true }) + const [noFollow, follow] = await Promise.all([ + glob(pattern), + glob(pattern, { follow: true }), + ]) + t.same(follow, syncFollow, 'sync and async follow should match') + t.same(noFollow, syncNoFollow, 'sync and async noFollow should match') + var long = 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c' + t.ok(follow.includes(long), 'follow should have long entry') + t.ok(syncFollow.includes(long), 'syncFollow should have long entry') + t.end() }) diff --git a/test/globstar-match-memfs.ts b/test/globstar-match-memfs.ts deleted file mode 100644 index 3598fb2c..00000000 --- a/test/globstar-match-memfs.ts +++ /dev/null @@ -1,30 +0,0 @@ -require('./global-leakage.js') -var memfs = require('memfs') -var test = require('tap').test -var glob = require('../glob.js') - -test('fs-compatible file system can be used', function (t) { - var volJson = { - './text1.txt': 'abc', - './javascript.js': 'abc', - './text2.txt': 'abc', - } - var vol = memfs.Volume.fromJSON(volJson, '/some/directory') - glob('*.txt', { cwd: '/some/directory', fs: vol }, function (e, f) { - t.equal(e, null, 'no error') - t.same(f, ['text1.txt', 'text2.txt'], 'matched txt files') - t.end() - }) -}) - -test('fs-compatible file system can be used with glob.sync', function (t) { - var volJson = { - './text1.txt': 'abc', - './javascript.js': 'abc', - './text2.txt': 'abc', - } - var vol = memfs.Volume.fromJSON(volJson, '/some/directory') - var f = glob.sync('*.txt', { cwd: '/some/directory', fs: vol }) - t.same(f, ['text1.txt', 'text2.txt'], 'matched txt files') - t.end() -}) diff --git a/test/globstar-match.ts b/test/globstar-match.ts deleted file mode 100644 index b3b517fb..00000000 --- a/test/globstar-match.ts +++ /dev/null @@ -1,18 +0,0 @@ -require('./global-leakage.js') -var Glob = require('../glob.js').Glob -var test = require('tap').test - -test('globstar should not have dupe matches', function (t) { - var pattern = 'a/**/[gh]' - var g = new Glob(pattern, { cwd: __dirname }) - var matches = [] - g.on('match', function (m) { - matches.push(m) - }) - g.on('end', function (set) { - matches = matches.sort() - set = set.sort() - t.same(matches, set, 'should have same set of matches') - t.end() - }) -}) diff --git a/test/has-magic.ts b/test/has-magic.ts index 78e0d13e..5fc9ed45 100644 --- a/test/has-magic.ts +++ b/test/has-magic.ts @@ -1,30 +1,18 @@ -require('./global-leakage.js') -var test = require('tap').test -var glob = require('../') +import t from 'tap' +import glob from '../' process.chdir(__dirname) -glob.GlobSync.prototype._process = glob.Glob.prototype._process = - function () { - throw new Error('should not call _process() in these tests') - } - -test('create glob object without processing', function (t) { - t.ok(glob('a', { noprocess: true }) instanceof glob.Glob) - t.ok(glob.GlobSync('a', { noprocess: true }) instanceof glob.GlobSync) - t.end() -}) - -test('non-string pattern is evil magic', function (t) { - var patterns = [0, null, 12, { x: 1 }, undefined, /x/, NaN] +t.test('non-string pattern is evil magic', async t => { + const patterns = [0, null, 12, { x: 1 }, undefined, /x/, NaN] patterns.forEach(function (p) { - t.throws('' + p, function () { + t.throws(function () { + // @ts-expect-error glob.hasMagic(p) }) }) - t.end() }) -test('detect magic in glob patterns', function (t) { +t.test('detect magic in glob patterns', async t => { t.notOk(glob.hasMagic(''), "no magic in ''") t.notOk(glob.hasMagic('a/b/c/'), 'no magic a/b/c/') t.ok(glob.hasMagic('a/b/**/'), 'magic in a/b/**/') @@ -39,5 +27,4 @@ test('detect magic in glob patterns', function (t) { glob.hasMagic('{a,b}', { nobrace: true }), 'magic in {a,b} nobrace:true' ) - t.end() }) From d77081a0789ca3a0caca2e68bc6e79b4451c274a Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 16 Jan 2023 10:16:32 -0800 Subject: [PATCH 033/163] fix and document some Ignore behavior fixes --- changelog.md | 14 ++++++- src/ignore.ts | 2 +- test/ignore.ts | 109 ++++++++++++++++++++++++------------------------- 3 files changed, 66 insertions(+), 59 deletions(-) diff --git a/changelog.md b/changelog.md index cd2f9d2b..a770d51b 100644 --- a/changelog.md +++ b/changelog.md @@ -9,8 +9,11 @@ This is a full rewrite. - Removed `root` option and mounting behavior. - Removed `stat` option. It's slow and pointless. (Could bring back easily if there's demand.) -- Simplified `cwd` behavior. Now it just serves as the initial - argument to `fs.readdir`. +- Simplified `cwd` behavior so it is far less magical, and relies + less on platform-specific absolute path representations. +- More efficient handling for absolute patterns. (That is, + patterns that start with `/` on any platform, or start with a + drive letter on Windows.) - Removed all stat calls, in favor of using `withFileTypes:true` with `fs.readdir()`. - Consolidated all caching to a single object that only caches @@ -25,6 +28,13 @@ This is a full rewrite. - Removed `fs` option. This module only operates on the real filesystem. (Could bring back if there's demand for it.) - Only support node 16 and higher. +- When `{nonull:true}` is set, and an `ignore` pattern causes all + entries to be ignored, then the pattern is returned, as it + would be if no matches were found. This _may_ result in the + surprising situation where a pattern like `x/y/z` is returned + even, even though the ignore value like `x/**` would have + excluded it. However, _not_ returning anything when + `nonull:true` is set, is arguably a worse contract violation. ## 8.1 diff --git a/src/ignore.ts b/src/ignore.ts index 17069620..37f4b461 100644 --- a/src/ignore.ts +++ b/src/ignore.ts @@ -15,7 +15,7 @@ export class Ignore { for (const pattern of patterns) { this.matchers.push(new Minimatch(pattern, { dot: true })) if (pattern.substring(pattern.length - 3) === '/**') { - const gp = pattern.slice(0, pattern.length - 3) + const gp = pattern.replace(/(\/\*\*)+$/, '') this.gmatchers.push(new Minimatch(gp, { dot: true })) } } diff --git a/test/ignore.ts b/test/ignore.ts index 0f265591..f4b1fd40 100644 --- a/test/ignore.ts +++ b/test/ignore.ts @@ -1,12 +1,17 @@ -require('./global-leakage.js') // Ignore option test // Show that glob ignores results matching pattern on ignore option -var glob = require('../glob.js') -var test = require('tap').test +import t from 'tap' +import glob, { GlobOptions } from '../' // [pattern, ignore, expect, opt (object) or cwd (string)] -var cases = [ +type Case = [ + pattern: string, + ignore: null | string | string[], + expect: string[], + optOrCwd?: GlobOptions | string | undefined +] +const cases: Case[] = [ [ '*', null, @@ -305,66 +310,58 @@ var cases = [ process.chdir(__dirname + '/fixtures') -cases.forEach(function (c, i) { - var pattern = c[0] - var ignore = c[1] - var expect = c[2].sort() - var opt = c[3] - var name = i + ' ' + pattern + ' ' + JSON.stringify(ignore) - if (typeof opt === 'string') opt = { cwd: opt } - - if (opt) name += ' ' + JSON.stringify(opt) - else opt = {} - - var matches = [] +for (const c of cases) { + const [pattern, ignore, ex, optCwd] = c + const expect = ( + process.platform === 'win32' + ? ex.filter(e => !/\bsymlink\b/.test(e)) + : ex + ).sort() + expect.sort() + const opt: GlobOptions = + (typeof optCwd === 'string' ? { cwd: optCwd } : optCwd) || {} + const name = `p=${pattern} i=${JSON.stringify(ignore)} ${JSON.stringify( + opt + )}` - opt.ignore = ignore + if (ignore) { + opt.ignore = ignore + } - test(name, function (t) { - glob(pattern, opt, function (er, res) { - if (er) throw er - - if (process.platform === 'win32') { - expect = expect.filter(function (f) { - return !/\bsymlink\b/.test(f) - }) - } - - t.same(res.sort(), expect, 'async') - t.same(matches.sort(), expect, 'match events') - res = glob.sync(pattern, opt) - t.same(res.sort(), expect, 'sync') - t.end() - }).on('match', function (p) { - matches.push(p) - }) + t.test(name, async t => { + const res = await glob(pattern, opt) + t.same(res.sort(), expect, 'async') + const resSync = glob.sync(pattern, opt) + t.same(resSync.sort(), expect, 'sync') }) -}) +} -test('race condition', function (t) { +t.test('race condition', async t => { process.chdir(__dirname) var pattern = 'fixtures/*' - ;[true, false].forEach(function (dot) { - ;['fixtures/**', null].forEach(function (ignore) { - ;[false, true].forEach(function (nonull) { - ;[false, process.cwd(), '.'].forEach(function (cwd) { - var opt = { - dot: dot, - ignore: ignore, - nonull: nonull, + t.jobs = 64 + for (const dot of [true, false]) { + for (const ignore of ['fixtures/**', undefined]) { + for (const nonull of [true, false]) { + for (const cwd of [undefined, process.cwd(), '.']) { + const opt: GlobOptions = { + dot, + ignore, + nonull, } if (cwd) opt.cwd = cwd - var expect = ignore ? [] : ['fixtures/a'] - t.test(JSON.stringify(opt), function (t) { + const expect = ignore + ? nonull + ? ['fixtures/*'] + : [] + : ['fixtures/a'] + t.test(JSON.stringify(opt), async t => { t.plan(2) - t.same(glob.sync(pattern, opt), expect) - glob(pattern, opt).on('end', function (res) { - t.same(res, expect) - }) + t.same(glob.sync(pattern, opt).sort(), expect) + t.same((await glob(pattern, opt)).sort(), expect) }) - }) - }) - }) - }) - t.end() + } + } + } + } }) From cf01af4e41276f98c29aa3c13d18be1d44407522 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 16 Jan 2023 11:20:17 -0800 Subject: [PATCH 034/163] more tests, fix marking when cwd is set --- src/walker.ts | 12 +- test/mark.ts | 321 +++++++++++++----------------- test/match-base.ts | 52 ++--- test/multiple-weird-error.ts | 19 -- test/new-glob-optional-options.ts | 18 +- test/nocase-nomagic.ts | 251 +++++++++++------------ 6 files changed, 286 insertions(+), 387 deletions(-) delete mode 100644 test/multiple-weird-error.ts diff --git a/src/walker.ts b/src/walker.ts index 8381ece3..d603f813 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -156,7 +156,7 @@ export class GlobWalker { return [] } if (this.nodir || this.mark) { - const isDir = this.rd.isDirectory(p) + const isDir = this.rd.isDirectory(this.join(p, this.cwd)) if (isDir) { if (this.nodir) { return [] @@ -222,12 +222,12 @@ export class GlobWalker { return this.ignore ? flat.filter(f => !this.ignore?.ignored(f)) : flat } - join(p: string) { - return this.path === '' + join(p: string, base: string = this.path) { + return base === '' ? p - : this.path === '/' - ? `${this.path}${p}` - : `${this.path}/${p}` + : base.substring(base.length - 1) === '/' + ? `${base}${p}` + : `${base}/${p}` } getChildrenString( diff --git a/test/mark.ts b/test/mark.ts index 0dbb2775..c715ffbb 100644 --- a/test/mark.ts +++ b/test/mark.ts @@ -1,203 +1,162 @@ -require('./global-leakage.js') -var test = require('tap').test -var glob = require('../') +import t from 'tap' +import glob from '../' process.chdir(__dirname + '/fixtures') -// expose timing issues -var lag = 5 -glob.Glob.prototype._stat = (function (o) { - return function (f, cb) { - var args = arguments - setTimeout( - function () { - o.call(this, f, cb) - }.bind(this), - (lag += 5) - ) +t.test('mark with cwd', async t => { + const pattern = '*/*' + const opt = { mark: true, cwd: 'a' } + const expect = [ + 'abcdef/g/', + 'abcfed/g/', + 'b/c/', + 'bc/e/', + 'c/d/', + 'cb/e/', + ].sort() + + const res = await glob(pattern, opt) + if (process.platform !== 'win32') { + expect.push('symlink/a/') } -})(glob.Glob.prototype._stat) -test('mark with cwd', function (t) { - var pattern = '*/*' - var opt = { mark: true, cwd: 'a' } - glob(pattern, opt, function (er, res) { - if (er) throw er - - var expect = [ - 'abcdef/g/', - 'abcfed/g/', - 'b/c/', - 'bc/e/', - 'c/d/', - 'cb/e/', - ].sort() - - if (process.platform !== 'win32') expect.push('symlink/a/') - - t.same(res.sort(), expect) - t.same(glob.sync(pattern, opt).sort(), expect) - t.end() - }) + t.same(res.sort(), expect) + t.same(glob.sync(pattern, opt).sort(), expect) }) -test('mark, with **', function (t) { - var pattern = 'a/*b*/**' - var opt = { mark: true } - glob(pattern, opt, function (er, results) { - if (er) throw er - var expect = [ - 'a/abcdef/', - 'a/abcdef/g/', - 'a/abcdef/g/h', - 'a/abcfed/', - 'a/abcfed/g/', - 'a/abcfed/g/h', - 'a/b/', - 'a/b/c/', - 'a/b/c/d', - 'a/bc/', - 'a/bc/e/', - 'a/bc/e/f', - 'a/cb/', - 'a/cb/e/', - 'a/cb/e/f', - ] - - t.same(results, expect) - t.same(glob.sync(pattern, opt), expect) - t.end() - }) +t.test('mark, with **', async t => { + const pattern = 'a/*b*/**' + const opt = { mark: true } + const expect = [ + 'a/abcdef/', + 'a/abcdef/g/', + 'a/abcdef/g/h', + 'a/abcfed/', + 'a/abcfed/g/', + 'a/abcfed/g/h', + 'a/b/', + 'a/b/c/', + 'a/b/c/d', + 'a/bc/', + 'a/bc/e/', + 'a/bc/e/f', + 'a/cb/', + 'a/cb/e/', + 'a/cb/e/f', + ] + + const results = await glob(pattern, opt) + t.same(results, expect) + t.same(glob.sync(pattern, opt), expect) }) -test('mark, no / on pattern', function (t) { - var pattern = 'a/*' - var opt = { mark: true } - glob(pattern, opt, function (er, results) { - if (er) throw er - var expect = [ - 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/', - 'a/x/', - 'a/z/', - ] - - if (process.platform !== 'win32') expect.push('a/symlink/') - - expect = expect.sort() - - t.same(results, expect) - t.same(glob.sync(pattern, opt), expect) - t.end() - }).on('match', function (m) { - t.match(m, /\/$/) - }) +t.test('mark, no / on pattern', async t => { + const pattern = 'a/*' + const opt = { mark: true } + const expect = [ + 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/', + 'a/x/', + 'a/z/', + ] + if (process.platform !== 'win32') { + expect.push('a/symlink/') + } + expect.sort() + const results = await glob(pattern, opt) + t.same(results, expect) + t.same(glob.sync(pattern, opt), expect) }) -test('mark=false, no / on pattern', function (t) { - var pattern = 'a/*' - var opt = null - glob(pattern, opt, function (er, results) { - if (er) throw er - var expect = [ - 'a/abcdef', - 'a/abcfed', - 'a/b', - 'a/bc', - 'a/c', - 'a/cb', - 'a/x', - 'a/z', - ] - - if (process.platform !== 'win32') expect.push('a/symlink') - - expect = expect.sort() +t.test('mark=false, no / on pattern', async t => { + const pattern = 'a/*' + const expect = [ + 'a/abcdef', + 'a/abcfed', + 'a/b', + 'a/bc', + 'a/c', + 'a/cb', + 'a/x', + 'a/z', + ] + if (process.platform !== 'win32') { + expect.push('a/symlink') + } + expect.sort() + const results = await glob(pattern) - t.same(results, expect) - t.same(glob.sync(pattern, opt), expect) - t.end() - }).on('match', function (m) { - t.match(m, /[^\/]$/) - }) + t.same(results, expect) + t.same(glob.sync(pattern), expect) }) -test('mark=true, / on pattern', function (t) { - var pattern = 'a/*/' - var opt = { mark: true } - glob(pattern, opt, function (er, results) { - if (er) throw er - var expect = [ - 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/', - 'a/x/', - 'a/z/', - ] - - if (process.platform !== 'win32') expect.push('a/symlink/') - - expect = expect.sort() - - t.same(results, expect) - t.same(glob.sync(pattern, opt), expect) - t.end() - }).on('match', function (m) { - t.match(m, /\/$/) - }) +t.test('mark=true, / on pattern', async t => { + const pattern = 'a/*/' + const opt = { mark: true } + const expect = [ + 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/', + 'a/x/', + 'a/z/', + ] + + if (process.platform !== 'win32') { + expect.push('a/symlink/') + } + expect.sort() + const results = await glob(pattern, opt) + t.same(results, expect) + t.same(glob.sync(pattern, opt), expect) }) -test('mark=false, / on pattern', function (t) { - var pattern = 'a/*/' - var opt = null - glob(pattern, opt, function (er, results) { - if (er) throw er - var expect = [ - 'a/abcdef/', - 'a/abcfed/', - 'a/b/', - 'a/bc/', - 'a/c/', - 'a/cb/', - 'a/x/', - 'a/z/', - ] - if (process.platform !== 'win32') expect.push('a/symlink/') - - expect = expect.sort() +t.test('mark=false, / on pattern', async t => { + const pattern = 'a/*/' + const expect = [ + 'a/abcdef/', + 'a/abcfed/', + 'a/b/', + 'a/bc/', + 'a/c/', + 'a/cb/', + 'a/x/', + 'a/z/', + ] + if (process.platform !== 'win32') { + expect.push('a/symlink/') + } + expect.sort() - t.same(results, expect) - t.same(glob.sync(pattern, opt), expect) - t.end() - }).on('match', function (m) { - t.match(m, /\/$/) - }) + const results = await glob(pattern) + t.same(results, expect) + t.same(glob.sync(pattern), expect) }) -var cwd = process +const cwd = process .cwd() .replace(/[\/\\]+$/, '') .replace(/\\/g, '/') -;[true, false].forEach(function (mark) { - ;[true, false].forEach(function (slash) { - test('cwd mark:' + mark + ' slash:' + slash, function (t) { - var pattern = cwd + (slash ? '/' : '') - glob(pattern, { mark: mark }, function (er, results) { - t.equal(results.length, 1) - var res = results[0].replace(/\\/g, '/') - var syncRes = glob.sync(pattern, { mark: mark }) - syncRes = syncRes[0].replace(/\\/g, '/') - if (slash || mark) t.equal(res, cwd + '/') - else t.equal(res.indexOf(cwd), 0) - t.equal(syncRes, res, 'sync should match async') - t.end() - }) +for (const mark of [true, false]) { + for (const slash of [true, false]) { + t.test('cwd mark:' + mark + ' slash:' + slash, async t => { + const pattern = cwd + (slash ? '/' : '') + const results = await glob(pattern, { mark }) + t.equal(results.length, 1) + const res = results[0].replace(/\\/g, '/') + const syncResults = glob.sync(pattern, { mark: mark }) + const syncRes = syncResults[0].replace(/\\/g, '/') + if (slash || mark) { + t.equal(res, cwd + '/') + } else { + t.equal(res.indexOf(cwd), 0) + } + t.equal(syncRes, res, 'sync should match async') }) - }) -}) + } +} diff --git a/test/match-base.ts b/test/match-base.ts index 8291ad2a..632034f8 100644 --- a/test/match-base.ts +++ b/test/match-base.ts @@ -1,46 +1,32 @@ -var t = require('tap') -var glob = require('../') -var path = require('path') -var fixtureDir = path.resolve(__dirname, 'fixtures') +import t from 'tap' +import glob from '../' -var pattern = 'a*' -var expect = ['a', 'a/abcdef', 'a/abcfed'] +import { resolve } from 'path' -if (process.platform !== 'win32') +const fixtureDir = resolve(__dirname, 'fixtures') + +const pattern = 'a*' +const expect = ['a', 'a/abcdef', 'a/abcfed'] + +if (process.platform !== 'win32') { expect.push('a/symlink/a', 'a/symlink/a/b/c/a') +} -t.test('chdir', function (t) { - var origCwd = process.cwd() +t.test('chdir', async t => { + const origCwd = process.cwd() process.chdir(fixtureDir) t.same(glob.sync(pattern, { matchBase: true }), expect) - t.same(glob(pattern, { matchBase: true, sync: true }), expect) - glob(pattern, { matchBase: true }, function (er, res) { - if (er) throw er - t.same(res, expect) - process.chdir(origCwd) - t.end() - }) + t.same(await glob(pattern, { matchBase: true }), expect) + process.chdir(origCwd) }) -t.test('cwd', function (t) { +t.test('cwd', async t => { t.same(glob.sync(pattern, { matchBase: true, cwd: fixtureDir }), expect) - t.same( - glob(pattern, { matchBase: true, sync: true, cwd: fixtureDir }), - expect - ) - glob(pattern, { matchBase: true, cwd: fixtureDir }, function (er, res) { - if (er) throw er - t.same(res, expect) - t.end() - }) + t.same(await glob(pattern, { matchBase: true, cwd: fixtureDir }), expect) }) -t.test('noglobstar', function (t) { - t.throws(function () { - glob(pattern, { matchBase: true, noglobstar: true }) - }) - t.throws(function () { - glob.sync(pattern, { matchBase: true, noglobstar: true }) - }) +t.test('noglobstar', async t => { + t.rejects(glob(pattern, { matchBase: true, noglobstar: true })) + t.throws(() => glob.sync(pattern, { matchBase: true, noglobstar: true })) t.end() }) diff --git a/test/multiple-weird-error.ts b/test/multiple-weird-error.ts deleted file mode 100644 index f53552b5..00000000 --- a/test/multiple-weird-error.ts +++ /dev/null @@ -1,19 +0,0 @@ -var t = require('tap') -var fs = require('fs') -fs.readdir = function (path, cb) { - cb(new Error('expected')) -} -var glob = require('../') - -// also test that silent:true is actually silent! -console.error = function () { - throw 'SILENCE, INSECT!' -} - -t.plan(2) -glob('*', { silent: true }, function (err, files) { - t.ok(err, 'got first error') -}) -glob('*', { silent: true }, function (err, files) { - t.ok(err, 'got second error') -}) diff --git a/test/new-glob-optional-options.ts b/test/new-glob-optional-options.ts index a51786af..a8055a56 100644 --- a/test/new-glob-optional-options.ts +++ b/test/new-glob-optional-options.ts @@ -1,12 +1,10 @@ -require('./global-leakage.js') -var Glob = require('../glob.js').Glob -var test = require('tap').test -var f = __filename.replace(/\\/g, '/') +import t from 'tap' +import { Glob } from '../' +const f = __filename.replace(/\\/g, '/') -test('new glob, with cb, and no options', function (t) { - new Glob(f, function (er, results) { - if (er) throw er - t.same(results, [f]) - t.end() - }) +t.test('new glob, with cb, and no options', async t => { + const gs = new Glob(f) + t.same(gs.processSync(), [f]) + const g = new Glob(f) + t.same(await g.process(), [f]) }) diff --git a/test/nocase-nomagic.ts b/test/nocase-nomagic.ts index 7f99ecb9..3b617845 100644 --- a/test/nocase-nomagic.ts +++ b/test/nocase-nomagic.ts @@ -1,96 +1,92 @@ -require('./global-leakage.js') -var fs = require('fs') -var test = require('tap').test -var glob = require('../') +import * as fs from 'fs' +import t from 'tap' -var cwd = process.cwd() -var drive = 'c' -if (/^[a-zA-Z]:[\\\/]/.test(cwd)) { - drive = cwd.charAt(0).toLowerCase() -} - -test('mock fs', function (t) { - var stat = fs.stat - var statSync = fs.statSync - var readdir = fs.readdir - var readdirSync = fs.readdirSync +const cwd = process.cwd() +const drive = /^[a-zA-Z]:[\\\/]/.test(cwd) + ? cwd.charAt(0).toLowerCase() + : 'c' - function fakeStat(path) { - var ret - switch (path.toLowerCase().replace(/\\/g, '/')) { - case '/tmp': - case '/tmp/': - case drive + ':\\tmp': - case drive + ':\\tmp\\': - ret = { - isDirectory: function () { - return true - }, - } - break - case '/tmp/a': - case drive + ':/tmp/a': - ret = { - isDirectory: function () { - return false - }, - } - break - } - return ret +const fakeStat = ( + path: string +): { isDirectory: () => boolean; isSymbolicLink: () => boolean } => { + let ret: { isDirectory: () => boolean; isSymbolicLink: () => false } + switch (path.toLowerCase().replace(/\\/g, '/')) { + case '/tmp': + case '/tmp/': + case drive + ':/tmp': + case drive + ':/tmp/': + ret = { + isSymbolicLink: () => false, + isDirectory: () => true, + } + break + case '/tmp/a': + case drive + ':/tmp/a': + ret = { + isSymbolicLink: () => false, + isDirectory: () => false, + } + break + default: + throw new Error('invalid: ' + path) } + return ret +} - fs.stat = function (path, cb) { - var f = fakeStat(path) - if (f) { - process.nextTick(function () { - cb(null, f) - }) - } else { - stat.call(fs, path, cb) - } - } +const join = (r: string, p: string) => + r === '/' ? `${r}${p}` : `${r}/${p}` - fs.statSync = function (path) { - return fakeStat(path) || statSync.call(fs, path) +function fakeReaddir(path: string) { + let ret: string[] + switch (path.toLowerCase().replace(/\\/g, '/')) { + case '/tmp': + case '/tmp/': + case drive + ':/tmp': + case drive + ':/tmp/': + ret = ['a', 'A'] + break + case '/': + case drive + ':': + case drive + ':/': + ret = ['tMp', 'tmp', 'tMP', 'TMP'] + break + default: + throw new Error('not mocked') } + return ret.map(name => ({ name, ...fakeStat(join(path, name)) })) +} - function fakeReaddir(path) { - var ret - switch (path.toLowerCase().replace(/\\/g, '/')) { - case '/tmp': - case '/tmp/': - case drive + ':/tmp': - case drive + ':/tmp/': - ret = ['a', 'A'] - break - case '/': - case drive + ':/': - ret = ['tmp', 'tMp', 'tMP', 'TMP'] +const mockFs = { + ...fs, + readdir: ( + path: string, + _options: { withFileTypes: true }, + cb: ( + er: null | NodeJS.ErrnoException, + entries?: ReturnType + ) => void + ) => { + try { + const f = fakeReaddir(path) + process.nextTick(() => cb(null, f)) + } catch (_) { + fs.readdir(path, { withFileTypes: true }, cb) } - return ret - } + }, - fs.readdir = function (path, cb) { - var f = fakeReaddir(path) - if (f) - process.nextTick(function () { - cb(null, f) - }) - else readdir.call(fs, path, cb) - } - - fs.readdirSync = function (path) { - return fakeReaddir(path) || readdirSync.call(fs, path) - } + readdirSync: (path: string, _options?: { withFileTypes: true }) => { + try { + return fakeReaddir(path) + } catch (_) { + return fs.readdirSync(path, { withFileTypes: true }) + } + }, +} - t.pass('mocked') - t.end() -}) +const { glob } = t.mock('../dist/cjs/index.js', { fs: mockFs }) -test('nocase, nomagic', function (t) { - var n = 2 - var want = [ +t.test('nocase, nomagic', async t => { + const raw = [ '/TMP/A', '/TMP/a', '/tMP/A', @@ -100,38 +96,28 @@ test('nocase, nomagic', function (t) { '/tmp/A', '/tmp/a', ] - if (process.platform.match(/^win/)) { - want = want.map(function (p) { - return drive + ':' + p + const want = + process.platform === 'win32' ? raw.map(p => drive + ':' + p) : raw + + await Promise.all( + ['/tmp/a', '/TmP/A'].map(async pattern => { + const rawRes: string[] = await glob(pattern, { nocase: true }) + const g = new glob.Glob(pattern, { nocase: true }) + const res = + process.platform === 'win32' + ? rawRes.map(r => + r + .replace(/\\/g, '/') + .replace(new RegExp('^' + drive + ':', 'i'), drive + ':') + ) + : rawRes + t.same(res.sort(), want, pattern) }) - } - glob('/tmp/a', { nocase: true }, function (er, res) { - if (er) throw er - if (process.platform.match(/^win/)) - res = res.map(function (r) { - return r - .replace(/\\/g, '/') - .replace(new RegExp('^' + drive + ':', 'i'), drive + ':') - }) - t.same(res.sort(), want) - if (--n === 0) t.end() - }) - glob('/tmp/A', { nocase: true }, function (er, res) { - if (er) throw er - if (process.platform.match(/^win/)) - res = res.map(function (r) { - return r - .replace(/\\/g, '/') - .replace(new RegExp('^' + drive + ':', 'i'), drive + ':') - }) - t.same(res.sort(), want) - if (--n === 0) t.end() - }) + ) }) -test('nocase, with some magic', function (t) { - t.plan(2) - var want = [ +t.test('nocase, with some magic', async t => { + const raw = [ '/TMP/A', '/TMP/a', '/tMP/A', @@ -141,32 +127,21 @@ test('nocase, with some magic', function (t) { '/tmp/A', '/tmp/a', ] - if (process.platform.match(/^win/)) { - want = want.map(function (p) { - return drive + ':' + p - }) - } + const want = + process.platform === 'win32' ? raw.map(p => drive + ':' + p) : raw - glob('/tmp/*', { nocase: true }, function (er, res) { - if (er) throw er - if (process.platform.match(/^win/)) { - res = res.map(function (r) { - return r - .replace(/\\/g, '/') - .replace(new RegExp('^' + drive + ':', 'i'), drive + ':') - }) - } - t.same(res.sort(), want) - }) - glob('/tmp/*', { nocase: true }, function (er, res) { - if (er) throw er - if (process.platform.match(/^win/)) { - res = res.map(function (r) { - return r - .replace(/\\/g, '/') - .replace(new RegExp('^' + drive + ':', 'i'), drive + ':') - }) - } - t.same(res.sort(), want) - }) + await Promise.all( + ['/tmp/*', '/tMp/*'].map(async pattern => { + const resRaw: string[] = glob.sync(pattern, { nocase: true }) + const res = + process.platform === 'win32' + ? resRaw.map(r => + r + .replace(/\\/g, '/') + .replace(new RegExp('^' + drive + ':', 'i'), drive + ':') + ) + : resRaw + t.same(res.sort(), want) + }) + ) }) From 9c3ec00e38a6c0a04c7ec6c8ba9d8a39bc93cd91 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 16 Jan 2023 16:40:09 -0800 Subject: [PATCH 035/163] delete some now irrelevant tests --- test/pause-resume.ts | 74 ---------------------------- test/root-nomount.ts | 73 ---------------------------- test/root.ts | 109 ------------------------------------------ test/stat.ts | 41 ---------------- test/sync-cb-throw.ts | 44 ----------------- 5 files changed, 341 deletions(-) delete mode 100644 test/pause-resume.ts delete mode 100644 test/root-nomount.ts delete mode 100644 test/root.ts delete mode 100644 test/stat.ts delete mode 100644 test/sync-cb-throw.ts diff --git a/test/pause-resume.ts b/test/pause-resume.ts deleted file mode 100644 index eb2df0b1..00000000 --- a/test/pause-resume.ts +++ /dev/null @@ -1,74 +0,0 @@ -require('./global-leakage.js') -// show that no match events happen while paused. -var tap = require('tap') -var child_process = require('child_process') -// just some gnarly pattern with lots of matches -var pattern = 'a/!(symlink)/**' -var bashResults = require('./bash-results.json') -var glob = require('../') -var Glob = glob.Glob -var path = require('path') - -process.chdir(__dirname + '/fixtures') - -function alphasort(a, b) { - a = a.toLowerCase() - b = b.toLowerCase() - return a > b ? 1 : a < b ? -1 : 0 -} - -function cleanResults(m) { - // normalize discrepancies in ordering, duplication, - // and ending slashes. - return m - .map(function (m) { - return m.replace(/\/+/g, '/').replace(/\/$/, '') - }) - .sort(alphasort) - .reduce(function (set, f) { - if (f !== set[set.length - 1]) set.push(f) - return set - }, []) - .sort(alphasort) - .map(function (f) { - // de-windows - return process.platform !== 'win32' - ? f - : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/') - }) -} - -var globResults = [] -tap.test('use a Glob object, and pause/resume it', function (t) { - var g = new Glob(pattern) - var paused = false - var res = [] - var expect = bashResults[pattern] - - g.on('match', function (m) { - t.notOk(g.paused, 'must not be paused') - globResults.push(m) - g.pause() - t.ok(g.paused, 'must be paused') - setTimeout(g.resume.bind(g), 10) - }) - - g.on('end', function (matches) { - t.pass('reached glob end') - globResults = cleanResults(globResults) - matches = cleanResults(matches) - t.same( - matches, - globResults, - 'end event matches should be the same as match events' - ) - - t.same( - matches, - expect, - 'glob matches should be the same as bash results' - ) - - t.end() - }) -}) diff --git a/test/root-nomount.ts b/test/root-nomount.ts deleted file mode 100644 index 75d121e9..00000000 --- a/test/root-nomount.ts +++ /dev/null @@ -1,73 +0,0 @@ -require('./global-leakage.js') -var tap = require('tap') -var glob = require('../') -var path = require('path') - -function cacheCheck(g, t) { - // verify that path cache keys are all absolute - var caches = ['cache', 'statCache', 'symlinks'] - caches.forEach(function (c) { - Object.keys(g[c]).forEach(function (p) { - t.ok(path.isAbsolute(p), p + ' should be absolute') - }) - }) -} - -process.chdir(__dirname + '/fixtures') - -tap.test('changing root and searching for /b*/**', function (t) { - t.test('.', function (t) { - var g = glob( - '/b*/**', - { root: '.', nomount: true }, - function (er, matches) { - t.error(er) - t.same(matches, []) - cacheCheck(g, t) - t.end() - } - ) - }) - - t.test('a', function (t) { - var g = glob( - '/b*/**', - { root: path.resolve('a'), nomount: true }, - function (er, matches) { - t.error(er) - t.same(matches, [ - '/b', - '/b/c', - '/b/c/d', - '/bc', - '/bc/e', - '/bc/e/f', - ]) - cacheCheck(g, t) - t.end() - } - ) - }) - - t.test('root=a, cwd=a/b', function (t) { - var g = glob( - '/b*/**', - { root: 'a', cwd: path.resolve('a/b'), nomount: true }, - function (er, matches) { - t.error(er) - t.same(matches, [ - '/b', - '/b/c', - '/b/c/d', - '/bc', - '/bc/e', - '/bc/e/f', - ]) - cacheCheck(g, t) - t.end() - } - ) - }) - - t.end() -}) diff --git a/test/root.ts b/test/root.ts deleted file mode 100644 index 60153537..00000000 --- a/test/root.ts +++ /dev/null @@ -1,109 +0,0 @@ -require('./global-leakage.js') -var t = require('tap') - -process.chdir(__dirname + '/fixtures') - -var glob = require('../') -var path = require('path') - -function cacheCheck(g, t) { - // verify that path cache keys are all absolute - var caches = ['cache', 'statCache', 'symlinks'] - caches.forEach(function (c) { - Object.keys(g[c]).forEach(function (p) { - t.ok(path.isAbsolute(p), p + ' should be absolute') - }) - }) -} - -t.test('.', function (t) { - var g = glob('/b*/**', { root: '.' }, function (er, matches) { - t.error(er) - t.same(matches, []) - cacheCheck(g, t) - t.end() - }) -}) - -t.test('a', function (t) { - var g = glob( - '/b*/**', - { root: path.resolve('a') }, - function (er, matches) { - t.error(er) - var wanted = ['/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'].map( - function (m) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - } - ) - - t.same(matches, wanted) - cacheCheck(g, t) - t.end() - } - ) -}) - -t.test('root=a, cwd=a/b', function (t) { - var g = glob( - '/b*/**', - { root: 'a', cwd: path.resolve('a/b') }, - function (er, matches) { - t.error(er) - t.same( - matches, - ['/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'].map(function ( - m - ) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - }) - ) - cacheCheck(g, t) - t.end() - } - ) -}) - -t.test('combined with absolute option', function (t) { - var g = glob( - '/b*/**', - { root: path.resolve('a'), absolute: true }, - function (er, matches) { - t.error(er) - t.same( - matches, - ['/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'].map(function ( - m - ) { - return path.join(path.resolve('a'), m).replace(/\\/g, '/') - }) - ) - cacheCheck(g, t) - t.end() - } - ) -}) - -t.test('cwdAbs when root=a, absolute=true', function (t) { - var g = glob( - '/b*/**', - { root: path.resolve('a'), absolute: true }, - function (er, matches) { - t.error(er) - t.same(g.cwdAbs, process.cwd().replace(/\\/g, '/')) - t.end() - } - ) -}) - -t.test('cwdAbs when root=a, absolute=true, cwd=__dirname', function (t) { - var g = glob( - '/b*/**', - { root: path.resolve('a'), absolute: true, cwd: __dirname }, - function (er, matches) { - t.error(er) - t.same(g.cwdAbs, __dirname.replace(/\\/g, '/')) - t.end() - } - ) -}) diff --git a/test/stat.ts b/test/stat.ts deleted file mode 100644 index 857a7315..00000000 --- a/test/stat.ts +++ /dev/null @@ -1,41 +0,0 @@ -require('./global-leakage.js') -var glob = require('../') -var test = require('tap').test -var path = require('path') -var Stats = require('fs').Stats -var dir = __dirname + '/fixtures' - -test('stat all the things', function (t) { - var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: dir }) - var matches = [] - g.on('match', function (m) { - matches.push(m) - }) - var stats = [] - g.on('stat', function (m, st) { - stats.push(m) - t.ok(st instanceof Stats) - }) - g.on('end', function (eof) { - stats = stats.sort() - matches = matches.sort() - eof = eof.sort() - t.same(stats, matches) - t.same(eof, matches) - var cache = Object.keys(this.statCache) - t.same( - cache - .map(function (f) { - return path.relative(dir, f).replace(/\\/g, '/') - }) - .sort(), - matches - ) - - cache.forEach(function (c) { - t.equal(typeof this.statCache[c], 'object') - }, this) - - t.end() - }) -}) diff --git a/test/sync-cb-throw.ts b/test/sync-cb-throw.ts deleted file mode 100644 index 007afc29..00000000 --- a/test/sync-cb-throw.ts +++ /dev/null @@ -1,44 +0,0 @@ -require('./global-leakage.js') -var test = require('tap').test -var g = require('../') -test('sync throws if provided callback', function (t) { - t.throws(function () { - g('*', { sync: true }, function () {}) - }) - t.throws(function () { - g.sync('*', function () {}) - }) - t.throws(function () { - g.sync('*', {}, function () {}) - }) - - t.throws(function () { - g.Glob('*', { sync: true }, function () {}) - }) - - t.throws(function () { - g.GlobSync('*', {}, function () {}) - }) - - t.throws(function () { - g.GlobSync('*', function () {}) - }) - - t.throws(function () { - g.GlobSync() - }) - - t.throws(function () { - g.sync() - }) - - t.throws(function () { - g() - }) - - t.throws(function () { - g.Glob() - }) - - t.end() -}) From 8d16dfe5ad0e41f58749434b3dd8f41d43c2483b Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 16 Jan 2023 17:34:40 -0800 Subject: [PATCH 036/163] hybrid module setup tweaks --- changelog.md | 3 +++ package.json | 14 +++++++++----- tsconfig-base.json | 1 - tsconfig-esm.json | 1 + tsconfig-cjs.json => tsconfig.json | 3 ++- 5 files changed, 15 insertions(+), 7 deletions(-) rename tsconfig-cjs.json => tsconfig.json (62%) diff --git a/changelog.md b/changelog.md index a770d51b..c0efedeb 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,9 @@ This is a full rewrite. - Promise API instead of callbacks. - Accept pattern as string or array of strings. - Hybrid module distribution. +- `module.exports` in CommonJS mode is an object, not a function. + Use the exported `default` or `glob` members to access the + default function export in CommonJS modes. - Full TypeScript support. - Removed `root` option and mounting behavior. - Removed `stat` option. It's slow and pointless. (Could bring diff --git a/package.json b/package.json index 9fb3a1a8..4aecabea 100644 --- a/package.json +++ b/package.json @@ -9,12 +9,16 @@ }, "main": "./dist/cjs/index.js", "module": "./dist/mjs/index.js", - "types": "./dist/cjs/index.d.ts", "exports": { ".": { - "types": "./dist/cjs/index.d.ts", - "import": "./dist/mjs/index.js", - "require": "./dist/cjs/index.js" + "import": { + "default": "./dist/mjs/index.js", + "types": "./dist/mjs/index.d.ts" + }, + "require": { + "default": "./dist/cjs/index.js", + "types": "./dist/cjs/index.d.ts" + } } }, "files": [ @@ -25,7 +29,7 @@ "postversion": "npm publish", "prepublishOnly": "git push origin --follow-tags", "preprepare": "rm -rf dist", - "prepare": "tsc -p tsconfig-cjs.json && tsc -p tsconfig-esm.json", + "prepare": "tsc -p tsconfig.json && tsc -p tsconfig-esm.json", "postprepare": "bash fixup.sh", "pretest": "npm run prepare", "presnap": "npm run prepare", diff --git a/tsconfig-base.json b/tsconfig-base.json index b72747bb..45872adc 100644 --- a/tsconfig-base.json +++ b/tsconfig-base.json @@ -6,7 +6,6 @@ "declaration": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, - "isolatedModules": true, "moduleResolution": "node", "resolveJsonModule": true, "skipLibCheck": true, diff --git a/tsconfig-esm.json b/tsconfig-esm.json index 9a571575..e8ccb836 100644 --- a/tsconfig-esm.json +++ b/tsconfig-esm.json @@ -1,5 +1,6 @@ { "extends": "./tsconfig-base.json", + "exclude": ["./test", "./tap-snapshots", "src/index-cjs.ts"], "compilerOptions": { "module": "esnext", "outDir": "dist/mjs" diff --git a/tsconfig-cjs.json b/tsconfig.json similarity index 62% rename from tsconfig-cjs.json rename to tsconfig.json index 7aae8118..13690021 100644 --- a/tsconfig-cjs.json +++ b/tsconfig.json @@ -2,6 +2,7 @@ "extends": "./tsconfig-base.json", "compilerOptions": { "module": "commonjs", - "outDir": "dist/cjs" + "outDir": "dist/cjs", + "moduleResolution": "Node" } } From d3b9bd1d954f2bdfbf43eb7cc7aeae5e69ba1e20 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 16 Jan 2023 17:35:00 -0800 Subject: [PATCH 037/163] fix more tests, interaction with realpath and cwd --- src/walker.ts | 16 +-- test/bash-comparison.ts | 2 +- test/broken-symlink.ts | 2 +- test/cwd-test.ts | 2 +- test/empty-set.ts | 2 +- test/follow.ts | 2 +- test/nodir.ts | 67 +++++------- test/nonull.ts | 32 +++--- test/readme-issue.ts | 37 +++---- test/realpath.ts | 174 +++++++++++++++++--------------- test/slash-cwd.ts | 24 ++--- test/windows-paths-fs.ts | 77 +++++++------- test/windows-paths-no-escape.ts | 29 +++--- 13 files changed, 227 insertions(+), 239 deletions(-) diff --git a/src/walker.ts b/src/walker.ts index d603f813..bee7a6d2 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -173,13 +173,14 @@ export class GlobWalker { if (!this.realpath && !this.absolute) { return p } + const pp = this.join(p, this.cwd) if (!this.realpath) { - return resolve(p) + return resolve(pp) } const rp: string = await new Promise(res => - realpath(p, (er, rp) => (er ? res(resolve(p)) : res(rp))) + realpath(pp, (er, rp) => (er ? res(resolve(pp)) : res(rp))) ) - this.rd.alias(rp, p) + this.rd.alias(rp, pp) return rp } @@ -187,16 +188,17 @@ export class GlobWalker { if (!this.realpath && !this.absolute) { return p } + const pp = this.join(p, this.cwd) if (!this.realpath) { - return resolve(p) + return resolve(pp) } let rp: string try { - rp = realpathSync(p) + rp = realpathSync(pp) } catch (_) { - rp = resolve(p) + rp = resolve(pp) } - this.rd.alias(rp, p) + this.rd.alias(rp, pp) return rp } diff --git a/test/bash-comparison.ts b/test/bash-comparison.ts index 5495e7b0..12fbcbe4 100644 --- a/test/bash-comparison.ts +++ b/test/bash-comparison.ts @@ -2,7 +2,7 @@ // show that it does the same thing by default as the shell. import { resolve } from 'path' import t from 'tap' -import glob from '../' +import { glob } from '../' import { bashResults } from './bash-results' const globs = Object.keys(bashResults) diff --git a/test/broken-symlink.ts b/test/broken-symlink.ts index 3cd7c2b9..797136e9 100644 --- a/test/broken-symlink.ts +++ b/test/broken-symlink.ts @@ -1,6 +1,6 @@ import { relative } from 'path' import t from 'tap' -import glob, { GlobOptions } from '../' +import { glob, GlobOptions } from '../' if (process.platform === 'win32') { t.plan(0, 'skip on windows') diff --git a/test/cwd-test.ts b/test/cwd-test.ts index 695a10ea..bf732279 100644 --- a/test/cwd-test.ts +++ b/test/cwd-test.ts @@ -1,6 +1,6 @@ import { join, resolve } from 'path' import t from 'tap' -import glob from '../' +import { glob } from '../' const origCwd = process.cwd() process.chdir(__dirname + '/fixtures') diff --git a/test/empty-set.ts b/test/empty-set.ts index 822a16e2..e6abe330 100644 --- a/test/empty-set.ts +++ b/test/empty-set.ts @@ -1,5 +1,5 @@ import t from 'tap' -import glob from '../' +import { glob } from '../' // Patterns that cannot match anything const patterns = [ diff --git a/test/follow.ts b/test/follow.ts index bdc18d58..53d377f6 100644 --- a/test/follow.ts +++ b/test/follow.ts @@ -1,5 +1,5 @@ import t from 'tap' -import glob from '../' +import { glob } from '../' if (process.platform === 'win32') { t.plan(0, 'skip on windows') diff --git a/test/nodir.ts b/test/nodir.ts index 0f147ad5..48722ee2 100644 --- a/test/nodir.ts +++ b/test/nodir.ts @@ -1,26 +1,23 @@ -require('./global-leakage.js') -var test = require('tap').test -var glob = require('../') -var path = require('path') +import { resolve } from 'path' +import t from 'tap' +import glob, { GlobOptions } from '../' process.chdir(__dirname + '/fixtures') -function cacheCheck(g, t) { - // verify that path cache keys are all absolute - var caches = ['cache', 'statCache', 'symlinks'] - caches.forEach(function (c) { - Object.keys(g[c]).forEach(function (p) { - t.ok(path.isAbsolute(p), p + ' should be absolute') - }) - }) -} - // [pattern, options, expect] -var root = path.resolve('a') -var cases = [ +const root = resolve('a') +const cases: [string, GlobOptions, string[]][] = [ [ '*/**', { cwd: 'a' }, - ['abcdef/g/h', 'abcfed/g/h', 'b/c/d', 'bc/e/f', 'c/d/c/b', 'cb/e/f'], + [ + 'abcdef/g/h', + 'abcfed/g/h', + 'b/c/d', + 'bc/e/f', + 'c/d/c/b', + 'cb/e/f', + 'symlink/a/b/c', + ], ], [ 'a/*b*/**', @@ -29,30 +26,20 @@ var cases = [ ], ['a/*b*/**/', {}, []], ['*/*', { cwd: 'a' }, []], - ['/*/*', { root: root }, []], - [ - '/b*/**', - { root: root }, - ['/b/c/d', '/bc/e/f'].map(function (m) { - return path.join(root, m).replace(/\\/g, '/') - }), - ], + ['*/*', { cwd: root }, []], ] -cases.forEach(function (c) { - var pattern = c[0] - var options = c[1] || {} +for (const [pattern, options, expectRaw] of cases) { options.nodir = true - var expect = c[2].sort() - test(pattern + ' ' + JSON.stringify(options), function (t) { - var res = glob.sync(pattern, options).sort() - t.same(res, expect, 'sync results') - var g = glob(pattern, options, function (er, res) { - if (er) throw er - res = res.sort() - t.same(res, expect, 'async results') - cacheCheck(g, t) - t.end() - }) + const expect = + process.platform === 'win32' + ? expectRaw.filter(e => !/\bsymlink\b/.test(e)) + : expectRaw + expect.sort() + if (process.platform !== 'win32') { + } + t.test(pattern + ' ' + JSON.stringify(options), async t => { + t.same(glob.sync(pattern, options).sort(), expect, 'sync results') + t.same((await glob(pattern, options)).sort(), expect, 'async results') }) -}) +} diff --git a/test/nonull.ts b/test/nonull.ts index b09a2400..ba08ae8e 100644 --- a/test/nonull.ts +++ b/test/nonull.ts @@ -1,30 +1,24 @@ -require('./global-leakage.js') -var test = require('tap').test -var glob = require('../') -var common = require('../common.js') +import t from 'tap' +import {glob, GlobOptions} from '../' process.chdir(__dirname) // [pattern, options, expect] -var cases = [ +const cases:[string, GlobOptions, string[]][] = [ ['a/*NOFILE*/**/', {}, ['a/*NOFILE*/**/']], ['*/*', { cwd: 'NODIR' }, ['*/*']], ['NOFILE', {}, ['NOFILE']], ['NOFILE', { cwd: 'NODIR' }, ['NOFILE']], + // this is the weird one, because a/b actually does exist, + // and we've said we want to ignore it, but also it's the pattern, + // and nonull is set, so nonull takes precedence. + ['a/b', { ignore: 'a/**' }, ['a/b']], ] -cases.forEach(function (c) { - var pattern = c[0] - var options = c[1] || {} +for (const [pattern, options, expect] of cases) { options.nonull = true - var expect = c[2].sort() - test(pattern + ' ' + JSON.stringify(options), function (t) { - var res = glob.sync(pattern, options).sort() - t.same(res, expect, 'sync results') - var g = glob(pattern, options, function (er, res) { - if (er) throw er - res = res.sort() - t.same(res, expect, 'async results') - t.end() - }) + expect.sort() + t.test(pattern + ' ' + JSON.stringify(options), async t => { + t.same(glob.sync(pattern, options).sort(), expect, 'sync results') + t.same((await glob(pattern, options)).sort(), expect, 'async results') }) -}) +} diff --git a/test/readme-issue.ts b/test/readme-issue.ts index 7f44f626..58843a36 100644 --- a/test/readme-issue.ts +++ b/test/readme-issue.ts @@ -1,36 +1,25 @@ -require('./global-leakage.js') -var test = require('tap').test -var glob = require('../') +import t from 'tap' +import glob from '../' -var mkdirp = require('mkdirp') -var fs = require('fs') -var rimraf = require('rimraf') -var dir = __dirname + '/package' +import { writeFileSync } from 'fs' +import mkdirp from 'mkdirp' +import rimraf from 'rimraf' +const dir = __dirname + '/package' -test('setup', function (t) { +t.before(() => { mkdirp.sync(dir) - fs.writeFileSync(dir + '/package.json', '{}', 'ascii') - fs.writeFileSync(dir + '/README', 'x', 'ascii') - t.pass('setup done') - t.end() + writeFileSync(dir + '/package.json', '{}', 'ascii') + writeFileSync(dir + '/README', 'x', 'ascii') }) -test('glob', function (t) { +t.teardown(() => rimraf.sync(dir)) + +t.test('glob', async t => { var opt = { cwd: dir, nocase: true, mark: true, } - glob('README?(.*)', opt, function (er, files) { - if (er) throw er - t.same(files, ['README']) - t.end() - }) -}) - -test('cleanup', function (t) { - rimraf.sync(dir) - t.pass('clean') - t.end() + t.same(await glob('README?(.*)', opt), ['README']) }) diff --git a/test/realpath.ts b/test/realpath.ts index 09264d2e..25e9f71c 100644 --- a/test/realpath.ts +++ b/test/realpath.ts @@ -1,101 +1,115 @@ -var glob = require('../') -var test = require('tap').test +import { resolve } from 'path' +import t from 'tap' +import glob, { GlobOptions } from '../' // pattern to find a bunch of duplicates -var pattern = 'a/symlink/{*,**/*/*/*,*/*/**,*/*/*/*/*/*}' -var path = require('path') -var fixtureDir = path.resolve(__dirname, 'fixtures') +const pattern = 'a/symlink/{*,**/*/*/*,*/*/**,*/*/*/*/*/*}' +const fixtureDir = resolve(__dirname, 'fixtures') process.chdir(fixtureDir) -if (process.platform === 'win32') - return require('tap').plan(0, 'skip on windows') +if (process.platform === 'win32') { + t.plan(0, 'skip on windows') +} else { + // options, results + // realpath:true set on each option -// options, results -// realpath:true set on each option -var cases = [ - [{}, ['a/symlink', 'a/symlink/a', 'a/symlink/a/b']], + type Case = [options: GlobOptions, results: string[], pattern?: string] + const cases: Case[] = [ + [{}, ['a/symlink', 'a/symlink/a', 'a/symlink/a/b']], - [{ mark: true }, ['a/symlink/', 'a/symlink/a/', 'a/symlink/a/b/']], + [{ mark: true }, ['a/symlink/', 'a/symlink/a/', 'a/symlink/a/b/']], - [{ stat: true }, ['a/symlink', 'a/symlink/a', 'a/symlink/a/b']], + [{ follow: true }, ['a/symlink', 'a/symlink/a', 'a/symlink/a/b']], - [{ follow: true }, ['a/symlink', 'a/symlink/a', 'a/symlink/a/b']], - - [ - { cwd: 'a' }, - ['symlink', 'symlink/a', 'symlink/a/b'], - pattern.substr(2), - ], - - [{ cwd: 'a' }, [], 'no one here but us chickens'], + [ + { cwd: 'a' }, + ['symlink', 'symlink/a', 'symlink/a/b'], + pattern.substring(2), + ], - [ - { nonull: true }, - ['no one here but us chickens', 'no one here but us sheep'], - 'no one here but us {chickens,sheep}', - ], + [{ cwd: 'a' }, [], 'no one here but us chickens'], - [ - { nounique: true }, [ - 'a/symlink', - 'a/symlink', - 'a/symlink', - 'a/symlink/a', - 'a/symlink/a', - 'a/symlink/a/b', - 'a/symlink/a/b', + { nonull: true }, + ['no one here but us chickens', 'no one here but us sheep'], + 'no one here but us {chickens,sheep}', ], - ], - [ - { nounique: true, mark: true }, [ - 'a/symlink/', - 'a/symlink/', - 'a/symlink/', - 'a/symlink/a/', - 'a/symlink/a/', - 'a/symlink/a/b/', - 'a/symlink/a/b/', + { nounique: true }, + [ + 'a/symlink', + 'a/symlink', + 'a/symlink', + 'a/symlink', + 'a/symlink/a', + 'a/symlink/a', + 'a/symlink/a', + 'a/symlink/a/b', + 'a/symlink/a/b', + 'a/symlink/a/b', + ], ], - ], - [ - { nounique: true, mark: true, follow: true }, [ - 'a/symlink/', - 'a/symlink/', - 'a/symlink/', - 'a/symlink/a/', - 'a/symlink/a/', - 'a/symlink/a/', - 'a/symlink/a/b/', - 'a/symlink/a/b/', + { nounique: true, mark: true }, + [ + 'a/symlink/', + 'a/symlink/', + 'a/symlink/', + 'a/symlink/', + 'a/symlink/a/', + 'a/symlink/a/', + 'a/symlink/a/', + 'a/symlink/a/b/', + 'a/symlink/a/b/', + 'a/symlink/a/b/', + ], ], - ], -] -cases.forEach(function (c) { - var opt = c[0] - var expect = c[1] - if (!(opt.nonull && expect[0].match(/^no one here/))) { - expect = expect.map(function (d) { - d = (opt.cwd ? path.resolve(opt.cwd) : fixtureDir) + '/' + d - return d.replace(/\\/g, '/') - }) - } - var p = c[2] || pattern + [ + { nounique: true, mark: true, follow: true }, + [ + // this one actually just has HELLA entries, don't list them all here + // plus it differs based on the platform. follow:true is kinda cray. + 'a/symlink/', + 'a/symlink/a/', + 'a/symlink/a/b/', + ], + ], + ] - opt.realpath = true + for (const [opt, raw, p = pattern] of cases) { + const expect = !(opt.nonull && raw[0].match(/^no one here/)) + ? raw.map(function (d) { + d = (opt.cwd ? resolve(opt.cwd) : fixtureDir) + '/' + d + return d.replace(/\\/g, '/') + }) + : raw - test(JSON.stringify(opt), function (t) { - opt.realpath = true - var sync = glob.sync(p, opt) - t.same(sync, expect, 'sync') - glob(p, opt, function (er, async) { - if (er) throw er - t.same(async, expect, 'async') - t.end() + t.test(p + ' ' + JSON.stringify(opt), async t => { + opt.realpath = true + if (!(opt.follow && opt.nounique)) { + t.same(glob.sync(p, opt), expect, 'sync') + const a = await glob(p, opt) + t.same(a, expect, 'async') + } else { + // follow with nounique is wild, just verify it has a lot of entries, + // and that all the expected ones are found. + const s = glob.sync(p, opt) + const a = await glob(p, opt) + t.ok(s.length > 10, 'more than 10 entries found sync', { + found: s.length, + expect: '>10', + }) + t.ok(a.length > 10, 'more than 10 entries found async', { + found: a.length, + expect: '>10', + }) + for (const e of expect) { + t.ok(s.includes(e), 'found ' + e + ' sync') + t.ok(a.includes(e), 'found ' + e + ' async') + } + } }) - }) -}) + } +} diff --git a/test/slash-cwd.ts b/test/slash-cwd.ts index f1771e09..1f72689a 100644 --- a/test/slash-cwd.ts +++ b/test/slash-cwd.ts @@ -1,19 +1,15 @@ // regression test to make sure that slash-ended patterns // don't match files when using a different cwd. -var glob = require('../') -var test = require('tap').test -var pattern = '../{*.md,test}/' -var expect = ['../test/'] -var cwd = __dirname -var opt = { cwd: cwd } +import t from 'tap' +import glob, { GlobOptions } from '../' + +const pattern = '../{*.md,test}/' +const expect = ['../test/'] +const cwd = __dirname +const opt: GlobOptions = { cwd } process.chdir(__dirname + '/..') -test('slashes only match directories', function (t) { - var sync = glob.sync(pattern, { cwd: cwd }) - t.same(sync, expect, 'sync test') - glob(pattern, { cwd: cwd }, function (er, async) { - if (er) throw er - t.same(async, expect, 'async test') - t.end() - }) +t.test('slashes only match directories', async t => { + t.same(glob.sync(pattern, opt), expect, 'sync test') + t.same(await glob(pattern, opt), expect, 'async test') }) diff --git a/test/windows-paths-fs.ts b/test/windows-paths-fs.ts index 61bea54b..52b04437 100644 --- a/test/windows-paths-fs.ts +++ b/test/windows-paths-fs.ts @@ -1,7 +1,9 @@ // test that escape chars are handled properly according to configs // when found in patterns and paths containing glob magic. -const t = require('tap') +import t from 'tap' +import glob from '../' + const dir = t.testdir({ // treat escapes as path separators a: { @@ -19,54 +21,57 @@ const dir = t.testdir({ 'a[x]by': '', }) -const glob = require('../') -t.test('treat backslash as escape', async t => { - const cases = { +t.test('treat backslash as escape', t => { + const cases = Object.entries({ 'a[x]b/y': [], 'a\\[x\\]b/y': ['a[x]b/y'], 'a\\[x\\]b\\y': ['a[x]by'], - } - for (const [pattern, expect] of Object.entries(cases)) { - t.test(pattern, t => { - const s = glob - .sync(pattern, { cwd: dir }) - .map(s => s.replace(/\\/g, '/')) - t.strictSame(s, expect, 'sync') - glob(pattern, { cwd: dir }, (er, s) => { - if (er) { - throw er - } - s = s.map(s => s.replace(/\\/g, '/')) - t.strictSame(s, expect, 'async') - t.end() - }) + }) + t.plan(cases.length) + for (const [pattern, expect] of cases) { + t.test(pattern, async t => { + t.strictSame( + glob.sync(pattern, { cwd: dir }).map(s => s.replace(/\\/g, '/')), + expect, + 'sync' + ) + t.strictSame( + (await glob(pattern, { cwd: dir })).map(s => + s.replace(/\\/g, '/') + ), + expect, + 'async' + ) }) } }) -t.test('treat backslash as separator', async t => { +t.test('treat backslash as separator', t => { Object.defineProperty(process, 'platform', { value: 'win32', }) - const cases = { + const cases = Object.entries({ 'a[x]b/y': [], 'a\\[x\\]b/y': ['a/[x/]b/y'], 'a\\[x\\]b\\y': ['a/[x/]b/y'], - } - for (const [pattern, expect] of Object.entries(cases)) { - t.test(pattern, t => { - const s = glob - .sync(pattern, { cwd: dir, windowsPathsNoEscape: true }) - .map(s => s.replace(/\\/g, '/')) - t.strictSame(s, expect, 'sync') - glob(pattern, { cwd: dir, windowsPathsNoEscape: true }, (er, s) => { - if (er) { - throw er - } - s = s.map(s => s.replace(/\\/g, '/')) - t.strictSame(s, expect, 'async') - t.end() - }) + }) + t.plan(cases.length) + for (const [pattern, expect] of cases) { + t.test(pattern, async t => { + t.strictSame( + glob + .sync(pattern, { cwd: dir, windowsPathsNoEscape: true }) + .map(s => s.replace(/\\/g, '/')), + expect, + 'sync' + ) + t.strictSame( + ( + await glob(pattern, { cwd: dir, windowsPathsNoEscape: true }) + ).map(s => s.replace(/\\/g, '/')), + expect, + 'async' + ) }) } }) diff --git a/test/windows-paths-no-escape.ts b/test/windows-paths-no-escape.ts index dcff9645..58681306 100644 --- a/test/windows-paths-no-escape.ts +++ b/test/windows-paths-no-escape.ts @@ -1,11 +1,15 @@ -const t = require('tap') -const g = require('../') +import t from 'tap' +import {Glob} from '../' const platforms = ['win32', 'posix'] const originalPlatform = Object.getOwnPropertyDescriptor( process, 'platform' -) +) as PropertyDescriptor +t.teardown(() => { + Object.defineProperty(process, 'platform', originalPlatform) +}) + for (const p of platforms) { t.test(p, t => { Object.defineProperty(process, 'platform', { @@ -16,18 +20,15 @@ for (const p of platforms) { }) t.equal(process.platform, p, 'gut check: actually set platform') const pattern = '/a/b/c/x\\[a-b\\]y\\*' - const def = new g.Glob(pattern, { noprocess: true }) - const winpath = new g.Glob(pattern, { + const def = new Glob(pattern) + const winpath = new Glob(pattern, { windowsPathsNoEscape: true, - noprocess: true, }) - const winpathLegacy = new g.Glob(pattern, { + const winpathLegacy = new Glob(pattern, { allowWindowsEscape: false, - noprocess: true, }) - const nowinpath = new g.Glob(pattern, { + const nowinpath = new Glob(pattern, { windowsPathsNoEscape: false, - noprocess: true, }) t.strictSame( @@ -38,10 +39,10 @@ for (const p of platforms) { winpathLegacy.pattern, ], [ - '/a/b/c/x\\[a-b\\]y\\*', - '/a/b/c/x\\[a-b\\]y\\*', - '/a/b/c/x/[a-b/]y/*', - '/a/b/c/x/[a-b/]y/*', + ['/a/b/c/x\\[a-b\\]y\\*'], + ['/a/b/c/x\\[a-b\\]y\\*'], + ['/a/b/c/x/[a-b/]y/*'], + ['/a/b/c/x/[a-b/]y/*'], ] ) t.end() From 392c4b72de59aef3c3397c21bdff591eb2677c34 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 16 Jan 2023 19:58:32 -0800 Subject: [PATCH 038/163] do not clean up fixtures Too annoying to keep having to run test-regen in dev. Also, use t.testdir() in the one test that was writing and tearing down its fixture manually. --- package.json | 1 - test/00-setup.ts | 3 --- test/readme-issue.ts | 14 +++----------- test/zz-cleanup.ts | 13 ------------- 4 files changed, 3 insertions(+), 28 deletions(-) delete mode 100644 test/zz-cleanup.ts diff --git a/package.json b/package.json index 4aecabea..6849d52a 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,6 @@ }, "tap": { "before": "test/00-setup.ts", - "after": "test/zz-cleanup.ts", "coverage": false, "node-arg": [ "--no-warnings", diff --git a/test/00-setup.ts b/test/00-setup.ts index b4aee586..16d3376f 100644 --- a/test/00-setup.ts +++ b/test/00-setup.ts @@ -5,7 +5,6 @@ import { spawn } from 'child_process' import { createWriteStream, promises } from 'fs' import mkdirp from 'mkdirp' import { dirname, resolve } from 'path' -import { rimraf } from 'rimraf' import t from 'tap' const { writeFile, symlink } = promises @@ -32,8 +31,6 @@ const symlinkFrom = '../..' const files = filesUnresolved.map(f => resolve(fixtureDir, f)) -t.test('remove fixtures', async () => await rimraf(fixtureDir)) - for (const file of files) { t.test(file, { bail: true }, async () => { const f = resolve(fixtureDir, file) diff --git a/test/readme-issue.ts b/test/readme-issue.ts index 58843a36..dd45be52 100644 --- a/test/readme-issue.ts +++ b/test/readme-issue.ts @@ -1,19 +1,11 @@ import t from 'tap' import glob from '../' -import { writeFileSync } from 'fs' -import mkdirp from 'mkdirp' -import rimraf from 'rimraf' -const dir = __dirname + '/package' - -t.before(() => { - mkdirp.sync(dir) - writeFileSync(dir + '/package.json', '{}', 'ascii') - writeFileSync(dir + '/README', 'x', 'ascii') +const dir = t.testdir({ + 'package.json': '{}', + 'README': 'x', }) -t.teardown(() => rimraf.sync(dir)) - t.test('glob', async t => { var opt = { cwd: dir, diff --git a/test/zz-cleanup.ts b/test/zz-cleanup.ts deleted file mode 100644 index c6b1b818..00000000 --- a/test/zz-cleanup.ts +++ /dev/null @@ -1,13 +0,0 @@ -// remove the fixtures -process.env.TAP_BAIL = '1' -import { createWriteStream } from 'fs' -import { resolve } from 'path' -import { rimraf } from 'rimraf' -import t from 'tap' -//@ts-ignore -t.pipe(createWriteStream('zz-cleanup.tap')) - -t.test( - 'cleanup fixtures', - async () => await rimraf(resolve(__dirname, 'fixtures')) -) From 9b1187900cbc1b32b15a7cdf8603251a004ef0bb Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 16 Jan 2023 21:16:24 -0800 Subject: [PATCH 039/163] Clean up some dead code, get tests to 100% coverage --- src/glob.ts | 41 +++++-------- src/walker.ts | 49 +++++++-------- test/00-setup.ts | 2 + test/bash-results.ts | 2 + test/match-base.ts | 23 ++++++- test/nosort.ts | 53 ++++++++++++++++ test/pattern-absolute.ts | 129 +++++++++++++++++++++++++++++++++++++++ test/realpath.ts | 31 ++++++++++ 8 files changed, 279 insertions(+), 51 deletions(-) create mode 100644 test/nosort.ts create mode 100644 test/pattern-absolute.ts diff --git a/src/glob.ts b/src/glob.ts index 56160e0f..3c42c42c 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -91,25 +91,10 @@ export class Glob { ) } - doNonull(matches: string[], i: number) { - if (!matches.length && this.nonull) { - const gs: string | undefined = this.globSet[i] - if (gs) { - return [gs] - } else { - return [] - } - } - return matches - } - async process() { return this.finish( await Promise.all( this.matchSet.map(async (set, i) => { - if (!set.length) { - return [] - } const matches = await this.getWalker(set as Pattern).walk() return this.doNonull(matches, i) }) @@ -117,6 +102,21 @@ export class Glob { ) } + processSync() { + return this.finish( + this.matchSet.map((set, i) => + this.doNonull(this.getWalker(set as Pattern).walkSync(), i) + ) + ) + } + + doNonull(matches: string[], i: number): string[] { + if (!matches.length && this.nonull) { + return [this.globSet[i]] + } + return matches + } + finish(matches: string[][]): string[] { const raw = matches.reduce((set, m) => set.concat(m), []) const flat = this.nounique ? raw : [...new Set(raw)] @@ -128,15 +128,4 @@ export class Glob { getWalker(set: Pattern) { return new GlobWalker(set, '', this) } - - processSync() { - return this.finish( - this.matchSet.map((set, i) => { - if (!set.length) { - return [] - } - return this.doNonull(this.getWalker(set as Pattern).walkSync(), i) - }) - ) - } } diff --git a/src/walker.ts b/src/walker.ts index bee7a6d2..80fa1b94 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -21,8 +21,6 @@ import { resolve } from 'path' import { Ignore } from './ignore.js' import { GlobCache, Readdir } from './readdir.js' -import { join } from 'path' - // a single minimatch set entry with 1 or more parts type ParseReturnFiltered = string | RegExp | typeof GLOBSTAR export type Pattern = [ @@ -104,14 +102,22 @@ export class GlobWalker { const [first, ...rest] = this.pattern // a pattern like /a/s/d/f discards the cwd // a pattern like / (or c:/ on windows) can only match the root - const setAbs = - typeof first === 'string' && - ((first === '' && rest.length) || - (process.platform === 'win32' && /^[a-z]:$/i.test(first))) - if (setAbs) { - this.pattern = rest.length ? (rest as Pattern) : [''] - this.cwd = first || '/' - this.path = first || '/' + if (typeof first === 'string') { + const patternSlash = first === '' && !!rest.length + const isWin = process.platform === 'win32' + const patternDrive = isWin && /^[a-z]:$/i.test(first) + const setAbs = patternSlash || patternDrive + if (setAbs) { + // a pattern like '/' on windows goes to the root of + // the drive that cwd is on. If cwd isn't on a drive, use / + const cwd = this.join(this.path, this.cwd) + const cwdRe = /^[a-z]:($|[\\\/])/i + const cwdDrive = isWin && patternSlash && cwd.match(cwdRe) + const root = cwdDrive ? cwdDrive[0] : '/' + this.pattern = rest.length ? (rest as Pattern) : [''] + this.cwd = first || root + this.path = first || root + } } while ( this.pattern.length > 1 && @@ -120,7 +126,7 @@ export class GlobWalker { this.path = this.join(this.pattern[0]) this.pattern.shift() } - return join(this.cwd, this.path) || '.' + return this.join(this.path, this.cwd) || '.' } child(pattern: Pattern, path: string) { @@ -239,19 +245,14 @@ export class GlobWalker { ): Children { const children: Children = [] const e = entries.find(e => e.name === p) - const traverse = - p === '..' || - p === '.' || - p === '' || - (e && (e.isDirectory() || e.isSymbolicLink())) - if (p === '.' || p === '' || p === '..' || e) { - if (rest) { - if (traverse) { - children.push(this.child(rest, this.join(p))) - } - } else { - children.push(this.join(p)) - } + + // since we pull all string portions up to minimize readdir() calls, + // the only way we can possibly have a rest here is if something + // OTHER than a string comes next. + // However, if we're landing on ., '', .., or a string that matches + // an entry in the directory we just read, then it's a match. + if ((p === '.' || p === '' || p === '..' || e) && !rest) { + children.push(this.join(p)) } return children } diff --git a/test/00-setup.ts b/test/00-setup.ts index 16d3376f..50372e38 100644 --- a/test/00-setup.ts +++ b/test/00-setup.ts @@ -66,6 +66,8 @@ if (process.platform === 'win32' || !process.env.TEST_REGEN) { // put more patterns here. // anything that would be directly in / should be in /tmp/glob-test [ + 'a/c/d/*/b', + 'a/*/d/*/b', 'a/*/+(c|g)/./d', 'a/**/[cg]/../[cg]', 'a/{b,c,d,e,f}/**/g', diff --git a/test/bash-results.ts b/test/bash-results.ts index 90a783ba..fb41c591 100644 --- a/test/bash-results.ts +++ b/test/bash-results.ts @@ -3,6 +3,8 @@ if (module === require.main) { console.log('TAP version 13\n1..1\nok\n') } export const bashResults: { [path: string]: string[] } = { + 'a/c/d/*/b': ['a/c/d/c/b'], + 'a/*/d/*/b': ['a/c/d/c/b'], 'a/*/+(c|g)/./d': ['a/b/c/./d'], 'a/**/[cg]/../[cg]': [ 'a/abcdef/g/../g', diff --git a/test/match-base.ts b/test/match-base.ts index 632034f8..0b3adb06 100644 --- a/test/match-base.ts +++ b/test/match-base.ts @@ -15,9 +15,9 @@ if (process.platform !== 'win32') { t.test('chdir', async t => { const origCwd = process.cwd() process.chdir(fixtureDir) + t.teardown(() => process.chdir(origCwd)) t.same(glob.sync(pattern, { matchBase: true }), expect) t.same(await glob(pattern, { matchBase: true }), expect) - process.chdir(origCwd) }) t.test('cwd', async t => { @@ -30,3 +30,24 @@ t.test('noglobstar', async t => { t.throws(() => glob.sync(pattern, { matchBase: true, noglobstar: true })) t.end() }) + +t.test('pattern includes /', async t => { + const pattern = 'a/b*' + const expect = ['a/b', 'a/bc'] + t.same(glob.sync(pattern, { matchBase: true, cwd: fixtureDir }), expect) + t.same(await glob(pattern, { matchBase: true, cwd: fixtureDir }), expect) +}) + +t.test('one brace section of pattern includes /', async t => { + const pattern = 'a{*,/b*}' + const exp = ['a', 'a/b', 'a/bc'] + t.same(glob.sync(pattern, { matchBase: true, cwd: fixtureDir }), exp) + t.same(await glob(pattern, { matchBase: true, cwd: fixtureDir }), exp) +}) + +t.test('one array member of pattern includes /', async t => { + const pattern = ['a*', 'a/b*'] + const exp = expect.concat(['a/b', 'a/bc']).sort() + t.same(glob.sync(pattern, { matchBase: true, cwd: fixtureDir }), exp) + t.same(await glob(pattern, { matchBase: true, cwd: fixtureDir }), exp) +}) diff --git a/test/nosort.ts b/test/nosort.ts new file mode 100644 index 00000000..3e92663c --- /dev/null +++ b/test/nosort.ts @@ -0,0 +1,53 @@ +import * as fs from 'fs' +import { Dirent, readdir, readdirSync } from 'fs' +import {resolve} from 'path' +import t from 'tap' +const { glob } = t.mock('../dist/cjs/index.js', { + fs: { + ...fs, + readdir: ( + path: string, + o: { withFileTypes: true }, + cb: (er: null | NodeJS.ErrnoException, entries?: Dirent[]) => void + ) => { + readdir(path, o, (er, entries) => { + if (entries) { + cb( + er, + entries.sort(({ name: b }, { name: a }) => + a.localeCompare(b, 'en') + ) + ) + } else { + cb(er) + } + }) + }, + readdirSync: (path: string, o: { withFileTypes: true }) => + readdirSync(path, o).sort(({ name: b }, { name: a }) => + a.localeCompare(b, 'en') + ), + }, +}) + +const pattern = 'a/[bz]*' +t.test('nosort', async t => { + const opt = { nosort: true, cwd: resolve(__dirname, 'fixtures') } + const expect = ['a/z', 'a/bc', 'a/b'] + t.same(glob.sync(pattern, opt), expect) + t.same(await glob(pattern, opt), expect) +}) + +t.test('nosort unset', async t => { + const opt = { cwd: resolve(__dirname, 'fixtures') } + const expect = ['a/b', 'a/bc', 'a/z'] + t.same(glob.sync(pattern, opt), expect) + t.same(await glob(pattern, opt), expect) +}) + +t.test('nosort:false', async t => { + const opt = { nosort: false, cwd: resolve(__dirname, 'fixtures') } + const expect = ['a/b', 'a/bc', 'a/z'] + t.same(glob.sync(pattern, opt), expect) + t.same(await glob(pattern, opt), expect) +}) diff --git a/test/pattern-absolute.ts b/test/pattern-absolute.ts new file mode 100644 index 00000000..6492cf98 --- /dev/null +++ b/test/pattern-absolute.ts @@ -0,0 +1,129 @@ +// there's some special behavior if the pattern starts with '/' +// or if it starts with a drive letter on Windows systems. +// This is a weirdly specific test of unexported implementation, not my +// favorite, but it is the easiest way to verify what we expect here. +import t from 'tap' +import {GlobWalker} from '../dist/cjs/walker.js' + +const setPlatform = (platform:string) => { +Object.defineProperty(process, 'platform', { + value: platform, + enumerable: true, + configurable: true, + writable: true, +}) +} + +const { platform } = process +t.teardown(() => setPlatform(platform)) + +t.test('posix', t => { + setPlatform('posix') + + // pattern like [a]/[b] + t.match(new GlobWalker([/^[a]$/, /^[b]$/], ''), { + pattern: [/^[a]$/, /^[b]$/], + path: '', + cwd: '', + start: '.', + }, 'pattern=[a]/[b] path=""') + + t.match(new GlobWalker(['', ''], '/tmp'), { + pattern: [''], + path: '/', + cwd: '/', + start: '/', + }, 'pattern=/') + + t.match(new GlobWalker(['', 'x'], '/tmp'), { + pattern: ['x'], + path: '/', + cwd: '/', + start: '/', + }, 'pattern=/x') + + t.match(new GlobWalker(['', 'x'], '/tmp'), { + pattern: ['x'], + path: '/', + cwd: '/', + start: '/', + }, 'pattern=/x') + + t.match(new GlobWalker(['c:'], 'd:/tmp'), { + pattern: ['c:'], + path: 'd:/tmp', + cwd: '', + start: 'd:/tmp', + }) + + t.match(new GlobWalker(['c:', 'x'], 'd:/tmp'), { + pattern: ['x'], + path: 'd:/tmp/c:', + cwd: '', + start: 'd:/tmp/c:', + }) + + t.end() +}) + +t.test('win32', t => { + setPlatform('win32') + + t.match(new GlobWalker(['', ''], '/tmp'), { + pattern: [''], + path: '/', + cwd: '/', + start: '/', + }, 'pattern=/') + + t.match(new GlobWalker(['', 'x'], '/tmp'), { + pattern: ['x'], + path: '/', + cwd: '/', + start: '/', + }, 'pattern=/x') + + t.match(new GlobWalker(['', 'x'], '/tmp'), { + pattern: ['x'], + path: '/', + cwd: '/', + start: '/', + }, 'pattern=/x') + + t.match(new GlobWalker(['', ''], 'd:/tmp'), { + pattern: [''], + path: 'd:/', + cwd: 'd:/', + start: 'd:/', + }, 'pattern=/, path=d:/tmp') + + t.match(new GlobWalker(['', 'x'], 'x:/tmp'), { + pattern: ['x'], + path: 'x:', + cwd: 'x:', + start: 'x:', + }, 'pattern=/x, path=x:/tmp') + + t.match(new GlobWalker(['', 'x'], 'y:/tmp'), { + pattern: ['x'], + path: 'y:', + cwd: 'y:', + start: 'y:', + }, 'pattern=/x path=y:/tmp') + + t.match(new GlobWalker(['c:'], 'd:/tmp'), { + pattern: [''], + path: 'c:', + cwd: 'c:', + start: 'c:', + }, 'pattern=c: path=d:/tmp') + + t.match(new GlobWalker(['c:', 'x'], 'd:/tmp'), { + pattern: ['x'], + path: 'c:', + cwd: 'c:', + start: 'c:', + }, 'pattern=c:/x path=d:/tmp') + + t.end() +}) diff --git a/test/realpath.ts b/test/realpath.ts index 25e9f71c..24e1b8e3 100644 --- a/test/realpath.ts +++ b/test/realpath.ts @@ -1,9 +1,12 @@ +import * as fs from 'fs' import { resolve } from 'path' import t from 'tap' import glob, { GlobOptions } from '../' + // pattern to find a bunch of duplicates const pattern = 'a/symlink/{*,**/*/*/*,*/*/**,*/*/*/*/*/*}' const fixtureDir = resolve(__dirname, 'fixtures') +const origCwd = process.cwd() process.chdir(fixtureDir) if (process.platform === 'win32') { @@ -112,4 +115,32 @@ if (process.platform === 'win32') { } }) } + + t.test('realpath failure', async t => { + process.chdir(origCwd) + const { glob } = t.mock('../dist/cjs/index.js', { + fs: { + ...fs, + realpath: (_: string, cb: (er: Error) => void) => + cb(new Error('no realpath for you async')), + realpathSync: () => { + throw new Error('no error for you sync') + }, + }, + }) + const pattern = 'a/symlink/a/b/c/a/b/**' + const expect = ['a/symlink/a/b/c/a/b/', 'a/symlink/a/b/c/a/b/c'] + .map(e => resolve(fixtureDir, e)) + t.test('setting cwd explicitly', async t => { + const opt = { realpath: true, cwd: fixtureDir } + t.same(glob.sync(pattern, opt), expect) + t.same(await glob(pattern, opt), expect) + }) + t.test('looking in cwd', async t => { + process.chdir(fixtureDir) + const opt = { realpath: true } + t.same(glob.sync(pattern, opt), expect) + t.same(await glob(pattern, opt), expect) + }) + }) } From 622a8d010efb77fef12c4aec295dfca102d2c73e Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 17 Jan 2023 00:43:34 -0800 Subject: [PATCH 040/163] preserve repeated slashes, support UNC paths --- README.md | 52 ++++++++++++++++++++++++++++++++++-- changelog.md | 6 +++++ package-lock.json | 14 +++++----- package.json | 2 +- src/glob.ts | 7 ++++- src/walker.ts | 57 +++++++++++++++++++++++++++++++++++----- test/00-setup.ts | 5 +++- test/bash-comparison.ts | 2 +- test/bash-results.ts | 9 ++++--- test/pattern-absolute.ts | 23 +++++++++++++--- 10 files changed, 149 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 3cc84508..6bf6a369 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,8 @@ sped up by sharing information about the filesystem. Defaults to `process.cwd()`. This option is always coerced to use forward-slashes as a path separator, because it is not tested as a glob pattern, so there is no need to escape - anything. + anything. See also: "Windows, CWDs, Drive Letters, and UNC + Paths", below. - `windowsPathsNoEscape` Use `\\` as a path separator _only_, and _never_ as an escape character. If set, all `\\` characters are replaced with `/` in the pattern. Note that this makes it @@ -126,7 +127,8 @@ sped up by sharing information about the filesystem. have find matches, setting `{nonull:true}` will cause glob to return the pattern itself instead of the empty set. -`nocomment` and `nonegate` are always set to `false`. +`preserveSlashes` is always set to `true`, and `nocomment` and +`nonegate` are always set to `false`. ## `hasMagic(pattern: string, options?: GlobOptions) => boolean` @@ -280,6 +282,19 @@ classes), `[=c=]` (locale-specific character collation weight), and `[.symbol.]` (collating symbol) style class patterns are _not_ supported by this implementation. +### Repeated Slashes + +Patterns that have excess `/` characters between non-magic +portions will have their excess `/` characters preserved in the +result. That is, empty path portions in the pattern will match +the parent directory, be appended to the parent path with a `/`, +and returned. + +Empty path portions immediately following any "magic" glob +pattern will be omitted. + +This is by design to match the behavior of the Bash shell. + ### Comments and Negation Previously, this module let you mark a pattern as a "comment" if @@ -309,6 +324,39 @@ strings, **thus making it impossible to escape literal glob characters**, you may set the `windowsPathsNoEscape` option to `true`. +### Windows, CWDs, Drive Letters, and UNC Paths + +On posix systems, when a pattern starts with `/`, any `cwd` +option is ignored, and the traversal starts at `/`, plus any +non-magic path portions specified in the pattern. + +On Windows systems, the behavior is similar, but the concept of +an "absolute path" is much more involved. + +#### UNC Paths + +A UNC path may be used as the start of a pattern. For example, a +pattern like: `//?/x:/*` will return all file entries in the root +of the `x:` drive. A pattern like `//ComputerName/Share/*` will +return all files in the associated share. + +#### Drive Letters + +A pattern starting with a drive letter, like `c:/*`, will search +in that drive, regardless of any `cwd` option provided. + +If the pattern starts with `/`, and is not a UNC path, and there +is an explicit `cwd` option set with a drive letter, then the +drive letter in the `cwd` is used as the root of the directory +traversal. + +For example, `glob('/tmp', { cwd: 'c:/any/thing' })` will return +`['c:/tmp']` as the result. + +If an explicit `cwd` option is not provided, then the traversal +will run on whichever drive the active `process.cwd()` returns. +(That is, the result of `path.resolve('/')`.) + ## Race Conditions Glob searching, by its very nature, is susceptible to race diff --git a/changelog.md b/changelog.md index c0efedeb..0f5b89ef 100644 --- a/changelog.md +++ b/changelog.md @@ -38,6 +38,12 @@ This is a full rewrite. even, even though the ignore value like `x/**` would have excluded it. However, _not_ returning anything when `nonull:true` is set, is arguably a worse contract violation. +- Patterns starting with drive letters on Windows are now + properly treated as absolute paths, and the drive letter in an + absolute `{cwd}` option will be used as the root of patterns + that start with `/`. +- Patterns with multiple slashes will behave the same as the + Bash 5 shell. ## 8.1 diff --git a/package-lock.json b/package-lock.json index e9dfca7d..011de31d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", - "minimatch": "^6.0.4" + "minimatch": "6.1" }, "devDependencies": { "@types/mkdirp": "^1.0.2", @@ -2910,9 +2910,9 @@ } }, "node_modules/minimatch": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.0.4.tgz", - "integrity": "sha512-9SQupyyavjdAc1VFjJS/5kdtFtlLAhKSWt7HocG0h/npy626jYrGegSslcM7Xxet5z0U9GOx9YbcpyIjBzn7tA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.0.tgz", + "integrity": "sha512-eqe4xaKs1/JmNylXNFY2f41n3jNZAZTZlmOitWd71YazZlvvXMtzL+gK67jRKhrTQmHfrCbErYWV8z9Nz4aNuQ==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -8530,9 +8530,9 @@ } }, "minimatch": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.0.4.tgz", - "integrity": "sha512-9SQupyyavjdAc1VFjJS/5kdtFtlLAhKSWt7HocG0h/npy626jYrGegSslcM7Xxet5z0U9GOx9YbcpyIjBzn7tA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.0.tgz", + "integrity": "sha512-eqe4xaKs1/JmNylXNFY2f41n3jNZAZTZlmOitWd71YazZlvvXMtzL+gK67jRKhrTQmHfrCbErYWV8z9Nz4aNuQ==", "requires": { "brace-expansion": "^2.0.1" } diff --git a/package.json b/package.json index 6849d52a..236fd143 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ }, "dependencies": { "fs.realpath": "^1.0.0", - "minimatch": "^6.0.4" + "minimatch": "6.1" }, "devDependencies": { "@types/mkdirp": "^1.0.2", diff --git a/src/glob.ts b/src/glob.ts index 3c42c42c..3d308ea6 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -82,7 +82,12 @@ export class Glob { this.pattern = pattern - const mmo = { ...options, nonegate: true, nocomment: true } + const mmo: MinimatchOptions = { + ...options, + nonegate: true, + nocomment: true, + preserveMultipleSlashes: true, + } const mms = this.pattern.map(p => new Minimatch(p, mmo)) this.matchSet = mms.reduce((set: MatchSet, m) => set.concat(m.set), []) this.globSet = mms.reduce( diff --git a/src/walker.ts b/src/walker.ts index 80fa1b94..d2f8d53e 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -57,6 +57,7 @@ export class GlobWalker { cache: GlobCache cwd: string start: string + parent?: GlobWalker constructor( pattern: Pattern, @@ -75,6 +76,9 @@ export class GlobWalker { ignore, cwd = '', } = options + if (options instanceof GlobWalker) { + this.parent = options + } // if the pattern starts with a bunch of strings, then skip ahead this.pattern = [...pattern] @@ -98,11 +102,14 @@ export class GlobWalker { } } + // TODO: this belongs in the Glob class probably + // since then we can remove the parent bit. + // Also, then we can ditch the cwd setStart() { const [first, ...rest] = this.pattern // a pattern like /a/s/d/f discards the cwd // a pattern like / (or c:/ on windows) can only match the root - if (typeof first === 'string') { + if (typeof first === 'string' && !this.parent) { const patternSlash = first === '' && !!rest.length const isWin = process.platform === 'win32' const patternDrive = isWin && /^[a-z]:$/i.test(first) @@ -110,22 +117,54 @@ export class GlobWalker { if (setAbs) { // a pattern like '/' on windows goes to the root of // the drive that cwd is on. If cwd isn't on a drive, use / - const cwd = this.join(this.path, this.cwd) + const cwd = this.cwd ? this.join(this.path, this.cwd) : this.path const cwdRe = /^[a-z]:($|[\\\/])/i const cwdDrive = isWin && patternSlash && cwd.match(cwdRe) - const root = cwdDrive ? cwdDrive[0] : '/' + // don't mount UNC paths on a drive letter + // eg: //?/c:/* or //host/share/* + // Only relevant if we WOULD have tried to mount it + // We'll gobble those strings shortly, so use '/' for now + const isUNC = + cwdDrive && + first === '' && + rest[0] === '' && + rest[1] && + typeof rest[1] === 'string' && + rest[2] && + typeof rest[2] === 'string' + const root = isUNC + ? '/' + : cwdDrive + ? cwdDrive[0] + : isWin + ? resolve('/') + : '' + if (isUNC && rest.length === 3) { + rest.push('') + } this.pattern = rest.length ? (rest as Pattern) : [''] this.cwd = first || root - this.path = first || root + this.path = first || root || '/' } } while ( this.pattern.length > 1 && typeof this.pattern[0] === 'string' ) { - this.path = this.join(this.pattern[0]) + this.path = + this.path === '/' + ? this.path + this.pattern[0] + : this.join(this.pattern[0]) this.pattern.shift() } + while ( + (this.pattern[0] instanceof RegExp || + this.pattern[0] === GLOBSTAR) && + this.pattern[1] === '' && + this.pattern.length > 2 + ) { + this.pattern.splice(1, 1) + } return this.join(this.path, this.cwd) || '.' } @@ -233,7 +272,7 @@ export class GlobWalker { join(p: string, base: string = this.path) { return base === '' ? p - : base.substring(base.length - 1) === '/' + : base === '/' && p ? `${base}${p}` : `${base}/${p}` } @@ -244,7 +283,11 @@ export class GlobWalker { rest: Pattern | null ): Children { const children: Children = [] - const e = entries.find(e => e.name === p) + const e = + p !== '' && + p !== '.' && + p !== '..' && + entries.find(e => e.name === p) // since we pull all string portions up to minimize readdir() calls, // the only way we can possibly have a rest here is if something diff --git a/test/00-setup.ts b/test/00-setup.ts index 50372e38..47ce7d7d 100644 --- a/test/00-setup.ts +++ b/test/00-setup.ts @@ -62,11 +62,13 @@ if (process.platform !== 'win32') { if (process.platform === 'win32' || !process.env.TEST_REGEN) { console.error('Windows, or TEST_REGEN unset. Using cached fixtures.') } else { + const globs = // put more patterns here. // anything that would be directly in / should be in /tmp/glob-test [ 'a/c/d/*/b', + 'a//c//d//*//b', 'a/*/d/*/b', 'a/*/+(c|g)/./d', 'a/**/[cg]/../[cg]', @@ -86,6 +88,7 @@ if (process.platform === 'win32' || !process.env.TEST_REGEN) { 'a/!(symlink)/**', 'a/symlink/a/**/*', ] + const bashOutput: { [k: string]: string[] } = {} for (const pattern of globs) { @@ -144,7 +147,7 @@ export const bashResults:{ [path: string]: string[] } = ${ // and ending slashes. return m .map(function (m) { - return m.replace(/\/+/g, '/').replace(/\/$/, '') + return m.replace(/\/$/, '') }) .sort(alphasort) .reduce(function (set: string[], f) { diff --git a/test/bash-comparison.ts b/test/bash-comparison.ts index 12fbcbe4..976e827c 100644 --- a/test/bash-comparison.ts +++ b/test/bash-comparison.ts @@ -18,7 +18,7 @@ const cleanResults = (m: string[]) => { // normalize discrepancies in ordering, duplication, // and ending slashes. return m - .map(m => m.replace(/\/+/g, '/').replace(/\/$/, '')) + .map(m => m.replace(/\/$/, '')) .sort(alphasort) .reduce((set: string[], f) => { if (f !== set[set.length - 1]) set.push(f) diff --git a/test/bash-results.ts b/test/bash-results.ts index fb41c591..3db61ddb 100644 --- a/test/bash-results.ts +++ b/test/bash-results.ts @@ -4,6 +4,7 @@ if (module === require.main) { } export const bashResults: { [path: string]: string[] } = { 'a/c/d/*/b': ['a/c/d/c/b'], + 'a//c//d//*//b': ['a//c//d//c/b'], 'a/*/d/*/b': ['a/c/d/c/b'], 'a/*/+(c|g)/./d': ['a/b/c/./d'], 'a/**/[cg]/../[cg]': [ @@ -56,10 +57,10 @@ export const bashResults: { [path: string]: string[] } = { '*/*/*/f': ['a/bc/e/f', 'a/cb/e/f'], './**/f': ['./a/bc/e/f', './a/cb/e/f'], 'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**': [ - 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c', - 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a', - 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b', - 'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c', + 'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/a/b/c', + 'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/a/b/c/a', + 'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/a/b/c/a/b', + 'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/a/b/c/a/b/c', ], '{./*/*,/tmp/glob-test/*}': [ './a/abcdef', diff --git a/test/pattern-absolute.ts b/test/pattern-absolute.ts index 6492cf98..cd0275f7 100644 --- a/test/pattern-absolute.ts +++ b/test/pattern-absolute.ts @@ -31,24 +31,25 @@ t.test('posix', t => { t.match(new GlobWalker(['', ''], '/tmp'), { pattern: [''], path: '/', - cwd: '/', + cwd: '', start: '/', }, 'pattern=/') t.match(new GlobWalker(['', 'x'], '/tmp'), { pattern: ['x'], path: '/', - cwd: '/', + cwd: '', start: '/', }, 'pattern=/x') - t.match(new GlobWalker(['', 'x'], '/tmp'), { + t.match(new GlobWalker(['', 'x'], '/tmp', { cwd: '/a/b/c/d' }), { pattern: ['x'], path: '/', - cwd: '/', + cwd: '', start: '/', }, 'pattern=/x') + t.match(new GlobWalker(['c:'], 'd:/tmp'), { pattern: ['c:'], path: 'd:/tmp', @@ -125,5 +126,19 @@ t.test('win32', t => { start: 'c:', }, 'pattern=c:/x path=d:/tmp') + t.match(new GlobWalker(['', '', '?', 'c:'], 'd:/tmp'), { + pattern: [''], + path: '/?/c:', + cwd: '/', + start: '//?/c:', + }, 'pattern=//?/c: path=d:/tmp') + + t.match(new GlobWalker(['', '', '?', 'c:', /^[ab]$/], 'd:/tmp'), { + pattern: [/^[ab]$/], + path: '/?/c:', + cwd: '/', + start: '//?/c:', + }, 'pattern=//?/c:/[ab] path=d:/tmp') + t.end() }) From a0db3179fc7596739f11c133a2bba2612ad81f03 Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 17 Jan 2023 11:58:53 -0800 Subject: [PATCH 041/163] minimatch@6.1.4 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 011de31d..6eebba0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", - "minimatch": "6.1" + "minimatch": "^6.1.4" }, "devDependencies": { "@types/mkdirp": "^1.0.2", @@ -2910,9 +2910,9 @@ } }, "node_modules/minimatch": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.0.tgz", - "integrity": "sha512-eqe4xaKs1/JmNylXNFY2f41n3jNZAZTZlmOitWd71YazZlvvXMtzL+gK67jRKhrTQmHfrCbErYWV8z9Nz4aNuQ==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.4.tgz", + "integrity": "sha512-NsDTCCf9qKxjUUxSfhnF2AbYR9xSpWvJx/HL/4E+KbqhKqdHMXjn81So56Hga/lpyhXL98aLPZLdPmUUEyIrWA==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -8530,9 +8530,9 @@ } }, "minimatch": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.0.tgz", - "integrity": "sha512-eqe4xaKs1/JmNylXNFY2f41n3jNZAZTZlmOitWd71YazZlvvXMtzL+gK67jRKhrTQmHfrCbErYWV8z9Nz4aNuQ==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.4.tgz", + "integrity": "sha512-NsDTCCf9qKxjUUxSfhnF2AbYR9xSpWvJx/HL/4E+KbqhKqdHMXjn81So56Hga/lpyhXL98aLPZLdPmUUEyIrWA==", "requires": { "brace-expansion": "^2.0.1" } diff --git a/package.json b/package.json index 236fd143..30e271b5 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ }, "dependencies": { "fs.realpath": "^1.0.0", - "minimatch": "6.1" + "minimatch": "^6.1.4" }, "devDependencies": { "@types/mkdirp": "^1.0.2", From c381907614e0b4a67da040d34529452b504eae3b Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 17 Jan 2023 12:17:28 -0800 Subject: [PATCH 042/163] proper require() default export support --- README.md | 5 +++++ package.json | 6 +++--- src/index-cjs.ts | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 src/index-cjs.ts diff --git a/README.md b/README.md index 6bf6a369..b75dd706 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,11 @@ import { glob } from 'glob' // or using commonjs const { glob } = require('glob') +// or default export is fine too +import glob from 'glob' +// or using commonjs +const glob = require('glob') + // these all return arrays of filenames // all js files, but don't look in node_modules diff --git a/package.json b/package.json index 30e271b5..ab2afb72 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "type": "git", "url": "git://github.com/isaacs/node-glob.git" }, - "main": "./dist/cjs/index.js", + "main": "./dist/cjs/index-cjs.js", "module": "./dist/mjs/index.js", "exports": { ".": { @@ -16,8 +16,8 @@ "types": "./dist/mjs/index.d.ts" }, "require": { - "default": "./dist/cjs/index.js", - "types": "./dist/cjs/index.d.ts" + "default": "./dist/cjs/index-cjs.js", + "types": "./dist/cjs/index-cjs.d.ts" } } }, diff --git a/src/index-cjs.ts b/src/index-cjs.ts new file mode 100644 index 00000000..9cdb55a2 --- /dev/null +++ b/src/index-cjs.ts @@ -0,0 +1,3 @@ +import glob from './index.js' + +export = Object.assign(glob, { default: glob, glob }) From f66a08a14588e450b75f12cb41a3b7408aa1bb9a Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 17 Jan 2023 14:19:55 -0800 Subject: [PATCH 043/163] remove old abandoned benchmark script --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index ab2afb72..6494fb65 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "test": "c8 tap", "snap": "c8 tap", "format": "prettier --write . --loglevel warn", - "benchmark": "node benchmark/index.js", "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts", "prepublish": "npm run benchclean", "profclean": "rm -f v8.log profile.txt", From 9bc4065eda4ebee226b6b427232d4de1be8052c4 Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 17 Jan 2023 14:20:33 -0800 Subject: [PATCH 044/163] fix: bundling library using webpack this change ensures "default" conditions are last, fixing the following webpack bundling error: ``` Module not found: Error: Default condition should be last one ``` Re: https://github.com/isaacs/minimatch/pull/190 Credit: @AviVahl Reviewed-by: @isaacs --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 6494fb65..60d30646 100644 --- a/package.json +++ b/package.json @@ -12,12 +12,12 @@ "exports": { ".": { "import": { - "default": "./dist/mjs/index.js", - "types": "./dist/mjs/index.d.ts" + "types": "./dist/mjs/index.d.ts", + "default": "./dist/mjs/index.js" }, "require": { - "default": "./dist/cjs/index-cjs.js", - "types": "./dist/cjs/index-cjs.d.ts" + "types": "./dist/cjs/index-cjs.d.ts", + "default": "./dist/cjs/index-cjs.js" } } }, From 0142c85947a355da91057913d9a96891fedb60d2 Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 17 Jan 2023 14:21:53 -0800 Subject: [PATCH 045/163] update benchmark script Only show the real time, and include glob v7/v8 for comparison. --- benchmark.sh | 74 +++++++++++++++++++++++++++++++++++++++++----------- prof.sh | 21 ++++++++------- 2 files changed, 71 insertions(+), 24 deletions(-) diff --git a/benchmark.sh b/benchmark.sh index df31b8b2..72643d73 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -1,28 +1,37 @@ #!/bin/bash export CDPATH= +set -e tmp=${TMPDIR:-/tmp} bash make-benchmark-fixture.sh wd=$PWD cd $tmp/benchmark-fixture +tt () { + time "$@" +} + +t () { + tt "$@" 2>&1 | grep real +} + set -e -if [[ "`bash --version`" =~ version\ 4 ]]; then +if [[ "`bash --version`" =~ version\ 4 ]] || [[ "`bash --version`" =~ version\ 5 ]]; then echo Bash timing: - time bash -c 'shopt -s globstar; echo **/*.txt | wc -w' + t bash -c 'shopt -s globstar; echo **/*.txt | wc -w' | grep real fi echo -if type zsh; then +if type zsh &>/dev/null; then echo Zsh timing: - time zsh -c 'echo **/*.txt | wc -w' + t zsh -c 'echo **/*.txt | wc -w' fi echo echo Node statSync and readdirSync timing: -time node -e ' +t node -e ' var fs=require("fs"); var count = 0; function walk (path) { @@ -35,23 +44,58 @@ time node -e ' } } walk("."); - console.log(count)' + console.log(count)' | grep real +echo + +mkdir -p "$wd/old/7" +echo '{"dependencies":{"glob":"7"}}' > "$wd/old/7/package.json" +(cd "$wd/old/7" &>/dev/null; npm i --silent) + +echo Node glob v7 sync timing: +t node -e ' + var glob=require(process.argv[1]) + console.log(glob.sync("**/*.txt").length) +' "$wd/old/7/node_modules/glob" | grep real +echo + +echo Node glob v7 async timing: +t node -e ' + var glob=require(process.argv[1]) + glob("**/*.txt", (er, files) => { + console.log(files.length) + })' "$wd/old/7/node_modules/glob" | grep real echo -echo Node glob.sync timing: -time node -e ' +mkdir -p "$wd/old/8" +echo '{"dependencies":{"glob":"8"}}' > "$wd/old/8/package.json" +(cd "$wd/old/8" &>/dev/null; npm i --silent) + +echo Node glob v8 sync timing: +t node -e ' + var glob=require(process.argv[1]) + console.log(glob.sync("**/*.txt").length) +' "$wd/old/8/node_modules/glob" +echo + +echo Node glob v8 async timing: +t node -e ' + var glob=require(process.argv[1]) + glob("**/*.txt", (er, files) => { + console.log(files.length) + })' "$wd/old/8/node_modules/glob" +echo + + +echo Node current glob.sync timing: +t node -e ' var glob=require(process.argv[1]); console.log(glob.sync("**/*.txt").length);' "$wd" echo -echo Node glob async timing: -time node -e ' +echo Node current glob async timing: +t node -e ' var glob=require(process.argv[1]); - glob("**/*.txt", function (er, files) { + glob("**/*.txt").then((files) => { console.log(files.length) })' "$wd" echo - -echo Node glob with --prof -cd $wd -bash prof.sh diff --git a/prof.sh b/prof.sh index 7fa97fd3..3c5b75a5 100644 --- a/prof.sh +++ b/prof.sh @@ -1,19 +1,22 @@ #!/bin/bash export CDPATH= set -e +set -x tmp=${TMPDIR:-/tmp} -bash make-benchmark-fixture.sh +bash -x make-benchmark-fixture.sh wd=$PWD -cd $tmp/benchmark-fixture +cd "$tmp/benchmark-fixture" -node --prof -e ' - var glob=require(process.argv[1]); - glob("**/*.txt", function (er, files) { - console.log(files.length) - }) - //console.log(glob.sync("**/*.txt").length); - ' "$wd" +cat > "profscript.mjs" < { +// console.log(files.length) +// }) +MJS + +node --prof "$tmp/benchmark-fixture/profscript.mjs" mv *v8.log "$wd/v8.log" cd "$wd" node-tick-processor > profile.txt From a9bbbaa93a7fe556ebfca462e6e1c23172897f94 Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 17 Jan 2023 14:23:02 -0800 Subject: [PATCH 046/163] Avoid creating unnecessary stack traces This makes the glob.sync method MUCH faster, like >30% faster in the benchmark. This implementation is now considerably ahead of v7 and v8. --- src/readdir.ts | 42 +++++++++++++++++++++++------------------- src/walker.ts | 4 ++-- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/readdir.ts b/src/readdir.ts index 101fe879..f1d947e1 100644 --- a/src/readdir.ts +++ b/src/readdir.ts @@ -3,12 +3,16 @@ import { Dirent } from 'fs' -import { readdir as origReaddir, readdirSync as origReaddirSync } from 'fs' +import { + statSync, + readdir as origReaddir, + readdirSync as origReaddirSync, +} from 'fs' import { basename, dirname, resolve } from 'path' // when we read a directory, put its entries in here as well export interface GlobCache { - [path: string]: Dirent[] | NodeJS.ErrnoException + [path: string]: Dirent[] | false } export class Readdir { @@ -42,46 +46,46 @@ export class Readdir { : !!this.lookup(path)?.isDirectory() } - async readdir(path: string): Promise { + async readdir(path: string): Promise { const resolved = resolve(path) const cacheEntry = this.cache[resolved] if (cacheEntry) { if (Array.isArray(cacheEntry)) { return cacheEntry } else { - throw cacheEntry + return false } } - return new Promise((res, rej) => { - origReaddir(resolved, { withFileTypes: true }, (er, entities) => { - this.cache[resolved] = er || entities - if (er) { - rej(er) - } else { - res(entities) - } + return new Promise(res => { + origReaddir(resolved, { withFileTypes: true }, (_, entities) => { + res((this.cache[resolved] = entities || false)) }) }) } - readdirSync(path: string): Dirent[] { + readdirSync(path: string): Dirent[] | false { const resolved = resolve(path) const cacheEntry = this.cache[resolved] if (cacheEntry) { if (Array.isArray(cacheEntry)) { return cacheEntry } else { - throw cacheEntry + return false } } + // try to avoid getting an error object created if we can + // stack traces are expensive, and we don't use them. + const st = statSync(resolved, { throwIfNoEntry: false }) + if (!st || !st.isDirectory()) { + return (this.cache[resolved] = false) + } try { - const entities = origReaddirSync(resolved, { withFileTypes: true }) - this.cache[resolved] = entities - return entities + return (this.cache[resolved] = origReaddirSync(resolved, { + withFileTypes: true, + })) } catch (er) { - this.cache[resolved] = er as NodeJS.ErrnoException - throw er + return (this.cache[resolved] = false) } } } diff --git a/src/walker.ts b/src/walker.ts index d2f8d53e..360155a0 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -180,7 +180,7 @@ export class GlobWalker { // if it's not a directory, or we can't read it, then // that means no match, because we still have pattern to consume try { - entries = await this.rd.readdir(this.start) + entries = await this.rd.readdir(this.start) || [] } catch (er) { return [] } @@ -255,7 +255,7 @@ export class GlobWalker { // if it's not a directory, or we can't read it, then // that means no match, because we still have pattern to consume try { - entries = this.rd.readdirSync(this.start) + entries = this.rd.readdirSync(this.start) || [] } catch (er) { return [] } From 59a9700d6c311004c8fbc8774153defee6f9c05d Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 17 Jan 2023 14:54:10 -0800 Subject: [PATCH 047/163] make benchmark script easier to parse --- benchmark.sh | 104 +++++++++++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 44 deletions(-) diff --git a/benchmark.sh b/benchmark.sh index 72643d73..155a4fd9 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -12,25 +12,20 @@ tt () { } t () { - tt "$@" 2>&1 | grep real + tt "$@" 2>&1 | grep real | awk -F $'\t' '{ print $2 }' } -set -e - if [[ "`bash --version`" =~ version\ 4 ]] || [[ "`bash --version`" =~ version\ 5 ]]; then - echo Bash timing: - t bash -c 'shopt -s globstar; echo **/*.txt | wc -w' | grep real + echo -n $'bash \t' + t bash -c 'shopt -s globstar; echo **/*.txt | wc -w' fi -echo if type zsh &>/dev/null; then - echo Zsh timing: + echo -n $'zsh \t' t zsh -c 'echo **/*.txt | wc -w' fi -echo - -echo Node statSync and readdirSync timing: +echo -n $'node raw \t' t node -e ' var fs=require("fs"); var count = 0; @@ -44,58 +39,79 @@ t node -e ' } } walk("."); - console.log(count)' | grep real -echo - -mkdir -p "$wd/old/7" -echo '{"dependencies":{"glob":"7"}}' > "$wd/old/7/package.json" -(cd "$wd/old/7" &>/dev/null; npm i --silent) + console.log(count)' + +mkdir -p "$wd/old" +cat > "$wd/old/package.json" </dev/null; npm i --silent) -echo Node glob v7 sync timing: +echo -n $'node glob v7 sync \t' t node -e ' var glob=require(process.argv[1]) console.log(glob.sync("**/*.txt").length) -' "$wd/old/7/node_modules/glob" | grep real -echo +' "$wd/old/node_modules/glob7" -echo Node glob v7 async timing: +echo -n $'node glob v7 async \t' t node -e ' var glob=require(process.argv[1]) glob("**/*.txt", (er, files) => { console.log(files.length) - })' "$wd/old/7/node_modules/glob" | grep real -echo - -mkdir -p "$wd/old/8" -echo '{"dependencies":{"glob":"8"}}' > "$wd/old/8/package.json" -(cd "$wd/old/8" &>/dev/null; npm i --silent) + })' "$wd/old/node_modules/glob7" -echo Node glob v8 sync timing: +echo -n $'node glob v8 sync \t' t node -e ' var glob=require(process.argv[1]) console.log(glob.sync("**/*.txt").length) -' "$wd/old/8/node_modules/glob" -echo +' "$wd/old/node_modules/glob8" -echo Node glob v8 async timing: +echo -n $'node glob v8 async \t' t node -e ' var glob=require(process.argv[1]) glob("**/*.txt", (er, files) => { console.log(files.length) - })' "$wd/old/8/node_modules/glob" -echo - - -echo Node current glob.sync timing: + })' "$wd/old/node_modules/glob8" + +echo -n $'node current glob.sync cjs \t' +cat > "$wd/old/sync.cjs" < "$wd/old/async.cjs" < console.log(files.length)) +CJS +t node "$wd/old/async.cjs" + +echo -n $'node current glob.sync mjs \t' +cat > "$wd/old/sync.mjs" < "$wd/old/async.mjs" < console.log(files.length)) +MJS +t node "$wd/old/async.mjs" + +echo -n $'node current glob async cjs -e\t' t node -e ' - var glob=require(process.argv[1]); - console.log(glob.sync("**/*.txt").length);' "$wd" -echo +require(process.argv[1])("**/*.txt").then((files) => console.log(files.length)) +' "$wd/dist/cjs/index-cjs.js" -echo Node current glob async timing: +echo -n $'node current glob sync cjs -e \t' t node -e ' - var glob=require(process.argv[1]); - glob("**/*.txt").then((files) => { - console.log(files.length) - })' "$wd" -echo +console.log(require(process.argv[1]).sync("**/*.txt").length) +' "$wd/dist/cjs/index-cjs.js" From fe5efba2e05d197a06399c41d5f3f7c90c172a01 Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 18 Jan 2023 10:47:05 -0800 Subject: [PATCH 048/163] improve performance somewhat Quite a lot, actually. Still a pathological case where a '**' pattern is followed by multiple glob patterns, especially if the subsequent set of patterns includes another globstar with the same problem, it seems to grow geometrically. So '**/*/*.txt' takes about twice as long as it should, and '**/*/**/*/*.txt' takes about twice as long again, increasining geometrically. Need to rethink the globstar handling approach, maybe the whole shape of the walker class. Currently, it's pretty naive, and the proof of concept I added to test my assumption only works if there'e exactly 1 path portion following the globstar. That is, it makes **/*.txt go as fast as it should, but **/*/*.txt is still slow. Right now, a test for **/*/*.txt in a path a/b/c, with directory child paths [d, e] will create child walkers for the following paths/patterns: */*.txt a/b/c Test without the ** portion, against this path **/*/*.txt a/b/c/d Test with the globstar in each child directory **/*/*.txt a/b/c/e */*.txt a/b/c/d Test without globstar in each child directory */*.txt a/b/c/e This happens at each directory level, so if d and e both have directory children x and y, you get: */*.txt a/b/c/d **/*/*.txt a/b/c/d/x **/*/*.txt a/b/c/d/y */*.txt a/b/c/d/x */*.txt a/b/c/d/y */*.txt a/b/c/e **/*/*.txt a/b/c/e/x **/*/*.txt a/b/c/e/y */*.txt a/b/c/e/x */*.txt a/b/c/e/y Added a check when there's exactly 1 entry after the globstar, but this actually has a bug and isn't scalable anyway. --- benchmark.sh | 210 ++++++++++++++++++++++++++++--------------------- package.json | 2 +- prof.sh | 12 +-- src/glob.ts | 21 +++-- src/readdir.ts | 39 ++++----- src/walker.ts | 73 ++++++++--------- 6 files changed, 193 insertions(+), 164 deletions(-) diff --git a/benchmark.sh b/benchmark.sh index 155a4fd9..a959218f 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -7,111 +7,139 @@ bash make-benchmark-fixture.sh wd=$PWD cd $tmp/benchmark-fixture +mkdir -p "$wd/bench-working-dir" +cat > "$wd/bench-working-dir/package.json" </dev/null; npm i --silent) +fi + tt () { time "$@" } t () { - tt "$@" 2>&1 | grep real | awk -F $'\t' '{ print $2 }' + tt "$@" 2>&1 | grep real | awk -F $'\t' '{ print $2 }' || true } -if [[ "`bash --version`" =~ version\ 4 ]] || [[ "`bash --version`" =~ version\ 5 ]]; then - echo -n $'bash \t' - t bash -c 'shopt -s globstar; echo **/*.txt | wc -w' -fi - -if type zsh &>/dev/null; then - echo -n $'zsh \t' - t zsh -c 'echo **/*.txt | wc -w' -fi - -echo -n $'node raw \t' -t node -e ' - var fs=require("fs"); - var count = 0; - function walk (path) { - if (path.slice(-4) === ".txt") count++; - var stat = fs.statSync(path); - if (stat.isDirectory()) { - fs.readdirSync(path).forEach(function(entry) { - walk(path + "/" + entry); - }) - } - } - walk("."); - console.log(count)' +patterns=( + '**/*.txt' + # './**/*.txt' + './**/**/**/**/**/**/**/**/*.txt' + '**/*/*.txt' + '**/0/**/*.txt' + '**/[0-9]/**/*.txt' + # '0/@([5-9]/*.txt|8/**)' + # '[0-9]/[0-9]/[0-9]/[0-9]/[0-9].txt' + # /**/**/**/**//////**/**//*.txt' + # '**/[5-9]/*.txt' + # '[678]/**/2.txt' + # '0/!(1|2)@(4|5)/**/**/**/**/*.txt' + # '0/!(1|2|@(4|5))/**/**/**/**/*.txt' +) + +for p in "${patterns[@]}"; do + echo + echo "# pattern: $p" + + # if [[ "`bash --version`" =~ version\ 4 ]] || [[ "`bash --version`" =~ version\ 5 ]]; then + # echo -n $'bash \t' + # t bash -c 'shopt -s globstar; echo '"$p"' | wc -w' + # fi + + # if type zsh &>/dev/null; then + # echo -n $'zsh \t' + # t zsh -c 'echo '"$p"' | wc -w' + # fi + + # echo -n $'node glob v7 sync \t' + # t node -e ' + # var glob=require(process.argv[1]) + # console.log(glob.sync(process.argv[2]).length) + # ' "$wd/bench-working-dir/node_modules/glob7" "$p" + + # echo -n $'node glob v7 async \t' + # t node -e ' + # var glob=require(process.argv[1]) + # glob(process.argv[2], (er, files) => { + # console.log(files.length) + # })' "$wd/bench-working-dir/node_modules/glob7" "$p" + + # echo -n $'node glob v8 sync \t' + # t node -e ' + # var glob=require(process.argv[1]) + # console.log(glob.sync(process.argv[2]).length) + # ' "$wd/bench-working-dir/node_modules/glob8" "$p" + + # echo -n $'node glob v8 async \t' + # t node -e ' + # var glob=require(process.argv[1]) + # glob(process.argv[2], (er, files) => { + # console.log(files.length) + # })' "$wd/bench-working-dir/node_modules/glob8" "$p" + + echo -n $'node globby sync \t' + cat > "$wd"/bench-working-dir/globby-sync.mjs < "$wd"/bench-working-dir/globby-async.mjs < { + console.log(files.length) + }) +MJS + t node "$wd/bench-working-dir/globby-async.mjs" "$p" -mkdir -p "$wd/old" -cat > "$wd/old/package.json" </dev/null; npm i --silent) - -echo -n $'node glob v7 sync \t' -t node -e ' - var glob=require(process.argv[1]) - console.log(glob.sync("**/*.txt").length) -' "$wd/old/node_modules/glob7" - -echo -n $'node glob v7 async \t' -t node -e ' - var glob=require(process.argv[1]) - glob("**/*.txt", (er, files) => { - console.log(files.length) - })' "$wd/old/node_modules/glob7" - -echo -n $'node glob v8 sync \t' -t node -e ' - var glob=require(process.argv[1]) - console.log(glob.sync("**/*.txt").length) -' "$wd/old/node_modules/glob8" - -echo -n $'node glob v8 async \t' -t node -e ' - var glob=require(process.argv[1]) - glob("**/*.txt", (er, files) => { - console.log(files.length) - })' "$wd/old/node_modules/glob8" - -echo -n $'node current glob.sync cjs \t' -cat > "$wd/old/sync.cjs" < "$wd/bench-working-dir/sync.cjs" < "$wd/old/async.cjs" < console.log(files.length)) + echo -n $'node current glob async cjs \t' + cat > "$wd/bench-working-dir/async.cjs" < console.log(files.length)) CJS -t node "$wd/old/async.cjs" + t node "$wd/bench-working-dir/async.cjs" "$p" -echo -n $'node current glob.sync mjs \t' -cat > "$wd/old/sync.mjs" < "$wd/bench-working-dir/sync.mjs" < "$wd/old/async.mjs" < console.log(files.length)) + echo -n $'node current glob async mjs \t' + cat > "$wd/bench-working-dir/async.mjs" < console.log(files.length)) MJS -t node "$wd/old/async.mjs" + t node "$wd/bench-working-dir/async.mjs" "$p" + + # echo -n $'node current glob sync cjs -e \t' + # t node -e ' + # console.log(require(process.argv[1]).sync(process.argv[2]).length) + # ' "$wd/dist/cjs/index-cjs.js" "$p" -echo -n $'node current glob async cjs -e\t' -t node -e ' -require(process.argv[1])("**/*.txt").then((files) => console.log(files.length)) -' "$wd/dist/cjs/index-cjs.js" + # echo -n $'node current glob async cjs -e\t' + # t node -e ' + # require(process.argv[1])(process.argv[2]).then((files) => console.log(files.length)) + # ' "$wd/dist/cjs/index-cjs.js" "$p" -echo -n $'node current glob sync cjs -e \t' -t node -e ' -console.log(require(process.argv[1]).sync("**/*.txt").length) -' "$wd/dist/cjs/index-cjs.js" +done diff --git a/package.json b/package.json index 60d30646..47f4ab59 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "profclean": "rm -f v8.log profile.txt", "test-regen": "npm run profclean && TEST_REGEN=1 node --no-warnings --loader ts-node/esm test/00-setup.js", "bench": "bash benchmark.sh", - "prof": "bash prof.sh && cat profile.txt", + "prof": "bash prof.sh", "benchclean": "node benchclean.js" }, "prettier": { diff --git a/prof.sh b/prof.sh index 3c5b75a5..b99cbb6a 100644 --- a/prof.sh +++ b/prof.sh @@ -8,15 +8,11 @@ bash -x make-benchmark-fixture.sh wd=$PWD cd "$tmp/benchmark-fixture" +export __GLOB_PROFILE__=1 + cat > "profscript.mjs" < { -// console.log(files.length) -// }) +console.log(glob.sync("**/*/*.txt").length); MJS -node --prof "$tmp/benchmark-fixture/profscript.mjs" -mv *v8.log "$wd/v8.log" -cd "$wd" -node-tick-processor > profile.txt +node "$tmp/benchmark-fixture/profscript.mjs" diff --git a/src/glob.ts b/src/glob.ts index 3d308ea6..96f178fc 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -109,28 +109,27 @@ export class Glob { processSync() { return this.finish( - this.matchSet.map((set, i) => - this.doNonull(this.getWalker(set as Pattern).walkSync(), i) - ) + this.matchSet.map((set, i) => { + return this.doNonull(this.getWalker(set as Pattern).walkSync(), i) + }) ) } doNonull(matches: string[], i: number): string[] { - if (!matches.length && this.nonull) { - return [this.globSet[i]] - } - return matches + return !matches.length && this.nonull ? [this.globSet[i]] : matches } finish(matches: string[][]): string[] { const raw = matches.reduce((set, m) => set.concat(m), []) const flat = this.nounique ? raw : [...new Set(raw)] - return this.nosort - ? flat - : flat.sort((a, b) => a.localeCompare(b, 'en')) + return this.nosort ? flat : this.sort(flat) + } + + sort(flat: string[]) { + return flat.sort((a, b) => a.localeCompare(b, 'en')) } getWalker(set: Pattern) { - return new GlobWalker(set, '', this) + return new GlobWalker(set, '', this, false) } } diff --git a/src/readdir.ts b/src/readdir.ts index f1d947e1..8b8c8325 100644 --- a/src/readdir.ts +++ b/src/readdir.ts @@ -4,15 +4,15 @@ import { Dirent } from 'fs' import { - statSync, readdir as origReaddir, readdirSync as origReaddirSync, + statSync, } from 'fs' import { basename, dirname, resolve } from 'path' // when we read a directory, put its entries in here as well export interface GlobCache { - [path: string]: Dirent[] | false + [path: string]: Dirent[] | false | Promise } export class Readdir { @@ -30,8 +30,7 @@ export class Readdir { } // look up the Dirent for the path, if it exists - lookup(path: string): Dirent | undefined { - const resolved = resolve(path) + lookup(resolved: string): Dirent | undefined { const dir = dirname(resolved) const entities = this.cache[dir] if (entities && Array.isArray(entities)) { @@ -43,21 +42,23 @@ export class Readdir { const resolved = resolve(path) return this.cache[resolved] ? Array.isArray(this.cache[resolved]) - : !!this.lookup(path)?.isDirectory() + : !!this.lookup(resolved)?.isDirectory() } async readdir(path: string): Promise { const resolved = resolve(path) const cacheEntry = this.cache[resolved] - if (cacheEntry) { - if (Array.isArray(cacheEntry)) { - return cacheEntry - } else { - return false - } + if (cacheEntry !== undefined) { + return cacheEntry + } + + const lu = this.lookup(resolved) + if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) { + return this.cache[resolved] = false } - return new Promise(res => { + // TODO: cache the promise, too + return this.cache[resolved] = new Promise(res => { origReaddir(resolved, { withFileTypes: true }, (_, entities) => { res((this.cache[resolved] = entities || false)) }) @@ -67,13 +68,15 @@ export class Readdir { readdirSync(path: string): Dirent[] | false { const resolved = resolve(path) const cacheEntry = this.cache[resolved] - if (cacheEntry) { - if (Array.isArray(cacheEntry)) { - return cacheEntry - } else { - return false - } + if (Array.isArray(cacheEntry) || cacheEntry === false) { + return cacheEntry + } + + const lu = this.lookup(resolved) + if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) { + return this.cache[resolved] = false } + // try to avoid getting an error object created if we can // stack traces are expensive, and we don't use them. const st = statSync(resolved, { throwIfNoEntry: false }) diff --git a/src/walker.ts b/src/walker.ts index 360155a0..c8c95eb5 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -57,12 +57,13 @@ export class GlobWalker { cache: GlobCache cwd: string start: string - parent?: GlobWalker + hasParent: boolean constructor( pattern: Pattern, path: string, - options: GlobWalkerOptions | GlobWalker = {} + options: GlobWalkerOptions | GlobWalker = {}, + hasParent: boolean = false ) { const { follow = false, @@ -76,9 +77,8 @@ export class GlobWalker { ignore, cwd = '', } = options - if (options instanceof GlobWalker) { - this.parent = options - } + + this.hasParent = hasParent // if the pattern starts with a bunch of strings, then skip ahead this.pattern = [...pattern] @@ -109,7 +109,7 @@ export class GlobWalker { const [first, ...rest] = this.pattern // a pattern like /a/s/d/f discards the cwd // a pattern like / (or c:/ on windows) can only match the root - if (typeof first === 'string' && !this.parent) { + if (typeof first === 'string' && !this.hasParent) { const patternSlash = first === '' && !!rest.length const isWin = process.platform === 'win32' const patternDrive = isWin && /^[a-z]:$/i.test(first) @@ -169,21 +169,15 @@ export class GlobWalker { } child(pattern: Pattern, path: string) { - return new GlobWalker(pattern, path, this) + // console.error('CHILD', path, pattern) + return new GlobWalker(pattern, path, this, true) } async walk(): Promise { if (this.ignore?.childrenIgnored(this.path)) { return [] } - let entries: Dirent[] - // if it's not a directory, or we can't read it, then - // that means no match, because we still have pattern to consume - try { - entries = await this.rd.readdir(this.start) || [] - } catch (er) { - return [] - } + let entries: Dirent[] = (await this.rd.readdir(this.start)) || [] const children = this.getChildren(entries) const matches: (string | string[])[] = await Promise.all( children.map(async c => @@ -193,7 +187,9 @@ export class GlobWalker { ) ) const flat = matches.reduce((set: string[], m) => set.concat(m), []) - return this.ignore ? flat.filter(f => !this.ignore?.ignored(f)) : flat + return this.ignore + ? flat.filter(f => !this.ignore?.ignored(f)) + : flat } finish(p: string | undefined): string | [] { @@ -251,14 +247,8 @@ export class GlobWalker { if (this.ignore?.childrenIgnored(this.path)) { return [] } - let entries: Dirent[] - // if it's not a directory, or we can't read it, then - // that means no match, because we still have pattern to consume - try { - entries = this.rd.readdirSync(this.start) || [] - } catch (er) { - return [] - } + + let entries: Dirent[] = this.rd.readdirSync(this.start) || [] const children = this.getChildren(entries) const matches: (string | string[])[] = children.map(c => { return typeof c === 'string' @@ -266,7 +256,9 @@ export class GlobWalker { : c.walkSync() }) const flat = matches.reduce((set: string[], m) => set.concat(m), []) - return this.ignore ? flat.filter(f => !this.ignore?.ignored(f)) : flat + return this.ignore + ? flat.filter(f => !this.ignore?.ignored(f)) + : flat } join(p: string, base: string = this.path) { @@ -313,20 +305,29 @@ export class GlobWalker { } for (const e of entries) { - if (!this.dot && e.name.startsWith('.')) { - continue - } - const path = this.join(e.name) + // do not match ** to dot files, or traverse into them + const dotCheck = !e.name.startsWith('.') || this.dot // ** does not traverse symlinks, unless follow:true is set. const traverse = - e.isDirectory() || (this.follow && e.isSymbolicLink()) + dotCheck && + (e.isDirectory() || (this.follow && e.isSymbolicLink())) + const path = this.join(e.name) if (traverse) { children.push(this.child(this.pattern, path)) } if (rest) { // can match a/b against child path - children.push(this.child(rest, path)) - } else { + if ( + (typeof rest[0] == 'string' && e.name === rest[0]) || + (rest[0] instanceof RegExp && rest[0].test(e.name)) + ) { + if (rest.length > 1) { + children.push(this.child(rest, path)) + } else { + children.push(path) + } + } + } else if (dotCheck) { // ** at the end, will match all children children.push(path) } @@ -361,12 +362,14 @@ export class GlobWalker { getChildren(entries: Dirent[]): Children { const [p, ...tail] = this.pattern const rest = tail.length ? (tail as Pattern) : null + let ret: Children if (typeof p === 'string') { - return this.getChildrenString(entries, p, rest) + ret = this.getChildrenString(entries, p, rest) } else if (p === GLOBSTAR) { - return this.getChildrenGlobstar(entries, rest) + ret = this.getChildrenGlobstar(entries, rest) } else { - return this.getChildrenRegexp(entries, p, rest) + ret = this.getChildrenRegexp(entries, p, rest) } + return ret } } From 8e7291e8beb6af5424502b90b43db0a0598f602c Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 18 Jan 2023 12:06:21 -0800 Subject: [PATCH 049/163] fix many bugs --- README.md | 6 +- changelog.md | 6 +- src/readdir.ts | 35 +++-- src/walker.ts | 62 +++----- test/00-setup.ts | 1 - test/broken-symlink.ts | 3 +- test/ignore.ts | 3 +- test/mark.ts | 5 +- test/nodir.ts | 3 +- test/nonull.ts | 5 +- test/nosort.ts | 2 +- test/pattern-absolute.ts | 267 +++++++++++++++++++------------- test/readme-issue.ts | 2 +- test/realpath.ts | 8 +- test/slash-cwd.ts | 3 +- test/windows-paths-no-escape.ts | 2 +- 16 files changed, 231 insertions(+), 182 deletions(-) diff --git a/README.md b/README.md index b75dd706..6b6a4316 100644 --- a/README.md +++ b/README.md @@ -291,7 +291,7 @@ _not_ supported by this implementation. Patterns that have excess `/` characters between non-magic portions will have their excess `/` characters preserved in the -result. That is, empty path portions in the pattern will match +result. That is, empty path portions in the pattern will match the parent directory, be appended to the parent path with a `/`, and returned. @@ -340,9 +340,9 @@ an "absolute path" is much more involved. #### UNC Paths -A UNC path may be used as the start of a pattern. For example, a +A UNC path may be used as the start of a pattern. For example, a pattern like: `//?/x:/*` will return all file entries in the root -of the `x:` drive. A pattern like `//ComputerName/Share/*` will +of the `x:` drive. A pattern like `//ComputerName/Share/*` will return all files in the associated share. #### Drive Letters diff --git a/changelog.md b/changelog.md index 0f5b89ef..c9e05b7d 100644 --- a/changelog.md +++ b/changelog.md @@ -14,7 +14,7 @@ This is a full rewrite. back easily if there's demand.) - Simplified `cwd` behavior so it is far less magical, and relies less on platform-specific absolute path representations. -- More efficient handling for absolute patterns. (That is, +- More efficient handling for absolute patterns. (That is, patterns that start with `/` on any platform, or start with a drive letter on Windows.) - Removed all stat calls, in favor of using `withFileTypes:true` @@ -33,10 +33,10 @@ This is a full rewrite. - Only support node 16 and higher. - When `{nonull:true}` is set, and an `ignore` pattern causes all entries to be ignored, then the pattern is returned, as it - would be if no matches were found. This _may_ result in the + would be if no matches were found. This _may_ result in the surprising situation where a pattern like `x/y/z` is returned even, even though the ignore value like `x/**` would have - excluded it. However, _not_ returning anything when + excluded it. However, _not_ returning anything when `nonull:true` is set, is arguably a worse contract violation. - Patterns starting with drive letters on Windows are now properly treated as absolute paths, and the drive letter in an diff --git a/src/readdir.ts b/src/readdir.ts index 8b8c8325..f8c3eac1 100644 --- a/src/readdir.ts +++ b/src/readdir.ts @@ -12,23 +12,18 @@ import { basename, dirname, resolve } from 'path' // when we read a directory, put its entries in here as well export interface GlobCache { - [path: string]: Dirent[] | false | Promise + [path: string]: Dirent[] | false } export class Readdir { cache: GlobCache + pcache: { [path: string]: Promise | undefined } constructor(cache: GlobCache = Object.create(null)) { + this.pcache = Object.create(null) this.cache = cache } - // alias cached lookup from p to realpath rp, if not already set - alias(rp: string, p: string): void { - if (!this.cache[rp]) { - this.cache[rp] = this.cache[p] - } - } - // look up the Dirent for the path, if it exists lookup(resolved: string): Dirent | undefined { const dir = dirname(resolved) @@ -54,15 +49,21 @@ export class Readdir { const lu = this.lookup(resolved) if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) { - return this.cache[resolved] = false + return (this.cache[resolved] = false) + } + + const pc = this.pcache[resolved] + if (pc) { + return pc } // TODO: cache the promise, too - return this.cache[resolved] = new Promise(res => { + return (this.pcache[resolved] = new Promise(res => { origReaddir(resolved, { withFileTypes: true }, (_, entities) => { + this.pcache[resolved] = undefined res((this.cache[resolved] = entities || false)) }) - }) + })) } readdirSync(path: string): Dirent[] | false { @@ -74,20 +75,20 @@ export class Readdir { const lu = this.lookup(resolved) if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) { - return this.cache[resolved] = false + return (this.cache[resolved] = false) } // try to avoid getting an error object created if we can // stack traces are expensive, and we don't use them. - const st = statSync(resolved, { throwIfNoEntry: false }) - if (!st || !st.isDirectory()) { - return (this.cache[resolved] = false) - } try { + const st = statSync(resolved, { throwIfNoEntry: false }) + if (!st || !st.isDirectory()) { + return (this.cache[resolved] = false) + } return (this.cache[resolved] = origReaddirSync(resolved, { withFileTypes: true, })) - } catch (er) { + } catch (_) { return (this.cache[resolved] = false) } } diff --git a/src/walker.ts b/src/walker.ts index c8c95eb5..b68acecf 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -177,7 +177,10 @@ export class GlobWalker { if (this.ignore?.childrenIgnored(this.path)) { return [] } - let entries: Dirent[] = (await this.rd.readdir(this.start)) || [] + let entries: Dirent[] | false = await this.rd.readdir(this.start) + if (!entries) { + return [] + } const children = this.getChildren(entries) const matches: (string | string[])[] = await Promise.all( children.map(async c => @@ -187,9 +190,7 @@ export class GlobWalker { ) ) const flat = matches.reduce((set: string[], m) => set.concat(m), []) - return this.ignore - ? flat.filter(f => !this.ignore?.ignored(f)) - : flat + return this.ignore ? flat.filter(f => !this.ignore?.ignored(f)) : flat } finish(p: string | undefined): string | [] { @@ -214,33 +215,28 @@ export class GlobWalker { if (!this.realpath && !this.absolute) { return p } - const pp = this.join(p, this.cwd) + const pp = resolve(this.join(p, this.cwd)) if (!this.realpath) { - return resolve(pp) + return pp } - const rp: string = await new Promise(res => - realpath(pp, (er, rp) => (er ? res(resolve(pp)) : res(rp))) + return await new Promise(res => + realpath(pp, (er, rp) => (er ? res(pp) : res(rp))) ) - this.rd.alias(rp, pp) - return rp } doRealpathSync(p: string): string | undefined { if (!this.realpath && !this.absolute) { return p } - const pp = this.join(p, this.cwd) + const pp = resolve(this.join(p, this.cwd)) if (!this.realpath) { - return resolve(pp) + return pp } - let rp: string try { - rp = realpathSync(pp) + return realpathSync(pp) } catch (_) { - rp = resolve(pp) + return pp } - this.rd.alias(rp, pp) - return rp } walkSync(): string[] { @@ -248,7 +244,10 @@ export class GlobWalker { return [] } - let entries: Dirent[] = this.rd.readdirSync(this.start) || [] + let entries: Dirent[] | false = this.rd.readdirSync(this.start) + if (!entries) { + return [] + } const children = this.getChildren(entries) const matches: (string | string[])[] = children.map(c => { return typeof c === 'string' @@ -256,9 +255,7 @@ export class GlobWalker { : c.walkSync() }) const flat = matches.reduce((set: string[], m) => set.concat(m), []) - return this.ignore - ? flat.filter(f => !this.ignore?.ignored(f)) - : flat + return this.ignore ? flat.filter(f => !this.ignore?.ignored(f)) : flat } join(p: string, base: string = this.path) { @@ -305,29 +302,20 @@ export class GlobWalker { } for (const e of entries) { - // do not match ** to dot files, or traverse into them - const dotCheck = !e.name.startsWith('.') || this.dot + if (!this.dot && e.name.startsWith('.')) { + continue + } + const path = this.join(e.name) // ** does not traverse symlinks, unless follow:true is set. const traverse = - dotCheck && - (e.isDirectory() || (this.follow && e.isSymbolicLink())) - const path = this.join(e.name) + e.isDirectory() || (this.follow && e.isSymbolicLink()) if (traverse) { children.push(this.child(this.pattern, path)) } if (rest) { // can match a/b against child path - if ( - (typeof rest[0] == 'string' && e.name === rest[0]) || - (rest[0] instanceof RegExp && rest[0].test(e.name)) - ) { - if (rest.length > 1) { - children.push(this.child(rest, path)) - } else { - children.push(path) - } - } - } else if (dotCheck) { + children.push(this.child(rest, path)) + } else { // ** at the end, will match all children children.push(path) } diff --git a/test/00-setup.ts b/test/00-setup.ts index 47ce7d7d..1024d8b9 100644 --- a/test/00-setup.ts +++ b/test/00-setup.ts @@ -62,7 +62,6 @@ if (process.platform !== 'win32') { if (process.platform === 'win32' || !process.env.TEST_REGEN) { console.error('Windows, or TEST_REGEN unset. Using cached fixtures.') } else { - const globs = // put more patterns here. // anything that would be directly in / should be in /tmp/glob-test diff --git a/test/broken-symlink.ts b/test/broken-symlink.ts index 797136e9..ca1ca89e 100644 --- a/test/broken-symlink.ts +++ b/test/broken-symlink.ts @@ -1,6 +1,7 @@ import { relative } from 'path' import t from 'tap' -import { glob, GlobOptions } from '../' +import { glob } from '../' +import type { GlobOptions } from '../src/index.js' if (process.platform === 'win32') { t.plan(0, 'skip on windows') diff --git a/test/ignore.ts b/test/ignore.ts index f4b1fd40..3d6cf874 100644 --- a/test/ignore.ts +++ b/test/ignore.ts @@ -2,7 +2,8 @@ // Show that glob ignores results matching pattern on ignore option import t from 'tap' -import glob, { GlobOptions } from '../' +import glob from '../' +import type { GlobOptions } from '../src/index.js' // [pattern, ignore, expect, opt (object) or cwd (string)] type Case = [ diff --git a/test/mark.ts b/test/mark.ts index c715ffbb..47996b94 100644 --- a/test/mark.ts +++ b/test/mark.ts @@ -44,9 +44,8 @@ t.test('mark, with **', async t => { 'a/cb/e/f', ] - const results = await glob(pattern, opt) - t.same(results, expect) - t.same(glob.sync(pattern, opt), expect) + t.same(await glob(pattern, opt), expect, 'async') + t.same(glob.sync(pattern, opt), expect, 'sync') }) t.test('mark, no / on pattern', async t => { diff --git a/test/nodir.ts b/test/nodir.ts index 48722ee2..2c4fc676 100644 --- a/test/nodir.ts +++ b/test/nodir.ts @@ -1,6 +1,7 @@ import { resolve } from 'path' import t from 'tap' -import glob, { GlobOptions } from '../' +import glob from '../' +import type { GlobOptions } from '../src/index.js' process.chdir(__dirname + '/fixtures') // [pattern, options, expect] diff --git a/test/nonull.ts b/test/nonull.ts index ba08ae8e..2946a101 100644 --- a/test/nonull.ts +++ b/test/nonull.ts @@ -1,9 +1,10 @@ import t from 'tap' -import {glob, GlobOptions} from '../' +import { glob } from '../' +import type { GlobOptions } from '../src/index.js' process.chdir(__dirname) // [pattern, options, expect] -const cases:[string, GlobOptions, string[]][] = [ +const cases: [string, GlobOptions, string[]][] = [ ['a/*NOFILE*/**/', {}, ['a/*NOFILE*/**/']], ['*/*', { cwd: 'NODIR' }, ['*/*']], ['NOFILE', {}, ['NOFILE']], diff --git a/test/nosort.ts b/test/nosort.ts index 3e92663c..00bbbb84 100644 --- a/test/nosort.ts +++ b/test/nosort.ts @@ -1,6 +1,6 @@ import * as fs from 'fs' import { Dirent, readdir, readdirSync } from 'fs' -import {resolve} from 'path' +import { resolve } from 'path' import t from 'tap' const { glob } = t.mock('../dist/cjs/index.js', { fs: { diff --git a/test/pattern-absolute.ts b/test/pattern-absolute.ts index cd0275f7..f18b51b2 100644 --- a/test/pattern-absolute.ts +++ b/test/pattern-absolute.ts @@ -3,15 +3,15 @@ // This is a weirdly specific test of unexported implementation, not my // favorite, but it is the easiest way to verify what we expect here. import t from 'tap' -import {GlobWalker} from '../dist/cjs/walker.js' - -const setPlatform = (platform:string) => { -Object.defineProperty(process, 'platform', { - value: platform, - enumerable: true, - configurable: true, - writable: true, -}) +import { GlobWalker } from '../dist/cjs/walker.js' + +const setPlatform = (platform: string) => { + Object.defineProperty(process, 'platform', { + value: platform, + enumerable: true, + configurable: true, + writable: true, + }) } const { platform } = process @@ -21,34 +21,49 @@ t.test('posix', t => { setPlatform('posix') // pattern like [a]/[b] - t.match(new GlobWalker([/^[a]$/, /^[b]$/], ''), { - pattern: [/^[a]$/, /^[b]$/], - path: '', - cwd: '', - start: '.', - }, 'pattern=[a]/[b] path=""') - - t.match(new GlobWalker(['', ''], '/tmp'), { - pattern: [''], - path: '/', - cwd: '', - start: '/', - }, 'pattern=/') - - t.match(new GlobWalker(['', 'x'], '/tmp'), { - pattern: ['x'], - path: '/', - cwd: '', - start: '/', - }, 'pattern=/x') - - t.match(new GlobWalker(['', 'x'], '/tmp', { cwd: '/a/b/c/d' }), { - pattern: ['x'], - path: '/', - cwd: '', - start: '/', - }, 'pattern=/x') - + t.match( + new GlobWalker([/^[a]$/, /^[b]$/], ''), + { + pattern: [/^[a]$/, /^[b]$/], + path: '', + cwd: '', + start: '.', + }, + 'pattern=[a]/[b] path=""' + ) + + t.match( + new GlobWalker(['', ''], '/tmp'), + { + pattern: [''], + path: '/', + cwd: '', + start: '/', + }, + 'pattern=/' + ) + + t.match( + new GlobWalker(['', 'x'], '/tmp'), + { + pattern: ['x'], + path: '/', + cwd: '', + start: '/', + }, + 'pattern=/x' + ) + + t.match( + new GlobWalker(['', 'x'], '/tmp', { cwd: '/a/b/c/d' }), + { + pattern: ['x'], + path: '/', + cwd: '', + start: '/', + }, + 'pattern=/x' + ) t.match(new GlobWalker(['c:'], 'd:/tmp'), { pattern: ['c:'], @@ -70,75 +85,115 @@ t.test('posix', t => { t.test('win32', t => { setPlatform('win32') - t.match(new GlobWalker(['', ''], '/tmp'), { - pattern: [''], - path: '/', - cwd: '/', - start: '/', - }, 'pattern=/') - - t.match(new GlobWalker(['', 'x'], '/tmp'), { - pattern: ['x'], - path: '/', - cwd: '/', - start: '/', - }, 'pattern=/x') - - t.match(new GlobWalker(['', 'x'], '/tmp'), { - pattern: ['x'], - path: '/', - cwd: '/', - start: '/', - }, 'pattern=/x') - - t.match(new GlobWalker(['', ''], 'd:/tmp'), { - pattern: [''], - path: 'd:/', - cwd: 'd:/', - start: 'd:/', - }, 'pattern=/, path=d:/tmp') - - t.match(new GlobWalker(['', 'x'], 'x:/tmp'), { - pattern: ['x'], - path: 'x:', - cwd: 'x:', - start: 'x:', - }, 'pattern=/x, path=x:/tmp') - - t.match(new GlobWalker(['', 'x'], 'y:/tmp'), { - pattern: ['x'], - path: 'y:', - cwd: 'y:', - start: 'y:', - }, 'pattern=/x path=y:/tmp') - - t.match(new GlobWalker(['c:'], 'd:/tmp'), { - pattern: [''], - path: 'c:', - cwd: 'c:', - start: 'c:', - }, 'pattern=c: path=d:/tmp') - - t.match(new GlobWalker(['c:', 'x'], 'd:/tmp'), { - pattern: ['x'], - path: 'c:', - cwd: 'c:', - start: 'c:', - }, 'pattern=c:/x path=d:/tmp') - - t.match(new GlobWalker(['', '', '?', 'c:'], 'd:/tmp'), { - pattern: [''], - path: '/?/c:', - cwd: '/', - start: '//?/c:', - }, 'pattern=//?/c: path=d:/tmp') - - t.match(new GlobWalker(['', '', '?', 'c:', /^[ab]$/], 'd:/tmp'), { - pattern: [/^[ab]$/], - path: '/?/c:', - cwd: '/', - start: '//?/c:', - }, 'pattern=//?/c:/[ab] path=d:/tmp') + t.match( + new GlobWalker(['', ''], '/tmp'), + { + pattern: [''], + path: '/', + cwd: '/', + start: '/', + }, + 'pattern=/' + ) + + t.match( + new GlobWalker(['', 'x'], '/tmp'), + { + pattern: ['x'], + path: '/', + cwd: '/', + start: '/', + }, + 'pattern=/x' + ) + + t.match( + new GlobWalker(['', 'x'], '/tmp'), + { + pattern: ['x'], + path: '/', + cwd: '/', + start: '/', + }, + 'pattern=/x' + ) + + t.match( + new GlobWalker(['', ''], 'd:/tmp'), + { + pattern: [''], + path: 'd:/', + cwd: 'd:/', + start: 'd:/', + }, + 'pattern=/, path=d:/tmp' + ) + + t.match( + new GlobWalker(['', 'x'], 'x:/tmp'), + { + pattern: ['x'], + path: 'x:', + cwd: 'x:', + start: 'x:', + }, + 'pattern=/x, path=x:/tmp' + ) + + t.match( + new GlobWalker(['', 'x'], 'y:/tmp'), + { + pattern: ['x'], + path: 'y:', + cwd: 'y:', + start: 'y:', + }, + 'pattern=/x path=y:/tmp' + ) + + t.match( + new GlobWalker(['c:'], 'd:/tmp'), + { + pattern: [''], + path: 'c:', + cwd: 'c:', + start: 'c:', + }, + 'pattern=c: path=d:/tmp' + ) + + t.match( + new GlobWalker(['c:', 'x'], 'd:/tmp'), + { + pattern: ['x'], + path: 'c:', + cwd: 'c:', + start: 'c:', + }, + 'pattern=c:/x path=d:/tmp' + ) + + t.match( + new GlobWalker(['', '', '?', 'c:'], 'd:/tmp'), + { + pattern: [''], + path: '/?/c:', + cwd: '/', + start: '//?/c:', + }, + 'pattern=//?/c: path=d:/tmp' + ) + + t.match( + new GlobWalker(['', '', '?', 'c:', /^[ab]$/], 'd:/tmp'), + { + pattern: [/^[ab]$/], + path: '/?/c:', + cwd: '/', + start: '//?/c:', + }, + 'pattern=//?/c:/[ab] path=d:/tmp' + ) t.end() }) diff --git a/test/readme-issue.ts b/test/readme-issue.ts index dd45be52..28a72cf7 100644 --- a/test/readme-issue.ts +++ b/test/readme-issue.ts @@ -3,7 +3,7 @@ import glob from '../' const dir = t.testdir({ 'package.json': '{}', - 'README': 'x', + README: 'x', }) t.test('glob', async t => { diff --git a/test/realpath.ts b/test/realpath.ts index 24e1b8e3..04287668 100644 --- a/test/realpath.ts +++ b/test/realpath.ts @@ -1,7 +1,8 @@ import * as fs from 'fs' import { resolve } from 'path' import t from 'tap' -import glob, { GlobOptions } from '../' +import glob from '../' +import type { GlobOptions } from '../src/index.js' // pattern to find a bunch of duplicates const pattern = 'a/symlink/{*,**/*/*/*,*/*/**,*/*/*/*/*/*}' @@ -129,8 +130,9 @@ if (process.platform === 'win32') { }, }) const pattern = 'a/symlink/a/b/c/a/b/**' - const expect = ['a/symlink/a/b/c/a/b/', 'a/symlink/a/b/c/a/b/c'] - .map(e => resolve(fixtureDir, e)) + const expect = ['a/symlink/a/b/c/a/b/', 'a/symlink/a/b/c/a/b/c'].map( + e => resolve(fixtureDir, e) + ) t.test('setting cwd explicitly', async t => { const opt = { realpath: true, cwd: fixtureDir } t.same(glob.sync(pattern, opt), expect) diff --git a/test/slash-cwd.ts b/test/slash-cwd.ts index 1f72689a..d54f048b 100644 --- a/test/slash-cwd.ts +++ b/test/slash-cwd.ts @@ -1,7 +1,8 @@ // regression test to make sure that slash-ended patterns // don't match files when using a different cwd. import t from 'tap' -import glob, { GlobOptions } from '../' +import glob from '../' +import type { GlobOptions } from '../src/index.js' const pattern = '../{*.md,test}/' const expect = ['../test/'] diff --git a/test/windows-paths-no-escape.ts b/test/windows-paths-no-escape.ts index 58681306..997162a9 100644 --- a/test/windows-paths-no-escape.ts +++ b/test/windows-paths-no-escape.ts @@ -1,5 +1,5 @@ import t from 'tap' -import {Glob} from '../' +import { Glob } from '../' const platforms = ['win32', 'posix'] const originalPlatform = Object.getOwnPropertyDescriptor( From 732430aa554b8f3e82d92a74060a995438418fed Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 18 Jan 2023 12:10:51 -0800 Subject: [PATCH 050/163] fix benchclean script --- benchclean.js | 4 +--- package-lock.json | 14 +++++++------- package.json | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/benchclean.js b/benchclean.js index 462ccbb1..718479e6 100644 --- a/benchclean.js +++ b/benchclean.js @@ -1,5 +1,3 @@ var rimraf = require('rimraf') var bf = (process.env.TMPDIR || '/tmp') + '/benchmark-fixture' -rimraf('{' + [bf, 'v8.log', 'profile.txt'].join(',') + '}', function (er) { - if (er) throw er -}) +rimraf.sync(bf) diff --git a/package-lock.json b/package-lock.json index 6eebba0d..cde6f012 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "eslint-config-prettier": "^8.6.0", "mkdirp": "^2.0.0", "prettier": "^2.8.3", - "rimraf": "^4.0.7", + "rimraf": "^4.1.1", "tap": "^16.3.4", "ts-node": "^10.9.1", "typedoc": "^0.23.24", @@ -3438,9 +3438,9 @@ } }, "node_modules/rimraf": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.0.7.tgz", - "integrity": "sha512-CUEDDrZvc0swDgVdXGiv3FcYYQMpJxjvSGt85Amj6yU+MCVWurrLCeLiJDdJPHCzNJnwuebBEdcO//eP11Xa7w==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.1.tgz", + "integrity": "sha512-Z4Y81w8atcvaJuJuBB88VpADRH66okZAuEm+Jtaufa+s7rZmIz+Hik2G53kGaNytE7lsfXyWktTmfVz0H9xuDg==", "dev": true, "bin": { "rimraf": "dist/cjs/src/bin.js" @@ -8918,9 +8918,9 @@ "peer": true }, "rimraf": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.0.7.tgz", - "integrity": "sha512-CUEDDrZvc0swDgVdXGiv3FcYYQMpJxjvSGt85Amj6yU+MCVWurrLCeLiJDdJPHCzNJnwuebBEdcO//eP11Xa7w==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.1.tgz", + "integrity": "sha512-Z4Y81w8atcvaJuJuBB88VpADRH66okZAuEm+Jtaufa+s7rZmIz+Hik2G53kGaNytE7lsfXyWktTmfVz0H9xuDg==", "dev": true }, "run-parallel": { diff --git a/package.json b/package.json index 47f4ab59..e1e3890d 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "eslint-config-prettier": "^8.6.0", "mkdirp": "^2.0.0", "prettier": "^2.8.3", - "rimraf": "^4.0.7", + "rimraf": "^4.1.1", "tap": "^16.3.4", "ts-node": "^10.9.1", "typedoc": "^0.23.24", From 210eb464b1f85eb631a5a72516c4eb7297e1380c Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 18 Jan 2023 12:15:48 -0800 Subject: [PATCH 051/163] fake stat for linux tests --- test/nocase-nomagic.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/nocase-nomagic.ts b/test/nocase-nomagic.ts index 3b617845..34f571f3 100644 --- a/test/nocase-nomagic.ts +++ b/test/nocase-nomagic.ts @@ -11,6 +11,14 @@ const fakeStat = ( ): { isDirectory: () => boolean; isSymbolicLink: () => boolean } => { let ret: { isDirectory: () => boolean; isSymbolicLink: () => false } switch (path.toLowerCase().replace(/\\/g, '/')) { + case '/': + case drive + '/': + case drive: + ret = { + isSymbolicLink: () => false, + isDirectory: () => true, + } + break case '/tmp': case '/tmp/': case drive + ':/tmp': @@ -58,6 +66,7 @@ function fakeReaddir(path: string) { const mockFs = { ...fs, + statSync: fakeStat, readdir: ( path: string, _options: { withFileTypes: true }, From 87a8f30b57f8135f5edc662434867a60d523a75c Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 18 Jan 2023 17:32:14 -0800 Subject: [PATCH 052/163] make pattern-absolute test windows-friendly --- test/pattern-absolute.ts | 100 +++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/test/pattern-absolute.ts b/test/pattern-absolute.ts index f18b51b2..abc9110c 100644 --- a/test/pattern-absolute.ts +++ b/test/pattern-absolute.ts @@ -3,7 +3,7 @@ // This is a weirdly specific test of unexported implementation, not my // favorite, but it is the easiest way to verify what we expect here. import t from 'tap' -import { GlobWalker } from '../dist/cjs/walker.js' +import { posix, win32 } from 'path' const setPlatform = (platform: string) => { Object.defineProperty(process, 'platform', { @@ -19,6 +19,10 @@ t.teardown(() => setPlatform(platform)) t.test('posix', t => { setPlatform('posix') + const root = '/' + const { GlobWalker } = t.mock('../dist/cjs/walker.js', { + path: posix, + }) // pattern like [a]/[b] t.match( @@ -36,9 +40,9 @@ t.test('posix', t => { new GlobWalker(['', ''], '/tmp'), { pattern: [''], - path: '/', + path: root, cwd: '', - start: '/', + start: root, }, 'pattern=/' ) @@ -47,9 +51,9 @@ t.test('posix', t => { new GlobWalker(['', 'x'], '/tmp'), { pattern: ['x'], - path: '/', + path: root, cwd: '', - start: '/', + start: root, }, 'pattern=/x' ) @@ -58,25 +62,25 @@ t.test('posix', t => { new GlobWalker(['', 'x'], '/tmp', { cwd: '/a/b/c/d' }), { pattern: ['x'], - path: '/', + path: root, cwd: '', - start: '/', + start: root, }, 'pattern=/x' ) - t.match(new GlobWalker(['c:'], 'd:/tmp'), { - pattern: ['c:'], - path: 'd:/tmp', + t.match(new GlobWalker(['p:'], 'q:/tmp'), { + pattern: ['p:'], + path: 'q:/tmp', cwd: '', - start: 'd:/tmp', + start: 'q:/tmp', }) - t.match(new GlobWalker(['c:', 'x'], 'd:/tmp'), { + t.match(new GlobWalker(['p:', 'x'], 'q:/tmp'), { pattern: ['x'], - path: 'd:/tmp/c:', + path: 'q:/tmp/p:', cwd: '', - start: 'd:/tmp/c:', + start: 'q:/tmp/p:', }) t.end() @@ -84,14 +88,18 @@ t.test('posix', t => { t.test('win32', t => { setPlatform('win32') + const { GlobWalker } = t.mock('../dist/cjs/walker.js', { + path: win32, + }) + const root = win32.resolve('/') t.match( new GlobWalker(['', ''], '/tmp'), { pattern: [''], - path: '/', - cwd: '/', - start: '/', + path: root, + cwd: root, + start: root, }, 'pattern=/' ) @@ -100,9 +108,9 @@ t.test('win32', t => { new GlobWalker(['', 'x'], '/tmp'), { pattern: ['x'], - path: '/', - cwd: '/', - start: '/', + path: root, + cwd: root, + start: root, }, 'pattern=/x' ) @@ -111,22 +119,22 @@ t.test('win32', t => { new GlobWalker(['', 'x'], '/tmp'), { pattern: ['x'], - path: '/', - cwd: '/', - start: '/', + path: root, + cwd: root, + start: root, }, 'pattern=/x' ) t.match( - new GlobWalker(['', ''], 'd:/tmp'), + new GlobWalker(['', ''], 'q:/tmp'), { pattern: [''], - path: 'd:/', - cwd: 'd:/', - start: 'd:/', + path: 'q:/', + cwd: 'q:/', + start: 'q:/', }, - 'pattern=/, path=d:/tmp' + 'pattern=/, path=q:/tmp' ) t.match( @@ -152,47 +160,47 @@ t.test('win32', t => { ) t.match( - new GlobWalker(['c:'], 'd:/tmp'), + new GlobWalker(['p:'], 'q:/tmp'), { pattern: [''], - path: 'c:', - cwd: 'c:', - start: 'c:', + path: 'p:', + cwd: 'p:', + start: 'p:', }, - 'pattern=c: path=d:/tmp' + 'pattern=c: path=q:/tmp' ) t.match( - new GlobWalker(['c:', 'x'], 'd:/tmp'), + new GlobWalker(['p:', 'x'], 'q:/tmp'), { pattern: ['x'], - path: 'c:', - cwd: 'c:', - start: 'c:', + path: 'p:', + cwd: 'p:', + start: 'p:', }, - 'pattern=c:/x path=d:/tmp' + 'pattern=c:/x path=q:/tmp' ) t.match( - new GlobWalker(['', '', '?', 'c:'], 'd:/tmp'), + new GlobWalker(['', '', '?', 'p:'], 'q:/tmp'), { pattern: [''], - path: '/?/c:', + path: '/?/p:', cwd: '/', - start: '//?/c:', + start: '//?/p:', }, - 'pattern=//?/c: path=d:/tmp' + 'pattern=//?/p: path=q:/tmp' ) t.match( - new GlobWalker(['', '', '?', 'c:', /^[ab]$/], 'd:/tmp'), + new GlobWalker(['', '', '?', 'p:', /^[ab]$/], 'q:/tmp'), { pattern: [/^[ab]$/], - path: '/?/c:', + path: '/?/p:', cwd: '/', - start: '//?/c:', + start: '//?/p:', }, - 'pattern=//?/c:/[ab] path=d:/tmp' + 'pattern=//?/p:/[ab] path=q:/tmp' ) t.end() From b2f561497b8ec34f1f4f128eb523a0bedd7da273 Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 18 Jan 2023 20:15:53 -0800 Subject: [PATCH 053/163] comments --- src/walker.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/walker.ts b/src/walker.ts index b68acecf..407644e8 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -147,6 +147,8 @@ export class GlobWalker { this.path = first || root || '/' } } + + // skip ahead any literal portions, and read that dir instead while ( this.pattern.length > 1 && typeof this.pattern[0] === 'string' @@ -157,6 +159,9 @@ export class GlobWalker { : this.join(this.pattern[0]) this.pattern.shift() } + + // match bash behavior, discard any empty path portions that + // follow a path portion with magic chars while ( (this.pattern[0] instanceof RegExp || this.pattern[0] === GLOBSTAR) && @@ -165,6 +170,8 @@ export class GlobWalker { ) { this.pattern.splice(1, 1) } + + // this is the dir to read return this.join(this.path, this.cwd) || '.' } From a7c542d3f8207548c336ab7484601e461b0ddd42 Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 18 Jan 2023 20:17:01 -0800 Subject: [PATCH 054/163] run benchmarks locally, not in TMPDIR --- .gitignore | 1 + benchclean.js | 2 +- benchmark.sh | 7 +++---- make-benchmark-fixture.sh | 10 ++++++---- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index f8dfd121..5ce40583 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /.nyc_output /coverage /test/fixtures +/bench-working-dir diff --git a/benchclean.js b/benchclean.js index 718479e6..d768826a 100644 --- a/benchclean.js +++ b/benchclean.js @@ -1,3 +1,3 @@ var rimraf = require('rimraf') -var bf = (process.env.TMPDIR || '/tmp') + '/benchmark-fixture' +var bf = './bench-working-dir/fixture' rimraf.sync(bf) diff --git a/benchmark.sh b/benchmark.sh index a959218f..6326cd37 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -2,12 +2,11 @@ export CDPATH= set -e -tmp=${TMPDIR:-/tmp} bash make-benchmark-fixture.sh wd=$PWD -cd $tmp/benchmark-fixture -mkdir -p "$wd/bench-working-dir" +mkdir -p "$wd/bench-working-dir/fixture" +cd "$wd/bench-working-dir" cat > "$wd/bench-working-dir/package.json" < Date: Wed, 18 Jan 2023 23:29:37 -0800 Subject: [PATCH 055/163] wip, getting closer, realpath broken for some reason --- benchmark.sh | 4 +- prof.sh | 14 +++-- src/glob.ts | 21 ++++--- src/readdir.ts | 7 ++- src/walker.ts | 155 ++++++++++++++++++++++++++++++++++--------------- 5 files changed, 139 insertions(+), 62 deletions(-) diff --git a/benchmark.sh b/benchmark.sh index 6326cd37..1f1e2199 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -32,11 +32,13 @@ t () { } patterns=( + './**/0/**/0/**/0/**/0/**/*.txt' + './**/0/**/0/**/*.txt' '**/*.txt' # './**/*.txt' './**/**/**/**/**/**/**/**/*.txt' '**/*/*.txt' - './**/0/**/0/**/*.txt' + '**/*/**/*.txt' '**/[0-9]/**/*.txt' # '0/@([5-9]/*.txt|8/**)' # '[0-9]/[0-9]/[0-9]/[0-9]/[0-9].txt' diff --git a/prof.sh b/prof.sh index b99cbb6a..618a1812 100644 --- a/prof.sh +++ b/prof.sh @@ -3,16 +3,22 @@ export CDPATH= set -e set -x -tmp=${TMPDIR:-/tmp} bash -x make-benchmark-fixture.sh wd=$PWD -cd "$tmp/benchmark-fixture" +tmp="$wd/bench-working-dir" +cd "$tmp" export __GLOB_PROFILE__=1 cat > "profscript.mjs" < profile.out +mkdir -p profiles +d=./profiles/$(date +%s) +mv isolate*.log ${d}.log +node --prof-process ${d}.log > ${d}.txt +cp ${d}.txt ../profile.txt +#cat ${d}.txt diff --git a/src/glob.ts b/src/glob.ts index 96f178fc..84acbf8f 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -37,6 +37,7 @@ export class Glob { windowsPathsNoEscape: boolean noglobstar: boolean cache: GlobCache + matches?: Set constructor( pattern: string | string[], @@ -48,6 +49,9 @@ export class Glob { this.nodir = !!options.nodir this.mark = !!options.mark this.nounique = !!options.nounique + if (this.nounique) { + this.matches = new Set() + } this.nosort = !!options.nosort this.cwd = options.cwd || '' if (process.platform === 'win32') { @@ -110,19 +114,22 @@ export class Glob { processSync() { return this.finish( this.matchSet.map((set, i) => { - return this.doNonull(this.getWalker(set as Pattern).walkSync(), i) + const matches = this.getWalker(set as Pattern).walkSync() + return this.doNonull(matches, i) }) ) } - doNonull(matches: string[], i: number): string[] { - return !matches.length && this.nonull ? [this.globSet[i]] : matches + doNonull(matches: Set, i: number): Set { + return !matches.size && this.nonull ? new Set([this.globSet[i]]) : matches } - finish(matches: string[][]): string[] { - const raw = matches.reduce((set, m) => set.concat(m), []) - const flat = this.nounique ? raw : [...new Set(raw)] - return this.nosort ? flat : this.sort(flat) + finish(matches: Set[]): string[] { + const raw: string[] = [] + for (const set of matches) { + raw.push(...set) + } + return this.nosort ? raw : this.sort(raw) } sort(flat: string[]) { diff --git a/src/readdir.ts b/src/readdir.ts index f8c3eac1..d938cd07 100644 --- a/src/readdir.ts +++ b/src/readdir.ts @@ -35,8 +35,11 @@ export class Readdir { isDirectory(path: string): boolean { const resolved = resolve(path) - return this.cache[resolved] - ? Array.isArray(this.cache[resolved]) + const cached = this.cache[resolved] + return Array.isArray(cached) + ? true + : cached === false + ? false : !!this.lookup(resolved)?.isDirectory() } diff --git a/src/walker.ts b/src/walker.ts index 407644e8..659ad838 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -21,14 +21,16 @@ import { resolve } from 'path' import { Ignore } from './ignore.js' import { GlobCache, Readdir } from './readdir.js' +type MMRegExp = RegExp & { _glob: string } + // a single minimatch set entry with 1 or more parts -type ParseReturnFiltered = string | RegExp | typeof GLOBSTAR +type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR export type Pattern = [ p: ParseReturnFiltered, ...rest: ParseReturnFiltered[] ] -type Children = (GlobWalker | string)[] +type Children = (GlobWalker | string | undefined)[] export interface GlobWalkerOptions { follow?: boolean @@ -41,6 +43,8 @@ export interface GlobWalkerOptions { dot?: boolean absolute?: boolean cwd?: string + matches?: Set + seen?: Map> } export class GlobWalker { @@ -58,6 +62,10 @@ export class GlobWalker { cwd: string start: string hasParent: boolean + matches: Set + seen: Map> + + //pkey: string constructor( pattern: Pattern, @@ -76,9 +84,25 @@ export class GlobWalker { cache, ignore, cwd = '', + matches = new Set(), + seen = new Map(), } = options + this.matches = matches this.hasParent = hasParent + this.seen = seen + + //this.pkey = pattern + // .map(p => + // p === GLOBSTAR ? '**' : p instanceof RegExp ? p._glob : p + // ) + // .join('/') + //const pathSeen = seen.get(path) + //if (!pathSeen) { + // seen.set(path, new Set([this.pkey])) + //} else { + // pathSeen.add(this.pkey) + //} // if the pattern starts with a bunch of strings, then skip ahead this.pattern = [...pattern] @@ -175,50 +199,54 @@ export class GlobWalker { return this.join(this.path, this.cwd) || '.' } + // don't do the same walk more than one time, ever + // hasSeen(pattern: Pattern, path: string): boolean { + // const seenPath = this.seen.get(path) + // if (seenPath) { + // const pkey = pattern + // .map(e => + // e === GLOBSTAR ? '**' : e instanceof RegExp ? e._glob : e + // ) + // .join('/') + // if (seenPath.has(pkey)) { + // return true + // } + // } + // return false + // } + child(pattern: Pattern, path: string) { - // console.error('CHILD', path, pattern) + //if (!this.hasSeen(pattern, path)) { return new GlobWalker(pattern, path, this, true) + //} } - async walk(): Promise { - if (this.ignore?.childrenIgnored(this.path)) { - return [] - } - let entries: Dirent[] | false = await this.rd.readdir(this.start) - if (!entries) { - return [] + match(p: string): void { + if (!this.ignore?.ignored(p)) { + this.matches.add(p) } - const children = this.getChildren(entries) - const matches: (string | string[])[] = await Promise.all( - children.map(async c => - typeof c === 'string' - ? this.finish(await this.doRealpath(c)) - : c.walk() - ) - ) - const flat = matches.reduce((set: string[], m) => set.concat(m), []) - return this.ignore ? flat.filter(f => !this.ignore?.ignored(f)) : flat } - finish(p: string | undefined): string | [] { - if (!p) { - return [] + finish(p: string): void { + if (!p || this.ignore?.ignored(p)) { + return } if (this.nodir || this.mark) { const isDir = this.rd.isDirectory(this.join(p, this.cwd)) if (isDir) { if (this.nodir) { - return [] + return } if (p.substring(p.length - 1) !== '/') { - return p + '/' + this.match(p + '/') + return } } } - return p + this.match(p) } - async doRealpath(p: string): Promise { + async doRealpath(p: string): Promise { if (!this.realpath && !this.absolute) { return p } @@ -231,7 +259,7 @@ export class GlobWalker { ) } - doRealpathSync(p: string): string | undefined { + doRealpathSync(p: string): string { if (!this.realpath && !this.absolute) { return p } @@ -246,23 +274,42 @@ export class GlobWalker { } } - walkSync(): string[] { + async walk(): Promise> { if (this.ignore?.childrenIgnored(this.path)) { - return [] + return this.matches } + let entries: Dirent[] | false = await this.rd.readdir(this.start) + if (!entries) { + return this.matches + } + const children = this.getChildren(entries) + await Promise.all( + children.map(async c => + typeof c === 'string' + ? this.finish(await this.doRealpath(c)) + : c?.walk() + ) + ) + return this.matches + } + walkSync(): Set { + if (this.ignore?.childrenIgnored(this.path)) { + return this.matches + } let entries: Dirent[] | false = this.rd.readdirSync(this.start) if (!entries) { - return [] + return this.matches } const children = this.getChildren(entries) - const matches: (string | string[])[] = children.map(c => { - return typeof c === 'string' - ? this.finish(this.doRealpathSync(c)) - : c.walkSync() - }) - const flat = matches.reduce((set: string[], m) => set.concat(m), []) - return this.ignore ? flat.filter(f => !this.ignore?.ignored(f)) : flat + for (const c of children) { + if (typeof c === 'string') { + this.finish(this.doRealpathSync(c)) + } else { + c?.walkSync() + } + } + return this.matches } join(p: string, base: string = this.path) { @@ -301,8 +348,18 @@ export class GlobWalker { // eg, p=**/a/b if (rest) { + // XXX this is breaking symlink following?? + // // it can match a/b against this path, without the ** - children.push(this.child(rest, this.path)) + // skip ahead one step + const p = rest[0] + const r = rest.length > 1 ? rest.slice(1) as Pattern : null + if (typeof p === 'string') { + children.push(...this.getChildrenString(entries, p, r)) + } else if (p instanceof RegExp) { + children.push(...this.getChildrenRegexp(entries, p, r)) + } + // children.push(this.child(rest, this.path)) } else { // but if ** is at the end, then this path definitely matches children.push(this.path) @@ -320,8 +377,13 @@ export class GlobWalker { children.push(this.child(this.pattern, path)) } if (rest) { - // can match a/b against child path - children.push(this.child(rest, path)) + // matching bash behavior + // **/a will not traverse symlinks, but ./**/a WILL traverse + // a single symlink + if (e.isDirectory() || e.isSymbolicLink()) { + // can match a/b against child path + children.push(this.child(rest, path)) + } } else { // ** at the end, will match all children children.push(path) @@ -341,9 +403,8 @@ export class GlobWalker { if (!p.test(e.name)) { continue } - const traverse = e.isDirectory() || e.isSymbolicLink() if (rest) { - if (traverse) { + if (e.isDirectory() || e.isSymbolicLink()) { children.push(this.child(rest, this.join(e.name))) } } else { @@ -357,14 +418,12 @@ export class GlobWalker { getChildren(entries: Dirent[]): Children { const [p, ...tail] = this.pattern const rest = tail.length ? (tail as Pattern) : null - let ret: Children if (typeof p === 'string') { - ret = this.getChildrenString(entries, p, rest) + return this.getChildrenString(entries, p, rest) } else if (p === GLOBSTAR) { - ret = this.getChildrenGlobstar(entries, rest) + return this.getChildrenGlobstar(entries, rest) } else { - ret = this.getChildrenRegexp(entries, p, rest) + return this.getChildrenRegexp(entries, p, rest) } - return ret } } From 8f06674fda7ecbbac9f851eb4afa1274f3443cfa Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 19 Jan 2023 00:47:18 -0800 Subject: [PATCH 056/163] more perf wins --- benchmark.sh | 39 ++++++++++++++++++++------------------ src/glob.ts | 45 +++++++++++++++++++++++++------------------- src/readdir.ts | 19 ++++++++----------- src/walker.ts | 23 +++++++++++----------- test/00-setup.ts | 8 ++++++++ test/bash-results.ts | 43 ++++++++++++++++++++++++++++++++++++++++++ test/realpath.ts | 14 ++++++-------- 7 files changed, 124 insertions(+), 67 deletions(-) diff --git a/benchmark.sh b/benchmark.sh index 1f1e2199..b56ac0d8 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -2,6 +2,27 @@ export CDPATH= set -e +patterns=( + './**/?/**/?/**/?/**/?/**/*.txt' + './**/*/**/*/**/*/**/*/**/*.txt' + './**/0/**/0/**/0/**/0/**/*.txt' + './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' + './**/0/**/0/**/*.txt' + '**/*.txt' + # './**/*.txt' + './**/**/**/**/**/**/**/**/*.txt' + '**/*/*.txt' + '**/*/**/*.txt' + '**/[0-9]/**/*.txt' + # '0/@([5-9]/*.txt|8/**)' + # '[0-9]/[0-9]/[0-9]/[0-9]/[0-9].txt' + # /**/**/**/**//////**/**//*.txt' + # '**/[5-9]/*.txt' + # '[678]/**/2.txt' + # '0/!(1|2)@(4|5)/**/**/**/**/*.txt' + # '0/!(1|2|@(4|5))/**/**/**/**/*.txt' +) + bash make-benchmark-fixture.sh wd=$PWD @@ -31,24 +52,6 @@ t () { tt "$@" 2>&1 | grep real | awk -F $'\t' '{ print $2 }' || true } -patterns=( - './**/0/**/0/**/0/**/0/**/*.txt' - './**/0/**/0/**/*.txt' - '**/*.txt' - # './**/*.txt' - './**/**/**/**/**/**/**/**/*.txt' - '**/*/*.txt' - '**/*/**/*.txt' - '**/[0-9]/**/*.txt' - # '0/@([5-9]/*.txt|8/**)' - # '[0-9]/[0-9]/[0-9]/[0-9]/[0-9].txt' - # /**/**/**/**//////**/**//*.txt' - # '**/[5-9]/*.txt' - # '[678]/**/2.txt' - # '0/!(1|2)@(4|5)/**/**/**/**/*.txt' - # '0/!(1|2|@(4|5))/**/**/**/**/*.txt' -) - for p in "${patterns[@]}"; do echo echo "# pattern: $p" diff --git a/src/glob.ts b/src/glob.ts index 84acbf8f..0ca60836 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -49,7 +49,7 @@ export class Glob { this.nodir = !!options.nodir this.mark = !!options.mark this.nounique = !!options.nounique - if (this.nounique) { + if (!this.nounique) { this.matches = new Set() } this.nosort = !!options.nosort @@ -101,33 +101,40 @@ export class Glob { } async process() { - return this.finish( - await Promise.all( - this.matchSet.map(async (set, i) => { - const matches = await this.getWalker(set as Pattern).walk() - return this.doNonull(matches, i) - }) - ) + const matches = await Promise.all( + this.matchSet.map(async set => { + return await this.getWalker(set as Pattern).walk() + }) ) + return this.finish(this.doNonull(matches)) } processSync() { - return this.finish( - this.matchSet.map((set, i) => { - const matches = this.getWalker(set as Pattern).walkSync() - return this.doNonull(matches, i) - }) - ) + const matches = this.matchSet.map(set => { + return this.getWalker(set as Pattern).walkSync() + }) + return this.finish(this.doNonull(matches)) } - doNonull(matches: Set, i: number): Set { - return !matches.size && this.nonull ? new Set([this.globSet[i]]) : matches + doNonull(matches: Set[]): Set[] { + const nulls: string[] = [] + matches.forEach((set, i) => { + if (!set.size && this.nonull) { + nulls.push(this.globSet[i]) + } + }) + for (const n of nulls) { + matches[0].add(n) + } + return matches } finish(matches: Set[]): string[] { - const raw: string[] = [] - for (const set of matches) { - raw.push(...set) + const raw: string[] = [...matches[0]] + if (this.nounique) { + for (const set of matches) { + raw.push(...set) + } } return this.nosort ? raw : this.sort(raw) } diff --git a/src/readdir.ts b/src/readdir.ts index d938cd07..6b960a47 100644 --- a/src/readdir.ts +++ b/src/readdir.ts @@ -38,8 +38,6 @@ export class Readdir { const cached = this.cache[resolved] return Array.isArray(cached) ? true - : cached === false - ? false : !!this.lookup(resolved)?.isDirectory() } @@ -50,17 +48,16 @@ export class Readdir { return cacheEntry } - const lu = this.lookup(resolved) - if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) { - return (this.cache[resolved] = false) - } + // const lu = this.lookup(resolved) + // if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) { + // return (this.cache[resolved] = false) + // } const pc = this.pcache[resolved] if (pc) { return pc } - // TODO: cache the promise, too return (this.pcache[resolved] = new Promise(res => { origReaddir(resolved, { withFileTypes: true }, (_, entities) => { this.pcache[resolved] = undefined @@ -76,10 +73,10 @@ export class Readdir { return cacheEntry } - const lu = this.lookup(resolved) - if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) { - return (this.cache[resolved] = false) - } + // const lu = this.lookup(resolved) + // if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) { + // return (this.cache[resolved] = false) + // } // try to avoid getting an error object created if we can // stack traces are expensive, and we don't use them. diff --git a/src/walker.ts b/src/walker.ts index 659ad838..9765270f 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -348,18 +348,19 @@ export class GlobWalker { // eg, p=**/a/b if (rest) { - // XXX this is breaking symlink following?? + // XXX this is faster, but it breaks some bash comparisons + // also, it's still not fast enough, even with this. // // it can match a/b against this path, without the ** // skip ahead one step - const p = rest[0] - const r = rest.length > 1 ? rest.slice(1) as Pattern : null - if (typeof p === 'string') { - children.push(...this.getChildrenString(entries, p, r)) - } else if (p instanceof RegExp) { - children.push(...this.getChildrenRegexp(entries, p, r)) - } - // children.push(this.child(rest, this.path)) + // const p = rest[0] + // const r = rest.length > 1 ? rest.slice(1) as Pattern : null + // if (typeof p === 'string') { + // children.push(...this.getChildrenString(entries, p, r)) + // } else if (p instanceof RegExp) { + // children.push(...this.getChildrenRegexp(entries, p, r)) + // } + children.push(this.child(rest, this.path)) } else { // but if ** is at the end, then this path definitely matches children.push(this.path) @@ -377,10 +378,10 @@ export class GlobWalker { children.push(this.child(this.pattern, path)) } if (rest) { - // matching bash behavior + // TODO: match bash behavior // **/a will not traverse symlinks, but ./**/a WILL traverse // a single symlink - if (e.isDirectory() || e.isSymbolicLink()) { + if (e.isSymbolicLink()) { // can match a/b against child path children.push(this.child(rest, path)) } diff --git a/test/00-setup.ts b/test/00-setup.ts index 1024d8b9..6b41c31b 100644 --- a/test/00-setup.ts +++ b/test/00-setup.ts @@ -77,7 +77,15 @@ if (process.platform === 'win32' || !process.env.TEST_REGEN) { 'a/abc{fed,def}/g/h', 'a/abc{fed/g,def}/**/', 'a/abc{fed/g,def}/**///**/', + // TODO: match bash behavior + // When a ** is the FIRST item in a pattern, it has + // slightly dfferent symbolic link handling behavior. + // '**/a', + // '**/a/**', + './**/a', './**/a/**/', + './**/a/**', + './**/a/**/a/**/', '+(a|b|c)/a{/,bc*}/**', '*/*/*/f', './**/f', diff --git a/test/bash-results.ts b/test/bash-results.ts index 3db61ddb..665eba9f 100644 --- a/test/bash-results.ts +++ b/test/bash-results.ts @@ -21,6 +21,7 @@ export const bashResults: { [path: string]: string[] } = { 'a/abc{fed,def}/g/h': ['a/abcdef/g/h', 'a/abcfed/g/h'], 'a/abc{fed/g,def}/**/': ['a/abcdef', 'a/abcdef/g', 'a/abcfed/g'], 'a/abc{fed/g,def}/**///**/': ['a/abcdef', 'a/abcdef/g', 'a/abcfed/g'], + './**/a': ['./a', './a/symlink/a', './a/symlink/a/b/c/a'], './**/a/**/': [ './a', './a/abcdef', @@ -46,6 +47,48 @@ export const bashResults: { [path: string]: string[] } = { './a/x', './a/z', ], + './**/a/**': [ + './a', + './a/abcdef', + './a/abcdef/g', + './a/abcdef/g/h', + './a/abcfed', + './a/abcfed/g', + './a/abcfed/g/h', + './a/b', + './a/b/c', + './a/b/c/d', + './a/bc', + './a/bc/e', + './a/bc/e/f', + './a/c', + './a/c/d', + './a/c/d/c', + './a/c/d/c/b', + './a/cb', + './a/cb/e', + './a/cb/e/f', + './a/symlink', + './a/symlink/a', + './a/symlink/a/b', + './a/symlink/a/b/c', + './a/symlink/a/b/c/a', + './a/symlink/a/b/c/a/b', + './a/symlink/a/b/c/a/b/c', + './a/x', + './a/z', + ], + './**/a/**/a/**/': [ + './a/symlink/a', + './a/symlink/a/b', + './a/symlink/a/b/c', + './a/symlink/a/b/c/a', + './a/symlink/a/b/c/a/b', + './a/symlink/a/b/c/a/b/c', + './a/symlink/a/b/c/a/b/c/a', + './a/symlink/a/b/c/a/b/c/a/b', + './a/symlink/a/b/c/a/b/c/a/b/c', + ], '+(a|b|c)/a{/,bc*}/**': [ 'a/abcdef', 'a/abcdef/g', diff --git a/test/realpath.ts b/test/realpath.ts index 04287668..543b76c5 100644 --- a/test/realpath.ts +++ b/test/realpath.ts @@ -44,13 +44,11 @@ if (process.platform === 'win32') { 'a/symlink', 'a/symlink', 'a/symlink', - 'a/symlink', 'a/symlink/a', 'a/symlink/a', 'a/symlink/a', 'a/symlink/a/b', 'a/symlink/a/b', - 'a/symlink/a/b', ], ], @@ -60,13 +58,11 @@ if (process.platform === 'win32') { 'a/symlink/', 'a/symlink/', 'a/symlink/', - 'a/symlink/', 'a/symlink/a/', 'a/symlink/a/', 'a/symlink/a/', 'a/symlink/a/b/', 'a/symlink/a/b/', - 'a/symlink/a/b/', ], ], @@ -101,13 +97,15 @@ if (process.platform === 'win32') { // and that all the expected ones are found. const s = glob.sync(p, opt) const a = await glob(p, opt) - t.ok(s.length > 10, 'more than 10 entries found sync', { + t.ok(s.length > 5, 'more than 5 entries found sync', { found: s.length, - expect: '>10', + expect: '>5', + matches: s, }) - t.ok(a.length > 10, 'more than 10 entries found async', { + t.ok(a.length > 5, 'more than 5 entries found async', { found: a.length, - expect: '>10', + expect: '>5', + matches: a, }) for (const e of expect) { t.ok(s.includes(e), 'found ' + e + ' sync') From 8fd4b21afcab376a576d59dc25098b6017bca736 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 19 Jan 2023 08:37:01 -0800 Subject: [PATCH 057/163] avoid walking same path/pattern repeatedly Still a bit slower than I'd like, but no longer subject to _quite_ as pathological geometric explosions on patterns with multiple ** portions. I think at this point, the way to squeeze out the last bit of performance is just cutting out a lot of the string and array operations. They're convenient and make the code a bit more elegant and readable, but also it seems to be where it's spending most of the time. Rather than doing a lot of 'const [p, ...rest] = pattern' types of code, and then passing a pattern array to each child walker, what we could do is pass the _same_ pattern array to every child in the walk, along with an index telling it where to start. This will be a bit of an annoying refactor, and make the code a bit less elegant, but it should yield a considerable performance increase. Along with that, it'll have to pass that index into the stringPattern() method, or maybe just pass a patternString index as well as a pattern index, indicating how far in the single shared patternString it should operate on. Alternatively, it could pass the globParts array along with pattern array, which would make this.patternString a simple array subset string concat op. Once that's done, the other potential idea to try to get even faster is to use worker threads for readdir in the async case. Not sure if that'll be beneficial in the end, since node async fs ops already fan out to multiple threads, or if it might have other undesirable knock-on effects from using ALL THE CPUs for glob activities, but it could be an interesing approach. Note on the benchmarks below, since globby has essentially equivalent performance to all the other fastglob-based implementations, and has the closest API to node-glob, I don't include any of the others in the benchmark script, since they're a bit more of a pain to do an apples-to-apples comparison with, and in the end didn't add much information. Using fastglob directly _is_ slightly faster than globby, but not by enough to really matter. Benchmarks with this change: $ npm run bench > glob@9.0.0-0 bench > bash benchmark.sh --- pattern: './**/?/**/?/**/?/**/?/**/*.txt' --- node globby sync 0m0.423s node globby async 0m0.300s node current glob.sync cjs 0m0.702s node current glob async cjs 0m0.621s node current glob.sync mjs 0m0.701s node current glob async mjs 0m0.639s ^ still taking about twice as much time as it should, but no longer increasing geometrically with each ** portion. --- pattern: './**/*/**/*/**/*/**/*/**/*.txt' --- node globby sync 0m0.412s node globby async 0m0.309s node current glob.sync cjs 0m0.718s node current glob async cjs 0m0.641s node current glob.sync mjs 0m0.736s node current glob async mjs 0m0.657s ^ same here, these two were really bad before, like 1-2 seconds --- pattern: './**/0/**/0/**/0/**/0/**/*.txt' --- node globby sync 0m0.297s node globby async 0m0.189s node current glob.sync cjs 0m0.411s node current glob async cjs 0m0.316s node current glob.sync mjs 0m0.408s node current glob async mjs 0m0.345s --- pattern: './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' --- node globby sync 0m0.297s node globby async 0m0.185s node current glob.sync cjs 0m0.416s node current glob async cjs 0m0.281s node current glob.sync mjs 0m0.421s node current glob async mjs 0m0.282s --- pattern: './**/0/**/0/**/*.txt' --- node globby sync 0m0.302s node globby async 0m0.193s node current glob.sync cjs 0m0.392s node current glob async cjs 0m0.298s node current glob.sync mjs 0m0.405s node current glob async mjs 0m0.329s ^ getting SOOO CLOSE to fastglob/globby! --- pattern: '**/*.txt' --- node globby sync 0m0.410s node globby async 0m0.296s node current glob.sync cjs 0m0.402s node current glob async cjs 0m0.253s node current glob.sync mjs 0m0.415s node current glob async mjs 0m0.259s ^ basically exactly where it should be, but faster = better --- pattern: './**/**/**/**/**/**/**/**/*.txt' --- node globby sync 0m0.408s node globby async 0m0.292s node current glob.sync cjs 0m0.399s node current glob async cjs 0m0.257s node current glob.sync mjs 0m0.412s node current glob async mjs 0m0.290s --- pattern: '**/*/*.txt' --- node globby sync 0m0.412s node globby async 0m0.305s node current glob.sync cjs 0m0.433s node current glob async cjs 0m0.300s node current glob.sync mjs 0m0.442s node current glob async mjs 0m0.321s --- pattern: '**/*/**/*.txt' --- node globby sync 0m0.416s node globby async 0m0.300s node current glob.sync cjs 0m0.476s node current glob async cjs 0m0.337s node current glob.sync mjs 0m0.480s node current glob async mjs 0m0.346s ^ perf issue almost completely gone --- pattern: '**/[0-9]/**/*.txt' --- node globby sync 0m0.401s node globby async 0m0.294s node current glob.sync cjs 0m0.478s node current glob async cjs 0m0.334s node current glob.sync mjs 0m0.494s node current glob async mjs 0m0.346s ^ same here --- src/glob.ts | 4 +-- src/walker.ts | 68 +++++++++++++++++++++++++++------------------------ 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/glob.ts b/src/glob.ts index 0ca60836..35945655 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -143,7 +143,7 @@ export class Glob { return flat.sort((a, b) => a.localeCompare(b, 'en')) } - getWalker(set: Pattern) { - return new GlobWalker(set, '', this, false) + getWalker(pattern: Pattern) { + return new GlobWalker(pattern, '', this, false) } } diff --git a/src/walker.ts b/src/walker.ts index 9765270f..f6e5923f 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -17,7 +17,7 @@ import { Dirent, realpath, realpathSync } from 'fs' import { GLOBSTAR } from 'minimatch' -import { resolve } from 'path' +import { join, resolve } from 'path' import { Ignore } from './ignore.js' import { GlobCache, Readdir } from './readdir.js' @@ -30,6 +30,13 @@ export type Pattern = [ ...rest: ParseReturnFiltered[] ] +const stringPattern = (pattern: Pattern): string => + pattern + .map(p => + typeof p === 'string' ? p : p === GLOBSTAR ? '**' : p._glob + ) + .join('/') + type Children = (GlobWalker | string | undefined)[] export interface GlobWalkerOptions { @@ -65,7 +72,7 @@ export class GlobWalker { matches: Set seen: Map> - //pkey: string + patternString: string constructor( pattern: Pattern, @@ -92,23 +99,23 @@ export class GlobWalker { this.hasParent = hasParent this.seen = seen - //this.pkey = pattern - // .map(p => - // p === GLOBSTAR ? '**' : p instanceof RegExp ? p._glob : p - // ) - // .join('/') - //const pathSeen = seen.get(path) - //if (!pathSeen) { - // seen.set(path, new Set([this.pkey])) - //} else { - // pathSeen.add(this.pkey) - //} + this.patternString = stringPattern(pattern) // if the pattern starts with a bunch of strings, then skip ahead this.pattern = [...pattern] this.path = path this.cwd = cwd this.start = this.setStart() + + // note that we've now tested this pattern at this path + const jp = join(path) + const pathSeen = seen.get(jp) + if (!pathSeen) { + seen.set(jp, new Set([this.patternString])) + } else { + pathSeen.add(this.patternString) + } + this.follow = follow this.realpath = realpath this.absolute = absolute @@ -200,25 +207,22 @@ export class GlobWalker { } // don't do the same walk more than one time, ever - // hasSeen(pattern: Pattern, path: string): boolean { - // const seenPath = this.seen.get(path) - // if (seenPath) { - // const pkey = pattern - // .map(e => - // e === GLOBSTAR ? '**' : e instanceof RegExp ? e._glob : e - // ) - // .join('/') - // if (seenPath.has(pkey)) { - // return true - // } - // } - // return false - // } - - child(pattern: Pattern, path: string) { - //if (!this.hasSeen(pattern, path)) { - return new GlobWalker(pattern, path, this, true) - //} + hasSeen(pattern: Pattern, path: string): boolean { + const patternString = stringPattern(pattern) + const jp = join(path) + const seenPath = this.seen.get(jp) + if (seenPath) { + if (seenPath.has(patternString)) { + return true + } + } + return false + } + + child(pattern: Pattern, path: string): GlobWalker | undefined { + if (!this.hasSeen(pattern, path)) { + return new GlobWalker(pattern, path, this, true) + } } match(p: string): void { From 135a95e82140ae98b7199e278a3a2e896a50b586 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 19 Jan 2023 11:36:11 -0800 Subject: [PATCH 058/163] x --- test/pattern-absolute.ts | 207 --------------------------------------- 1 file changed, 207 deletions(-) delete mode 100644 test/pattern-absolute.ts diff --git a/test/pattern-absolute.ts b/test/pattern-absolute.ts deleted file mode 100644 index abc9110c..00000000 --- a/test/pattern-absolute.ts +++ /dev/null @@ -1,207 +0,0 @@ -// there's some special behavior if the pattern starts with '/' -// or if it starts with a drive letter on Windows systems. -// This is a weirdly specific test of unexported implementation, not my -// favorite, but it is the easiest way to verify what we expect here. -import t from 'tap' -import { posix, win32 } from 'path' - -const setPlatform = (platform: string) => { - Object.defineProperty(process, 'platform', { - value: platform, - enumerable: true, - configurable: true, - writable: true, - }) -} - -const { platform } = process -t.teardown(() => setPlatform(platform)) - -t.test('posix', t => { - setPlatform('posix') - const root = '/' - const { GlobWalker } = t.mock('../dist/cjs/walker.js', { - path: posix, - }) - - // pattern like [a]/[b] - t.match( - new GlobWalker([/^[a]$/, /^[b]$/], ''), - { - pattern: [/^[a]$/, /^[b]$/], - path: '', - cwd: '', - start: '.', - }, - 'pattern=[a]/[b] path=""' - ) - - t.match( - new GlobWalker(['', ''], '/tmp'), - { - pattern: [''], - path: root, - cwd: '', - start: root, - }, - 'pattern=/' - ) - - t.match( - new GlobWalker(['', 'x'], '/tmp'), - { - pattern: ['x'], - path: root, - cwd: '', - start: root, - }, - 'pattern=/x' - ) - - t.match( - new GlobWalker(['', 'x'], '/tmp', { cwd: '/a/b/c/d' }), - { - pattern: ['x'], - path: root, - cwd: '', - start: root, - }, - 'pattern=/x' - ) - - t.match(new GlobWalker(['p:'], 'q:/tmp'), { - pattern: ['p:'], - path: 'q:/tmp', - cwd: '', - start: 'q:/tmp', - }) - - t.match(new GlobWalker(['p:', 'x'], 'q:/tmp'), { - pattern: ['x'], - path: 'q:/tmp/p:', - cwd: '', - start: 'q:/tmp/p:', - }) - - t.end() -}) - -t.test('win32', t => { - setPlatform('win32') - const { GlobWalker } = t.mock('../dist/cjs/walker.js', { - path: win32, - }) - const root = win32.resolve('/') - - t.match( - new GlobWalker(['', ''], '/tmp'), - { - pattern: [''], - path: root, - cwd: root, - start: root, - }, - 'pattern=/' - ) - - t.match( - new GlobWalker(['', 'x'], '/tmp'), - { - pattern: ['x'], - path: root, - cwd: root, - start: root, - }, - 'pattern=/x' - ) - - t.match( - new GlobWalker(['', 'x'], '/tmp'), - { - pattern: ['x'], - path: root, - cwd: root, - start: root, - }, - 'pattern=/x' - ) - - t.match( - new GlobWalker(['', ''], 'q:/tmp'), - { - pattern: [''], - path: 'q:/', - cwd: 'q:/', - start: 'q:/', - }, - 'pattern=/, path=q:/tmp' - ) - - t.match( - new GlobWalker(['', 'x'], 'x:/tmp'), - { - pattern: ['x'], - path: 'x:', - cwd: 'x:', - start: 'x:', - }, - 'pattern=/x, path=x:/tmp' - ) - - t.match( - new GlobWalker(['', 'x'], 'y:/tmp'), - { - pattern: ['x'], - path: 'y:', - cwd: 'y:', - start: 'y:', - }, - 'pattern=/x path=y:/tmp' - ) - - t.match( - new GlobWalker(['p:'], 'q:/tmp'), - { - pattern: [''], - path: 'p:', - cwd: 'p:', - start: 'p:', - }, - 'pattern=c: path=q:/tmp' - ) - - t.match( - new GlobWalker(['p:', 'x'], 'q:/tmp'), - { - pattern: ['x'], - path: 'p:', - cwd: 'p:', - start: 'p:', - }, - 'pattern=c:/x path=q:/tmp' - ) - - t.match( - new GlobWalker(['', '', '?', 'p:'], 'q:/tmp'), - { - pattern: [''], - path: '/?/p:', - cwd: '/', - start: '//?/p:', - }, - 'pattern=//?/p: path=q:/tmp' - ) - - t.match( - new GlobWalker(['', '', '?', 'p:', /^[ab]$/], 'q:/tmp'), - { - pattern: [/^[ab]$/], - path: '/?/p:', - cwd: '/', - start: '//?/p:', - }, - 'pattern=//?/p:/[ab] path=q:/tmp' - ) - - t.end() -}) From 71d981327579f49d73ff11fc61184e6c3eda4f1f Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 19 Jan 2023 12:03:33 -0800 Subject: [PATCH 059/163] prettier benchmark output --- benchmark.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmark.sh b/benchmark.sh index b56ac0d8..f7e1c198 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -54,7 +54,7 @@ t () { for p in "${patterns[@]}"; do echo - echo "# pattern: $p" + echo "--- pattern: '$p' ---" # if [[ "`bash --version`" =~ version\ 4 ]] || [[ "`bash --version`" =~ version\ 5 ]]; then # echo -n $'bash \t' From bcf07a37c7908e46b335f9db3bdf419f65171000 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 19 Jan 2023 12:03:53 -0800 Subject: [PATCH 060/163] more aggressive profiling --- prof.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/prof.sh b/prof.sh index 618a1812..5e96e758 100644 --- a/prof.sh +++ b/prof.sh @@ -12,7 +12,8 @@ export __GLOB_PROFILE__=1 cat > "profscript.mjs" < console.log(m.length)) MJS node --prof profscript.mjs &> profile.out From c6cf352083139d8dedd2427989c94fdcc34d6777 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 19 Jan 2023 12:09:15 -0800 Subject: [PATCH 061/163] needstests: new Pattern class instead of array gymnastics --- src/glob.ts | 31 ++++++--- src/pattern.ts | 184 +++++++++++++++++++++++++++++++++++++++++++++++++ src/walker.ts | 106 ++++++++-------------------- 3 files changed, 233 insertions(+), 88 deletions(-) create mode 100644 src/pattern.ts diff --git a/src/glob.ts b/src/glob.ts index 35945655..4b73f1ff 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -1,9 +1,11 @@ import { Minimatch, MinimatchOptions } from 'minimatch' +import { Pattern } from './pattern.js' import { GlobCache } from './readdir.js' -import { GlobWalker, Pattern } from './walker.js' +import { GlobWalker } from './walker.js' type MatchSet = Minimatch['set'] type GlobSet = Exclude +type GlobParts = Exclude export interface GlobOptions extends MinimatchOptions { ignore?: string | string[] @@ -30,6 +32,7 @@ export class Glob { cwd: string matchSet: MatchSet globSet: GlobSet + globParts: GlobParts realpath: boolean nonull: boolean absolute: boolean @@ -92,26 +95,36 @@ export class Glob { nocomment: true, preserveMultipleSlashes: true, } + const mms = this.pattern.map(p => new Minimatch(p, mmo)) - this.matchSet = mms.reduce((set: MatchSet, m) => set.concat(m.set), []) - this.globSet = mms.reduce( - (set: GlobSet, m) => set.concat(m.globSet), - [] + const [matchSet, globSet, globParts] = mms.reduce( + (set: [MatchSet, GlobSet, GlobParts], m) => { + set[0].push(...m.set) + set[1].push(...m.globSet) + set[2].push(...m.globParts) + return set + }, + [[], [], []] ) + this.matchSet = matchSet + this.globSet = globSet + this.globParts = globParts } async process() { const matches = await Promise.all( - this.matchSet.map(async set => { - return await this.getWalker(set as Pattern).walk() + this.matchSet.map(async (set, i) => { + const p = new Pattern(set, this.globParts[i], 0) + return await this.getWalker(p).walk() }) ) return this.finish(this.doNonull(matches)) } processSync() { - const matches = this.matchSet.map(set => { - return this.getWalker(set as Pattern).walkSync() + const matches = this.matchSet.map((set, i) => { + const p = new Pattern(set, this.globParts[i], 0) + return this.getWalker(p).walkSync() }) return this.finish(this.doNonull(matches)) } diff --git a/src/pattern.ts b/src/pattern.ts new file mode 100644 index 00000000..ca297204 --- /dev/null +++ b/src/pattern.ts @@ -0,0 +1,184 @@ +// this is just a very light wrapper around 2 arrays with an offset index + +import { GLOBSTAR } from 'minimatch' +import { resolve } from 'path' +type MMRegExp = RegExp & { + _glob?: string + _src?: string +} +type MMPattern = string | MMRegExp | typeof GLOBSTAR + +// an array of length >= 1 +type PatternList = [p: MMPattern, ...rest: MMPattern[]] +type GlobList = [p: string, ...rest: string[]] + +const isWin = process.platform === 'win32' +const isPatternList = (pl: MMPattern[]): pl is PatternList => pl.length >= 1 +const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1 + +export class Pattern { + patternList: PatternList + globList: GlobList + index: number + length: number + + constructor( + patternList: MMPattern[], + globList: string[], + index: number + ) { + if (!isPatternList(patternList)) { + throw new TypeError('empty pattern list') + } + if (!isGlobList(globList)) { + throw new TypeError('empty glob list') + } + if (globList.length !== patternList.length) { + throw new TypeError('mismatched pattern list and glob list lengths') + } + this.length = patternList.length + if (index >= this.length) { + //console.error('P', [index, globList]) + throw new TypeError('index out of range') + } + this.patternList = patternList + this.globList = globList + this.index = index + + // do some cleanup of the pattern if we're starting out. + if (this.index === 0) { + // '//host/share' => '//host/share/' + // 'c:' => 'c:/' + if ( + (this.isUNC() && this.length === 4) || + (this.isDrive() && this.length === 1) + ) { + this.patternList.push('') + this.globList.push('') + this.length++ + } + } else { + // match bash behavior, discard any empty path portions that + // follow a path portion with magic chars, except the last one. + const prev = this.patternList[this.index - 1] + while ( + typeof prev !== 'string' && + this.index < this.length - 1 && + this.pattern() === '' + ) { + this.shift() + } + } + } + + pattern(): MMPattern { + return this.patternList[this.index] + } + + isString(): boolean { + return typeof this.patternList[this.index] === 'string' + } + isGlobstar(): boolean { + return this.patternList[this.index] === GLOBSTAR + } + isMagic(): boolean { + return this.patternList[this.index] instanceof RegExp + } + shift() { + if (this.index === this.length - 1) { + throw new Error('cannot shift final pattern') + } + const p = this.pattern() + this.index++ + return p + } + + glob(): string { + return this.globList[this.index] + } + + globString(): string { + return ( + this.index === 0 ? this.globList : this.globList.slice(this.index) + ).join('/') + } + + hasMore(): boolean { + return this.length > this.index + 1 + } + + rest(): Pattern | null { + return this.hasMore() + ? new Pattern(this.patternList, this.globList, this.index + 1) + : null + } + + // pattern like: //host/share/... + // split = [ '', '', 'host', 'share', ... ] + isUNC(): boolean { + const pl = this.patternList + return ( + isWin && + this.index === 0 && + pl[0] === '' && + pl[1] === '' && + typeof pl[2] === 'string' && + !!pl[2] && + typeof pl[3] === 'string' && + !!pl[3] + ) + } + + // pattern like C:/... + // split = ['C:', ...] + // XXX: would be nice to handle patterns like `c:*` to test the cwd + // in c: for *, but I don't know of a way to even figure out what that + // cwd is without actually chdir'ing into it? + isDrive(): boolean { + const p = this.patternList[0] + return ( + isWin && + this.index === 0 && + this.length > 1 && + typeof p === 'string' && + /^[a-z]:$/i.test(p) + ) + } + + // pattern = '/' or '/...' or '/x/...' + // split = ['', ''] or ['', ...] or ['', 'x', ...] + // Drive and UNC both considered absolute on windows + isAbsolute(): boolean { + return ( + (this.patternList[0] === '' && this.length > 1) || + this.isDrive() || + this.isUNC() + ) + } + + // given a current working dir, what's the root that we should + // start looking in? + root(cwd: string): string { + if (this.index !== 0) { + throw new Error('should only check root on initial walk') + } + const driveRE = /^[a-z]:($|[\\\/])/i + return ( + // UNC paths start at /, because we gobble the string parts anyway + ( + this.isUNC() + ? '/' + : // drive letter pattern, start in the root of that drive letter + this.isDrive() + ? (this.patternList[0] as string) + '/' + : isWin && driveRE.test(cwd) + ? (cwd.match(driveRE) as RegExpMatchArray)[0] + : this.isAbsolute() + ? isWin + ? resolve(cwd, '/') + : '/' + : cwd + ).replace(/\\/g, '/') + ) + } +} diff --git a/src/walker.ts b/src/walker.ts index f6e5923f..32048b2f 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -17,25 +17,15 @@ import { Dirent, realpath, realpathSync } from 'fs' import { GLOBSTAR } from 'minimatch' -import { join, resolve } from 'path' +import { posix, resolve } from 'path' +// always use posix join because it's faster, and it's just for keys +const { join } = posix import { Ignore } from './ignore.js' import { GlobCache, Readdir } from './readdir.js' -type MMRegExp = RegExp & { _glob: string } +import { Pattern } from './pattern.js' // a single minimatch set entry with 1 or more parts -type ParseReturnFiltered = string | MMRegExp | typeof GLOBSTAR -export type Pattern = [ - p: ParseReturnFiltered, - ...rest: ParseReturnFiltered[] -] - -const stringPattern = (pattern: Pattern): string => - pattern - .map(p => - typeof p === 'string' ? p : p === GLOBSTAR ? '**' : p._glob - ) - .join('/') type Children = (GlobWalker | string | undefined)[] @@ -72,14 +62,13 @@ export class GlobWalker { matches: Set seen: Map> - patternString: string - constructor( pattern: Pattern, path: string, options: GlobWalkerOptions | GlobWalker = {}, hasParent: boolean = false ) { + //console.error('GW', [path, pattern.globString()]) const { follow = false, realpath = false, @@ -99,10 +88,7 @@ export class GlobWalker { this.hasParent = hasParent this.seen = seen - this.patternString = stringPattern(pattern) - - // if the pattern starts with a bunch of strings, then skip ahead - this.pattern = [...pattern] + this.pattern = pattern this.path = path this.cwd = cwd this.start = this.setStart() @@ -111,9 +97,9 @@ export class GlobWalker { const jp = join(path) const pathSeen = seen.get(jp) if (!pathSeen) { - seen.set(jp, new Set([this.patternString])) + seen.set(jp, new Set([this.pattern.globString()])) } else { - pathSeen.add(this.patternString) + pathSeen.add(this.pattern.globString()) } this.follow = follow @@ -137,69 +123,31 @@ export class GlobWalker { // since then we can remove the parent bit. // Also, then we can ditch the cwd setStart() { - const [first, ...rest] = this.pattern + const first = this.pattern.pattern() // a pattern like /a/s/d/f discards the cwd // a pattern like / (or c:/ on windows) can only match the root if (typeof first === 'string' && !this.hasParent) { - const patternSlash = first === '' && !!rest.length - const isWin = process.platform === 'win32' - const patternDrive = isWin && /^[a-z]:$/i.test(first) - const setAbs = patternSlash || patternDrive - if (setAbs) { + const setAbs = this.pattern.isAbsolute() + const rest = this.pattern.rest() + if (setAbs && rest) { // a pattern like '/' on windows goes to the root of // the drive that cwd is on. If cwd isn't on a drive, use / const cwd = this.cwd ? this.join(this.path, this.cwd) : this.path - const cwdRe = /^[a-z]:($|[\\\/])/i - const cwdDrive = isWin && patternSlash && cwd.match(cwdRe) // don't mount UNC paths on a drive letter // eg: //?/c:/* or //host/share/* // Only relevant if we WOULD have tried to mount it // We'll gobble those strings shortly, so use '/' for now - const isUNC = - cwdDrive && - first === '' && - rest[0] === '' && - rest[1] && - typeof rest[1] === 'string' && - rest[2] && - typeof rest[2] === 'string' - const root = isUNC - ? '/' - : cwdDrive - ? cwdDrive[0] - : isWin - ? resolve('/') - : '' - if (isUNC && rest.length === 3) { - rest.push('') - } - this.pattern = rest.length ? (rest as Pattern) : [''] - this.cwd = first || root - this.path = first || root || '/' + const root = this.pattern.root(cwd) + this.cwd = root + this.path = root || '/' } } // skip ahead any literal portions, and read that dir instead - while ( - this.pattern.length > 1 && - typeof this.pattern[0] === 'string' - ) { - this.path = - this.path === '/' - ? this.path + this.pattern[0] - : this.join(this.pattern[0]) - this.pattern.shift() - } - - // match bash behavior, discard any empty path portions that - // follow a path portion with magic chars - while ( - (this.pattern[0] instanceof RegExp || - this.pattern[0] === GLOBSTAR) && - this.pattern[1] === '' && - this.pattern.length > 2 - ) { - this.pattern.splice(1, 1) + while (this.pattern.hasMore() && this.pattern.isString()) { + const p = this.pattern.pattern() as string + this.path = this.path === '/' ? this.path + p : this.join(p) + this.pattern = this.pattern.rest() as Pattern } // this is the dir to read @@ -208,11 +156,10 @@ export class GlobWalker { // don't do the same walk more than one time, ever hasSeen(pattern: Pattern, path: string): boolean { - const patternString = stringPattern(pattern) const jp = join(path) const seenPath = this.seen.get(jp) if (seenPath) { - if (seenPath.has(patternString)) { + if (seenPath.has(pattern.globString())) { return true } } @@ -302,6 +249,7 @@ export class GlobWalker { return this.matches } let entries: Dirent[] | false = this.rd.readdirSync(this.start) + //console.error(' >', [this.path, this.pattern.globString()], entries && entries.map(e => e.name)) if (!entries) { return this.matches } @@ -357,11 +305,11 @@ export class GlobWalker { // // it can match a/b against this path, without the ** // skip ahead one step - // const p = rest[0] - // const r = rest.length > 1 ? rest.slice(1) as Pattern : null - // if (typeof p === 'string') { + // const p = rest.pattern() + // const r = rest.rest() + // if (rest.isString()) { // children.push(...this.getChildrenString(entries, p, r)) - // } else if (p instanceof RegExp) { + // } else if (rest.isMagic()) { // children.push(...this.getChildrenRegexp(entries, p, r)) // } children.push(this.child(rest, this.path)) @@ -421,8 +369,8 @@ export class GlobWalker { } getChildren(entries: Dirent[]): Children { - const [p, ...tail] = this.pattern - const rest = tail.length ? (tail as Pattern) : null + const p = this.pattern.pattern() + const rest = this.pattern.rest() if (typeof p === 'string') { return this.getChildrenString(entries, p, rest) } else if (p === GLOBSTAR) { From 80a21dca29ff48d9a6d0ac07a7e7f2858daa8e3a Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 19 Jan 2023 16:41:32 -0800 Subject: [PATCH 062/163] run prepare before bench/prof --- benchmark.sh | 1 + package.json | 2 ++ 2 files changed, 3 insertions(+) diff --git a/benchmark.sh b/benchmark.sh index f7e1c198..d40f9680 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -4,6 +4,7 @@ set -e patterns=( './**/?/**/?/**/?/**/?/**/*.txt' + './**/0/**/../[01]/**/0/../**/0/*.txt' './**/*/**/*/**/*/**/*/**/*.txt' './**/0/**/0/**/0/**/0/**/*.txt' './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' diff --git a/package.json b/package.json index e1e3890d..243091ac 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,9 @@ "prepublish": "npm run benchclean", "profclean": "rm -f v8.log profile.txt", "test-regen": "npm run profclean && TEST_REGEN=1 node --no-warnings --loader ts-node/esm test/00-setup.js", + "prebench": "npm run prepare", "bench": "bash benchmark.sh", + "preprof": "npm run prepare", "prof": "bash prof.sh", "benchclean": "node benchclean.js" }, From f5904058b6afe50458e58cbd8dc743b4524d0078 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 19 Jan 2023 16:46:00 -0800 Subject: [PATCH 063/163] more hacking to try to squeeze out some excess path.resolve() calls Really, what has to happen here is instead of just relying on getting a string, take over the path resolution by making the walker intelligently track what its actual start directory will be. When we pull string portions off the path, calculate the start directory based on the path portions being pulled off. Ie, if we see .., go up a dir, if we see '' or '.', then leave it as is, anything else append with '/'. The result should be that every GlobWalker always has the posix-separator-style absolute path, _without_ having to call path.resolve() except at the top level if the pattern and cwd are both not absolute. Also, need tests for the Pattern class, that's why that's failing coverage now. --- src/readdir.ts | 35 ++++++++++++++++++----------------- src/walker.ts | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/readdir.ts b/src/readdir.ts index 6b960a47..63e4b3df 100644 --- a/src/readdir.ts +++ b/src/readdir.ts @@ -42,54 +42,55 @@ export class Readdir { } async readdir(path: string): Promise { - const resolved = resolve(path) - const cacheEntry = this.cache[resolved] + const cacheEntry = this.cache[path] if (cacheEntry !== undefined) { return cacheEntry } - // const lu = this.lookup(resolved) + // const lu = this.lookup(path) // if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) { - // return (this.cache[resolved] = false) + // return (this.cache[path] = false) // } - const pc = this.pcache[resolved] + const pc = this.pcache[path] if (pc) { return pc } - return (this.pcache[resolved] = new Promise(res => { - origReaddir(resolved, { withFileTypes: true }, (_, entities) => { - this.pcache[resolved] = undefined - res((this.cache[resolved] = entities || false)) + return (this.pcache[path] = new Promise(res => { + origReaddir(path, { withFileTypes: true }, (_, entities) => { + this.pcache[path] = undefined + res((this.cache[path] = entities || false)) }) })) } readdirSync(path: string): Dirent[] | false { - const resolved = resolve(path) - const cacheEntry = this.cache[resolved] + // if (path.startsWith('//')) { + // console.error('WAT', path) + // } + const cacheEntry = this.cache[path] if (Array.isArray(cacheEntry) || cacheEntry === false) { return cacheEntry } - // const lu = this.lookup(resolved) + // const lu = this.lookup(path) // if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) { - // return (this.cache[resolved] = false) + // return (this.cache[path] = false) // } // try to avoid getting an error object created if we can // stack traces are expensive, and we don't use them. try { - const st = statSync(resolved, { throwIfNoEntry: false }) + const st = statSync(path, { throwIfNoEntry: false }) if (!st || !st.isDirectory()) { - return (this.cache[resolved] = false) + return (this.cache[path] = false) } - return (this.cache[resolved] = origReaddirSync(resolved, { + return (this.cache[path] = origReaddirSync(path, { withFileTypes: true, })) } catch (_) { - return (this.cache[resolved] = false) + return (this.cache[path] = false) } } } diff --git a/src/walker.ts b/src/walker.ts index 32048b2f..9884d2a3 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -17,11 +17,11 @@ import { Dirent, realpath, realpathSync } from 'fs' import { GLOBSTAR } from 'minimatch' -import { posix, resolve } from 'path' -// always use posix join because it's faster, and it's just for keys -const { join } = posix +import { isAbsolute, posix, resolve } from 'path' import { Ignore } from './ignore.js' import { GlobCache, Readdir } from './readdir.js' +// always use posix join because it's faster, and it's just for keys +const { join } = posix import { Pattern } from './pattern.js' @@ -42,6 +42,7 @@ export interface GlobWalkerOptions { cwd?: string matches?: Set seen?: Map> + absCwd?: string } export class GlobWalker { @@ -61,6 +62,7 @@ export class GlobWalker { hasParent: boolean matches: Set seen: Map> + absCwd: string constructor( pattern: Pattern, @@ -82,6 +84,7 @@ export class GlobWalker { cwd = '', matches = new Set(), seen = new Map(), + absCwd, } = options this.matches = matches @@ -91,6 +94,7 @@ export class GlobWalker { this.pattern = pattern this.path = path this.cwd = cwd + this.absCwd = absCwd || resolve(cwd || '.').replace(/\\/g, '/') this.start = this.setStart() // note that we've now tested this pattern at this path @@ -119,9 +123,6 @@ export class GlobWalker { } } - // TODO: this belongs in the Glob class probably - // since then we can remove the parent bit. - // Also, then we can ditch the cwd setStart() { const first = this.pattern.pattern() // a pattern like /a/s/d/f discards the cwd @@ -138,8 +139,9 @@ export class GlobWalker { // Only relevant if we WOULD have tried to mount it // We'll gobble those strings shortly, so use '/' for now const root = this.pattern.root(cwd) - this.cwd = root - this.path = root || '/' + this.cwd = root || '/' + this.absCwd = root || '/' + this.path = '/' } } @@ -150,8 +152,14 @@ export class GlobWalker { this.pattern = this.pattern.rest() as Pattern } - // this is the dir to read - return this.join(this.path, this.cwd) || '.' + // console.error( + // 'ss', + // this.path, + // this.absCwd, + // this.join(this.path, this.absCwd) + // ) + + return this.join(this.path, this.absCwd) } // don't do the same walk more than one time, ever @@ -183,7 +191,10 @@ export class GlobWalker { return } if (this.nodir || this.mark) { - const isDir = this.rd.isDirectory(this.join(p, this.cwd)) + const isDir = this.rd.isDirectory( + isAbsolute(p) ? p : resolve(this.join(p, this.cwd)) + ) + // console.error('finish mark', p, isAbsolute(p), isDir, require('fs').statSync(p).isDirectory(), this.cache) if (isDir) { if (this.nodir) { return @@ -267,8 +278,12 @@ export class GlobWalker { join(p: string, base: string = this.path) { return base === '' ? p - : base === '/' && p - ? `${base}${p}` + : base === '/' + ? p.startsWith('/') + ? p + : p + ? `${base}${p}` + : `${base}/` : `${base}/${p}` } From 9eadd92bd95c0b8dcaa85f2ff81cbbcbd80fc73f Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 30 Jan 2023 15:06:17 -0800 Subject: [PATCH 064/163] add link to projects homepage from gh page --- typedoc.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 typedoc.json diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 00000000..74ce9869 --- /dev/null +++ b/typedoc.json @@ -0,0 +1,5 @@ +{ + "navigationLinks": { + "isaacs projects": "https://isaacs.github.io/" + } +} From 25f14e79d896f545bcb275d50616a930baa4a81b Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 9 Feb 2023 11:29:22 -0800 Subject: [PATCH 065/163] wip: path-scurry implementation Basically just a spike at this point. Still need to implement most of the options. --- package-lock.json | 53 ++++- package.json | 3 +- src/glob.ts | 150 +++++++++---- src/has-magic.ts | 2 +- src/index.ts | 8 +- src/pattern.ts | 89 +++++--- src/walker.ts | 526 ++++++++++++++++------------------------------ 7 files changed, 396 insertions(+), 435 deletions(-) diff --git a/package-lock.json b/package-lock.json index cde6f012..a6911770 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", - "minimatch": "^6.1.4" + "minimatch": "^6.1.4", + "path-scurry": "1.2" }, "devDependencies": { "@types/mkdirp": "^1.0.2", @@ -2845,6 +2846,14 @@ "node": ">=0.8.6" } }, + "node_modules/lru-cache": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", + "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==", + "engines": { + "node": ">=12" + } + }, "node_modules/lunr": { "version": "2.3.9", "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", @@ -2931,6 +2940,14 @@ "optional": true, "peer": true }, + "node_modules/minipass": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.3.tgz", + "integrity": "sha512-OW2r4sQ0sI+z5ckEt5c1Tri4xTgZwYDxpE54eqWlQloQRoWtXjqt9udJ5Z4dSv7wK+nfFI7FRXyCpBSft+gpFw==", + "engines": { + "node": ">=8" + } + }, "node_modules/mkdirp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.0.0.tgz", @@ -3207,6 +3224,21 @@ "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.2.0.tgz", + "integrity": "sha512-+4ziUPFIhQA8uuTcq2cKF59ySJ85v4t57+DEEY2QayNf9UfHKAuLkr2OSOySfPIAZOtag1w5Htw7glKT71KAPA==", + "dependencies": { + "lru-cache": "^7.14.1", + "minipass": "^4.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -8483,6 +8515,11 @@ "optional": true, "peer": true }, + "lru-cache": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz", + "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==" + }, "lunr": { "version": "2.3.9", "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", @@ -8545,6 +8582,11 @@ "optional": true, "peer": true }, + "minipass": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.3.tgz", + "integrity": "sha512-OW2r4sQ0sI+z5ckEt5c1Tri4xTgZwYDxpE54eqWlQloQRoWtXjqt9udJ5Z4dSv7wK+nfFI7FRXyCpBSft+gpFw==" + }, "mkdirp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.0.0.tgz", @@ -8757,6 +8799,15 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "path-scurry": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.2.0.tgz", + "integrity": "sha512-+4ziUPFIhQA8uuTcq2cKF59ySJ85v4t57+DEEY2QayNf9UfHKAuLkr2OSOySfPIAZOtag1w5Htw7glKT71KAPA==", + "requires": { + "lru-cache": "^7.14.1", + "minipass": "^4.0.2" + } + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", diff --git a/package.json b/package.json index 243091ac..4366605f 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,8 @@ }, "dependencies": { "fs.realpath": "^1.0.0", - "minimatch": "^6.1.4" + "minimatch": "^6.1.4", + "path-scurry": "1.2" }, "devDependencies": { "@types/mkdirp": "^1.0.2", diff --git a/src/glob.ts b/src/glob.ts index 4b73f1ff..9d0b8827 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -1,14 +1,15 @@ -import { Minimatch, MinimatchOptions } from 'minimatch' -import { Pattern } from './pattern.js' -import { GlobCache } from './readdir.js' -import { GlobWalker } from './walker.js' +import {Minimatch, MinimatchOptions} from 'minimatch' +import {Path, PathScurry} from 'path-scurry' +import {Ignore} from './ignore.js' +import {Pattern} from './pattern.js' +import {GlobWalker} from './walker.js' type MatchSet = Minimatch['set'] type GlobSet = Exclude type GlobParts = Exclude export interface GlobOptions extends MinimatchOptions { - ignore?: string | string[] + ignore?: string | string[] | Ignore follow?: boolean mark?: boolean nodir?: boolean @@ -17,12 +18,42 @@ export interface GlobOptions extends MinimatchOptions { cwd?: string realpath?: boolean absolute?: boolean - cache?: GlobCache + withFileTypes?: boolean + scurry?: PathScurry } -export class Glob { +export type GlobOptionsWithFileTypesTrue = GlobOptions & { + withFileTypes: true +} + +export type GlobOptionsWithFileTypesFalse = GlobOptions & { + withFileTypes?: false +} + +export type GlobOptionsWithFileTypesUnset = GlobOptions & { + withFileTypes?: undefined +} + +type Results = Opts extends GlobOptionsWithFileTypesTrue + ? Path[] + : Opts extends GlobOptionsWithFileTypesFalse + ? string[] + : Opts extends GlobOptionsWithFileTypesUnset + ? string[] + : string[] | Path[] + +type FileTypes = Opts extends GlobOptionsWithFileTypesTrue + ? true + : Opts extends GlobOptionsWithFileTypesFalse + ? false + : Opts extends GlobOptionsWithFileTypesUnset + ? false + : boolean + +export class Glob { + withFileTypes: FileTypes pattern: string[] - ignore?: string | string[] + ignore?: Ignore follow: boolean dot: boolean mark: boolean @@ -39,35 +70,52 @@ export class Glob { matchBase: boolean windowsPathsNoEscape: boolean noglobstar: boolean - cache: GlobCache - matches?: Set - - constructor( - pattern: string | string[], - options: GlobOptions | Glob = {} - ) { - this.ignore = options.ignore + matches?: Set + nocase?: boolean + scurry: PathScurry + + constructor(pattern: string | string[], options: Opts) { + this.withFileTypes = !!options.withFileTypes as FileTypes + const { ignore } = options + if (typeof ignore === 'string') { + this.ignore = new Ignore([ignore]) + } else if (Array.isArray(ignore)) { + this.ignore = new Ignore(ignore) + } else if (ignore && (ignore instanceof Ignore)) { + this.ignore = ignore + } this.follow = !!options.follow this.dot = !!options.dot this.nodir = !!options.nodir this.mark = !!options.mark this.nounique = !!options.nounique - if (!this.nounique) { - this.matches = new Set() - } this.nosort = !!options.nosort this.cwd = options.cwd || '' - if (process.platform === 'win32') { - this.cwd = this.cwd.replace(/\\/g, '/') - } this.realpath = !!options.realpath this.nonull = !!options.nonull this.absolute = !!options.absolute - this.cache = options.cache || Object.create(null) this.noglobstar = !!options.noglobstar this.matchBase = !!options.matchBase + // if we're returning Path objects, we can't do nonull, because + // the pattern is a string, not a Path + if (this.withFileTypes) { + if (this.nonull) { + throw new TypeError( + 'cannot set nonull:true and withFileTypes:true' + ) + } + if (this.absolute) { + throw new Error('cannot set absolute:true and withFileTypes:true') + } + } + + // if we want unique entries, we need a single set to hold them all + if (!this.nounique) { + this.matches = new Set() + } + if (typeof pattern === 'string') { pattern = [pattern] } @@ -109,54 +157,64 @@ export class Glob { this.matchSet = matchSet this.globSet = globSet this.globParts = globParts + this.scurry = + options.scurry || + new PathScurry(this.cwd, { nocase: options.nocase }) } - async process() { - const matches = await Promise.all( + process(): Promise> + async process(): Promise { + // Walkers always return array of Path objects, so we just have to + // coerce them into the right shape. It will have already called + // realpath() if the option was set to do so, so we know that's cached. + const matches: Set[] = await Promise.all( this.matchSet.map(async (set, i) => { const p = new Pattern(set, this.globParts[i], 0) return await this.getWalker(p).walk() }) ) - return this.finish(this.doNonull(matches)) + // TODO: nonull filling in the blanks + return this.finish(matches) } processSync() { - const matches = this.matchSet.map((set, i) => { + const matches: Set[] = this.matchSet.map((set, i) => { const p = new Pattern(set, this.globParts[i], 0) return this.getWalker(p).walkSync() }) - return this.finish(this.doNonull(matches)) - } - - doNonull(matches: Set[]): Set[] { - const nulls: string[] = [] - matches.forEach((set, i) => { - if (!set.size && this.nonull) { - nulls.push(this.globSet[i]) - } - }) - for (const n of nulls) { - matches[0].add(n) - } - return matches + return this.finish(matches) } - finish(matches: Set[]): string[] { - const raw: string[] = [...matches[0]] + finish( + matches: Set[] + ): Results + finish(matches: Set[]): string[] | Path[] { + const raw: Path[] = [] if (this.nounique) { for (const set of matches) { raw.push(...set) } + } else { + raw.push(...matches[0]) } - return this.nosort ? raw : this.sort(raw) + return this.withFileTypes + ? raw + : this.absolute + ? this.sort(raw.map(r => r.fullpath())) + : this.realpath + ? this.sort( + raw.map(r => (r.realpathCached() || r).fullpath()) + ) + : this.sort(raw.map(r => r.fullpath())) } sort(flat: string[]) { - return flat.sort((a, b) => a.localeCompare(b, 'en')) + return this.nosort + ? flat + : flat.sort((a, b) => a.localeCompare(b, 'en')) } getWalker(pattern: Pattern) { - return new GlobWalker(pattern, '', this, false) + return new GlobWalker(pattern, this.scurry.cwd, this.matches) } } diff --git a/src/has-magic.ts b/src/has-magic.ts index aa39aec7..7a88cb0c 100644 --- a/src/has-magic.ts +++ b/src/has-magic.ts @@ -2,7 +2,7 @@ import { Glob, GlobOptions } from './glob.js' export const hasMagic = ( pattern: string | string[], - options?: Glob | GlobOptions + options: GlobOptions = {} ): boolean => { if (!Array.isArray(pattern)) { pattern = [pattern] diff --git a/src/index.ts b/src/index.ts index d019bd3f..339e71ae 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,14 +3,14 @@ import { hasMagic } from './has-magic.js' export const globSync = ( pattern: string | string[], - options?: Glob | GlobOptions -): string[] => new Glob(pattern, options).processSync() + options: GlobOptions = {} +): string[] => new Glob(pattern, { ...options, withFileTypes: false }).processSync() export const glob = Object.assign( async ( pattern: string | string[], - options?: Glob | GlobOptions - ): Promise => new Glob(pattern, options).process(), + options: GlobOptions = {} + ): Promise => new Glob(pattern, { ...options, withFileTypes: false }).process(), { sync: globSync, globSync, diff --git a/src/pattern.ts b/src/pattern.ts index ca297204..025dbc69 100644 --- a/src/pattern.ts +++ b/src/pattern.ts @@ -1,19 +1,29 @@ // this is just a very light wrapper around 2 arrays with an offset index import { GLOBSTAR } from 'minimatch' -import { resolve } from 'path' type MMRegExp = RegExp & { _glob?: string _src?: string } -type MMPattern = string | MMRegExp | typeof GLOBSTAR +export type MMPattern = string | MMRegExp | typeof GLOBSTAR // an array of length >= 1 type PatternList = [p: MMPattern, ...rest: MMPattern[]] +type UNCPatternList = [ + p0: '', + p1: '', + p2: string, + p3: string, + ...rest: MMPattern[] +] +type DrivePatternList = [p0: string, ...rest: MMPattern[]] +type AbsolutePatternList = [p0: '', ...rest: MMPattern[]] type GlobList = [p: string, ...rest: string[]] +// TODO: this should be a parameter const isWin = process.platform === 'win32' -const isPatternList = (pl: MMPattern[]): pl is PatternList => pl.length >= 1 +const isPatternList = (pl: MMPattern[]): pl is PatternList => + pl.length >= 1 const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1 export class Pattern { @@ -107,6 +117,25 @@ export class Pattern { return this.length > this.index + 1 } + copy(): Pattern { + return new Pattern(this.patternList, this.globList, this.index) + } + insert(p: MMPattern, g: string): Pattern { + return new Pattern( + [ + ...this.patternList.slice(0, this.index), + p, + ...this.patternList.slice(this.index), + ], + [ + ...this.globList.slice(0, this.index), + g, + ...this.globList.slice(this.index), + ], + this.index + ) + } + rest(): Pattern | null { return this.hasMore() ? new Pattern(this.patternList, this.globList, this.index + 1) @@ -115,8 +144,7 @@ export class Pattern { // pattern like: //host/share/... // split = [ '', '', 'host', 'share', ... ] - isUNC(): boolean { - const pl = this.patternList + isUNC(pl = this.patternList): pl is UNCPatternList { return ( isWin && this.index === 0 && @@ -134,51 +162,44 @@ export class Pattern { // XXX: would be nice to handle patterns like `c:*` to test the cwd // in c: for *, but I don't know of a way to even figure out what that // cwd is without actually chdir'ing into it? - isDrive(): boolean { - const p = this.patternList[0] + isDrive(pl = this.patternList): pl is DrivePatternList { return ( isWin && this.index === 0 && this.length > 1 && - typeof p === 'string' && - /^[a-z]:$/i.test(p) + typeof pl[0] === 'string' && + /^[a-z]:$/i.test(pl[0]) ) } // pattern = '/' or '/...' or '/x/...' // split = ['', ''] or ['', ...] or ['', 'x', ...] // Drive and UNC both considered absolute on windows - isAbsolute(): boolean { + isAbsolute(pl = this.patternList): pl is AbsolutePatternList { return ( - (this.patternList[0] === '' && this.length > 1) || - this.isDrive() || - this.isUNC() + (pl[0] === '' && this.length > 1) || + this.isDrive(pl) || + this.isUNC(pl) ) } - // given a current working dir, what's the root that we should - // start looking in? - root(cwd: string): string { + // consume the root of the pattern, and return it + root(): string { if (this.index !== 0) { throw new Error('should only check root on initial walk') } - const driveRE = /^[a-z]:($|[\\\/])/i - return ( - // UNC paths start at /, because we gobble the string parts anyway - ( - this.isUNC() - ? '/' - : // drive letter pattern, start in the root of that drive letter - this.isDrive() - ? (this.patternList[0] as string) + '/' - : isWin && driveRE.test(cwd) - ? (cwd.match(driveRE) as RegExpMatchArray)[0] - : this.isAbsolute() - ? isWin - ? resolve(cwd, '/') - : '/' - : cwd - ).replace(/\\/g, '/') - ) + // //x/y/z -> ['', '', x, y, z] + // c:/x -> ['c:', x] + // /x -> ['', 'x'] + const pl = this.patternList + if (this.isUNC(pl)) { + this.index = 4 + return pl[0] + pl[1] + pl[2] + pl[3] + } else if (this.isDrive(pl) || this.isAbsolute(pl)) { + this.index = 1 + return pl[0] + '/' + } else { + return '' + } } } diff --git a/src/walker.ts b/src/walker.ts index 9884d2a3..e0d23c09 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -1,397 +1,227 @@ -// glob walker -// The simplest first pass at finding a bunch of paths matching a glob -// Takes a single pattern entry from the minimatch (string|re|globstar)[] -// and operate on a single path, fanning out to child entries as appropriate. -// -// - if pattern is empty, return [path] -// - readdir path -// - if ENOTDIR, return [] -// - if pattern[0] is string (including '.' or '..') and pattern[0] in -// entries, or pattern[0] is . or .. -// - return walk(dir+pattern[0], pattern.slice(1)) -// - if pattern[0] is globstar: -// - return walk all entries with pattern AND pattern.slice(1) if len>1 -// - discard any entries that don't match pattern[0] -// - child walk remaining entries with pattern.slice(1) -// - return all matching child walks - -import { Dirent, realpath, realpathSync } from 'fs' -import { GLOBSTAR } from 'minimatch' -import { isAbsolute, posix, resolve } from 'path' -import { Ignore } from './ignore.js' -import { GlobCache, Readdir } from './readdir.js' -// always use posix join because it's faster, and it's just for keys -const { join } = posix - -import { Pattern } from './pattern.js' +import type { Path } from 'path-scurry' // a single minimatch set entry with 1 or more parts +import { Pattern } from './pattern.js' -type Children = (GlobWalker | string | undefined)[] - -export interface GlobWalkerOptions { - follow?: boolean - rd?: Readdir - cache?: GlobCache - realpath?: boolean - mark?: boolean - nodir?: boolean - ignore?: string | string[] | Ignore - dot?: boolean - absolute?: boolean - cwd?: string - matches?: Set - seen?: Map> - absCwd?: string -} +// the "matches" set is a set of either: +// - Path objects (if withFileTypes:true) +// - resolved paths (if absolute:true) +// - real paths (if realpath:true) +// - built-up path strings (all other cases) +// get the Path objects that match the pattern export class GlobWalker { + path: Path pattern: Pattern - path: string - follow: boolean - rd: Readdir - realpath: boolean - absolute: boolean - mark: boolean - nodir: boolean - dot: boolean - ignore?: Ignore - cache: GlobCache - cwd: string - start: string - hasParent: boolean - matches: Set - seen: Map> - absCwd: string + matches: Set constructor( pattern: Pattern, - path: string, - options: GlobWalkerOptions | GlobWalker = {}, - hasParent: boolean = false + path: Path, + matches: Set = new Set() ) { - //console.error('GW', [path, pattern.globString()]) - const { - follow = false, - realpath = false, - absolute = false, - mark = false, - nodir = false, - dot = false, - rd, - cache, - ignore, - cwd = '', - matches = new Set(), - seen = new Map(), - absCwd, - } = options - - this.matches = matches - this.hasParent = hasParent - this.seen = seen - this.pattern = pattern this.path = path - this.cwd = cwd - this.absCwd = absCwd || resolve(cwd || '.').replace(/\\/g, '/') - this.start = this.setStart() - - // note that we've now tested this pattern at this path - const jp = join(path) - const pathSeen = seen.get(jp) - if (!pathSeen) { - seen.set(jp, new Set([this.pattern.globString()])) - } else { - pathSeen.add(this.pattern.globString()) - } - - this.follow = follow - this.realpath = realpath - this.absolute = absolute - this.mark = mark - this.nodir = nodir - this.rd = rd ? rd : new Readdir(cache) - this.cache = this.rd.cache - this.dot = dot - if (typeof ignore === 'string') { - this.ignore = new Ignore([ignore]) - } else if (Array.isArray(ignore)) { - this.ignore = new Ignore(ignore) - } else if (ignore instanceof Ignore) { - this.ignore = ignore - } - } - - setStart() { - const first = this.pattern.pattern() - // a pattern like /a/s/d/f discards the cwd - // a pattern like / (or c:/ on windows) can only match the root - if (typeof first === 'string' && !this.hasParent) { - const setAbs = this.pattern.isAbsolute() - const rest = this.pattern.rest() - if (setAbs && rest) { - // a pattern like '/' on windows goes to the root of - // the drive that cwd is on. If cwd isn't on a drive, use / - const cwd = this.cwd ? this.join(this.path, this.cwd) : this.path - // don't mount UNC paths on a drive letter - // eg: //?/c:/* or //host/share/* - // Only relevant if we WOULD have tried to mount it - // We'll gobble those strings shortly, so use '/' for now - const root = this.pattern.root(cwd) - this.cwd = root || '/' - this.absCwd = root || '/' - this.path = '/' - } - } - - // skip ahead any literal portions, and read that dir instead - while (this.pattern.hasMore() && this.pattern.isString()) { - const p = this.pattern.pattern() as string - this.path = this.path === '/' ? this.path + p : this.join(p) - this.pattern = this.pattern.rest() as Pattern - } - - // console.error( - // 'ss', - // this.path, - // this.absCwd, - // this.join(this.path, this.absCwd) - // ) - - return this.join(this.path, this.absCwd) + this.matches = matches } - // don't do the same walk more than one time, ever - hasSeen(pattern: Pattern, path: string): boolean { - const jp = join(path) - const seenPath = this.seen.get(jp) - if (seenPath) { - if (seenPath.has(pattern.globString())) { - return true + async walk(): Promise> { + // consume all pattern portions except the last one. + // if the last one is a string, then we stat and add it. + const promises: Promise[] = [] + while (this.pattern.hasMore()) { + const p = this.pattern.pattern() + if (typeof p === 'string') { + this.pattern.shift() + this.path = this.path.child(p) + } else if (p instanceof RegExp) { + // this fans out, but we must match the pattern against + // something, so nothing else to do here. + promises.push(this.walkRegExp(p, this.pattern)) + await Promise.all(promises) + return this.matches + } else { + // globstar! + // this fans out, but also continues without the ** + promises.push(this.walkGlobStar(this.pattern)) + this.pattern.shift() } } - return false - } - - child(pattern: Pattern, path: string): GlobWalker | undefined { - if (!this.hasSeen(pattern, path)) { - return new GlobWalker(pattern, path, this, true) - } - } - - match(p: string): void { - if (!this.ignore?.ignored(p)) { - this.matches.add(p) + const p = this.pattern.pattern() + if (typeof p === 'string') { + this.path = this.path.child(p) + this.maybeMatchPath(promises) + } else if (p instanceof RegExp) { + promises.push(this.walkRegExp(p, this.pattern)) + } else { + // globstar at the end is either nothing, or all children + // make sure our path actually exists, if it was something + // like a/b/** we might've got here without checking + this.maybeMatchPath(promises) + promises.push(this.walkGlobStar(this.pattern)) } + await Promise.all(promises) + return this.matches } - finish(p: string): void { - if (!p || this.ignore?.ignored(p)) { - return - } - if (this.nodir || this.mark) { - const isDir = this.rd.isDirectory( - isAbsolute(p) ? p : resolve(this.join(p, this.cwd)) - ) - // console.error('finish mark', p, isAbsolute(p), isDir, require('fs').statSync(p).isDirectory(), this.cache) - if (isDir) { - if (this.nodir) { - return - } - if (p.substring(p.length - 1) !== '/') { - this.match(p + '/') - return - } + walkSync(): Set { + // consume all pattern portions except the last one. + // if the last one is a string, then we stat and add it. + while (this.pattern.hasMore()) { + const p = this.pattern.pattern() + if (typeof p === 'string') { + this.path = this.path.child(p) + this.pattern.shift() + } else if (p instanceof RegExp) { + // this fans out, but we must match the pattern against + // something, so nothing else to do here. + this.walkRegExpSync(p, this.pattern) + this.pattern.shift() + return this.matches + } else { + // globstar! + // this fans out, but also continues without the ** + this.walkGlobStarSync(this.pattern) + this.pattern.shift() } } - this.match(p) - } - - async doRealpath(p: string): Promise { - if (!this.realpath && !this.absolute) { - return p - } - const pp = resolve(this.join(p, this.cwd)) - if (!this.realpath) { - return pp - } - return await new Promise(res => - realpath(pp, (er, rp) => (er ? res(pp) : res(rp))) - ) - } - - doRealpathSync(p: string): string { - if (!this.realpath && !this.absolute) { - return p - } - const pp = resolve(this.join(p, this.cwd)) - if (!this.realpath) { - return pp - } - try { - return realpathSync(pp) - } catch (_) { - return pp - } - } - - async walk(): Promise> { - if (this.ignore?.childrenIgnored(this.path)) { - return this.matches - } - let entries: Dirent[] | false = await this.rd.readdir(this.start) - if (!entries) { + const p = this.pattern.pattern() + if (typeof p === 'string') { + this.path = this.path.child(p) + this.maybeMatchPathSync() + } else if (p instanceof RegExp) { + this.walkRegExpSync(p, this.pattern) return this.matches + } else { + // globstar at the end is either nothing, or all children + // make sure our path actually exists, if it was something + // like a/b/** we might've got here without checking + this.maybeMatchPathSync() + this.walkGlobStarSync(this.pattern) } - const children = this.getChildren(entries) - await Promise.all( - children.map(async c => - typeof c === 'string' - ? this.finish(await this.doRealpath(c)) - : c?.walk() - ) - ) return this.matches } - walkSync(): Set { - if (this.ignore?.childrenIgnored(this.path)) { - return this.matches - } - let entries: Dirent[] | false = this.rd.readdirSync(this.start) - //console.error(' >', [this.path, this.pattern.globString()], entries && entries.map(e => e.name)) - if (!entries) { - return this.matches - } - const children = this.getChildren(entries) - for (const c of children) { - if (typeof c === 'string') { - this.finish(this.doRealpathSync(c)) + maybeMatchPath(promises: Promise[]) { + if (this.path.isUnknown()) { + const lsc = this.path.lstatCached() + if (lsc) { + this.matches.add(lsc) } else { - c?.walkSync() + promises.push( + this.path.lstat().then(p => { + if (p) this.matches.add(p) + }) + ) } + } else { + this.matches.add(this.path) } - return this.matches } - - join(p: string, base: string = this.path) { - return base === '' - ? p - : base === '/' - ? p.startsWith('/') - ? p - : p - ? `${base}${p}` - : `${base}/` - : `${base}/${p}` + maybeMatchPathSync() { + if (this.path.isUnknown()) { + const lsc = this.path.lstatCached() + if (lsc) { + this.matches.add(lsc) + } else { + const p = this.path.lstatSync() + if (p) this.matches.add(p) + } + } else { + this.matches.add(this.path) + } } - getChildrenString( - entries: Dirent[], - p: string, - rest: Pattern | null - ): Children { - const children: Children = [] - const e = - p !== '' && - p !== '.' && - p !== '..' && - entries.find(e => e.name === p) - - // since we pull all string portions up to minimize readdir() calls, - // the only way we can possibly have a rest here is if something - // OTHER than a string comes next. - // However, if we're landing on ., '', .., or a string that matches - // an entry in the directory we just read, then it's a match. - if ((p === '.' || p === '' || p === '..' || e) && !rest) { - children.push(this.join(p)) + async walkGlobStar(pattern: Pattern): Promise { + // get all children, and walk from there + if (!this.path.canReaddir()) { + return } - return children + return new Promise(res => { + this.path.readdirCB((_er, entries) => { + Promise.all( + entries.map(async (e: Path) => { + if (e.name.startsWith('.')) return + if (e.isSymbolicLink()) { + // we can MATCH a symlink, just not traverse it + this.matches.add(e) + return + } + const w = new GlobWalker(pattern.copy(), e, this.matches) + return w.walk() + }) + ).then(() => res) + }, true) + }) } - getChildrenGlobstar(entries: Dirent[], rest: Pattern | null): Children { - const children: Children = [] - - // eg, p=**/a/b - if (rest) { - // XXX this is faster, but it breaks some bash comparisons - // also, it's still not fast enough, even with this. - // - // it can match a/b against this path, without the ** - // skip ahead one step - // const p = rest.pattern() - // const r = rest.rest() - // if (rest.isString()) { - // children.push(...this.getChildrenString(entries, p, r)) - // } else if (rest.isMagic()) { - // children.push(...this.getChildrenRegexp(entries, p, r)) - // } - children.push(this.child(rest, this.path)) - } else { - // but if ** is at the end, then this path definitely matches - children.push(this.path) + walkGlobStarSync(pattern: Pattern): void { + // get all children, and walk from there + if (!this.path.canReaddir()) { + return } - + const entries = this.path.readdirSync() for (const e of entries) { - if (!this.dot && e.name.startsWith('.')) { + if (e.name.startsWith('.')) continue + if (e.isSymbolicLink()) { + // we can MATCH a symlink, just not traverse it + this.matches.add(e) continue } - const path = this.join(e.name) - // ** does not traverse symlinks, unless follow:true is set. - const traverse = - e.isDirectory() || (this.follow && e.isSymbolicLink()) - if (traverse) { - children.push(this.child(this.pattern, path)) - } - if (rest) { - // TODO: match bash behavior - // **/a will not traverse symlinks, but ./**/a WILL traverse - // a single symlink - if (e.isSymbolicLink()) { - // can match a/b against child path - children.push(this.child(rest, path)) - } - } else { - // ** at the end, will match all children - children.push(path) - } + const w = new GlobWalker(pattern.copy(), e, this.matches) + w.walkSync() } - - return children } - getChildrenRegexp( - entries: Dirent[], - p: RegExp, - rest: Pattern | null - ): Children { - const children: Children = [] - for (const e of entries) { - if (!p.test(e.name)) { - continue - } - if (rest) { - if (e.isDirectory() || e.isSymbolicLink()) { - children.push(this.child(rest, this.join(e.name))) - } - } else { - children.push(this.join(e.name)) - } + async walkRegExp(p: RegExp, pattern: Pattern): Promise { + if (!this.path.canReaddir()) { + return } - - return children + return new Promise(res => { + this.path.readdirCB((_, entries) => { + if (!pattern.hasMore()) { + for (const e of entries) { + if (p.test(e.name)) this.matches.add(e) + } + res() + } else { + const promises: Promise[] = [] + for (const e of entries) { + if (p.test(e.name)) { + const w = new GlobWalker( + pattern.rest() as Pattern, + e, + this.matches + ) + promises.push(w.walk().then(() => {})) + } + } + Promise.all(promises).then(() => res()) + } + }, true) + }) } - getChildren(entries: Dirent[]): Children { - const p = this.pattern.pattern() - const rest = this.pattern.rest() - if (typeof p === 'string') { - return this.getChildrenString(entries, p, rest) - } else if (p === GLOBSTAR) { - return this.getChildrenGlobstar(entries, rest) + walkRegExpSync(p: RegExp, pattern: Pattern): void { + if (!this.path.canReaddir()) { + return + } + const entries = this.path.readdirSync() + if (!pattern.hasMore()) { + for (const e of entries) { + if (p.test(e.name)) this.matches.add(e) + } } else { - return this.getChildrenRegexp(entries, p, rest) + for (const e of entries) { + if (p.test(e.name)) { + const w = new GlobWalker( + pattern.rest() as Pattern, + e, + this.matches + ) + w.walkSync() + } + } } } } From d24efba8ad95805223cb8c255ff78d31af4b6812 Mon Sep 17 00:00:00 2001 From: isaacs Date: Fri, 10 Feb 2023 08:29:59 -0800 Subject: [PATCH 066/163] working, too slow, need more parallel stuff --- src/glob.ts | 124 ++++++++++++------------- src/index.ts | 6 +- src/walker.ts | 246 ++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 262 insertions(+), 114 deletions(-) diff --git a/src/glob.ts b/src/glob.ts index 9d0b8827..d585f619 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -1,8 +1,8 @@ -import {Minimatch, MinimatchOptions} from 'minimatch' -import {Path, PathScurry} from 'path-scurry' -import {Ignore} from './ignore.js' -import {Pattern} from './pattern.js' -import {GlobWalker} from './walker.js' +import { Minimatch, MinimatchOptions } from 'minimatch' +import { Path, PathScurry } from 'path-scurry' +import { Ignore } from './ignore.js' +import { Pattern } from './pattern.js' +import { GlobWalker, Matches } from './walker.js' type MatchSet = Minimatch['set'] type GlobSet = Exclude @@ -34,21 +34,22 @@ export type GlobOptionsWithFileTypesUnset = GlobOptions & { withFileTypes?: undefined } -type Results = Opts extends GlobOptionsWithFileTypesTrue - ? Path[] - : Opts extends GlobOptionsWithFileTypesFalse - ? string[] - : Opts extends GlobOptionsWithFileTypesUnset - ? string[] - : string[] | Path[] +type Result = Opts extends GlobOptionsWithFileTypesTrue + ? Path + : Opts extends GlobOptionsWithFileTypesFalse + ? string + : Opts extends GlobOptionsWithFileTypesUnset + ? string + : string | Path +type Results = Result[] type FileTypes = Opts extends GlobOptionsWithFileTypesTrue - ? true - : Opts extends GlobOptionsWithFileTypesFalse - ? false - : Opts extends GlobOptionsWithFileTypesUnset - ? false - : boolean + ? true + : Opts extends GlobOptionsWithFileTypesFalse + ? false + : Opts extends GlobOptionsWithFileTypesUnset + ? false + : boolean export class Glob { withFileTypes: FileTypes @@ -70,33 +71,36 @@ export class Glob { matchBase: boolean windowsPathsNoEscape: boolean noglobstar: boolean - matches?: Set + matches?: Matches + seen?: Set nocase?: boolean scurry: PathScurry + opts: Opts - constructor(pattern: string | string[], options: Opts) { - this.withFileTypes = !!options.withFileTypes as FileTypes - const { ignore } = options + constructor(pattern: string | string[], opts: Opts) { + this.withFileTypes = !!opts.withFileTypes as FileTypes + const { ignore } = opts if (typeof ignore === 'string') { this.ignore = new Ignore([ignore]) } else if (Array.isArray(ignore)) { this.ignore = new Ignore(ignore) - } else if (ignore && (ignore instanceof Ignore)) { + } else if (ignore && ignore instanceof Ignore) { this.ignore = ignore } - this.follow = !!options.follow - this.dot = !!options.dot - this.nodir = !!options.nodir - this.mark = !!options.mark - this.nounique = !!options.nounique - this.nosort = !!options.nosort - this.cwd = options.cwd || '' - this.realpath = !!options.realpath - this.nonull = !!options.nonull - this.absolute = !!options.absolute - - this.noglobstar = !!options.noglobstar - this.matchBase = !!options.matchBase + this.opts = opts + this.follow = !!opts.follow + this.dot = !!opts.dot + this.nodir = !!opts.nodir + this.mark = !!opts.mark + this.nounique = !!opts.nounique + this.nosort = !!opts.nosort + this.cwd = opts.cwd || '' + this.realpath = !!opts.realpath + this.nonull = !!opts.nonull + this.absolute = !!opts.absolute + + this.noglobstar = !!opts.noglobstar + this.matchBase = !!opts.matchBase // if we're returning Path objects, we can't do nonull, because // the pattern is a string, not a Path @@ -113,7 +117,8 @@ export class Glob { // if we want unique entries, we need a single set to hold them all if (!this.nounique) { - this.matches = new Set() + this.matches = new Set() as Matches + this.seen = new Set() } if (typeof pattern === 'string') { @@ -121,15 +126,15 @@ export class Glob { } this.windowsPathsNoEscape = - !!options.windowsPathsNoEscape || - (options as GlobOptions).allowWindowsEscape === false + !!opts.windowsPathsNoEscape || + (opts as GlobOptions).allowWindowsEscape === false if (this.windowsPathsNoEscape) { pattern = pattern.map(p => p.replace(/\\/g, '/')) } if (this.matchBase) { - if (options.noglobstar) { + if (opts.noglobstar) { throw new TypeError('base matching requires globstar') } pattern = pattern.map(p => (p.includes('/') ? p : `**/${p}`)) @@ -138,7 +143,7 @@ export class Glob { this.pattern = pattern const mmo: MinimatchOptions = { - ...options, + ...opts, nonegate: true, nocomment: true, preserveMultipleSlashes: true, @@ -158,16 +163,15 @@ export class Glob { this.globSet = globSet this.globParts = globParts this.scurry = - options.scurry || - new PathScurry(this.cwd, { nocase: options.nocase }) + opts.scurry || new PathScurry(this.cwd, { nocase: opts.nocase }) } process(): Promise> - async process(): Promise { + async process(): Promise> { // Walkers always return array of Path objects, so we just have to // coerce them into the right shape. It will have already called // realpath() if the option was set to do so, so we know that's cached. - const matches: Set[] = await Promise.all( + const matches: Matches[] = await Promise.all( this.matchSet.map(async (set, i) => { const p = new Pattern(set, this.globParts[i], 0) return await this.getWalker(p).walk() @@ -178,18 +182,16 @@ export class Glob { } processSync() { - const matches: Set[] = this.matchSet.map((set, i) => { + const matches: Matches[] = this.matchSet.map((set, i) => { const p = new Pattern(set, this.globParts[i], 0) return this.getWalker(p).walkSync() }) return this.finish(matches) } - finish( - matches: Set[] - ): Results - finish(matches: Set[]): string[] | Path[] { - const raw: Path[] = [] + finish(matches: Matches[]): Results + finish(matches: Set[]): (string | Path)[] { + const raw: (string | Path)[] = [] if (this.nounique) { for (const set of matches) { raw.push(...set) @@ -197,15 +199,7 @@ export class Glob { } else { raw.push(...matches[0]) } - return this.withFileTypes - ? raw - : this.absolute - ? this.sort(raw.map(r => r.fullpath())) - : this.realpath - ? this.sort( - raw.map(r => (r.realpathCached() || r).fullpath()) - ) - : this.sort(raw.map(r => r.fullpath())) + return raw } sort(flat: string[]) { @@ -214,7 +208,13 @@ export class Glob { : flat.sort((a, b) => a.localeCompare(b, 'en')) } - getWalker(pattern: Pattern) { - return new GlobWalker(pattern, this.scurry.cwd, this.matches) + getWalker(pattern: Pattern): GlobWalker { + return new GlobWalker( + pattern, + this.scurry.cwd, + this.matches, + this.seen, + this.opts + ) } } diff --git a/src/index.ts b/src/index.ts index 339e71ae..0ac3637a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,13 +4,15 @@ import { hasMagic } from './has-magic.js' export const globSync = ( pattern: string | string[], options: GlobOptions = {} -): string[] => new Glob(pattern, { ...options, withFileTypes: false }).processSync() +): string[] => + new Glob(pattern, { ...options, withFileTypes: false }).processSync() export const glob = Object.assign( async ( pattern: string | string[], options: GlobOptions = {} - ): Promise => new Glob(pattern, { ...options, withFileTypes: false }).process(), + ): Promise => + new Glob(pattern, { ...options, withFileTypes: false }).process(), { sync: globSync, globSync, diff --git a/src/walker.ts b/src/walker.ts index e0d23c09..e0877914 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -1,8 +1,40 @@ -import type { Path } from 'path-scurry' +import { Path } from 'path-scurry' // a single minimatch set entry with 1 or more parts import { Pattern } from './pattern.js' +export interface GlobWalkerOpts { + absolute?: boolean + realpath?: boolean + nodir?: boolean + mark?: boolean + withFileTypes?: boolean +} + +export type GWOFileTypesTrue = GlobWalkerOpts & { + withFileTypes: true +} +export type GWOFileTypesFalse = GlobWalkerOpts & { + withFileTypes: false +} +export type GWOFileTypesUnset = GlobWalkerOpts & { + withFileTypes?: undefined +} +export type Result = O extends GWOFileTypesTrue + ? Path + : O extends GWOFileTypesFalse + ? string + : O extends GWOFileTypesUnset + ? string + : Path | string +export type Matches = O extends GWOFileTypesTrue + ? Set + : O extends GWOFileTypesFalse + ? Set + : O extends GWOFileTypesUnset + ? Set + : Set + // the "matches" set is a set of either: // - Path objects (if withFileTypes:true) // - resolved paths (if absolute:true) @@ -10,25 +42,122 @@ import { Pattern } from './pattern.js' // - built-up path strings (all other cases) // get the Path objects that match the pattern -export class GlobWalker { +export class GlobWalker { path: Path pattern: Pattern - matches: Set + matches: O extends GWOFileTypesTrue + ? Set + : O extends GWOFileTypesFalse + ? Set + : O extends GWOFileTypesUnset + ? Set + : Set + opts: O + seen: Set constructor( pattern: Pattern, path: Path, - matches: Set = new Set() + matches: Matches | undefined, + seen: Set | undefined, + opts: O + ) + constructor( + pattern: Pattern, + path: Path, + matches: Matches | undefined, + seen: Set | undefined, + opts: O ) { this.pattern = pattern this.path = path - this.matches = matches + this.matches = (matches || new Set()) as Matches + this.opts = opts + this.seen = seen || new Set() } - async walk(): Promise> { + // do the requisite realpath/stat checking, and return true/false + // to say whether to include the match or filter it out. + async matchPrecheck(e: Path): Promise { + let rpc: Path | undefined + if (this.opts.realpath) { + rpc = e.realpathCached() + if (rpc) { + if (this.seen.has(rpc) || (e.isDirectory() && this.opts.nodir)) { + return undefined + } + e = rpc + } + } + if (e.isDirectory() && this.opts.nodir) { + return undefined + } + const needRealPath = this.opts.realpath && !rpc + const needStat = (this.opts.nodir || this.opts.mark) && e.isUnknown() + if (needRealPath && needStat) { + const r = await e.realpath().then(e => e && e.lstat()) + if (!r || this.seen.has(r) || (e.isDirectory() && this.opts.nodir)) { + return undefined + } + return r + } else if (needRealPath) { + const r = await e.realpath() + if (!r || this.seen.has(r) || (e.isDirectory() && this.opts.nodir)) { + return undefined + } + return r + } else if (needStat) { + return await e.lstat() + } + return e + } + + matchFinal(e: Path) { + const mark = this.opts.mark && e.isDirectory() ? '/' : '' + // ok, we have what we need! + if (this.opts.withFileTypes) { + this.matches.add(e) + } else if (this.opts.nodir && e.isDirectory()) { + return + } else if (this.opts.absolute) { + this.matches.add(e.fullpath() + mark) + } else { + this.matches.add(e.relative() + mark) + } + } + + async match(e: Path): Promise { + const p = await this.matchPrecheck(e) + if (p) this.matchFinal(p) + } + + matchSync(e: Path) { + if (this.opts.realpath) { + const r = e.realpathSync() + if (!r) return + e = r + } + if (e.isUnknown() && (this.opts.nodir || this.opts.mark)) { + const ls = e.lstatSync() + if (!ls) return + } + if (this.opts.nodir && e.isDirectory()) { + return + } + const mark = this.opts.mark && e.isDirectory() ? '/' : '' + // ok, we have what we need! + if (this.opts.withFileTypes) { + this.matches.add(e) + } else if (this.opts.absolute) { + this.matches.add(e.fullpath() + mark) + } else { + this.matches.add(e.relative() + mark) + } + } + + async walk(): Promise> { // consume all pattern portions except the last one. // if the last one is a string, then we stat and add it. - const promises: Promise[] = [] while (this.pattern.hasMore()) { const p = this.pattern.pattern() if (typeof p === 'string') { @@ -37,34 +166,34 @@ export class GlobWalker { } else if (p instanceof RegExp) { // this fans out, but we must match the pattern against // something, so nothing else to do here. - promises.push(this.walkRegExp(p, this.pattern)) - await Promise.all(promises) + await this.walkRegExp(p, this.pattern) return this.matches } else { // globstar! // this fans out, but also continues without the ** - promises.push(this.walkGlobStar(this.pattern)) + await this.walkGlobStar(this.pattern) this.pattern.shift() } } const p = this.pattern.pattern() if (typeof p === 'string') { this.path = this.path.child(p) - this.maybeMatchPath(promises) + await this.maybeMatchPath() } else if (p instanceof RegExp) { - promises.push(this.walkRegExp(p, this.pattern)) + await this.walkRegExp(p, this.pattern) } else { // globstar at the end is either nothing, or all children // make sure our path actually exists, if it was something // like a/b/** we might've got here without checking - this.maybeMatchPath(promises) - promises.push(this.walkGlobStar(this.pattern)) + await Promise.all([ + this.maybeMatchPath(), + this.walkGlobStar(this.pattern), + ]) } - await Promise.all(promises) return this.matches } - walkSync(): Set { + walkSync(): Matches { // consume all pattern portions except the last one. // if the last one is a string, then we stat and add it. while (this.pattern.hasMore()) { @@ -102,33 +231,29 @@ export class GlobWalker { return this.matches } - maybeMatchPath(promises: Promise[]) { + async maybeMatchPath(): Promise { if (this.path.isUnknown()) { const lsc = this.path.lstatCached() if (lsc) { - this.matches.add(lsc) + return this.match(lsc) } else { - promises.push( - this.path.lstat().then(p => { - if (p) this.matches.add(p) - }) - ) + return this.path.lstat().then(p => p && this.match(p)) } } else { - this.matches.add(this.path) + return this.match(this.path) } } maybeMatchPathSync() { if (this.path.isUnknown()) { const lsc = this.path.lstatCached() if (lsc) { - this.matches.add(lsc) + this.matchSync(lsc) } else { const p = this.path.lstatSync() - if (p) this.matches.add(p) + if (p) this.matchSync(p) } } else { - this.matches.add(this.path) + this.matchSync(this.path) } } @@ -139,18 +264,24 @@ export class GlobWalker { } return new Promise(res => { this.path.readdirCB((_er, entries) => { - Promise.all( - entries.map(async (e: Path) => { - if (e.name.startsWith('.')) return - if (e.isSymbolicLink()) { - // we can MATCH a symlink, just not traverse it - this.matches.add(e) - return - } - const w = new GlobWalker(pattern.copy(), e, this.matches) - return w.walk() - }) - ).then(() => res) + const promises: Promise[] = [] + for (const e of entries) { + if (e.name.startsWith('.')) continue + else if (!e.isDirectory()) { + promises.push(this.match(e)) + } else { + const w = new GlobWalker( + pattern.copy(), + e, + this.matches, + this.seen, + this.opts + ) + promises.push(w.walk()) + } + } + if (promises.length) return Promise.all(promises).then(() => res()) + else return res() }, true) }) } @@ -165,10 +296,16 @@ export class GlobWalker { if (e.name.startsWith('.')) continue if (e.isSymbolicLink()) { // we can MATCH a symlink, just not traverse it - this.matches.add(e) + this.matchSync(e) continue } - const w = new GlobWalker(pattern.copy(), e, this.matches) + const w = new GlobWalker( + pattern.copy(), + e, + this.matches, + this.seen, + this.opts + ) w.walkSync() } } @@ -180,22 +317,29 @@ export class GlobWalker { return new Promise(res => { this.path.readdirCB((_, entries) => { if (!pattern.hasMore()) { + const promises: Promise[] = [] for (const e of entries) { - if (p.test(e.name)) this.matches.add(e) + if (p.test(e.name)) { + promises.push(this.match(e)) + } } - res() + if (!entries.length) return res() + Promise.all(promises).then(() => res()) } else { - const promises: Promise[] = [] + const promises: Promise[] = [] for (const e of entries) { if (p.test(e.name)) { - const w = new GlobWalker( + const w = new GlobWalker( pattern.rest() as Pattern, e, - this.matches + this.matches, + this.seen, + this.opts ) - promises.push(w.walk().then(() => {})) + promises.push(w.walk()) } } + if (!entries.length) return res() Promise.all(promises).then(() => res()) } }, true) @@ -209,15 +353,17 @@ export class GlobWalker { const entries = this.path.readdirSync() if (!pattern.hasMore()) { for (const e of entries) { - if (p.test(e.name)) this.matches.add(e) + if (p.test(e.name)) this.matchSync(e) } } else { for (const e of entries) { if (p.test(e.name)) { - const w = new GlobWalker( + const w = new GlobWalker( pattern.rest() as Pattern, e, - this.matches + this.matches, + this.seen, + this.opts ) w.walkSync() } From ca1651c933723dc4939c694b25472cb8b3e1a28a Mon Sep 17 00:00:00 2001 From: isaacs Date: Sat, 11 Feb 2023 21:29:53 -0800 Subject: [PATCH 067/163] getting closer, saving to try another approach entirely --- benchmark.sh | 9 +- make-benchmark-fixture.sh | 13 ++ package-lock.json | 28 +-- package.json | 4 +- src/glob.ts | 14 +- src/walker.ts | 470 ++++++++++++++++++++++++-------------- 6 files changed, 340 insertions(+), 198 deletions(-) diff --git a/benchmark.sh b/benchmark.sh index d40f9680..7f650f45 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -3,13 +3,18 @@ export CDPATH= set -e patterns=( + '**/????/????/????/????/*.txt' + './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' + '**/*/**/*/**/*/**/*/**' + '5555/0000/**/*.txt' + '**/5555/0000/*.txt' + '*/*/9/**/**/**/**/*/**/**/*.txt' './**/?/**/?/**/?/**/?/**/*.txt' './**/0/**/../[01]/**/0/../**/0/*.txt' './**/*/**/*/**/*/**/*/**/*.txt' './**/0/**/0/**/0/**/0/**/*.txt' - './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' './**/0/**/0/**/*.txt' - '**/*.txt' + '**/*.txt', # './**/*.txt' './**/**/**/**/**/**/**/**/*.txt' '**/*/*.txt' diff --git a/make-benchmark-fixture.sh b/make-benchmark-fixture.sh index b3916dca..d7bb6903 100644 --- a/make-benchmark-fixture.sh +++ b/make-benchmark-fixture.sh @@ -13,4 +13,17 @@ if ! [ -d "$tmp/0" ]; then filenames=`echo {0..9}/{0..9}/{0..9}/{0..9}/{0..9}.txt` echo $dirnames | xargs mkdir -p echo $filenames | xargs touch + # add 10k more that are not single chars + for i in {0..9}; do + for j in {0..9}; do + for k in {0..9}; do + for l in {0..9}; do + mkdir -p "$i$i$i$i/$j$j$j$j/$k$k$k$k/$l$l$l$l" + for m in {0..9}; do + touch "$i$i$i$i/$j$j$j$j/$k$k$k$k/$l$l$l$l/$m$m$m$m.txt" + done + done + done + done + done fi diff --git a/package-lock.json b/package-lock.json index a6911770..3591ad1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,8 @@ "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", - "minimatch": "^6.1.4", - "path-scurry": "1.2" + "minimatch": "^6.1.8", + "path-scurry": "^1.3.0" }, "devDependencies": { "@types/mkdirp": "^1.0.2", @@ -2919,9 +2919,9 @@ } }, "node_modules/minimatch": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.4.tgz", - "integrity": "sha512-NsDTCCf9qKxjUUxSfhnF2AbYR9xSpWvJx/HL/4E+KbqhKqdHMXjn81So56Hga/lpyhXL98aLPZLdPmUUEyIrWA==", + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.8.tgz", + "integrity": "sha512-sTvS8Q4mIZiSnMo9192lZMxfeaGCslH5CC7B62hd9DlbifUVrc02ABTeRJINPosxKnvZlrmAaNSo8f4PZqDDdw==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -3225,9 +3225,9 @@ } }, "node_modules/path-scurry": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.2.0.tgz", - "integrity": "sha512-+4ziUPFIhQA8uuTcq2cKF59ySJ85v4t57+DEEY2QayNf9UfHKAuLkr2OSOySfPIAZOtag1w5Htw7glKT71KAPA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.3.0.tgz", + "integrity": "sha512-S1tMxbHwgGIPyf9e3caxqQKyxooMYMLPBI7hAvGHHaseqKwXgJISYBe9zpj3aUsAOGobb6tR24c3ebhmidb++w==", "dependencies": { "lru-cache": "^7.14.1", "minipass": "^4.0.2" @@ -8567,9 +8567,9 @@ } }, "minimatch": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.4.tgz", - "integrity": "sha512-NsDTCCf9qKxjUUxSfhnF2AbYR9xSpWvJx/HL/4E+KbqhKqdHMXjn81So56Hga/lpyhXL98aLPZLdPmUUEyIrWA==", + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.8.tgz", + "integrity": "sha512-sTvS8Q4mIZiSnMo9192lZMxfeaGCslH5CC7B62hd9DlbifUVrc02ABTeRJINPosxKnvZlrmAaNSo8f4PZqDDdw==", "requires": { "brace-expansion": "^2.0.1" } @@ -8800,9 +8800,9 @@ "dev": true }, "path-scurry": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.2.0.tgz", - "integrity": "sha512-+4ziUPFIhQA8uuTcq2cKF59ySJ85v4t57+DEEY2QayNf9UfHKAuLkr2OSOySfPIAZOtag1w5Htw7glKT71KAPA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.3.0.tgz", + "integrity": "sha512-S1tMxbHwgGIPyf9e3caxqQKyxooMYMLPBI7hAvGHHaseqKwXgJISYBe9zpj3aUsAOGobb6tR24c3ebhmidb++w==", "requires": { "lru-cache": "^7.14.1", "minipass": "^4.0.2" diff --git a/package.json b/package.json index 4366605f..869699e3 100644 --- a/package.json +++ b/package.json @@ -59,8 +59,8 @@ }, "dependencies": { "fs.realpath": "^1.0.0", - "minimatch": "^6.1.4", - "path-scurry": "1.2" + "minimatch": "^6.1.8", + "path-scurry": "^1.3.0" }, "devDependencies": { "@types/mkdirp": "^1.0.2", diff --git a/src/glob.ts b/src/glob.ts index d585f619..29a5b519 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -171,6 +171,8 @@ export class Glob { // Walkers always return array of Path objects, so we just have to // coerce them into the right shape. It will have already called // realpath() if the option was set to do so, so we know that's cached. + // start out knowing the cwd, at least + await this.scurry.lstat() const matches: Matches[] = await Promise.all( this.matchSet.map(async (set, i) => { const p = new Pattern(set, this.globParts[i], 0) @@ -182,6 +184,8 @@ export class Glob { } processSync() { + // start out knowing the cwd, at least + this.scurry.lstatSync() const matches: Matches[] = this.matchSet.map((set, i) => { const p = new Pattern(set, this.globParts[i], 0) return this.getWalker(p).walkSync() @@ -191,15 +195,17 @@ export class Glob { finish(matches: Matches[]): Results finish(matches: Set[]): (string | Path)[] { - const raw: (string | Path)[] = [] if (this.nounique) { + const raw: (string | Path)[] = [] for (const set of matches) { - raw.push(...set) + for (const e of set) { + raw.push(e) + } } + return raw } else { - raw.push(...matches[0]) + return [...matches[0]] } - return raw } sort(flat: string[]) { diff --git a/src/walker.ts b/src/walker.ts index e0877914..7327f86f 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -1,3 +1,24 @@ +// TODO: ok, new algorithm for this is needed, clearly +// forking out GlobWalkers for the set of children is just no good. +// When not the last piece of the pattern: +// if the pattern is a ** or regexp, we need to build a set of children +// paths that need to be walked once the piece is consumed. +// +// For **, this is a Scurry walk of all directories under the path +// For regexp, this is the children that match the regexp +// +// Then we iterate over that set, creating a new set of each child path +// that matches the next part of the pattern, and so on. +// +// At the end, we have the set of all the child paths that matched up to +// the last part of the pattern. +// +// If the last part is: +// '', ensure they're all directories, and return +// string, then .child it and maybe lstat +// **, scurry walk for all entries, only walking directories +// regexp, readdir and filter + import { Path } from 'path-scurry' // a single minimatch set entry with 1 or more parts @@ -112,7 +133,42 @@ export class GlobWalker { return e } + matchPrecheckSync(e: Path): Path | undefined { + let rpc: Path | undefined + if (this.opts.realpath) { + rpc = e.realpathCached() + if (rpc) { + if (this.seen.has(rpc) || (e.isDirectory() && this.opts.nodir)) { + return undefined + } + e = rpc + } + } + if (e.isDirectory() && this.opts.nodir) { + return undefined + } + const needRealPath = this.opts.realpath && !rpc + const needStat = (this.opts.nodir || this.opts.mark) && e.isUnknown() + if (needRealPath && needStat) { + const r = e.realpathSync()?.lstatSync() + if (!r || this.seen.has(r) || (e.isDirectory() && this.opts.nodir)) { + return undefined + } + return r + } else if (needRealPath) { + const r = e.realpathSync() + if (!r || this.seen.has(r) || (e.isDirectory() && this.opts.nodir)) { + return undefined + } + return r + } else if (needStat) { + return e.lstatSync() + } + return e + } + matchFinal(e: Path) { + this.seen.add(e) const mark = this.opts.mark && e.isDirectory() ? '/' : '' // ok, we have what we need! if (this.opts.withFileTypes) { @@ -131,104 +187,184 @@ export class GlobWalker { if (p) this.matchFinal(p) } - matchSync(e: Path) { - if (this.opts.realpath) { - const r = e.realpathSync() - if (!r) return - e = r + matchSync(e: Path): void { + const p = this.matchPrecheckSync(e) + if (p) this.matchFinal(p) + } + + // used to gather children to walk when ** appears mid-pattern + // pattern here is everything AFTER the ** + async walkGlobStarDirs( + path: Path, + pattern: Pattern + ): Promise> { + // return new Promise>(res => { + // this.walkGlobStarDirsEntriesCB([path], pattern, () => + // res(this.matches) + // ) + // }) + if ( + !(path.isDirectory() || path.isUnknown()) || + path.name.startsWith('.') + ) { + return this.matches } - if (e.isUnknown() && (this.opts.nodir || this.opts.mark)) { - const ls = e.lstatSync() - if (!ls) return + await this.match(path) + const entriesCached = path.readdirCached() + const entries = path.calledReaddir() + ? entriesCached + : await path.readdir() + if (!entries.length) return this.matches + const promises: Promise[] = [] + // collect all matches from this dir the rest of the pattern + await this.walk(path, pattern) + for (const e of entries) { + if (!(e.isDirectory() || e.isUnknown()) || e.name.startsWith('.')) { + continue + } + promises.push(this.walkGlobStarDirs(e, pattern)) } - if (this.opts.nodir && e.isDirectory()) { - return + if (promises.length) await Promise.all(promises) + return this.matches + } + + walkGlobStarDirsSync(path: Path, pattern: Pattern): Matches { + if ( + !(path.isDirectory() || path.isUnknown()) || + path.name.startsWith('.') + ) { + return this.matches } - const mark = this.opts.mark && e.isDirectory() ? '/' : '' - // ok, we have what we need! - if (this.opts.withFileTypes) { - this.matches.add(e) - } else if (this.opts.absolute) { - this.matches.add(e.fullpath() + mark) - } else { - this.matches.add(e.relative() + mark) + this.matchSync(path) + const entries = path.readdirSync() + if (!entries.length) return this.matches + this.walkSync(path, pattern) + for (const e of entries) { + if (!(e.isDirectory() || e.isUnknown()) || e.name.startsWith('.')) + continue + this.walkGlobStarDirsSync(e, pattern) } + return this.matches } - async walk(): Promise> { - // consume all pattern portions except the last one. - // if the last one is a string, then we stat and add it. - while (this.pattern.hasMore()) { - const p = this.pattern.pattern() + // used when the last item in the pattern is ** + async walkGlobStarAll(path: Path): Promise> { + if (path.name.startsWith('.')) { + return this.matches + } + await this.match(path) + if (!path.isDirectory()) return this.matches + const entriesCached = path.readdirCached() + const entries = path.calledReaddir() + ? entriesCached + : await path.readdir() + if (!entries.length) return this.matches + const promises: Promise[] = [] + for (const e of entries) { + if (e.name.startsWith('.')) continue + promises.push(this.match(e)) + if (e.isDirectory()) promises.push(this.walkGlobStarAll(e)) + } + if (promises.length) await Promise.all(promises) + return this.matches + } + + walkGlobStarAllSync(path: Path): Matches { + if (path.name.startsWith('.')) { + return this.matches + } + this.matchSync(path) + if (!path.isDirectory()) return this.matches + const entries = path.readdirSync() + if (!entries.length) return this.matches + for (const e of entries) { + if (e.name.startsWith('.')) continue + this.matchSync(e) + if (e.isDirectory()) this.walkGlobStarAllSync(e) + } + return this.matches + } + + async walk( + target: Path = this.path, + pattern: Pattern = this.pattern + ): Promise> { + // each step, we get the set of all items that match + // the current piece of the pattern, and recurse if there's + // pattern left. + // have more pattern: + // **: do a globStarDirs walk, attach rest to all found, return + // string: path.child(), walk rest of the pattern + // regexp: filter children, walk rest on all of them + // last pattern: + // **: if path is a dir, add to matches, along with all descendants + // string: if path exists, add to matches + // regexp: filter children, all are matches + + const p = pattern.pattern() + const rest = pattern.rest() + if (rest) { + if (!target.canReaddir()) return this.matches if (typeof p === 'string') { - this.pattern.shift() - this.path = this.path.child(p) + return this.walk(target.child(p), rest) } else if (p instanceof RegExp) { - // this fans out, but we must match the pattern against - // something, so nothing else to do here. - await this.walkRegExp(p, this.pattern) - return this.matches + return this.walkRegExp(target, pattern) } else { - // globstar! - // this fans out, but also continues without the ** - await this.walkGlobStar(this.pattern) - this.pattern.shift() + // globstar + return this.walkGlobStar(target, pattern) } - } - const p = this.pattern.pattern() - if (typeof p === 'string') { - this.path = this.path.child(p) - await this.maybeMatchPath() - } else if (p instanceof RegExp) { - await this.walkRegExp(p, this.pattern) } else { - // globstar at the end is either nothing, or all children - // make sure our path actually exists, if it was something - // like a/b/** we might've got here without checking - await Promise.all([ - this.maybeMatchPath(), - this.walkGlobStar(this.pattern), - ]) + if (p === '') { + //matches only if path is a dir + if (target.isUnknown()) await target.lstat() + if (target.isDirectory()) await this.match(target) + return this.matches + } else if (typeof p === 'string') { + // last item! will stat etc if needed. + const e = target.isUnknown() ? await target.lstat() : target + if (e) await this.match(e) + return this.matches + } else if (p instanceof RegExp) { + return this.walkRegExp(target, pattern) + } else { + return this.walkGlobStar(target, pattern) + } } - return this.matches } - walkSync(): Matches { - // consume all pattern portions except the last one. - // if the last one is a string, then we stat and add it. - while (this.pattern.hasMore()) { - const p = this.pattern.pattern() + walkSync( + target: Path = this.path, + pattern: Pattern = this.pattern + ): Matches { + const p = pattern.pattern() + const rest = pattern.rest() + if (rest) { + if (!target.canReaddir()) return this.matches if (typeof p === 'string') { - this.path = this.path.child(p) - this.pattern.shift() + return this.walkSync(target.child(p), rest) } else if (p instanceof RegExp) { - // this fans out, but we must match the pattern against - // something, so nothing else to do here. - this.walkRegExpSync(p, this.pattern) - this.pattern.shift() - return this.matches + return this.walkRegExpSync(target, pattern) } else { - // globstar! - // this fans out, but also continues without the ** - this.walkGlobStarSync(this.pattern) - this.pattern.shift() + // globstar + return this.walkGlobStarSync(target, pattern) } - } - const p = this.pattern.pattern() - if (typeof p === 'string') { - this.path = this.path.child(p) - this.maybeMatchPathSync() - } else if (p instanceof RegExp) { - this.walkRegExpSync(p, this.pattern) - return this.matches } else { - // globstar at the end is either nothing, or all children - // make sure our path actually exists, if it was something - // like a/b/** we might've got here without checking - this.maybeMatchPathSync() - this.walkGlobStarSync(this.pattern) + if (p === '') { + //matches only if path is a dir + if (target.isUnknown()) target.lstatSync() + if (target.isDirectory()) this.matchSync(target) + return this.matches + } else if (typeof p === 'string') { + // last item! will stat etc if needed. + const e = target.isUnknown() ? target.lstatSync() : target + if (e) this.matchSync(e) + return this.matches + } else if (p instanceof RegExp) { + return this.walkRegExpSync(target, pattern) + } else { + return this.walkGlobStarSync(target, pattern) + } } - return this.matches } async maybeMatchPath(): Promise { @@ -257,117 +393,99 @@ export class GlobWalker { } } - async walkGlobStar(pattern: Pattern): Promise { + // note: we do not need to add the current path as a match here, + // ONLY process children. The current path will be added in the walk + // method itself. + async walkGlobStar(path: Path, pattern: Pattern): Promise> { // get all children, and walk from there - if (!this.path.canReaddir()) { - return + if (!path.canReaddir()) { + return this.matches } - return new Promise(res => { - this.path.readdirCB((_er, entries) => { - const promises: Promise[] = [] - for (const e of entries) { - if (e.name.startsWith('.')) continue - else if (!e.isDirectory()) { - promises.push(this.match(e)) - } else { - const w = new GlobWalker( - pattern.copy(), - e, - this.matches, - this.seen, - this.opts - ) - promises.push(w.walk()) - } - } - if (promises.length) return Promise.all(promises).then(() => res()) - else return res() - }, true) - }) + const rest = pattern.rest() + return rest + ? this.walkGlobStarDirs(path, rest) + : this.walkGlobStarAll(path) } - walkGlobStarSync(pattern: Pattern): void { + walkGlobStarSync(path: Path, pattern: Pattern): Matches { // get all children, and walk from there - if (!this.path.canReaddir()) { - return - } - const entries = this.path.readdirSync() - for (const e of entries) { - if (e.name.startsWith('.')) continue - if (e.isSymbolicLink()) { - // we can MATCH a symlink, just not traverse it - this.matchSync(e) - continue - } - const w = new GlobWalker( - pattern.copy(), - e, - this.matches, - this.seen, - this.opts - ) - w.walkSync() + if (!path.canReaddir()) { + return this.matches } + const rest = pattern.rest() + return rest + ? this.walkGlobStarDirsSync(path, rest) + : this.walkGlobStarAllSync(path) } - async walkRegExp(p: RegExp, pattern: Pattern): Promise { - if (!this.path.canReaddir()) { - return + // kind of like walkGlobStar, but without the recursion, just one level + // and attach the rest of the pattern to it, or call it a match + async walkRegExp(path: Path, pattern: Pattern): Promise> { + if (!path.canReaddir()) { + return this.matches } - return new Promise(res => { - this.path.readdirCB((_, entries) => { - if (!pattern.hasMore()) { - const promises: Promise[] = [] - for (const e of entries) { - if (p.test(e.name)) { - promises.push(this.match(e)) - } - } - if (!entries.length) return res() - Promise.all(promises).then(() => res()) - } else { - const promises: Promise[] = [] - for (const e of entries) { - if (p.test(e.name)) { - const w = new GlobWalker( - pattern.rest() as Pattern, - e, - this.matches, - this.seen, - this.opts - ) - promises.push(w.walk()) - } - } - if (!entries.length) return res() - Promise.all(promises).then(() => res()) - } - }, true) - }) + const p = pattern.pattern() as RegExp + const rest = pattern.rest() + const promises: Promise[] = [] + const entries = path.calledReaddir() + ? path.readdirCached() + : await path.readdir() + for (const e of entries) { + if (!p.test(e.name)) continue + if (rest) { + if (!e.canReaddir()) continue + promises.push(this.walk(e, rest)) + } else { + promises.push(this.match(e)) + } + } + if (promises.length) await Promise.all(promises) + return this.matches + // if (!path.canReaddir()) { + // return this.matches + // } + // const p = pattern.pattern() as RegExp + // const rest = pattern.rest() + // return new Promise>(res => { + // const cb = () => res(this.matches) + // path.readdirCB((_, entries) => { + // if (!entries.length) return cb() + // let len = 1 + // for (const e of entries) { + // if (!p.test(e.name)) continue + // if (rest) { + // if (!e.canReaddir()) continue + // len++ + // this.walk(e, rest).then(() => { + // if (--len === 0) cb() + // }) + // } else { + // len++ + // this.match(e).then(() => { + // if (--len === 0) cb() + // }) + // } + // } + // if (--len === 0) cb() + // }, true) + // }) } - walkRegExpSync(p: RegExp, pattern: Pattern): void { - if (!this.path.canReaddir()) { - return + walkRegExpSync(path: Path, pattern: Pattern): Matches { + if (!path.canReaddir()) { + return this.matches } - const entries = this.path.readdirSync() - if (!pattern.hasMore()) { - for (const e of entries) { - if (p.test(e.name)) this.matchSync(e) - } - } else { - for (const e of entries) { - if (p.test(e.name)) { - const w = new GlobWalker( - pattern.rest() as Pattern, - e, - this.matches, - this.seen, - this.opts - ) - w.walkSync() - } + const p = pattern.pattern() as RegExp + const rest = pattern.rest() + for (const e of path.readdirSync()) { + if (!p.test(e.name)) continue + if (rest) { + if (!e.canReaddir()) continue + this.walkSync(e, rest) + } else { + this.matchSync(e) } } + return this.matches } } From 586be799ac7aa2586b0b4433f54fa4b08117c575 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sun, 12 Feb 2023 11:58:02 -0800 Subject: [PATCH 068/163] new walking methodology, much faster for most patterns This is still showing some pathological performance in the case where several '..' and '**' pattern portions are used together, for example with './*/**/../*/**/../*/**/../*/**/../*/**/*.txt' In all other benchmark cases, it's now out-performing fast-glob/globby, so I think this is the approach that'll stick! Just need to figure out how to handle those parent walks a bit more cleverly. --- benchmark.sh | 9 +- src/pattern.ts | 50 ++---- src/walker.ts | 467 ++++++++++++++++++++++--------------------------- 3 files changed, 228 insertions(+), 298 deletions(-) diff --git a/benchmark.sh b/benchmark.sh index 7f650f45..4ccc63c4 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -3,14 +3,15 @@ export CDPATH= set -e patterns=( + './**/?/**/?/**/?/**/?/**/*.txt' + './*/**/../*/**/../*/**/../*/**/../*/**/*.txt' + './**/0/**/../[01]/**/0/../**/0/*.txt' '**/????/????/????/????/*.txt' './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' '**/*/**/*/**/*/**/*/**' - '5555/0000/**/*.txt' + # '5555/0000/**/*.txt' '**/5555/0000/*.txt' - '*/*/9/**/**/**/**/*/**/**/*.txt' - './**/?/**/?/**/?/**/?/**/*.txt' - './**/0/**/../[01]/**/0/../**/0/*.txt' + # '*/*/9/**/**/**/**/*/**/**/*.txt' './**/*/**/*/**/*/**/*/**/*.txt' './**/0/**/0/**/0/**/0/**/*.txt' './**/0/**/0/**/*.txt' diff --git a/src/pattern.ts b/src/pattern.ts index 025dbc69..a8884033 100644 --- a/src/pattern.ts +++ b/src/pattern.ts @@ -27,10 +27,12 @@ const isPatternList = (pl: MMPattern[]): pl is PatternList => const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1 export class Pattern { - patternList: PatternList - globList: GlobList + readonly patternList: PatternList + readonly globList: GlobList index: number - length: number + readonly length: number + #rest?: Pattern | null + #globString?: string constructor( patternList: MMPattern[], @@ -76,7 +78,7 @@ export class Pattern { this.index < this.length - 1 && this.pattern() === '' ) { - this.shift() + this.index++ } } } @@ -94,23 +96,18 @@ export class Pattern { isMagic(): boolean { return this.patternList[this.index] instanceof RegExp } - shift() { - if (this.index === this.length - 1) { - throw new Error('cannot shift final pattern') - } - const p = this.pattern() - this.index++ - return p - } glob(): string { return this.globList[this.index] } globString(): string { - return ( - this.index === 0 ? this.globList : this.globList.slice(this.index) - ).join('/') + return (this.#globString = + this.#globString || + (this.index === 0 + ? this.globList + : this.globList.slice(this.index) + ).join('/')) } hasMore(): boolean { @@ -120,26 +117,13 @@ export class Pattern { copy(): Pattern { return new Pattern(this.patternList, this.globList, this.index) } - insert(p: MMPattern, g: string): Pattern { - return new Pattern( - [ - ...this.patternList.slice(0, this.index), - p, - ...this.patternList.slice(this.index), - ], - [ - ...this.globList.slice(0, this.index), - g, - ...this.globList.slice(this.index), - ], - this.index - ) - } rest(): Pattern | null { - return this.hasMore() - ? new Pattern(this.patternList, this.globList, this.index + 1) - : null + return this.#rest !== undefined + ? this.#rest + : (this.#rest = this.hasMore() + ? new Pattern(this.patternList, this.globList, this.index + 1) + : null) } // pattern like: //host/share/... diff --git a/src/walker.ts b/src/walker.ts index 7327f86f..aa889c9f 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -18,7 +18,32 @@ // string, then .child it and maybe lstat // **, scurry walk for all entries, only walking directories // regexp, readdir and filter +// +// +// NEW APPROACH +// Instead of recursively forking for each new chunk of the pattern, which gets +// a bit ridiculous when there's multiple globstars, let's try another +// approach. +// We just do a normal naive scurry, but where the set of possibly-matching +// patterns serve as a filter, which we update as we descend, passing them +// along. +// +// This ends up being equivalent if no globstars are present. We just +// walk the dirs, consuming pattern parts as they match. +// +// However, when we have a **, the descent gets *both* the "consumed" +// pattern, *and* the full pattern with the **. +// +// Then for each child entry, for each active pattern, if it matches, then +// it consumes the next bit of the pattern, and continues with all the patterns +// that it matched on. But if it's a globstar, then "consuming" means that we +// take the full globstar pattern set, as well as the pattern set without the +// globstar (ie, as if * was matched). +// +// This should result in only ever walking the tree a single time, as well as +// filtering out walk paths that can't possibly match anything. +import { GLOBSTAR } from 'minimatch' import { Path } from 'path-scurry' // a single minimatch set entry with 1 or more parts @@ -99,7 +124,7 @@ export class GlobWalker { // do the requisite realpath/stat checking, and return true/false // to say whether to include the match or filter it out. - async matchPrecheck(e: Path): Promise { + async matchCheck(e: Path): Promise { let rpc: Path | undefined if (this.opts.realpath) { rpc = e.realpathCached() @@ -128,12 +153,18 @@ export class GlobWalker { } return r } else if (needStat) { - return await e.lstat() + const r = await e.lstat() + if (!r || this.seen.has(r) || (r.isDirectory() && this.opts.nodir)) { + return undefined + } + } else if (this.seen.has(e) || (e.isDirectory() && this.opts.nodir)) { + return undefined + } else { + return e } - return e } - matchPrecheckSync(e: Path): Path | undefined { + matchCheckSync(e: Path): Path | undefined { let rpc: Path | undefined if (this.opts.realpath) { rpc = e.realpathCached() @@ -162,12 +193,18 @@ export class GlobWalker { } return r } else if (needStat) { - return e.lstatSync() + const r = e.lstatSync() + if (!r || this.seen.has(r) || (r.isDirectory() && this.opts.nodir)) { + return undefined + } + } else if (this.seen.has(e) || (e.isDirectory() && this.opts.nodir)) { + return undefined + } else { + return e } - return e } - matchFinal(e: Path) { + matchFinish(e: Path) { this.seen.add(e) const mark = this.opts.mark && e.isDirectory() ? '/' : '' // ok, we have what we need! @@ -183,188 +220,191 @@ export class GlobWalker { } async match(e: Path): Promise { - const p = await this.matchPrecheck(e) - if (p) this.matchFinal(p) + const p = await this.matchCheck(e) + if (p) this.matchFinish(p) } matchSync(e: Path): void { - const p = this.matchPrecheckSync(e) - if (p) this.matchFinal(p) + const p = this.matchCheckSync(e) + if (p) this.matchFinish(p) } - // used to gather children to walk when ** appears mid-pattern - // pattern here is everything AFTER the ** - async walkGlobStarDirs( - path: Path, - pattern: Pattern + async walk( + target: Path = this.path, + patterns: Pattern[] = [this.pattern] ): Promise> { - // return new Promise>(res => { - // this.walkGlobStarDirsEntriesCB([path], pattern, () => - // res(this.matches) - // ) - // }) - if ( - !(path.isDirectory() || path.isUnknown()) || - path.name.startsWith('.') - ) { - return this.matches - } - await this.match(path) - const entriesCached = path.readdirCached() - const entries = path.calledReaddir() - ? entriesCached - : await path.readdir() - if (!entries.length) return this.matches - const promises: Promise[] = [] - // collect all matches from this dir the rest of the pattern - await this.walk(path, pattern) - for (const e of entries) { - if (!(e.isDirectory() || e.isUnknown()) || e.name.startsWith('.')) { - continue + if (target.isUnknown()) await target.lstat() + return new Promise(res => { + this.walkCB(target, patterns, () => res(this.matches)) + }) + } + + // XXX + // ok just write this down then, this is getting hairy + // + // Get the list of patterns that the current target matches, + // and also, any that the parent matches (if the pattern is ..) + // + // If any of those matches (for self or parent) are a single + // part, then emit the match for them. + // + // If any matches for target have more, then walkCB with those on target + // If any matches for parent have more, then walkCB with those on parent + // but in both cases, only if the Path is walkable. + // When we walkCB, it's with pattern.rest() in the case of everything + // except globstar, which dupes both pattern and rest in the child set. + // + // So, for both target and parent: + // 1 all that match and have more and start with ** + // 2 all that match and have more and do not start with ** + // 3 all that match and do not have more and are ** + // 4 all that match and do not have more and are not ** + // if dir: + // - walk with all (1) duped+subbed, all (2) subbed, all (3) duped + // - match if any (3) or (4) + // if walkable: + // - walk with all (1) subbed, all (2) subbed + // - match if any (3) or (4) + // else: + // - match if any (3) or (4) + + walkCB(target: Path, patterns: Pattern[], cb: () => any) { + // console.error('WCB2', target.relative(), patterns.map(p => p.globString())) + target.readdirCB((_, entries) => { + let tasks = 1 + const next = () => { + if (--tasks <= 0) cb() } - promises.push(this.walkGlobStarDirs(e, pattern)) - } - if (promises.length) await Promise.all(promises) - return this.matches + for (const e of entries) { + tasks++ + this.walkCB2(e, patterns, next) + } + next() + })//, true) } - walkGlobStarDirsSync(path: Path, pattern: Pattern): Matches { - if ( - !(path.isDirectory() || path.isUnknown()) || - path.name.startsWith('.') - ) { - return this.matches + walkCB2(target: Path, patterns: Pattern[], cb: () => any) { + // console.error('WCB', target.fullpath(), patterns.map(p => p.globString())) + const parent = target.parent || target + const isGSWalkable = target.isDirectory() + const isWalkable = isGSWalkable || target.canReaddir() + // console.error({ isGSWalkable, isWalkable }) + const matchGS = !target.name.startsWith('.') + const parentWalkPatterns: Pattern[] = [] + const targetWalkPatterns: Pattern[] = [] + let isParentMatch = false + let isTargetMatch = false + for (const pattern of patterns) { + const p = pattern.pattern() + const rest = pattern.rest() + if (p === GLOBSTAR) { + if (!matchGS) continue + if (!rest) { + if (isGSWalkable) targetWalkPatterns.push(pattern) + isTargetMatch = true + } else { + if (isGSWalkable) targetWalkPatterns.push(pattern, rest) + } + } else if (p === '..') { + if (!rest) isParentMatch = true + else parentWalkPatterns.push(rest) + } else if (p === '' || p === '.') { + if (!rest) isTargetMatch = true + else if (isWalkable) targetWalkPatterns.push(rest) + } else if (typeof p === 'string' && p === target.name) { + if (!rest) isTargetMatch = true + else if (isWalkable) targetWalkPatterns.push(rest) + } else if (p instanceof RegExp && p.test(target.name)) { + if (!rest) isTargetMatch = true + else if (isWalkable) targetWalkPatterns.push(rest) + } } - this.matchSync(path) - const entries = path.readdirSync() - if (!entries.length) return this.matches - this.walkSync(path, pattern) - for (const e of entries) { - if (!(e.isDirectory() || e.isUnknown()) || e.name.startsWith('.')) - continue - this.walkGlobStarDirsSync(e, pattern) + let tasks = 1 + const doneTask = () => { + if (--tasks === 0) cb() } - return this.matches - } - - // used when the last item in the pattern is ** - async walkGlobStarAll(path: Path): Promise> { - if (path.name.startsWith('.')) { - return this.matches + if (isParentMatch && !this.seen.has(parent)) { + tasks++ + this.match(parent).then(doneTask) } - await this.match(path) - if (!path.isDirectory()) return this.matches - const entriesCached = path.readdirCached() - const entries = path.calledReaddir() - ? entriesCached - : await path.readdir() - if (!entries.length) return this.matches - const promises: Promise[] = [] - for (const e of entries) { - if (e.name.startsWith('.')) continue - promises.push(this.match(e)) - if (e.isDirectory()) promises.push(this.walkGlobStarAll(e)) + if (isTargetMatch && !this.seen.has(target)) { + tasks++ + this.match(target).then(doneTask) } - if (promises.length) await Promise.all(promises) - return this.matches - } - - walkGlobStarAllSync(path: Path): Matches { - if (path.name.startsWith('.')) { - return this.matches + if (parentWalkPatterns.length) { + tasks++ + this.walkCB(parent, parentWalkPatterns, doneTask) } - this.matchSync(path) - if (!path.isDirectory()) return this.matches - const entries = path.readdirSync() - if (!entries.length) return this.matches - for (const e of entries) { - if (e.name.startsWith('.')) continue - this.matchSync(e) - if (e.isDirectory()) this.walkGlobStarAllSync(e) + if (targetWalkPatterns.length) { + tasks++ + this.walkCB(target, targetWalkPatterns, doneTask) } - return this.matches + doneTask() } - async walk( + walkSync( target: Path = this.path, - pattern: Pattern = this.pattern - ): Promise> { - // each step, we get the set of all items that match - // the current piece of the pattern, and recurse if there's - // pattern left. - // have more pattern: - // **: do a globStarDirs walk, attach rest to all found, return - // string: path.child(), walk rest of the pattern - // regexp: filter children, walk rest on all of them - // last pattern: - // **: if path is a dir, add to matches, along with all descendants - // string: if path exists, add to matches - // regexp: filter children, all are matches + patterns: Pattern[] = [this.pattern] + ): Matches { + if (target.isUnknown()) target.lstatSync() + this.walkCBSync(target, patterns) + return this.matches + } - const p = pattern.pattern() - const rest = pattern.rest() - if (rest) { - if (!target.canReaddir()) return this.matches - if (typeof p === 'string') { - return this.walk(target.child(p), rest) - } else if (p instanceof RegExp) { - return this.walkRegExp(target, pattern) - } else { - // globstar - return this.walkGlobStar(target, pattern) - } - } else { - if (p === '') { - //matches only if path is a dir - if (target.isUnknown()) await target.lstat() - if (target.isDirectory()) await this.match(target) - return this.matches - } else if (typeof p === 'string') { - // last item! will stat etc if needed. - const e = target.isUnknown() ? await target.lstat() : target - if (e) await this.match(e) - return this.matches - } else if (p instanceof RegExp) { - return this.walkRegExp(target, pattern) - } else { - return this.walkGlobStar(target, pattern) - } + walkCBSync(target: Path, patterns: Pattern[]) { + const entries = target.readdirSync() + for (const e of entries) { + this.walkCB2Sync(e, patterns) } } - walkSync( - target: Path = this.path, - pattern: Pattern = this.pattern - ): Matches { - const p = pattern.pattern() - const rest = pattern.rest() - if (rest) { - if (!target.canReaddir()) return this.matches - if (typeof p === 'string') { - return this.walkSync(target.child(p), rest) - } else if (p instanceof RegExp) { - return this.walkRegExpSync(target, pattern) - } else { - // globstar - return this.walkGlobStarSync(target, pattern) - } - } else { - if (p === '') { - //matches only if path is a dir - if (target.isUnknown()) target.lstatSync() - if (target.isDirectory()) this.matchSync(target) - return this.matches - } else if (typeof p === 'string') { - // last item! will stat etc if needed. - const e = target.isUnknown() ? target.lstatSync() : target - if (e) this.matchSync(e) - return this.matches - } else if (p instanceof RegExp) { - return this.walkRegExpSync(target, pattern) - } else { - return this.walkGlobStarSync(target, pattern) + walkCB2Sync(target: Path, patterns: Pattern[]) { + const parent = target.parent || target + const isGSWalkable = target.isDirectory() + const isWalkable = isGSWalkable || target.canReaddir() + // console.error({ isGSWalkable, isWalkable }) + const matchGS = !target.name.startsWith('.') + const parentWalkPatterns: Pattern[] = [] + const targetWalkPatterns: Pattern[] = [] + let isParentMatch = false + let isTargetMatch = false + for (const pattern of patterns) { + const p = pattern.pattern() + const rest = pattern.rest() + if (p === GLOBSTAR) { + if (!matchGS) continue + if (!rest) { + if (isGSWalkable) targetWalkPatterns.push(pattern) + isTargetMatch = true + } else { + if (isGSWalkable) targetWalkPatterns.push(pattern, rest) + } + } else if (p === '..') { + if (!rest) isParentMatch = true + else parentWalkPatterns.push(rest) + } else if (p === '' || p === '.') { + if (!rest) isTargetMatch = true + else if (isWalkable) targetWalkPatterns.push(rest) + } else if (typeof p === 'string' && p === target.name) { + if (!rest) isTargetMatch = true + else if (isWalkable) targetWalkPatterns.push(rest) + } else if (p instanceof RegExp && p.test(target.name)) { + if (!rest) isTargetMatch = true + else if (isWalkable) targetWalkPatterns.push(rest) } } + if (isParentMatch && !this.seen.has(parent)) { + this.matchSync(parent) + } + if (isTargetMatch && !this.seen.has(target)) { + this.matchSync(target) + } + if (parentWalkPatterns.length) { + this.walkCBSync(parent, parentWalkPatterns) + } + if (targetWalkPatterns.length) { + this.walkCBSync(target, targetWalkPatterns) + } } async maybeMatchPath(): Promise { @@ -379,6 +419,7 @@ export class GlobWalker { return this.match(this.path) } } + maybeMatchPathSync() { if (this.path.isUnknown()) { const lsc = this.path.lstatCached() @@ -392,100 +433,4 @@ export class GlobWalker { this.matchSync(this.path) } } - - // note: we do not need to add the current path as a match here, - // ONLY process children. The current path will be added in the walk - // method itself. - async walkGlobStar(path: Path, pattern: Pattern): Promise> { - // get all children, and walk from there - if (!path.canReaddir()) { - return this.matches - } - const rest = pattern.rest() - return rest - ? this.walkGlobStarDirs(path, rest) - : this.walkGlobStarAll(path) - } - - walkGlobStarSync(path: Path, pattern: Pattern): Matches { - // get all children, and walk from there - if (!path.canReaddir()) { - return this.matches - } - const rest = pattern.rest() - return rest - ? this.walkGlobStarDirsSync(path, rest) - : this.walkGlobStarAllSync(path) - } - - // kind of like walkGlobStar, but without the recursion, just one level - // and attach the rest of the pattern to it, or call it a match - async walkRegExp(path: Path, pattern: Pattern): Promise> { - if (!path.canReaddir()) { - return this.matches - } - const p = pattern.pattern() as RegExp - const rest = pattern.rest() - const promises: Promise[] = [] - const entries = path.calledReaddir() - ? path.readdirCached() - : await path.readdir() - for (const e of entries) { - if (!p.test(e.name)) continue - if (rest) { - if (!e.canReaddir()) continue - promises.push(this.walk(e, rest)) - } else { - promises.push(this.match(e)) - } - } - if (promises.length) await Promise.all(promises) - return this.matches - // if (!path.canReaddir()) { - // return this.matches - // } - // const p = pattern.pattern() as RegExp - // const rest = pattern.rest() - // return new Promise>(res => { - // const cb = () => res(this.matches) - // path.readdirCB((_, entries) => { - // if (!entries.length) return cb() - // let len = 1 - // for (const e of entries) { - // if (!p.test(e.name)) continue - // if (rest) { - // if (!e.canReaddir()) continue - // len++ - // this.walk(e, rest).then(() => { - // if (--len === 0) cb() - // }) - // } else { - // len++ - // this.match(e).then(() => { - // if (--len === 0) cb() - // }) - // } - // } - // if (--len === 0) cb() - // }, true) - // }) - } - - walkRegExpSync(path: Path, pattern: Pattern): Matches { - if (!path.canReaddir()) { - return this.matches - } - const p = pattern.pattern() as RegExp - const rest = pattern.rest() - for (const e of path.readdirSync()) { - if (!p.test(e.name)) continue - if (rest) { - if (!e.canReaddir()) continue - this.walkSync(e, rest) - } else { - this.matchSync(e) - } - } - return this.matches - } } From 1f9cab1652a26cf1ee001d1acee3733c848059d6 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sun, 12 Feb 2023 22:55:11 -0800 Subject: [PATCH 069/163] minimatch@6.1.9 --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3591ad1b..b1c10c4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", - "minimatch": "^6.1.8", + "minimatch": "^6.1.9", "path-scurry": "^1.3.0" }, "devDependencies": { @@ -2919,9 +2919,9 @@ } }, "node_modules/minimatch": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.8.tgz", - "integrity": "sha512-sTvS8Q4mIZiSnMo9192lZMxfeaGCslH5CC7B62hd9DlbifUVrc02ABTeRJINPosxKnvZlrmAaNSo8f4PZqDDdw==", + "version": "6.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.9.tgz", + "integrity": "sha512-6Vjiyqqav1xqJqQzMFOS/tHZi3vn0bGsKykLvK36uUj9FtZdq6XpIdHXBjoln/q+i3mTTGFeBGzhZ44wLtFQyw==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -8567,9 +8567,9 @@ } }, "minimatch": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.8.tgz", - "integrity": "sha512-sTvS8Q4mIZiSnMo9192lZMxfeaGCslH5CC7B62hd9DlbifUVrc02ABTeRJINPosxKnvZlrmAaNSo8f4PZqDDdw==", + "version": "6.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.1.9.tgz", + "integrity": "sha512-6Vjiyqqav1xqJqQzMFOS/tHZi3vn0bGsKykLvK36uUj9FtZdq6XpIdHXBjoln/q+i3mTTGFeBGzhZ44wLtFQyw==", "requires": { "brace-expansion": "^2.0.1" } diff --git a/package.json b/package.json index 869699e3..07104c4c 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ }, "dependencies": { "fs.realpath": "^1.0.0", - "minimatch": "^6.1.8", + "minimatch": "^6.1.9", "path-scurry": "^1.3.0" }, "devDependencies": { From d7d274b16e2991eb01f2bd8559c22d403fcd3fa0 Mon Sep 17 00:00:00 2001 From: isaacs Date: Sun, 12 Feb 2023 22:55:33 -0800 Subject: [PATCH 070/163] factor out the matching actions tests --- src/walker.ts | 91 +++++++++++++++++---------------------------------- 1 file changed, 30 insertions(+), 61 deletions(-) diff --git a/src/walker.ts b/src/walker.ts index aa889c9f..55e43c03 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -283,8 +283,9 @@ export class GlobWalker { })//, true) } - walkCB2(target: Path, patterns: Pattern[], cb: () => any) { - // console.error('WCB', target.fullpath(), patterns.map(p => p.globString())) + // returns 0-2 length array of [path, isMatch, sub patterns][] + getActions(target: Path, patterns: Pattern[]): [Path, boolean, Pattern[]][] { + const actions: [Path, boolean, Pattern[]][] = [] const parent = target.parent || target const isGSWalkable = target.isDirectory() const isWalkable = isGSWalkable || target.canReaddir() @@ -319,25 +320,30 @@ export class GlobWalker { else if (isWalkable) targetWalkPatterns.push(rest) } } + if (isParentMatch || parentWalkPatterns.length) { + actions.push([parent, isParentMatch, parentWalkPatterns]) + } + if (isTargetMatch || targetWalkPatterns.length) { + actions.push([target, isTargetMatch, targetWalkPatterns]) + } + return actions + } + + walkCB2(target: Path, patterns: Pattern[], cb: () => any) { + const actions = this.getActions(target, patterns) let tasks = 1 const doneTask = () => { if (--tasks === 0) cb() } - if (isParentMatch && !this.seen.has(parent)) { - tasks++ - this.match(parent).then(doneTask) - } - if (isTargetMatch && !this.seen.has(target)) { - tasks++ - this.match(target).then(doneTask) - } - if (parentWalkPatterns.length) { - tasks++ - this.walkCB(parent, parentWalkPatterns, doneTask) - } - if (targetWalkPatterns.length) { - tasks++ - this.walkCB(target, targetWalkPatterns, doneTask) + for (const [path, isMatch, patterns] of actions) { + if (isMatch && !this.seen.has(path)) { + tasks ++ + this.match(path).then(doneTask) + } + if (patterns.length) { + tasks ++ + this.walkCB(path, patterns, doneTask) + } } doneTask() } @@ -359,51 +365,14 @@ export class GlobWalker { } walkCB2Sync(target: Path, patterns: Pattern[]) { - const parent = target.parent || target - const isGSWalkable = target.isDirectory() - const isWalkable = isGSWalkable || target.canReaddir() - // console.error({ isGSWalkable, isWalkable }) - const matchGS = !target.name.startsWith('.') - const parentWalkPatterns: Pattern[] = [] - const targetWalkPatterns: Pattern[] = [] - let isParentMatch = false - let isTargetMatch = false - for (const pattern of patterns) { - const p = pattern.pattern() - const rest = pattern.rest() - if (p === GLOBSTAR) { - if (!matchGS) continue - if (!rest) { - if (isGSWalkable) targetWalkPatterns.push(pattern) - isTargetMatch = true - } else { - if (isGSWalkable) targetWalkPatterns.push(pattern, rest) - } - } else if (p === '..') { - if (!rest) isParentMatch = true - else parentWalkPatterns.push(rest) - } else if (p === '' || p === '.') { - if (!rest) isTargetMatch = true - else if (isWalkable) targetWalkPatterns.push(rest) - } else if (typeof p === 'string' && p === target.name) { - if (!rest) isTargetMatch = true - else if (isWalkable) targetWalkPatterns.push(rest) - } else if (p instanceof RegExp && p.test(target.name)) { - if (!rest) isTargetMatch = true - else if (isWalkable) targetWalkPatterns.push(rest) + const actions = this.getActions(target, patterns) + for (const [path, isMatch, patterns] of actions) { + if (isMatch && !this.seen.has(path)) { + this.matchSync(path) + } + if (patterns.length) { + this.walkCBSync(path, patterns) } - } - if (isParentMatch && !this.seen.has(parent)) { - this.matchSync(parent) - } - if (isTargetMatch && !this.seen.has(target)) { - this.matchSync(target) - } - if (parentWalkPatterns.length) { - this.walkCBSync(parent, parentWalkPatterns) - } - if (targetWalkPatterns.length) { - this.walkCBSync(target, targetWalkPatterns) } } From 8293f86108e5e649d770951a8da2d1b72ed7e756 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 13 Feb 2023 01:16:05 -0800 Subject: [PATCH 071/163] optimizations for string portions, avoid repeated walks --- benchmark.sh | 27 +++++++------- package-lock.json | 14 +++---- package.json | 2 +- src/glob.ts | 36 +++++++++++++++--- src/pattern.ts | 5 --- src/walker.ts | 93 +++++++++++++++++++++++++++++++++++++++++------ 6 files changed, 133 insertions(+), 44 deletions(-) diff --git a/benchmark.sh b/benchmark.sh index 4ccc63c4..768366f0 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -4,6 +4,7 @@ set -e patterns=( './**/?/**/?/**/?/**/?/**/*.txt' + './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt' './*/**/../*/**/../*/**/../*/**/../*/**/*.txt' './**/0/**/../[01]/**/0/../**/0/*.txt' '**/????/????/????/????/*.txt' @@ -115,19 +116,19 @@ MJS MJS t node "$wd/bench-working-dir/globby-async.mjs" "$p" - echo -n $'node current glob.sync cjs \t' - cat > "$wd/bench-working-dir/sync.cjs" < "$wd/bench-working-dir/async.cjs" < console.log(files.length)) -CJS - t node "$wd/bench-working-dir/async.cjs" "$p" +# echo -n $'node current glob.sync cjs \t' +# cat > "$wd/bench-working-dir/sync.cjs" < "$wd/bench-working-dir/async.cjs" < console.log(files.length)) +#CJS +# t node "$wd/bench-working-dir/async.cjs" "$p" echo -n $'node current glob.sync mjs \t' cat > "$wd/bench-working-dir/sync.mjs" < { noglobstar: boolean matches?: Matches seen?: Set + walked?: Map nocase?: boolean scurry: PathScurry opts: Opts + platform?: typeof process.platform constructor(pattern: string | string[], opts: Opts) { this.withFileTypes = !!opts.withFileTypes as FileTypes @@ -119,6 +128,7 @@ export class Glob { if (!this.nounique) { this.matches = new Set() as Matches this.seen = new Set() + this.walked = new Map() } if (typeof pattern === 'string') { @@ -142,11 +152,29 @@ export class Glob { this.pattern = pattern + this.platform = opts.platform || process.platform + if (opts.scurry) { + this.scurry = opts.scurry + } else { + const Scurry = + opts.platform === 'win32' + ? PathScurryWin32 + : opts.platform === 'darwin' + ? PathScurryDarwin + : opts.platform + ? PathScurryPosix + : PathScurry + this.scurry = new Scurry(this.cwd, { nocase: opts.nocase }) + } + const mmo: MinimatchOptions = { + // default nocase based on platform + nocase: this.scurry.nocase, ...opts, nonegate: true, nocomment: true, preserveMultipleSlashes: true, + nocaseMagicOnly: true, } const mms = this.pattern.map(p => new Minimatch(p, mmo)) @@ -162,8 +190,6 @@ export class Glob { this.matchSet = matchSet this.globSet = globSet this.globParts = globParts - this.scurry = - opts.scurry || new PathScurry(this.cwd, { nocase: opts.nocase }) } process(): Promise> @@ -172,7 +198,6 @@ export class Glob { // coerce them into the right shape. It will have already called // realpath() if the option was set to do so, so we know that's cached. // start out knowing the cwd, at least - await this.scurry.lstat() const matches: Matches[] = await Promise.all( this.matchSet.map(async (set, i) => { const p = new Pattern(set, this.globParts[i], 0) @@ -184,8 +209,6 @@ export class Glob { } processSync() { - // start out knowing the cwd, at least - this.scurry.lstatSync() const matches: Matches[] = this.matchSet.map((set, i) => { const p = new Pattern(set, this.globParts[i], 0) return this.getWalker(p).walkSync() @@ -220,6 +243,7 @@ export class Glob { this.scurry.cwd, this.matches, this.seen, + this.walked, this.opts ) } diff --git a/src/pattern.ts b/src/pattern.ts index a8884033..3e7835fb 100644 --- a/src/pattern.ts +++ b/src/pattern.ts @@ -50,7 +50,6 @@ export class Pattern { } this.length = patternList.length if (index >= this.length) { - //console.error('P', [index, globList]) throw new TypeError('index out of range') } this.patternList = patternList @@ -114,10 +113,6 @@ export class Pattern { return this.length > this.index + 1 } - copy(): Pattern { - return new Pattern(this.patternList, this.globList, this.index) - } - rest(): Pattern | null { return this.#rest !== undefined ? this.#rest diff --git a/src/walker.ts b/src/walker.ts index 55e43c03..65332063 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -47,7 +47,7 @@ import { GLOBSTAR } from 'minimatch' import { Path } from 'path-scurry' // a single minimatch set entry with 1 or more parts -import { Pattern } from './pattern.js' +import { MMPattern, Pattern } from './pattern.js' export interface GlobWalkerOpts { absolute?: boolean @@ -100,12 +100,14 @@ export class GlobWalker { : Set opts: O seen: Set + walked: Map constructor( pattern: Pattern, path: Path, matches: Matches | undefined, seen: Set | undefined, + walked: Map | undefined, opts: O ) constructor( @@ -113,13 +115,43 @@ export class GlobWalker { path: Path, matches: Matches | undefined, seen: Set | undefined, + walked: Map | undefined, opts: O ) { + const root = pattern.root() + if (root) { + this.path = path.resolve(root) + } else { + this.path = path + } this.pattern = pattern - this.path = path + while (this.pattern.pattern() === '..') { + this.pattern.index++ + this.path = this.path.parent || this.path + } this.matches = (matches || new Set()) as Matches - this.opts = opts + this.opts = { + absolute: !!root, + ...opts, + } this.seen = seen || new Set() + this.walked = walked || new Map() + } + + newWalks(target: Path, patterns: Pattern[]): Pattern[] { + const walked = this.walked.get(target) + if (!walked) { + this.walked.set(target, patterns) + return patterns + } + const todo: Pattern[] = [] + for (const p of patterns) { + if (!walked.includes(p)) { + todo.push(p) + walked.push(p) + } + } + return todo } // do the requisite realpath/stat checking, and return true/false @@ -269,7 +301,19 @@ export class GlobWalker { // - match if any (3) or (4) walkCB(target: Path, patterns: Pattern[], cb: () => any) { - // console.error('WCB2', target.relative(), patterns.map(p => p.globString())) + // don't readdir just to get a string match, wasteful + if (patterns.length === 1) { + let p: MMPattern + let rest: Pattern | null + while ( + typeof (p = patterns[0].pattern()) === 'string' && + (rest = patterns[0].rest()) + ) { + target = target.child(p) + patterns[0] = rest + } + } + target.readdirCB((_, entries) => { let tasks = 1 const next = () => { @@ -280,16 +324,18 @@ export class GlobWalker { this.walkCB2(e, patterns, next) } next() - })//, true) + }, true) } // returns 0-2 length array of [path, isMatch, sub patterns][] - getActions(target: Path, patterns: Pattern[]): [Path, boolean, Pattern[]][] { + getActions( + target: Path, + patterns: Pattern[] + ): [Path, boolean, Pattern[]][] { const actions: [Path, boolean, Pattern[]][] = [] const parent = target.parent || target const isGSWalkable = target.isDirectory() const isWalkable = isGSWalkable || target.canReaddir() - // console.error({ isGSWalkable, isWalkable }) const matchGS = !target.name.startsWith('.') const parentWalkPatterns: Pattern[] = [] const targetWalkPatterns: Pattern[] = [] @@ -321,7 +367,11 @@ export class GlobWalker { } } if (isParentMatch || parentWalkPatterns.length) { - actions.push([parent, isParentMatch, parentWalkPatterns]) + actions.push([ + parent, + isParentMatch, + this.newWalks(parent, parentWalkPatterns), + ]) } if (isTargetMatch || targetWalkPatterns.length) { actions.push([target, isTargetMatch, targetWalkPatterns]) @@ -330,18 +380,21 @@ export class GlobWalker { } walkCB2(target: Path, patterns: Pattern[], cb: () => any) { - const actions = this.getActions(target, patterns) + const actions = this.getActions( + target, + this.newWalks(target, patterns) + ) let tasks = 1 const doneTask = () => { if (--tasks === 0) cb() } for (const [path, isMatch, patterns] of actions) { if (isMatch && !this.seen.has(path)) { - tasks ++ + tasks++ this.match(path).then(doneTask) } if (patterns.length) { - tasks ++ + tasks++ this.walkCB(path, patterns, doneTask) } } @@ -358,6 +411,19 @@ export class GlobWalker { } walkCBSync(target: Path, patterns: Pattern[]) { + // don't readdir just to get a string match, wasteful + if (patterns.length === 1) { + let p: MMPattern + let rest: Pattern | null + while ( + typeof (p = patterns[0].pattern()) === 'string' && + (rest = patterns[0].rest()) + ) { + target = target.child(p) + patterns[0] = rest + } + } + const entries = target.readdirSync() for (const e of entries) { this.walkCB2Sync(e, patterns) @@ -365,7 +431,10 @@ export class GlobWalker { } walkCB2Sync(target: Path, patterns: Pattern[]) { - const actions = this.getActions(target, patterns) + const actions = this.getActions( + target, + this.newWalks(target, patterns) + ) for (const [path, isMatch, patterns] of actions) { if (isMatch && !this.seen.has(path)) { this.matchSync(path) From 145bbdb84c8a7e7653503ed341e90920b8c47810 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 13 Feb 2023 09:07:21 -0800 Subject: [PATCH 072/163] api cleanup, use isNamed for unicode safety --- package-lock.json | 14 ++-- package.json | 2 +- src/glob.ts | 18 +++-- src/index.ts | 4 +- src/walker.ts | 186 ++++++++++++++++++---------------------------- 5 files changed, 96 insertions(+), 128 deletions(-) diff --git a/package-lock.json b/package-lock.json index c065ae72..a645c5ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "fs.realpath": "^1.0.0", "minimatch": "6.2", - "path-scurry": "^1.3.0" + "path-scurry": "^1.4.0" }, "devDependencies": { "@types/mkdirp": "^1.0.2", @@ -3225,9 +3225,9 @@ } }, "node_modules/path-scurry": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.3.0.tgz", - "integrity": "sha512-S1tMxbHwgGIPyf9e3caxqQKyxooMYMLPBI7hAvGHHaseqKwXgJISYBe9zpj3aUsAOGobb6tR24c3ebhmidb++w==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.4.0.tgz", + "integrity": "sha512-kSNY3gm5ul3nBwDFkX9i8pkqZ5r0YsutWwpaUmog0utwOGwiRBiJlks955VGSsKde5EmviX02DlEDEWj7miukA==", "dependencies": { "lru-cache": "^7.14.1", "minipass": "^4.0.2" @@ -8800,9 +8800,9 @@ "dev": true }, "path-scurry": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.3.0.tgz", - "integrity": "sha512-S1tMxbHwgGIPyf9e3caxqQKyxooMYMLPBI7hAvGHHaseqKwXgJISYBe9zpj3aUsAOGobb6tR24c3ebhmidb++w==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.4.0.tgz", + "integrity": "sha512-kSNY3gm5ul3nBwDFkX9i8pkqZ5r0YsutWwpaUmog0utwOGwiRBiJlks955VGSsKde5EmviX02DlEDEWj7miukA==", "requires": { "lru-cache": "^7.14.1", "minipass": "^4.0.2" diff --git a/package.json b/package.json index c50f5d6d..4b7c1d8f 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "dependencies": { "fs.realpath": "^1.0.0", "minimatch": "6.2", - "path-scurry": "^1.3.0" + "path-scurry": "^1.4.0" }, "devDependencies": { "@types/mkdirp": "^1.0.2", diff --git a/src/glob.ts b/src/glob.ts index 56d7a1ad..08f076b8 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -14,6 +14,15 @@ type MatchSet = Minimatch['set'] type GlobSet = Exclude type GlobParts = Exclude +// if no process global, just call it linux. +// so we default to case-sensitive, / separators +const defaultPlatform = + typeof process === 'object' && + process && + typeof process.platform === 'string' + ? process.platform + : 'linux' + export interface GlobOptions extends MinimatchOptions { ignore?: string | string[] | Ignore follow?: boolean @@ -152,7 +161,7 @@ export class Glob { this.pattern = pattern - this.platform = opts.platform || process.platform + this.platform = opts.platform || defaultPlatform if (opts.scurry) { this.scurry = opts.scurry } else { @@ -192,8 +201,8 @@ export class Glob { this.globParts = globParts } - process(): Promise> - async process(): Promise> { + walk(): Promise> + async walk(): Promise> { // Walkers always return array of Path objects, so we just have to // coerce them into the right shape. It will have already called // realpath() if the option was set to do so, so we know that's cached. @@ -208,7 +217,7 @@ export class Glob { return this.finish(matches) } - processSync() { + walkSync() { const matches: Matches[] = this.matchSet.map((set, i) => { const p = new Pattern(set, this.globParts[i], 0) return this.getWalker(p).walkSync() @@ -241,7 +250,6 @@ export class Glob { return new GlobWalker( pattern, this.scurry.cwd, - this.matches, this.seen, this.walked, this.opts diff --git a/src/index.ts b/src/index.ts index 0ac3637a..d914d471 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,14 +5,14 @@ export const globSync = ( pattern: string | string[], options: GlobOptions = {} ): string[] => - new Glob(pattern, { ...options, withFileTypes: false }).processSync() + new Glob(pattern, { ...options, withFileTypes: false }).walkSync() export const glob = Object.assign( async ( pattern: string | string[], options: GlobOptions = {} ): Promise => - new Glob(pattern, { ...options, withFileTypes: false }).process(), + new Glob(pattern, { ...options, withFileTypes: false }).walk(), { sync: globSync, globSync, diff --git a/src/walker.ts b/src/walker.ts index 65332063..e7707c36 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -1,47 +1,10 @@ -// TODO: ok, new algorithm for this is needed, clearly -// forking out GlobWalkers for the set of children is just no good. -// When not the last piece of the pattern: -// if the pattern is a ** or regexp, we need to build a set of children -// paths that need to be walked once the piece is consumed. -// -// For **, this is a Scurry walk of all directories under the path -// For regexp, this is the children that match the regexp -// -// Then we iterate over that set, creating a new set of each child path -// that matches the next part of the pattern, and so on. -// -// At the end, we have the set of all the child paths that matched up to -// the last part of the pattern. -// -// If the last part is: -// '', ensure they're all directories, and return -// string, then .child it and maybe lstat -// **, scurry walk for all entries, only walking directories -// regexp, readdir and filter -// -// -// NEW APPROACH -// Instead of recursively forking for each new chunk of the pattern, which gets -// a bit ridiculous when there's multiple globstars, let's try another -// approach. -// We just do a normal naive scurry, but where the set of possibly-matching -// patterns serve as a filter, which we update as we descend, passing them -// along. -// -// This ends up being equivalent if no globstars are present. We just -// walk the dirs, consuming pattern parts as they match. -// -// However, when we have a **, the descent gets *both* the "consumed" -// pattern, *and* the full pattern with the **. -// -// Then for each child entry, for each active pattern, if it matches, then -// it consumes the next bit of the pattern, and continues with all the patterns -// that it matched on. But if it's a globstar, then "consuming" means that we -// take the full globstar pattern set, as well as the pattern set without the -// globstar (ie, as if * was matched). -// -// This should result in only ever walking the tree a single time, as well as -// filtering out walk paths that can't possibly match anything. +// TODO: provide all the same iteration patterns that PathScurry has +// - [x] walk +// - [x] walkSync +// - [ ] stream +// - [ ] streamSync +// - [ ] iterator +// - [ ] iteratorSync import { GLOBSTAR } from 'minimatch' import { Path } from 'path-scurry' @@ -56,7 +19,6 @@ export interface GlobWalkerOpts { mark?: boolean withFileTypes?: boolean } - export type GWOFileTypesTrue = GlobWalkerOpts & { withFileTypes: true } @@ -66,6 +28,7 @@ export type GWOFileTypesFalse = GlobWalkerOpts & { export type GWOFileTypesUnset = GlobWalkerOpts & { withFileTypes?: undefined } + export type Result = O extends GWOFileTypesTrue ? Path : O extends GWOFileTypesFalse @@ -73,6 +36,7 @@ export type Result = O extends GWOFileTypesTrue : O extends GWOFileTypesUnset ? string : Path | string + export type Matches = O extends GWOFileTypesTrue ? Set : O extends GWOFileTypesFalse @@ -81,13 +45,49 @@ export type Matches = O extends GWOFileTypesTrue ? Set : Set -// the "matches" set is a set of either: -// - Path objects (if withFileTypes:true) -// - resolved paths (if absolute:true) -// - real paths (if realpath:true) -// - built-up path strings (all other cases) +export abstract class GlobUtil { + path: Path + pattern: Pattern + opts: O + seen: Set + walked: Map + + constructor( + pattern: Pattern, + path: Path, + matches: Matches | undefined, + seen: Set | undefined, + walked: Map | undefined, + opts: O + ) + constructor( + pattern: Pattern, + path: Path, + matches: Matches | undefined, + seen: Set | undefined, + walked: Map | undefined, + opts: O + ) { + const root = pattern.root() + if (root) { + this.path = path.resolve(root) + } else { + this.path = path + } + this.pattern = pattern + while (this.pattern.pattern() === '..') { + this.pattern.index++ + this.path = this.path.parent || this.path + } + this.opts = { + absolute: !!root, + ...opts, + } + this.seen = seen || new Set() + this.walked = walked || new Map() + } +} -// get the Path objects that match the pattern export class GlobWalker { path: Path pattern: Pattern @@ -105,7 +105,6 @@ export class GlobWalker { constructor( pattern: Pattern, path: Path, - matches: Matches | undefined, seen: Set | undefined, walked: Map | undefined, opts: O @@ -113,7 +112,6 @@ export class GlobWalker { constructor( pattern: Pattern, path: Path, - matches: Matches | undefined, seen: Set | undefined, walked: Map | undefined, opts: O @@ -129,7 +127,7 @@ export class GlobWalker { this.pattern.index++ this.path = this.path.parent || this.path } - this.matches = (matches || new Set()) as Matches + this.matches = new Set() as Matches this.opts = { absolute: !!root, ...opts, @@ -171,7 +169,7 @@ export class GlobWalker { return undefined } const needRealPath = this.opts.realpath && !rpc - const needStat = (this.opts.nodir || this.opts.mark) && e.isUnknown() + const needStat = e.isUnknown() if (needRealPath && needStat) { const r = await e.realpath().then(e => e && e.lstat()) if (!r || this.seen.has(r) || (e.isDirectory() && this.opts.nodir)) { @@ -189,6 +187,7 @@ export class GlobWalker { if (!r || this.seen.has(r) || (r.isDirectory() && this.opts.nodir)) { return undefined } + return r } else if (this.seen.has(e) || (e.isDirectory() && this.opts.nodir)) { return undefined } else { @@ -211,7 +210,7 @@ export class GlobWalker { return undefined } const needRealPath = this.opts.realpath && !rpc - const needStat = (this.opts.nodir || this.opts.mark) && e.isUnknown() + const needStat = e.isUnknown() if (needRealPath && needStat) { const r = e.realpathSync()?.lstatSync() if (!r || this.seen.has(r) || (e.isDirectory() && this.opts.nodir)) { @@ -229,6 +228,7 @@ export class GlobWalker { if (!r || this.seen.has(r) || (r.isDirectory() && this.opts.nodir)) { return undefined } + return r } else if (this.seen.has(e) || (e.isDirectory() && this.opts.nodir)) { return undefined } else { @@ -271,35 +271,6 @@ export class GlobWalker { }) } - // XXX - // ok just write this down then, this is getting hairy - // - // Get the list of patterns that the current target matches, - // and also, any that the parent matches (if the pattern is ..) - // - // If any of those matches (for self or parent) are a single - // part, then emit the match for them. - // - // If any matches for target have more, then walkCB with those on target - // If any matches for parent have more, then walkCB with those on parent - // but in both cases, only if the Path is walkable. - // When we walkCB, it's with pattern.rest() in the case of everything - // except globstar, which dupes both pattern and rest in the child set. - // - // So, for both target and parent: - // 1 all that match and have more and start with ** - // 2 all that match and have more and do not start with ** - // 3 all that match and do not have more and are ** - // 4 all that match and do not have more and are not ** - // if dir: - // - walk with all (1) duped+subbed, all (2) subbed, all (3) duped - // - match if any (3) or (4) - // if walkable: - // - walk with all (1) subbed, all (2) subbed - // - match if any (3) or (4) - // else: - // - match if any (3) or (4) - walkCB(target: Path, patterns: Pattern[], cb: () => any) { // don't readdir just to get a string match, wasteful if (patterns.length === 1) { @@ -312,8 +283,16 @@ export class GlobWalker { target = target.child(p) patterns[0] = rest } + // if the last item is ALSO a string, then just match it. + p = patterns[0].pattern() + if (typeof p === 'string' && !patterns[0].hasMore()) { + this.match(target.child(p)).then(cb) + return + } } + // skip the readdir if we can't read it, eg if it's a full + // path to a file or something. target.readdirCB((_, entries) => { let tasks = 1 const next = () => { @@ -358,7 +337,7 @@ export class GlobWalker { } else if (p === '' || p === '.') { if (!rest) isTargetMatch = true else if (isWalkable) targetWalkPatterns.push(rest) - } else if (typeof p === 'string' && p === target.name) { + } else if (typeof p === 'string' && target.isNamed(p)) { if (!rest) isTargetMatch = true else if (isWalkable) targetWalkPatterns.push(rest) } else if (p instanceof RegExp && p.test(target.name)) { @@ -422,8 +401,16 @@ export class GlobWalker { target = target.child(p) patterns[0] = rest } + // if the last item is ALSO a string, then just match it. + p = patterns[0].pattern() + if (typeof p === 'string' && !patterns[0].hasMore()) { + this.matchSync(target.child(p)) + return + } } + // skip the readdir if we can't read it, eg if it's a full + // path to a file or something. const entries = target.readdirSync() for (const e of entries) { this.walkCB2Sync(e, patterns) @@ -444,31 +431,4 @@ export class GlobWalker { } } } - - async maybeMatchPath(): Promise { - if (this.path.isUnknown()) { - const lsc = this.path.lstatCached() - if (lsc) { - return this.match(lsc) - } else { - return this.path.lstat().then(p => p && this.match(p)) - } - } else { - return this.match(this.path) - } - } - - maybeMatchPathSync() { - if (this.path.isUnknown()) { - const lsc = this.path.lstatCached() - if (lsc) { - this.matchSync(lsc) - } else { - const p = this.path.lstatSync() - if (p) this.matchSync(p) - } - } else { - this.matchSync(this.path) - } - } } From a3cbe44d0c2b1884c701878a2dbec1d542dcee62 Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 13 Feb 2023 10:50:45 -0800 Subject: [PATCH 073/163] stream implementation Also, realized I need to pass the full pattern set to the glob util objects, or else a brace expansion can trigger multiple walks, and really we want to ensure that we only ever walk the dir tree a single time. --- benchmark.sh | 16 +++ package-lock.json | 1 + package.json | 1 + src/glob.ts | 57 +++++++-- src/index.ts | 26 +++- src/walker.ts | 316 ++++++++++++++++++++++++++++++---------------- 6 files changed, 294 insertions(+), 123 deletions(-) diff --git a/benchmark.sh b/benchmark.sh index 768366f0..0d69452b 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -4,8 +4,10 @@ set -e patterns=( './**/?/**/?/**/?/**/?/**/*.txt' + './{**/?{/**/?{/**/?{/**/?,},},},}/**/*.txt' './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt' './*/**/../*/**/../*/**/../*/**/../*/**/*.txt' + './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,},},},},}/*.txt' './**/0/**/../[01]/**/0/../**/0/*.txt' '**/????/????/????/????/*.txt' './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' @@ -144,6 +146,20 @@ MJS MJS t node "$wd/bench-working-dir/async.mjs" "$p" + echo -n $'node current glob syncStream \t' + cat > "$wd/bench-working-dir/stream-sync.mjs" < "$wd/bench-working-dir/stream.mjs" < @@ -29,7 +30,6 @@ export interface GlobOptions extends MinimatchOptions { mark?: boolean nodir?: boolean nounique?: boolean - nosort?: boolean cwd?: string realpath?: boolean absolute?: boolean @@ -76,7 +76,6 @@ export class Glob { mark: boolean nodir: boolean nounique: boolean - nosort: boolean cwd: string matchSet: MatchSet globSet: GlobSet @@ -111,7 +110,6 @@ export class Glob { this.nodir = !!opts.nodir this.mark = !!opts.mark this.nounique = !!opts.nounique - this.nosort = !!opts.nosort this.cwd = opts.cwd || '' this.realpath = !!opts.realpath this.nonull = !!opts.nonull @@ -201,7 +199,6 @@ export class Glob { this.globParts = globParts } - walk(): Promise> async walk(): Promise> { // Walkers always return array of Path objects, so we just have to // coerce them into the right shape. It will have already called @@ -217,7 +214,7 @@ export class Glob { return this.finish(matches) } - walkSync() { + walkSync(): Results { const matches: Matches[] = this.matchSet.map((set, i) => { const p = new Pattern(set, this.globParts[i], 0) return this.getWalker(p).walkSync() @@ -240,10 +237,50 @@ export class Glob { } } - sort(flat: string[]) { - return this.nosort - ? flat - : flat.sort((a, b) => a.localeCompare(b, 'en')) + stream(): Minipass> + stream(): Minipass { + const s = new Minipass({ + objectMode: true, + }) as Minipass> + for (let i = 0; i < this.matchSet.length; i++) { + const p = new Pattern(this.matchSet[i], this.globParts[i], 0) + this.getStream(p).stream().pipe(s) + } + if (!this.nounique) { + // reset the stream so we can call multiple times. + this.matches = new Set() as Matches + this.seen = new Set() + this.walked = new Map() + } + return s + } + + streamSync(): Minipass> + streamSync(): Minipass { + const s = new Minipass({ + objectMode: true, + }) as Minipass> + for (let i = 0; i < this.matchSet.length; i++) { + const p = new Pattern(this.matchSet[i], this.globParts[i], 0) + this.getStream(p).streamSync().pipe(s) + } + if (!this.nounique) { + // reset the stream so we can call multiple times. + this.matches = new Set() as Matches + this.seen = new Set() + this.walked = new Map() + } + return s + } + + getStream(pattern: Pattern): GlobStream { + return new GlobStream( + pattern, + this.scurry.cwd, + this.seen, + this.walked, + this.opts + ) } getWalker(pattern: Pattern): GlobWalker { diff --git a/src/index.ts b/src/index.ts index d914d471..a64972de 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,27 @@ +import Minipass from 'minipass' import { Glob, GlobOptions } from './glob.js' import { hasMagic } from './has-magic.js' -export const globSync = ( +export const globStreamSync = ( pattern: string | string[], options: GlobOptions = {} -): string[] => - new Glob(pattern, { ...options, withFileTypes: false }).walkSync() +): Minipass => + new Glob(pattern, { ...options, withFileTypes: false }).streamSync() + +export const globStream = Object.assign( + ( + pattern: string | string[], + options: GlobOptions = {} + ): Minipass => + new Glob(pattern, { ...options, withFileTypes: false }).stream(), + { sync: globStreamSync } +) + +export const globSync = Object.assign( + (pattern: string | string[], options: GlobOptions = {}): string[] => + new Glob(pattern, { ...options, withFileTypes: false }).walkSync(), + { stream: globStreamSync } +) export const glob = Object.assign( async ( @@ -16,6 +32,10 @@ export const glob = Object.assign( { sync: globSync, globSync, + stream: globStream, + streamSync: globStreamSync, + globStream, + globStreamSync, Glob, hasMagic, } diff --git a/src/walker.ts b/src/walker.ts index e7707c36..4a4c797c 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -7,6 +7,7 @@ // - [ ] iteratorSync import { GLOBSTAR } from 'minimatch' +import Minipass from 'minipass' import { Path } from 'path-scurry' // a single minimatch set entry with 1 or more parts @@ -45,6 +46,18 @@ export type Matches = O extends GWOFileTypesTrue ? Set : Set +export type MatchStream = + O extends GWOFileTypesTrue + ? Minipass + : O extends GWOFileTypesFalse + ? Minipass + : O extends GWOFileTypesUnset + ? Minipass + : Minipass + +/** + * basic walking utilities that all the glob walker types use + */ export abstract class GlobUtil { path: Path pattern: Pattern @@ -52,10 +65,12 @@ export abstract class GlobUtil { seen: Set walked: Map + paused: boolean = false + #onResume: (() => any)[] = [] + constructor( pattern: Pattern, path: Path, - matches: Matches | undefined, seen: Set | undefined, walked: Map | undefined, opts: O @@ -63,7 +78,6 @@ export abstract class GlobUtil { constructor( pattern: Pattern, path: Path, - matches: Matches | undefined, seen: Set | undefined, walked: Map | undefined, opts: O @@ -86,54 +100,22 @@ export abstract class GlobUtil { this.seen = seen || new Set() this.walked = walked || new Map() } -} - -export class GlobWalker { - path: Path - pattern: Pattern - matches: O extends GWOFileTypesTrue - ? Set - : O extends GWOFileTypesFalse - ? Set - : O extends GWOFileTypesUnset - ? Set - : Set - opts: O - seen: Set - walked: Map - constructor( - pattern: Pattern, - path: Path, - seen: Set | undefined, - walked: Map | undefined, - opts: O - ) - constructor( - pattern: Pattern, - path: Path, - seen: Set | undefined, - walked: Map | undefined, - opts: O - ) { - const root = pattern.root() - if (root) { - this.path = path.resolve(root) - } else { - this.path = path - } - this.pattern = pattern - while (this.pattern.pattern() === '..') { - this.pattern.index++ - this.path = this.path.parent || this.path - } - this.matches = new Set() as Matches - this.opts = { - absolute: !!root, - ...opts, + // backpressure mechanism + pause() { + this.paused = true + } + resume() { + this.paused = false + let fn: (() => any) | undefined = undefined + while (!this.paused && (fn = this.#onResume.shift())) { + fn() + if (this.paused) break } - this.seen = seen || new Set() - this.walked = walked || new Map() + } + onResume(fn: () => any) { + if (!this.paused) fn() + else this.#onResume.push(fn) } newWalks(target: Path, patterns: Pattern[]): Pattern[] { @@ -236,18 +218,21 @@ export class GlobWalker { } } + abstract matchEmit(p: Result): void + abstract matchEmit(p: string | Path): void + matchFinish(e: Path) { this.seen.add(e) const mark = this.opts.mark && e.isDirectory() ? '/' : '' // ok, we have what we need! if (this.opts.withFileTypes) { - this.matches.add(e) + this.matchEmit(e) } else if (this.opts.nodir && e.isDirectory()) { return } else if (this.opts.absolute) { - this.matches.add(e.fullpath() + mark) + this.matchEmit(e.fullpath() + mark) } else { - this.matches.add(e.relative() + mark) + this.matchEmit(e.relative() + mark) } } @@ -261,51 +246,6 @@ export class GlobWalker { if (p) this.matchFinish(p) } - async walk( - target: Path = this.path, - patterns: Pattern[] = [this.pattern] - ): Promise> { - if (target.isUnknown()) await target.lstat() - return new Promise(res => { - this.walkCB(target, patterns, () => res(this.matches)) - }) - } - - walkCB(target: Path, patterns: Pattern[], cb: () => any) { - // don't readdir just to get a string match, wasteful - if (patterns.length === 1) { - let p: MMPattern - let rest: Pattern | null - while ( - typeof (p = patterns[0].pattern()) === 'string' && - (rest = patterns[0].rest()) - ) { - target = target.child(p) - patterns[0] = rest - } - // if the last item is ALSO a string, then just match it. - p = patterns[0].pattern() - if (typeof p === 'string' && !patterns[0].hasMore()) { - this.match(target.child(p)).then(cb) - return - } - } - - // skip the readdir if we can't read it, eg if it's a full - // path to a file or something. - target.readdirCB((_, entries) => { - let tasks = 1 - const next = () => { - if (--tasks <= 0) cb() - } - for (const e of entries) { - tasks++ - this.walkCB2(e, patterns, next) - } - next() - }, true) - } - // returns 0-2 length array of [path, isMatch, sub patterns][] getActions( target: Path, @@ -358,7 +298,50 @@ export class GlobWalker { return actions } + walkCB(target: Path, patterns: Pattern[], cb: () => any) { + if (this.paused) { + this.onResume(() => this.walkCB(target, patterns, cb)) + return + } + // don't readdir just to get a string match, wasteful + if (patterns.length === 1) { + let p: MMPattern + let rest: Pattern | null + while ( + typeof (p = patterns[0].pattern()) === 'string' && + (rest = patterns[0].rest()) + ) { + target = target.child(p) + patterns[0] = rest + } + // if the last item is ALSO a string, then just match it. + p = patterns[0].pattern() + if (typeof p === 'string' && !patterns[0].hasMore()) { + this.match(target.child(p)).then(cb) + return + } + } + + // skip the readdir if we can't read it, eg if it's a full + // path to a file or something. + target.readdirCB((_, entries) => { + let tasks = 1 + const next = () => { + if (--tasks <= 0) cb() + } + for (const e of entries) { + tasks++ + this.walkCB2(e, patterns, next) + } + next() + }, true) + } + walkCB2(target: Path, patterns: Pattern[], cb: () => any) { + if (this.paused) { + this.onResume(() => this.walkCB2(target, patterns, cb)) + return + } const actions = this.getActions( target, this.newWalks(target, patterns) @@ -380,16 +363,11 @@ export class GlobWalker { doneTask() } - walkSync( - target: Path = this.path, - patterns: Pattern[] = [this.pattern] - ): Matches { - if (target.isUnknown()) target.lstatSync() - this.walkCBSync(target, patterns) - return this.matches - } - - walkCBSync(target: Path, patterns: Pattern[]) { + walkCBSync(target: Path, patterns: Pattern[], cb: () => any) { + if (this.paused) { + this.onResume(() => this.walkCBSync(target, patterns, cb)) + return + } // don't readdir just to get a string match, wasteful if (patterns.length === 1) { let p: MMPattern @@ -405,6 +383,7 @@ export class GlobWalker { p = patterns[0].pattern() if (typeof p === 'string' && !patterns[0].hasMore()) { this.matchSync(target.child(p)) + cb() return } } @@ -412,23 +391,140 @@ export class GlobWalker { // skip the readdir if we can't read it, eg if it's a full // path to a file or something. const entries = target.readdirSync() + let tasks = 1 + const next = () => { + if (--tasks <= 0) cb() + } for (const e of entries) { - this.walkCB2Sync(e, patterns) + tasks++ + this.walkCB2Sync(e, patterns, next) } + next() } - - walkCB2Sync(target: Path, patterns: Pattern[]) { + walkCB2Sync(target: Path, patterns: Pattern[], cb: () => any) { + if (this.paused) { + this.onResume(() => this.walkCB2(target, patterns, cb)) + return + } const actions = this.getActions( target, this.newWalks(target, patterns) ) + let tasks = 1 + const doneTask = () => { + if (--tasks === 0) cb() + } for (const [path, isMatch, patterns] of actions) { if (isMatch && !this.seen.has(path)) { + tasks++ this.matchSync(path) + doneTask() } if (patterns.length) { - this.walkCBSync(path, patterns) + tasks++ + this.walkCBSync(path, patterns, doneTask) } } + doneTask() + } +} + +export class GlobWalker< + O extends GlobWalkerOpts = GlobWalkerOpts +> extends GlobUtil { + matches: O extends GWOFileTypesTrue + ? Set + : O extends GWOFileTypesFalse + ? Set + : O extends GWOFileTypesUnset + ? Set + : Set + + constructor( + pattern: Pattern, + path: Path, + seen: Set | undefined, + walked: Map | undefined, + opts: O + ) { + super(pattern, path, seen, walked, opts) + this.matches = new Set() as Matches + } + + matchEmit(e: Result): void + matchEmit(e: Path | string): void { + this.matches.add(e) + } + + async walk(): Promise> { + const target = this.path + const patterns = [this.pattern] + if (target.isUnknown()) await target.lstat() + return new Promise(res => { + this.walkCB(target, patterns, () => res(this.matches)) + }) + } + + walkSync(): Matches { + const target = this.path + const patterns = [this.pattern] + if (target.isUnknown()) target.lstatSync() + // nothing for the callback to do, because this never pauses + this.walkCBSync(target, patterns, () => {}) + return this.matches + } +} + +export class GlobStream< + O extends GlobWalkerOpts = GlobWalkerOpts +> extends GlobUtil { + results: O extends GWOFileTypesTrue + ? Minipass + : O extends GWOFileTypesFalse + ? Minipass + : O extends GWOFileTypesUnset + ? Minipass + : Minipass + + constructor( + pattern: Pattern, + path: Path, + seen: Set | undefined, + walked: Map | undefined, + opts: O + ) { + super(pattern, path, seen, walked, opts) + this.results = new Minipass({ objectMode: true }) as MatchStream + this.results.on('drain', () => this.resume()) + } + + matchEmit(e: Result): void + matchEmit(e: Path | string): void { + if (!this.results.write(e)) { + this.pause() + } + } + + stream(): MatchStream { + const target = this.path + const patterns = [this.pattern] + if (target.isUnknown()) { + target + .lstat() + .then(() => + this.walkCB(target, patterns, () => this.results.end()) + ) + } else { + this.walkCB(target, patterns, () => this.results.end()) + } + return this.results + } + + streamSync(): MatchStream { + const target = this.path + const patterns = [this.pattern] + if (target.isUnknown()) target.lstatSync() + this.walkCBSync(target, patterns, () => this.results.end()) + return this.results } } From ca1ae652577b14eff7fd1cdef67b8a2fb6fa5eef Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 14 Feb 2023 20:03:15 -0800 Subject: [PATCH 074/163] some pattern editing hacks (belongs in minimatch) Identified a bunch of ways that patterns can be altered in behavior-identical ways, to minimize the number of full-tree walks that are required. There's a slight perf hit up front with some of them, like the long repeated string of '*/**/..', because it's doing a lot of calculations that really ought to be done up front in the Minimatch constructor, rather than here in the Pattern object. If done *before* parsing the glob patterns into regexps and such, it'll be much more efficient, but it took a bit of fiddling to get the correct outcomes, so now the next step is porting it into Minimatch properly, along with a ton of tests. Also, this improves performance considerably by making the GlobUtil classes able to take a set of Pattern objects, so that they can track what patterns have already been walked, even when they appear in different parts of the brace-expanded set. It does also mean that nounique:true is gone, but I think that's a very acceptable trade-off. --- benchmark.sh | 8 +- src/glob.ts | 98 +++----- src/pattern.ts | 345 +++++++++++++++++++++------- src/walker.ts | 600 +++++++++++++++++++++++++++++-------------------- 4 files changed, 664 insertions(+), 387 deletions(-) diff --git a/benchmark.sh b/benchmark.sh index 0d69452b..1ab8963e 100644 --- a/benchmark.sh +++ b/benchmark.sh @@ -3,11 +3,15 @@ export CDPATH= set -e patterns=( + # some of these aren't particularly "representative" of real-world + # glob patterns, but they're here to highlight pathological perf + # cases that I found while working on the rewrite of this library. './**/?/**/?/**/?/**/?/**/*.txt' - './{**/?{/**/?{/**/?{/**/?,},},},}/**/*.txt' './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt' + './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt' + './{**/?{/**/?{/**/?{/**/?,,,,},,,,},,,,},,,}/**/*.txt' + './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,,,,},,,,},,,,},,,,},,,,}/*.txt' './*/**/../*/**/../*/**/../*/**/../*/**/*.txt' - './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,},},},},}/*.txt' './**/0/**/../[01]/**/0/../**/0/*.txt' '**/????/????/????/????/*.txt' './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' diff --git a/src/glob.ts b/src/glob.ts index 176bc27b..21fa259a 100644 --- a/src/glob.ts +++ b/src/glob.ts @@ -93,6 +93,7 @@ export class Glob { scurry: PathScurry opts: Opts platform?: typeof process.platform + patterns: Pattern[] constructor(pattern: string | string[], opts: Opts) { this.withFileTypes = !!opts.withFileTypes as FileTypes @@ -194,6 +195,10 @@ export class Glob { }, [[], [], []] ) + this.patterns = matchSet + .map((set, i) => new Pattern(set, globParts[i], 0)) + .map(p => p.expandGlobstarDotDot()) + .reduce((set: Pattern[], p) => set.concat(p), []) this.matchSet = matchSet this.globSet = globSet this.globParts = globParts @@ -204,92 +209,43 @@ export class Glob { // coerce them into the right shape. It will have already called // realpath() if the option was set to do so, so we know that's cached. // start out knowing the cwd, at least - const matches: Matches[] = await Promise.all( - this.matchSet.map(async (set, i) => { - const p = new Pattern(set, this.globParts[i], 0) - return await this.getWalker(p).walk() - }) + const walker = new GlobWalker( + this.patterns, + this.scurry.cwd, + this.opts ) - // TODO: nonull filling in the blanks - return this.finish(matches) + return this.finish(await walker.walk()) } walkSync(): Results { - const matches: Matches[] = this.matchSet.map((set, i) => { - const p = new Pattern(set, this.globParts[i], 0) - return this.getWalker(p).walkSync() - }) - return this.finish(matches) + const walker = new GlobWalker( + this.patterns, + this.scurry.cwd, + this.opts + ) + return this.finish(walker.walkSync()) } - finish(matches: Matches[]): Results - finish(matches: Set[]): (string | Path)[] { - if (this.nounique) { - const raw: (string | Path)[] = [] - for (const set of matches) { - for (const e of set) { - raw.push(e) - } - } - return raw - } else { - return [...matches[0]] - } + finish(matches: Matches): Results + finish(matches: Set): (string | Path)[] { + return [...matches] } stream(): Minipass> stream(): Minipass { - const s = new Minipass({ - objectMode: true, - }) as Minipass> - for (let i = 0; i < this.matchSet.length; i++) { - const p = new Pattern(this.matchSet[i], this.globParts[i], 0) - this.getStream(p).stream().pipe(s) - } - if (!this.nounique) { - // reset the stream so we can call multiple times. - this.matches = new Set() as Matches - this.seen = new Set() - this.walked = new Map() - } - return s - } - - streamSync(): Minipass> - streamSync(): Minipass { - const s = new Minipass({ - objectMode: true, - }) as Minipass> - for (let i = 0; i < this.matchSet.length; i++) { - const p = new Pattern(this.matchSet[i], this.globParts[i], 0) - this.getStream(p).streamSync().pipe(s) - } - if (!this.nounique) { - // reset the stream so we can call multiple times. - this.matches = new Set() as Matches - this.seen = new Set() - this.walked = new Map() - } - return s - } - - getStream(pattern: Pattern): GlobStream { - return new GlobStream( - pattern, + return new GlobStream( + this.patterns, this.scurry.cwd, - this.seen, - this.walked, this.opts - ) + ).stream() } - getWalker(pattern: Pattern): GlobWalker { - return new GlobWalker( - pattern, + streamSync(): Minipass> + streamSync(): Minipass { + return new GlobStream( + this.patterns, this.scurry.cwd, - this.seen, - this.walked, this.opts - ) + ).streamSync() } } diff --git a/src/pattern.ts b/src/pattern.ts index 3e7835fb..8a629bfc 100644 --- a/src/pattern.ts +++ b/src/pattern.ts @@ -7,6 +7,9 @@ type MMRegExp = RegExp & { } export type MMPattern = string | MMRegExp | typeof GLOBSTAR +import LRUCache from 'lru-cache' +const cache = new LRUCache({ max: 256 }) + // an array of length >= 1 type PatternList = [p: MMPattern, ...rest: MMPattern[]] type UNCPatternList = [ @@ -26,13 +29,25 @@ const isPatternList = (pl: MMPattern[]): pl is PatternList => pl.length >= 1 const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1 +const cacheKey = (index: number, patternList: PatternList): string => + index + + '\n' + + patternList + .map(p => + typeof p === 'string' ? p : p instanceof RegExp ? String(p) : '**' + ) + .join('\n') + export class Pattern { readonly patternList: PatternList readonly globList: GlobList - index: number + readonly #index: number readonly length: number #rest?: Pattern | null #globString?: string + #isDrive?: boolean + #isUNC?: boolean + #isAbsolute?: boolean constructor( patternList: MMPattern[], @@ -54,86 +69,274 @@ export class Pattern { } this.patternList = patternList this.globList = globList - this.index = index - - // do some cleanup of the pattern if we're starting out. - if (this.index === 0) { - // '//host/share' => '//host/share/' - // 'c:' => 'c:/' - if ( - (this.isUNC() && this.length === 4) || - (this.isDrive() && this.length === 1) - ) { - this.patternList.push('') - this.globList.push('') - this.length++ + this.#index = index + + // if the current item is not globstar, and the next item is .., skip ahead + if ( + this.patternList[this.#index] !== GLOBSTAR && + this.patternList[this.#index] !== '..' && + this.patternList[this.#index + 1] === '..' && + this.length > this.#index + 2 + ) { + this.#index += 2 + } + + // this is not so much to save on performance but more to ensure + // that if we get the same pattern, we'll have the same Pattern object, + // since these objects are used in cache entries to prevent rewalking. + // It won't cause any incorrect behavior on a cache miss, but it may + // adversely affect performance in really weird cases, like lots of + // **/.. patterns and such. + const key = cacheKey(index, patternList) + const cached = cache.get(key) + if (cached) return cached + cache.set(key, this) + + // normalize root entries of absolute patterns on initial creation. + if (this.#index === 0) { + // c: => ['c:/'] + // C:/ => ['C:/'] + // C:/x => ['C:/', 'x'] + // //host/share => ['//host/share/'] + // //host/share/ => ['//host/share/'] + // //host/share/x => ['//host/share/', 'x'] + // /etc => ['/', 'etc'] + // / => ['/'] + if (this.isUNC()) { + const [p1, p2, p3, ...prest] = this.patternList + const [g1, g2, g3, ...grest] = this.globList + if (prest[0] === '') { + // ends in / + prest.shift() + grest.shift() + } + const p = [p1, p2, p3, ''].join('/') + const g = [g1, g2, g3, ''].join('/') + this.patternList = [p, ...prest] + this.globList = [g, ...grest] + this.length = this.patternList.length + } else if (this.isDrive() || this.isAbsolute()) { + const [p1, ...prest] = this.patternList + const [g1, ...grest] = this.globList + if (prest[0] === '') { + // ends in / + prest.shift() + grest.shift() + } + const p = (p1 as string) + '/' + const g = g1 + '/' + this.patternList = [p, ...prest] + this.globList = [g, ...grest] + this.length = this.patternList.length } } else { - // match bash behavior, discard any empty path portions that - // follow a path portion with magic chars, except the last one. - const prev = this.patternList[this.index - 1] - while ( - typeof prev !== 'string' && - this.index < this.length - 1 && - this.pattern() === '' - ) { - this.index++ + // discard any empty path portions, except the last one. + while (this.#index < this.length - 1 && this.pattern() === '') { + this.#index++ } } } pattern(): MMPattern { - return this.patternList[this.index] + return this.patternList[this.#index] } isString(): boolean { - return typeof this.patternList[this.index] === 'string' + return typeof this.patternList[this.#index] === 'string' } isGlobstar(): boolean { - return this.patternList[this.index] === GLOBSTAR + return this.patternList[this.#index] === GLOBSTAR + } + isGlobstarDotDot(): boolean { + return this.isGlobstar() && this.globList[this.#index + 1] === '..' } isMagic(): boolean { - return this.patternList[this.index] instanceof RegExp + return this.patternList[this.#index] instanceof RegExp + } + + // This has to be ALL THE WAY THROUGH, and done early + expandGlobstarDotDot(): Pattern[] { + const sets: Map = new Map([ + [this.globList.join('/'), [this.patternList, this.globList]], + ]) + + let didSomething = false + let keepGoing = false + do { + keepGoing = false + for (const [globString, [patternList, globList]] of sets.entries()) { + // only expand up from the current index, for safety. + let gs: number = this.#index + while (-1 !== (gs = patternList.indexOf(GLOBSTAR, gs + 1))) { + const next = patternList[gs + 1] + if (next !== '..') { + continue + } + + // ok, found one + // expand it, and replace plgl + sets.delete(globString) + didSomething = true + keepGoing = true + + const headGL = gs === 0 ? [] : globList.slice(0, gs) + const headPL = gs === 0 ? [] : patternList.slice(0, gs) + const restGL = globList.slice(gs + 2) + const restPL = patternList.slice(gs + 2) + const dotRestGL = restGL.length ? restGL : ['.'] + const dotRestPL = restPL.length ? restPL : ['.'] + + sets.set([...headGL, '**', ...dotRestGL].join('/'), [ + [...headPL, GLOBSTAR, ...dotRestPL] as PatternList, + [...headGL, '**', ...dotRestGL] as GlobList, + ]) + sets.set([...headGL, '..', ...restGL].join('/'), [ + [...headPL, '..', ...restPL] as PatternList, + [...headGL, '..', ...restGL] as GlobList, + ]) + break + } + } + + for (const [globString, [patternList, globList]] of sets.entries()) { + let pl: PatternList = patternList + let gl: GlobList = globList + let dd: number = this.#index - 1 + while (-1 !== (dd = patternList.indexOf('..', dd + 1))) { + if (dd <= this.#index) { + break + } + const prev = patternList[dd - 1] + if (prev && prev !== GLOBSTAR && prev !== '.') { + didSomething = true + keepGoing = true + sets.delete(globString) + pl = [ + ...patternList.slice(0, dd - 1), + ...patternList.slice(dd + 1), + ] as PatternList + gl = [ + ...globList.slice(0, dd - 1), + ...globList.slice(dd + 1), + ] as GlobList + sets.set(gl.join('/'), [pl, gl]) + break + } + } + } + // **/*/ -> */**/ + for (const [globString, [patternList, globList]] of sets.entries()) { + let didSomething = false + for (let i = 0; i < globList.length - 2; i++) { + if (patternList[i] === GLOBSTAR) { + let j = i + while (j < patternList.length - 1 && globList[j + 1] === '*') { + j++ + } + if (i !== j) { + didSomething = true + patternList[i] = patternList[j] + patternList[j] = GLOBSTAR + globList[i] = '*' + globList[j] = '**' + } + } + } + if (didSomething) { + keepGoing = true + sets.delete(globString) + sets.set(globList.join('/'), [patternList, globList]) + } + } + // **/** => ** + for (const [globString, [patternList, globList]] of sets.entries()) { + let didSomething = false + for (let i = 0; i < globList.length - 2; i++) { + if (patternList[i] === GLOBSTAR) { + let j = i + while ( + j < patternList.length - 1 && + patternList[j + 1] === GLOBSTAR + ) { + j++ + } + if (i !== j) { + didSomething = true + patternList.splice(i, j - i) + globList.splice(i, j - i) + } + } + } + if (didSomething) { + keepGoing = true + sets.delete(globString) + sets.set(globList.join('/'), [patternList, globList]) + } + } + } while (keepGoing) + + if (!didSomething) return [this] + + // now sets is the fully expanded versions of each + return [...sets.values()] + .map(plgl => { + if (!plgl) return undefined + const [patternList, globList] = plgl + const p = new Pattern(patternList, globList, this.#index) + p.#isAbsolute = this.#isAbsolute + p.#isUNC = this.#isUNC + p.#isDrive = this.#isDrive + return p + }) + .filter(p => p) as Pattern[] } glob(): string { - return this.globList[this.index] + return this.globList[this.#index] } globString(): string { return (this.#globString = this.#globString || - (this.index === 0 - ? this.globList - : this.globList.slice(this.index) - ).join('/')) + (this.#index === 0 + ? this.isAbsolute() + ? this.globList[0] + this.globList.slice(1).join('/') + : this.globList.join('/') + : this.globList.slice(this.#index).join('/'))) } hasMore(): boolean { - return this.length > this.index + 1 + return this.length > this.#index + 1 } rest(): Pattern | null { - return this.#rest !== undefined - ? this.#rest - : (this.#rest = this.hasMore() - ? new Pattern(this.patternList, this.globList, this.index + 1) - : null) + if (this.#rest !== undefined) return this.#rest + if (!this.hasMore()) return (this.#rest = null) + this.#rest = new Pattern( + this.patternList, + this.globList, + this.#index + 1 + ) + this.#rest.#isAbsolute = this.#isAbsolute + this.#rest.#isUNC = this.#isUNC + this.#rest.#isDrive = this.#isDrive + return this.#rest } // pattern like: //host/share/... // split = [ '', '', 'host', 'share', ... ] isUNC(pl = this.patternList): pl is UNCPatternList { - return ( - isWin && - this.index === 0 && - pl[0] === '' && - pl[1] === '' && - typeof pl[2] === 'string' && - !!pl[2] && - typeof pl[3] === 'string' && - !!pl[3] - ) + return this.#isUNC !== undefined + ? this.#isUNC + : (this.#isUNC = + isWin && + this.#index === 0 && + pl[0] === '' && + pl[1] === '' && + typeof pl[2] === 'string' && + !!pl[2] && + typeof pl[3] === 'string' && + !!pl[3]) } // pattern like C:/... @@ -142,43 +345,33 @@ export class Pattern { // in c: for *, but I don't know of a way to even figure out what that // cwd is without actually chdir'ing into it? isDrive(pl = this.patternList): pl is DrivePatternList { - return ( - isWin && - this.index === 0 && - this.length > 1 && - typeof pl[0] === 'string' && - /^[a-z]:$/i.test(pl[0]) - ) + return this.#isDrive !== undefined + ? this.#isDrive + : (this.#isDrive = + isWin && + this.#index === 0 && + this.length > 1 && + typeof pl[0] === 'string' && + /^[a-z]:$/i.test(pl[0])) } // pattern = '/' or '/...' or '/x/...' // split = ['', ''] or ['', ...] or ['', 'x', ...] // Drive and UNC both considered absolute on windows isAbsolute(pl = this.patternList): pl is AbsolutePatternList { - return ( - (pl[0] === '' && this.length > 1) || - this.isDrive(pl) || - this.isUNC(pl) - ) + return this.#isAbsolute !== undefined + ? this.#isAbsolute + : (this.#isAbsolute = + (pl[0] === '' && pl.length > 1) || + this.isDrive(pl) || + this.isUNC(pl)) } // consume the root of the pattern, and return it root(): string { - if (this.index !== 0) { - throw new Error('should only check root on initial walk') - } - // //x/y/z -> ['', '', x, y, z] - // c:/x -> ['c:', x] - // /x -> ['', 'x'] - const pl = this.patternList - if (this.isUNC(pl)) { - this.index = 4 - return pl[0] + pl[1] + pl[2] + pl[3] - } else if (this.isDrive(pl) || this.isAbsolute(pl)) { - this.index = 1 - return pl[0] + '/' - } else { - return '' - } + const p = this.patternList[0] + return typeof p === 'string' && this.isAbsolute() && this.#index === 0 + ? p + : '' } } diff --git a/src/walker.ts b/src/walker.ts index 4a4c797c..bce8be35 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -6,6 +6,22 @@ // - [ ] iterator // - [ ] iteratorSync +// **/.. is really annoyingly slow, especially when repeated, because .. can't eliminate it. +// but!
/**/../ is equivalent to 
/..//**/ plus 
/.. or in other words:  
/**/./ plus 
/../
+//  so 
/**/../*/**/../ goes to: {
/../*/**/../, 
/**/*/**/../}
+//  which goes to: {
/../*/**/../, 
/*/**/**/../}
+//  {
/../*/**/../, 
/*/**/../} then do the second **/..
+//  {
/../*/**/, 
/../*/../, 
/*/../, 
/*/**/}
+//  {
/../*/**/, 
/../, 
/, 
/*/**/}
+//  reordering:
+//   1                     2                  3                4
+//  {
/../*/**/, 
/*/**/, 
/../, 
/}
+//
+//  When we walk 1, that'll end up walking over each child in 2 with **, and
+//  most of that pattern will be deduped out at some point, but we then can't
+//  rely on the Pattern objects being unique, I guess?
+
+import LRUCache from 'lru-cache'
 import { GLOBSTAR } from 'minimatch'
 import Minipass from 'minipass'
 import { Path } from 'path-scurry'
@@ -60,45 +76,25 @@ export type MatchStream =
  */
 export abstract class GlobUtil {
   path: Path
-  pattern: Pattern
+  patterns: Pattern[]
   opts: O
-  seen: Set
-  walked: Map
+  seen: Set = new Set()
+  hasWalkedCache: LRUCache = new LRUCache<
+    Path,
+    Pattern[]
+  >({
+    maxSize: 256,
+    sizeCalculation: v => v.length + 1,
+  })
 
   paused: boolean = false
   #onResume: (() => any)[] = []
 
-  constructor(
-    pattern: Pattern,
-    path: Path,
-    seen: Set | undefined,
-    walked: Map | undefined,
-    opts: O
-  )
-  constructor(
-    pattern: Pattern,
-    path: Path,
-    seen: Set | undefined,
-    walked: Map | undefined,
-    opts: O
-  ) {
-    const root = pattern.root()
-    if (root) {
-      this.path = path.resolve(root)
-    } else {
-      this.path = path
-    }
-    this.pattern = pattern
-    while (this.pattern.pattern() === '..') {
-      this.pattern.index++
-      this.path = this.path.parent || this.path
-    }
-    this.opts = {
-      absolute: !!root,
-      ...opts,
-    }
-    this.seen = seen || new Set()
-    this.walked = walked || new Map()
+  constructor(patterns: Pattern[], path: Path, opts: O)
+  constructor(patterns: Pattern[], path: Path, opts: O) {
+    this.patterns = patterns
+    this.path = path
+    this.opts = opts
   }
 
   // backpressure mechanism
@@ -118,25 +114,9 @@ export abstract class GlobUtil {
     else this.#onResume.push(fn)
   }
 
-  newWalks(target: Path, patterns: Pattern[]): Pattern[] {
-    const walked = this.walked.get(target)
-    if (!walked) {
-      this.walked.set(target, patterns)
-      return patterns
-    }
-    const todo: Pattern[] = []
-    for (const p of patterns) {
-      if (!walked.includes(p)) {
-        todo.push(p)
-        walked.push(p)
-      }
-    }
-    return todo
-  }
-
   // do the requisite realpath/stat checking, and return true/false
   // to say whether to include the match or filter it out.
-  async matchCheck(e: Path): Promise {
+  async matchCheck(e: Path, ifDir: boolean): Promise {
     let rpc: Path | undefined
     if (this.opts.realpath) {
       rpc = e.realpathCached()
@@ -150,34 +130,53 @@ export abstract class GlobUtil {
     if (e.isDirectory() && this.opts.nodir) {
       return undefined
     }
-    const needRealPath = this.opts.realpath && !rpc
+    const needRealPath = !rpc && this.opts.realpath
     const needStat = e.isUnknown()
     if (needRealPath && needStat) {
-      const r = await e.realpath().then(e => e && e.lstat())
-      if (!r || this.seen.has(r) || (e.isDirectory() && this.opts.nodir)) {
+      const r = await e.realpath().then(e => e?.lstat())
+      if (
+        !r ||
+        this.seen.has(r) ||
+        (!e.canReaddir() && ifDir) ||
+        (e.isDirectory() && this.opts.nodir)
+      ) {
         return undefined
       }
       return r
     } else if (needRealPath) {
       const r = await e.realpath()
-      if (!r || this.seen.has(r) || (e.isDirectory() && this.opts.nodir)) {
+      if (
+        !r ||
+        this.seen.has(r) ||
+        (!e.canReaddir() && ifDir) ||
+        (e.isDirectory() && this.opts.nodir)
+      ) {
         return undefined
       }
       return r
     } else if (needStat) {
       const r = await e.lstat()
-      if (!r || this.seen.has(r) || (r.isDirectory() && this.opts.nodir)) {
+      if (
+        !r ||
+        this.seen.has(r) ||
+        (!r.canReaddir() && ifDir) ||
+        (r.isDirectory() && this.opts.nodir)
+      ) {
         return undefined
       }
       return r
-    } else if (this.seen.has(e) || (e.isDirectory() && this.opts.nodir)) {
+    } else if (
+      this.seen.has(e) ||
+      (!e.canReaddir() && ifDir) ||
+      (e.isDirectory() && this.opts.nodir)
+    ) {
       return undefined
     } else {
       return e
     }
   }
 
-  matchCheckSync(e: Path): Path | undefined {
+  matchCheckSync(e: Path, ifDir: boolean): Path | undefined {
     let rpc: Path | undefined
     if (this.opts.realpath) {
       rpc = e.realpathCached()
@@ -191,27 +190,46 @@ export abstract class GlobUtil {
     if (e.isDirectory() && this.opts.nodir) {
       return undefined
     }
-    const needRealPath = this.opts.realpath && !rpc
+    const needRealPath = !rpc && this.opts.realpath
     const needStat = e.isUnknown()
     if (needRealPath && needStat) {
       const r = e.realpathSync()?.lstatSync()
-      if (!r || this.seen.has(r) || (e.isDirectory() && this.opts.nodir)) {
+      if (
+        !r ||
+        this.seen.has(r) ||
+        (!r.canReaddir() && ifDir) ||
+        (e.isDirectory() && this.opts.nodir)
+      ) {
         return undefined
       }
       return r
     } else if (needRealPath) {
       const r = e.realpathSync()
-      if (!r || this.seen.has(r) || (e.isDirectory() && this.opts.nodir)) {
+      if (
+        !r ||
+        this.seen.has(r) ||
+        (!r.canReaddir() && ifDir) ||
+        (e.isDirectory() && this.opts.nodir)
+      ) {
         return undefined
       }
       return r
     } else if (needStat) {
       const r = e.lstatSync()
-      if (!r || this.seen.has(r) || (r.isDirectory() && this.opts.nodir)) {
+      if (
+        !r ||
+        this.seen.has(r) ||
+        (!r.canReaddir() && ifDir) ||
+        (r.isDirectory() && this.opts.nodir)
+      ) {
         return undefined
       }
       return r
-    } else if (this.seen.has(e) || (e.isDirectory() && this.opts.nodir)) {
+    } else if (
+      this.seen.has(e) ||
+      (!e.canReaddir() && ifDir) ||
+      (e.isDirectory() && this.opts.nodir)
+    ) {
       return undefined
     } else {
       return e
@@ -221,7 +239,7 @@ export abstract class GlobUtil {
   abstract matchEmit(p: Result): void
   abstract matchEmit(p: string | Path): void
 
-  matchFinish(e: Path) {
+  matchFinish(e: Path, absolute: boolean) {
     this.seen.add(e)
     const mark = this.opts.mark && e.isDirectory() ? '/' : ''
     // ok, we have what we need!
@@ -229,112 +247,130 @@ export abstract class GlobUtil {
       this.matchEmit(e)
     } else if (this.opts.nodir && e.isDirectory()) {
       return
-    } else if (this.opts.absolute) {
+    } else if (this.opts.absolute || absolute) {
       this.matchEmit(e.fullpath() + mark)
     } else {
       this.matchEmit(e.relative() + mark)
     }
   }
 
-  async match(e: Path): Promise {
-    const p = await this.matchCheck(e)
-    if (p) this.matchFinish(p)
+  async match(e: Path, absolute: boolean, ifDir: boolean): Promise {
+    const p = await this.matchCheck(e, ifDir)
+    if (p) this.matchFinish(p, absolute)
   }
 
-  matchSync(e: Path): void {
-    const p = this.matchCheckSync(e)
-    if (p) this.matchFinish(p)
+  matchSync(e: Path, absolute: boolean, ifDir: boolean): void {
+    const p = this.matchCheckSync(e, ifDir)
+    if (p) this.matchFinish(p, absolute)
   }
 
-  // returns 0-2 length array of [path, isMatch, sub patterns][]
-  getActions(
+  hasWalked(target: Path, pattern: Pattern): boolean {
+    const cached = this.hasWalkedCache.get(target)
+    return !!cached?.includes(pattern)
+  }
+  storeWalked(target: Path, pattern: Pattern) {
+    const cached = this.hasWalkedCache.get(target)
+    if (!cached) this.hasWalkedCache.set(target, [pattern])
+    else if (!cached.includes(pattern)) cached.push(pattern)
+  }
+
+  processPatterns(
     target: Path,
     patterns: Pattern[]
-  ): [Path, boolean, Pattern[]][] {
-    const actions: [Path, boolean, Pattern[]][] = []
-    const parent = target.parent || target
-    const isGSWalkable = target.isDirectory()
-    const isWalkable = isGSWalkable || target.canReaddir()
-    const matchGS = !target.name.startsWith('.')
-    const parentWalkPatterns: Pattern[] = []
-    const targetWalkPatterns: Pattern[] = []
-    let isParentMatch = false
-    let isTargetMatch = false
-    for (const pattern of patterns) {
-      const p = pattern.pattern()
-      const rest = pattern.rest()
-      if (p === GLOBSTAR) {
-        if (!matchGS) continue
+  ): [Map, Map] {
+    const processingSet = new Set<[Path, Pattern]>(
+      patterns
+        .filter(p => !this.hasWalked(target, p))
+        .map(p => [target, p])
+    )
+
+    // found matches, path => [absolute, ifdir]
+    const matches = new Map()
+
+    // map of paths to the magic-starting subwalks they need to walk
+    // first item in patterns is the filter
+    const subwalks = new Map()
+
+    for (let [t, pattern] of processingSet) {
+      if (this.hasWalked(t, pattern)) continue
+      this.storeWalked(t, pattern)
+
+      // TODO: if (this.hasWalked(t, pattern)) continue
+      // TODO: update hasWalked to add the pattern to the list
+      // TODO: make hasWalked use an LRU
+      const root = pattern.root()
+      const absolute = pattern.isAbsolute()
+
+      // start absolute patterns at root
+      if (root) {
+        t = t.resolve(root)
+        const rest = pattern.rest()
         if (!rest) {
-          if (isGSWalkable) targetWalkPatterns.push(pattern)
-          isTargetMatch = true
+          matches.set(t, [true, false])
+          continue
         } else {
-          if (isGSWalkable) targetWalkPatterns.push(pattern, rest)
+          pattern = rest
         }
-      } else if (p === '..') {
-        if (!rest) isParentMatch = true
-        else parentWalkPatterns.push(rest)
-      } else if (p === '' || p === '.') {
-        if (!rest) isTargetMatch = true
-        else if (isWalkable) targetWalkPatterns.push(rest)
-      } else if (typeof p === 'string' && target.isNamed(p)) {
-        if (!rest) isTargetMatch = true
-        else if (isWalkable) targetWalkPatterns.push(rest)
-      } else if (p instanceof RegExp && p.test(target.name)) {
-        if (!rest) isTargetMatch = true
-        else if (isWalkable) targetWalkPatterns.push(rest)
       }
-    }
-    if (isParentMatch || parentWalkPatterns.length) {
-      actions.push([
-        parent,
-        isParentMatch,
-        this.newWalks(parent, parentWalkPatterns),
-      ])
-    }
-    if (isTargetMatch || targetWalkPatterns.length) {
-      actions.push([target, isTargetMatch, targetWalkPatterns])
-    }
-    return actions
-  }
 
-  walkCB(target: Path, patterns: Pattern[], cb: () => any) {
-    if (this.paused) {
-      this.onResume(() => this.walkCB(target, patterns, cb))
-      return
-    }
-    // don't readdir just to get a string match, wasteful
-    if (patterns.length === 1) {
+      // walk down strings
       let p: MMPattern
       let rest: Pattern | null
+      let changed = false
       while (
-        typeof (p = patterns[0].pattern()) === 'string' &&
-        (rest = patterns[0].rest())
+        typeof (p = pattern.pattern()) === 'string' &&
+        (rest = pattern.rest())
       ) {
-        target = target.child(p)
-        patterns[0] = rest
+        t = t.resolve(p)
+        pattern = rest
+        changed = true
       }
-      // if the last item is ALSO a string, then just match it.
-      p = patterns[0].pattern()
-      if (typeof p === 'string' && !patterns[0].hasMore()) {
-        this.match(target.child(p)).then(cb)
-        return
+      rest = pattern.rest()
+      if (changed) {
+        if (this.hasWalked(t, pattern)) continue
+        this.storeWalked(t, pattern)
       }
-    }
 
-    // skip the readdir if we can't read it, eg if it's a full
-    // path to a file or something.
-    target.readdirCB((_, entries) => {
-      let tasks = 1
-      const next = () => {
-        if (--tasks <= 0) cb()
-      }
-      for (const e of entries) {
-        tasks++
-        this.walkCB2(e, patterns, next)
+      // now we have either a final string, or a pattern starting with magic,
+      // mounted on t.
+      if (typeof p === 'string') {
+        // must be final entry
+        const ifDir = p === '..' || p === '' || p === '.'
+        matches.set(t.resolve(p), [absolute, ifDir])
+        continue
+      } else if (p === GLOBSTAR) {
+        // if no rest, match and subwalk pattern
+        // if rest, process rest and subwalk pattern
+        const subs = subwalks.get(t)
+        if (!subs) {
+          subwalks.set(t, [pattern])
+        } else {
+          subs.push(pattern)
+        }
+        if (!rest) {
+          matches.set(t, [absolute, false])
+        } else if (!this.hasWalked(t, rest)) {
+          processingSet.add([t, rest])
+        }
+      } else if (p instanceof RegExp) {
+        const subs = subwalks.get(t)
+        if (!subs) {
+          subwalks.set(t, [pattern])
+        } else {
+          subs.push(pattern)
+        }
       }
-      next()
-    }, true)
+    }
+    return [subwalks, matches]
+  }
+
+  walkCB(target: Path, patterns: Pattern[], cb: () => any) {
+    this.hasWalkedCache.clear()
+    if (this.paused) {
+      this.onResume(() => this.walkCB(target, patterns, cb))
+      return
+    }
+    this.walkCB2(target, patterns, cb)
   }
 
   walkCB2(target: Path, patterns: Pattern[], cb: () => any) {
@@ -342,90 +378,188 @@ export abstract class GlobUtil {
       this.onResume(() => this.walkCB2(target, patterns, cb))
       return
     }
-    const actions = this.getActions(
-      target,
-      this.newWalks(target, patterns)
-    )
+    const [subwalks, matches] = this.processPatterns(target, patterns)
+
+    // done processing.  all of the above is sync, can be abstracted out.
+    // subwalks is a map of paths to the entry filters they need
+    // matches is a map of paths to [absolute, ifDir] tuples.
     let tasks = 1
-    const doneTask = () => {
+    const next = () => {
       if (--tasks === 0) cb()
     }
-    for (const [path, isMatch, patterns] of actions) {
-      if (isMatch && !this.seen.has(path)) {
-        tasks++
-        this.match(path).then(doneTask)
+
+    for (const [m, [absolute, ifDir]] of matches.entries()) {
+      tasks++
+      this.match(m, absolute, ifDir).then(() => next())
+    }
+
+    for (const [t, patterns] of subwalks.entries()) {
+      // if we can't read it, no sense trying
+      if (!t.canReaddir()) continue
+      // if they're all globstar, and it's a symlink, skip it.
+      if (
+        t.isSymbolicLink() &&
+        !patterns.some(p => p.pattern() instanceof RegExp)
+      ) {
+        continue
       }
-      if (patterns.length) {
-        tasks++
-        this.walkCB(path, patterns, doneTask)
+
+      tasks++
+      const childrenCached = t.readdirCached()
+      if (t.calledReaddir()) this.walkCB3(childrenCached, patterns, next)
+      else {
+        t.readdirCB(
+          (_, entries) => this.walkCB3(entries, patterns, next),
+          true
+        )
       }
     }
-    doneTask()
+
+    next()
   }
 
-  walkCBSync(target: Path, patterns: Pattern[], cb: () => any) {
-    if (this.paused) {
-      this.onResume(() => this.walkCBSync(target, patterns, cb))
-      return
-    }
-    // don't readdir just to get a string match, wasteful
-    if (patterns.length === 1) {
-      let p: MMPattern
-      let rest: Pattern | null
-      while (
-        typeof (p = patterns[0].pattern()) === 'string' &&
-        (rest = patterns[0].rest())
-      ) {
-        target = target.child(p)
-        patterns[0] = rest
-      }
-      // if the last item is ALSO a string, then just match it.
-      p = patterns[0].pattern()
-      if (typeof p === 'string' && !patterns[0].hasMore()) {
-        this.matchSync(target.child(p))
-        cb()
-        return
+  filterEntries(
+    entries: Path[],
+    patterns: Pattern[]
+  ): [Map, Map] {
+    const subwalks = new Map()
+    const matches = new Map()
+    for (const e of entries) {
+      for (const pattern of patterns) {
+        const absolute = pattern.isAbsolute()
+        const p = pattern.pattern()
+        const rest = pattern.rest()
+        let doSub: Pattern | undefined = undefined
+        if (p === GLOBSTAR) {
+          if (e.name.startsWith('.')) continue
+          if (!rest) {
+            matches.set(e, [absolute, false])
+          } else if (e.isDirectory()) {
+            doSub = pattern
+          }
+        } else if (p instanceof RegExp) {
+          if (!p.test(e.name)) continue
+          if (!rest) {
+            matches.set(e, [absolute, false])
+          } else {
+            doSub = rest
+          }
+        } else {
+          // should never happen?
+          if (!e.isNamed(p)) continue
+          if (!rest) {
+            matches.set(e, [absolute, false])
+          } else {
+            doSub = rest
+          }
+        }
+        if (doSub && !this.hasWalked(e, doSub)) {
+          const subs = subwalks.get(e)
+          if (!subs) {
+            subwalks.set(e, [doSub])
+          } else {
+            subs.push(doSub)
+          }
+        }
       }
     }
+    return [subwalks, matches]
+  }
+
+  walkCB3(entries: Path[], patterns: Pattern[], cb: () => any) {
+    const [subwalks, matches] = this.filterEntries(entries, patterns)
 
-    // skip the readdir if we can't read it, eg if it's a full
-    // path to a file or something.
-    const entries = target.readdirSync()
     let tasks = 1
     const next = () => {
-      if (--tasks <= 0) cb()
+      if (--tasks === 0) cb()
     }
-    for (const e of entries) {
+
+    for (const [m, [absolute, ifDir]] of matches.entries()) {
       tasks++
-      this.walkCB2Sync(e, patterns, next)
+      this.match(m, absolute, ifDir).then(() => next())
     }
+    for (const [target, patterns] of subwalks.entries()) {
+      tasks++
+      this.walkCB2(target, patterns, next)
+    }
+
     next()
   }
+
+  walkCBSync(target: Path, patterns: Pattern[], cb: () => any) {
+    if (this.paused) {
+      this.onResume(() => this.walkCBSync(target, patterns, cb))
+      return
+    }
+    if (target.isUnknown()) {
+      target.lstat().then(t => {
+        if (!t) cb()
+        else this.walkCB2Sync(t, patterns, cb)
+      })
+    } else {
+      this.walkCB2Sync(target, patterns, cb)
+    }
+  }
+
   walkCB2Sync(target: Path, patterns: Pattern[], cb: () => any) {
     if (this.paused) {
       this.onResume(() => this.walkCB2(target, patterns, cb))
       return
     }
-    const actions = this.getActions(
-      target,
-      this.newWalks(target, patterns)
-    )
+    const [subwalks, matches] = this.processPatterns(target, patterns)
+
+    // done processing.  all of the above is sync, can be abstracted out.
+    // subwalks is a map of paths to the entry filters they need
+    // matches is a map of paths to [absolute, ifDir] tuples.
     let tasks = 1
-    const doneTask = () => {
+    const next = () => {
       if (--tasks === 0) cb()
     }
-    for (const [path, isMatch, patterns] of actions) {
-      if (isMatch && !this.seen.has(path)) {
-        tasks++
-        this.matchSync(path)
-        doneTask()
-      }
-      if (patterns.length) {
-        tasks++
-        this.walkCBSync(path, patterns, doneTask)
+
+    for (const [m, [absolute, ifDir]] of matches.entries()) {
+      tasks++
+      this.matchSync(m, absolute, ifDir)
+    }
+
+    for (const [t, patterns] of subwalks.entries()) {
+      // if we can't read it, no sense trying
+      if (!t.canReaddir()) continue
+      // if they're all globstar, and it's a symlink, skip it.
+      if (
+        t.isSymbolicLink() &&
+        !patterns.some(p => p.pattern() instanceof RegExp)
+      ) {
+        continue
       }
+
+      tasks++
+      const childrenCached = t.readdirCached()
+      if (t.calledReaddir())
+        this.walkCB3Sync(childrenCached, patterns, next)
+      else this.walkCB3Sync(t.readdirSync(), patterns, next)
     }
-    doneTask()
+
+    next()
+  }
+
+  walkCB3Sync(entries: Path[], patterns: Pattern[], cb: () => any) {
+    const [subwalks, matches] = this.filterEntries(entries, patterns)
+
+    let tasks = 1
+    const next = () => {
+      if (--tasks === 0) cb()
+    }
+
+    for (const [m, [absolute, ifDir]] of matches.entries()) {
+      tasks++
+      this.matchSync(m, absolute, ifDir)
+    }
+    for (const [target, patterns] of subwalks.entries()) {
+      tasks++
+      this.walkCB2Sync(target, patterns, next)
+    }
+
+    next()
   }
 }
 
@@ -440,14 +574,8 @@ export class GlobWalker<
     ? Set
     : Set
 
-  constructor(
-    pattern: Pattern,
-    path: Path,
-    seen: Set | undefined,
-    walked: Map | undefined,
-    opts: O
-  ) {
-    super(pattern, path, seen, walked, opts)
+  constructor(patterns: Pattern[], path: Path, opts: O) {
+    super(patterns, path, opts)
     this.matches = new Set() as Matches
   }
 
@@ -457,20 +585,19 @@ export class GlobWalker<
   }
 
   async walk(): Promise> {
-    const target = this.path
-    const patterns = [this.pattern]
-    if (target.isUnknown()) await target.lstat()
-    return new Promise(res => {
-      this.walkCB(target, patterns, () => res(this.matches))
-    })
+    const t = this.path.isUnknown() ? await this.path.lstat() : this.path
+    if (t) {
+      await new Promise(res => {
+        this.walkCB(t, this.patterns, () => res(this.matches))
+      })
+    }
+    return this.matches
   }
 
   walkSync(): Matches {
-    const target = this.path
-    const patterns = [this.pattern]
-    if (target.isUnknown()) target.lstatSync()
+    const t = this.path.isUnknown() ? this.path.lstatSync() : this.path
     // nothing for the callback to do, because this never pauses
-    this.walkCBSync(target, patterns, () => {})
+    if (t) this.walkCBSync(t, this.patterns, () => {})
     return this.matches
   }
 }
@@ -486,14 +613,8 @@ export class GlobStream<
     ? Minipass
     : Minipass
 
-  constructor(
-    pattern: Pattern,
-    path: Path,
-    seen: Set | undefined,
-    walked: Map | undefined,
-    opts: O
-  ) {
-    super(pattern, path, seen, walked, opts)
+  constructor(patterns: Pattern[], path: Path, opts: O) {
+    super(patterns, path, opts)
     this.results = new Minipass({ objectMode: true }) as MatchStream
     this.results.on('drain', () => this.resume())
   }
@@ -507,24 +628,27 @@ export class GlobStream<
 
   stream(): MatchStream {
     const target = this.path
-    const patterns = [this.pattern]
     if (target.isUnknown()) {
-      target
-        .lstat()
-        .then(() =>
-          this.walkCB(target, patterns, () => this.results.end())
-        )
+      target.lstat().then(e => {
+        if (e) {
+          this.walkCB(target, this.patterns, () => this.results.end())
+        } else {
+          this.results.end()
+        }
+      })
     } else {
-      this.walkCB(target, patterns, () => this.results.end())
+      this.walkCB(target, this.patterns, () => this.results.end())
     }
     return this.results
   }
 
   streamSync(): MatchStream {
-    const target = this.path
-    const patterns = [this.pattern]
-    if (target.isUnknown()) target.lstatSync()
-    this.walkCBSync(target, patterns, () => this.results.end())
+    const target = this.path.isUnknown()
+      ? this.path.lstatSync()
+      : this.path
+    if (target) {
+      this.walkCBSync(target, this.patterns, () => this.results.end())
+    }
     return this.results
   }
 }

From 19ff6ade2d0b3c9a92a01b1492639309d5b0b14e Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 14 Feb 2023 20:21:54 -0800
Subject: [PATCH 075/163] v9 changelog updates

---
 benchmark.sh |  4 ++--
 changelog.md | 29 ++++++++++++++---------------
 2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/benchmark.sh b/benchmark.sh
index 1ab8963e..23aecdee 100644
--- a/benchmark.sh
+++ b/benchmark.sh
@@ -8,7 +8,7 @@ patterns=(
   # cases that I found while working on the rewrite of this library.
   './**/?/**/?/**/?/**/?/**/*.txt'
   './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
-  './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt'
+  # './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt'
   './{**/?{/**/?{/**/?{/**/?,,,,},,,,},,,,},,,}/**/*.txt'
   './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,,,,},,,,},,,,},,,,},,,,}/*.txt'
   './*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
@@ -22,7 +22,7 @@ patterns=(
   './**/*/**/*/**/*/**/*/**/*.txt'
   './**/0/**/0/**/0/**/0/**/*.txt'
   './**/0/**/0/**/*.txt'
-  '**/*.txt',
+  '**/*.txt'
   # './**/*.txt'
   './**/**/**/**/**/**/**/**/*.txt'
   '**/*/*.txt'
diff --git a/changelog.md b/changelog.md
index c9e05b7d..00916443 100644
--- a/changelog.md
+++ b/changelog.md
@@ -17,33 +17,32 @@ This is a full rewrite.
 - More efficient handling for absolute patterns. (That is,
   patterns that start with `/` on any platform, or start with a
   drive letter on Windows.)
-- Removed all stat calls, in favor of using `withFileTypes:true`
+- Removed nearly all stat calls, in favor of using `withFileTypes:true`
   with `fs.readdir()`.
-- Consolidated all caching to a single object that only caches
-  directory entries and `readdir` errors. We can actually get
-  everything we need from just that.
+- Replaced almost all caching with a
+  [PathScurry](http://npm.im/path-scurry) base implementation.
 - Removed EventEmitter behavior from exported `Glob` class.
 - Consolidated sync and async `Glob` class behavior into a single
-  class with `process()` and `processSync()` methods.
+  class with `walk()`, `walkSync()`, `stream()`, and
+  `streamSync()` methods.
 - Removed `silent` and `strict` options. Any readdir errors are
   simply treated as "the directory could not be read", and it is
   treated as a normal file entry instead, like shells do.
 - Removed `fs` option. This module only operates on the real
-  filesystem. (Could bring back if there's demand for it.)
+  filesystem. (Could bring back if there's demand for it, but
+  it'd be an update to PathScurry, not Glob.)
 - Only support node 16 and higher.
-- When `{nonull:true}` is set, and an `ignore` pattern causes all
-  entries to be ignored, then the pattern is returned, as it
-  would be if no matches were found. This _may_ result in the
-  surprising situation where a pattern like `x/y/z` is returned
-  even, even though the ignore value like `x/**` would have
-  excluded it. However, _not_ returning anything when
-  `nonull:true` is set, is arguably a worse contract violation.
+- `nonull:true` is no longer supported.
+- `withFileTypes:true` option added, to get `Path` objects (like
+  a `Dirent`, but can also do a lot more).
 - Patterns starting with drive letters on Windows are now
   properly treated as absolute paths, and the drive letter in an
   absolute `{cwd}` option will be used as the root of patterns
   that start with `/`.
-- Patterns with multiple slashes will behave the same as the
-  Bash 5 shell.
+- `nounique:true` is no longer supported.  Result sets are always
+  unique.
+- `nosort:true` is no longer supported.  Result sets are never
+  sorted.
 
 ## 8.1
 

From 3ecafb08a40183a7470b8529df9bfc561dc104ec Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sat, 18 Feb 2023 13:37:18 -0800
Subject: [PATCH 076/163] savepoint, depending on some new minimatch features

---
 benchmark.sh      |  11 +++-
 package-lock.json |   2 +-
 package.json      |   2 +-
 prof.sh           |   4 +-
 src/glob.ts       |  11 ++--
 src/pattern.ts    | 147 ++--------------------------------------------
 src/walker.ts     |  65 +++++++++-----------
 7 files changed, 53 insertions(+), 189 deletions(-)

diff --git a/benchmark.sh b/benchmark.sh
index 23aecdee..6855ba7a 100644
--- a/benchmark.sh
+++ b/benchmark.sh
@@ -6,12 +6,17 @@ patterns=(
   # some of these aren't particularly "representative" of real-world
   # glob patterns, but they're here to highlight pathological perf
   # cases that I found while working on the rewrite of this library.
-  './**/?/**/?/**/?/**/?/**/*.txt'
-  './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
-  # './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt'
+  '**'
+  '**/*.txt'
+  '**/!(0|9).txt'
+  '{**/*.txt,**/?/**/*.txt,**/?/**/?/**/*.txt,**/?/**/?/**/?/**/*.txt,**/?/**/?/**/?/**/?/**/*.txt}'
   './{**/?{/**/?{/**/?{/**/?,,,,},,,,},,,,},,,}/**/*.txt'
+
   './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,,,,},,,,},,,,},,,,},,,,}/*.txt'
+  './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
   './*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
+  './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt'
+  './**/?/**/?/**/?/**/?/**/*.txt'
   './**/0/**/../[01]/**/0/../**/0/*.txt'
   '**/????/????/????/????/*.txt'
   './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt'
diff --git a/package-lock.json b/package-lock.json
index 33609bfd..eb9dbb4b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "minimatch": "6.2",
+        "minimatch": "^6.2.0",
         "minipass": "^4.0.3",
         "path-scurry": "^1.4.0"
       },
diff --git a/package.json b/package.json
index a39bef3a..b3988249 100644
--- a/package.json
+++ b/package.json
@@ -59,7 +59,7 @@
   },
   "dependencies": {
     "fs.realpath": "^1.0.0",
-    "minimatch": "6.2",
+    "minimatch": "^6.2.0",
     "minipass": "^4.0.3",
     "path-scurry": "^1.4.0"
   },
diff --git a/prof.sh b/prof.sh
index 5e96e758..78ce3fa9 100644
--- a/prof.sh
+++ b/prof.sh
@@ -12,8 +12,8 @@ export __GLOB_PROFILE__=1
 
 cat > "profscript.mjs" < console.log(m.length))
+console.log(glob.sync("./fixture/*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt").length)
+glob("./fixture/*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt").then(m => console.log(m.length))
 MJS
 
 node --prof profscript.mjs &> profile.out
diff --git a/src/glob.ts b/src/glob.ts
index 21fa259a..731f4230 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -181,13 +181,14 @@ export class Glob {
       ...opts,
       nonegate: true,
       nocomment: true,
-      preserveMultipleSlashes: true,
       nocaseMagicOnly: true,
     }
 
+    // console.error('glob pattern arg', this.pattern)
     const mms = this.pattern.map(p => new Minimatch(p, mmo))
     const [matchSet, globSet, globParts] = mms.reduce(
       (set: [MatchSet, GlobSet, GlobParts], m) => {
+        // console.error('globparts', m.globParts)
         set[0].push(...m.set)
         set[1].push(...m.globSet)
         set[2].push(...m.globParts)
@@ -195,10 +196,10 @@ export class Glob {
       },
       [[], [], []]
     )
-    this.patterns = matchSet
-      .map((set, i) => new Pattern(set, globParts[i], 0))
-      .map(p => p.expandGlobstarDotDot())
-      .reduce((set: Pattern[], p) => set.concat(p), [])
+    this.patterns = matchSet.map((set, i) => {
+      // console.error('globParts', globParts[i])
+      return new Pattern(set, globParts[i], 0)
+    })
     this.matchSet = matchSet
     this.globSet = globSet
     this.globParts = globParts
diff --git a/src/pattern.ts b/src/pattern.ts
index 8a629bfc..c8973b7d 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -75,6 +75,8 @@ export class Pattern {
     if (
       this.patternList[this.#index] !== GLOBSTAR &&
       this.patternList[this.#index] !== '..' &&
+      this.patternList[this.#index] !== '.' &&
+      this.patternList[this.#index] !== '' &&
       this.patternList[this.#index + 1] === '..' &&
       this.length > this.#index + 2
     ) {
@@ -87,10 +89,10 @@ export class Pattern {
     // It won't cause any incorrect behavior on a cache miss, but it may
     // adversely affect performance in really weird cases, like lots of
     // **/.. patterns and such.
-    const key = cacheKey(index, patternList)
-    const cached = cache.get(key)
-    if (cached) return cached
-    cache.set(key, this)
+    // const key = cacheKey(index, patternList)
+    // const cached = cache.get(key)
+    // if (cached) return cached
+    // cache.set(key, this)
 
     // normalize root entries of absolute patterns on initial creation.
     if (this.#index === 0) {
@@ -154,143 +156,6 @@ export class Pattern {
     return this.patternList[this.#index] instanceof RegExp
   }
 
-  // This has to be ALL THE WAY THROUGH, and done early
-  expandGlobstarDotDot(): Pattern[] {
-    const sets: Map = new Map([
-      [this.globList.join('/'), [this.patternList, this.globList]],
-    ])
-
-    let didSomething = false
-    let keepGoing = false
-    do {
-      keepGoing = false
-      for (const [globString, [patternList, globList]] of sets.entries()) {
-        // only expand up from the current index, for safety.
-        let gs: number = this.#index
-        while (-1 !== (gs = patternList.indexOf(GLOBSTAR, gs + 1))) {
-          const next = patternList[gs + 1]
-          if (next !== '..') {
-            continue
-          }
-
-          // ok, found one
-          // expand it, and replace plgl
-          sets.delete(globString)
-          didSomething = true
-          keepGoing = true
-
-          const headGL = gs === 0 ? [] : globList.slice(0, gs)
-          const headPL = gs === 0 ? [] : patternList.slice(0, gs)
-          const restGL = globList.slice(gs + 2)
-          const restPL = patternList.slice(gs + 2)
-          const dotRestGL = restGL.length ? restGL : ['.']
-          const dotRestPL = restPL.length ? restPL : ['.']
-
-          sets.set([...headGL, '**', ...dotRestGL].join('/'), [
-            [...headPL, GLOBSTAR, ...dotRestPL] as PatternList,
-            [...headGL, '**', ...dotRestGL] as GlobList,
-          ])
-          sets.set([...headGL, '..', ...restGL].join('/'), [
-            [...headPL, '..', ...restPL] as PatternList,
-            [...headGL, '..', ...restGL] as GlobList,
-          ])
-          break
-        }
-      }
-
-      for (const [globString, [patternList, globList]] of sets.entries()) {
-        let pl: PatternList = patternList
-        let gl: GlobList = globList
-        let dd: number = this.#index - 1
-        while (-1 !== (dd = patternList.indexOf('..', dd + 1))) {
-          if (dd <= this.#index) {
-            break
-          }
-          const prev = patternList[dd - 1]
-          if (prev && prev !== GLOBSTAR && prev !== '.') {
-            didSomething = true
-            keepGoing = true
-            sets.delete(globString)
-            pl = [
-              ...patternList.slice(0, dd - 1),
-              ...patternList.slice(dd + 1),
-            ] as PatternList
-            gl = [
-              ...globList.slice(0, dd - 1),
-              ...globList.slice(dd + 1),
-            ] as GlobList
-            sets.set(gl.join('/'), [pl, gl])
-            break
-          }
-        }
-      }
-      // **/*/ -> */**/
-      for (const [globString, [patternList, globList]] of sets.entries()) {
-        let didSomething = false
-        for (let i = 0; i < globList.length - 2; i++) {
-          if (patternList[i] === GLOBSTAR) {
-            let j = i
-            while (j < patternList.length - 1 && globList[j + 1] === '*') {
-              j++
-            }
-            if (i !== j) {
-              didSomething = true
-              patternList[i] = patternList[j]
-              patternList[j] = GLOBSTAR
-              globList[i] = '*'
-              globList[j] = '**'
-            }
-          }
-        }
-        if (didSomething) {
-          keepGoing = true
-          sets.delete(globString)
-          sets.set(globList.join('/'), [patternList, globList])
-        }
-      }
-      // **/** => **
-      for (const [globString, [patternList, globList]] of sets.entries()) {
-        let didSomething = false
-        for (let i = 0; i < globList.length - 2; i++) {
-          if (patternList[i] === GLOBSTAR) {
-            let j = i
-            while (
-              j < patternList.length - 1 &&
-              patternList[j + 1] === GLOBSTAR
-            ) {
-              j++
-            }
-            if (i !== j) {
-              didSomething = true
-              patternList.splice(i, j - i)
-              globList.splice(i, j - i)
-            }
-          }
-        }
-        if (didSomething) {
-          keepGoing = true
-          sets.delete(globString)
-          sets.set(globList.join('/'), [patternList, globList])
-        }
-      }
-    } while (keepGoing)
-
-    if (!didSomething) return [this]
-
-    // now sets is the fully expanded versions of each
-    return [...sets.values()]
-      .map(plgl => {
-        if (!plgl) return undefined
-        const [patternList, globList] = plgl
-        const p = new Pattern(patternList, globList, this.#index)
-        p.#isAbsolute = this.#isAbsolute
-        p.#isUNC = this.#isUNC
-        p.#isDrive = this.#isDrive
-        return p
-      })
-      .filter(p => p) as Pattern[]
-  }
-
   glob(): string {
     return this.globList[this.#index]
   }
diff --git a/src/walker.ts b/src/walker.ts
index bce8be35..6b37d343 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -21,7 +21,7 @@
 //  most of that pattern will be deduped out at some point, but we then can't
 //  rely on the Pattern objects being unique, I guess?
 
-import LRUCache from 'lru-cache'
+// import LRUCache from 'lru-cache'
 import { GLOBSTAR } from 'minimatch'
 import Minipass from 'minipass'
 import { Path } from 'path-scurry'
@@ -79,14 +79,6 @@ export abstract class GlobUtil {
   patterns: Pattern[]
   opts: O
   seen: Set = new Set()
-  hasWalkedCache: LRUCache = new LRUCache<
-    Path,
-    Pattern[]
-  >({
-    maxSize: 256,
-    sizeCalculation: v => v.length + 1,
-  })
-
   paused: boolean = false
   #onResume: (() => any)[] = []
 
@@ -264,26 +256,28 @@ export abstract class GlobUtil {
     if (p) this.matchFinish(p, absolute)
   }
 
-  hasWalked(target: Path, pattern: Pattern): boolean {
-    const cached = this.hasWalkedCache.get(target)
-    return !!cached?.includes(pattern)
-  }
-  storeWalked(target: Path, pattern: Pattern) {
-    const cached = this.hasWalkedCache.get(target)
-    if (!cached) this.hasWalkedCache.set(target, [pattern])
-    else if (!cached.includes(pattern)) cached.push(pattern)
-  }
-
+  // TODO: this function is the hottest path here,
+  // need to optimize this.  Using a double-Map might
+  // not be the best idea. Maybe could get away with 2 arrays?
   processPatterns(
     target: Path,
     patterns: Pattern[]
   ): [Map, Map] {
     const processingSet = new Set<[Path, Pattern]>(
       patterns
-        .filter(p => !this.hasWalked(target, p))
+        // .filter(p => !this.hasWalked(target, p))
         .map(p => [target, p])
     )
 
+    const hasWalkedCache = new Map>()
+    const hasWalked = (target: Path, pattern: Pattern) =>
+      hasWalkedCache.get(target)?.has(pattern.globString())
+    const storeWalked = (target: Path, pattern: Pattern) => {
+      const cached = hasWalkedCache.get(target)
+      if (cached) cached.add(pattern.globString())
+      else hasWalkedCache.set(target, new Set([pattern.globString()]))
+    }
+
     // found matches, path => [absolute, ifdir]
     const matches = new Map()
 
@@ -292,12 +286,9 @@ export abstract class GlobUtil {
     const subwalks = new Map()
 
     for (let [t, pattern] of processingSet) {
-      if (this.hasWalked(t, pattern)) continue
-      this.storeWalked(t, pattern)
+      if (hasWalked(t, pattern)) continue
+      storeWalked(t, pattern)
 
-      // TODO: if (this.hasWalked(t, pattern)) continue
-      // TODO: update hasWalked to add the pattern to the list
-      // TODO: make hasWalked use an LRU
       const root = pattern.root()
       const absolute = pattern.isAbsolute()
 
@@ -327,8 +318,8 @@ export abstract class GlobUtil {
       }
       rest = pattern.rest()
       if (changed) {
-        if (this.hasWalked(t, pattern)) continue
-        this.storeWalked(t, pattern)
+        if (hasWalked(t, pattern)) continue
+        storeWalked(t, pattern)
       }
 
       // now we have either a final string, or a pattern starting with magic,
@@ -349,8 +340,8 @@ export abstract class GlobUtil {
         }
         if (!rest) {
           matches.set(t, [absolute, false])
-        } else if (!this.hasWalked(t, rest)) {
-          processingSet.add([t, rest])
+        } else {
+          if (!hasWalked(t, rest)) processingSet.add([t, rest])
         }
       } else if (p instanceof RegExp) {
         const subs = subwalks.get(t)
@@ -365,7 +356,6 @@ export abstract class GlobUtil {
   }
 
   walkCB(target: Path, patterns: Pattern[], cb: () => any) {
-    this.hasWalkedCache.clear()
     if (this.paused) {
       this.onResume(() => this.walkCB(target, patterns, cb))
       return
@@ -395,7 +385,10 @@ export abstract class GlobUtil {
 
     for (const [t, patterns] of subwalks.entries()) {
       // if we can't read it, no sense trying
-      if (!t.canReaddir()) continue
+      if (!t.canReaddir()) {
+        continue
+      }
+
       // if they're all globstar, and it's a symlink, skip it.
       if (
         t.isSymbolicLink() &&
@@ -434,7 +427,8 @@ export abstract class GlobUtil {
           if (e.name.startsWith('.')) continue
           if (!rest) {
             matches.set(e, [absolute, false])
-          } else if (e.isDirectory()) {
+          }
+          if (e.isDirectory()) {
             doSub = pattern
           }
         } else if (p instanceof RegExp) {
@@ -453,7 +447,7 @@ export abstract class GlobUtil {
             doSub = rest
           }
         }
-        if (doSub && !this.hasWalked(e, doSub)) {
+        if (doSub /* && !this.hasWalked(e, doSub) */) {
           const subs = subwalks.get(e)
           if (!subs) {
             subwalks.set(e, [doSub])
@@ -617,13 +611,12 @@ export class GlobStream<
     super(patterns, path, opts)
     this.results = new Minipass({ objectMode: true }) as MatchStream
     this.results.on('drain', () => this.resume())
+    this.results.on('resume', () => this.resume())
   }
 
   matchEmit(e: Result): void
   matchEmit(e: Path | string): void {
-    if (!this.results.write(e)) {
-      this.pause()
-    }
+    if (!this.results.write(e)) this.pause()
   }
 
   stream(): MatchStream {

From 870c8e745b96c09c8e7d28f9a14186eefbb3187b Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sat, 18 Feb 2023 16:53:46 -0800
Subject: [PATCH 077/163] abstract out the pattern processing and entry
 filtering

this made perf a little worse, but I think it might be a good step towards
being able to make it faster
---
 src/pattern.ts   |   2 +-
 src/processor.ts | 205 +++++++++++++++++++++++++++++++++++++
 src/walker.ts    | 261 +++++++++++++++++++++--------------------------
 3 files changed, 322 insertions(+), 146 deletions(-)
 create mode 100644 src/processor.ts

diff --git a/src/pattern.ts b/src/pattern.ts
index c8973b7d..0c583e8e 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -152,7 +152,7 @@ export class Pattern {
   isGlobstarDotDot(): boolean {
     return this.isGlobstar() && this.globList[this.#index + 1] === '..'
   }
-  isMagic(): boolean {
+  isRegExp(): boolean {
     return this.patternList[this.#index] instanceof RegExp
   }
 
diff --git a/src/processor.ts b/src/processor.ts
new file mode 100644
index 00000000..70671112
--- /dev/null
+++ b/src/processor.ts
@@ -0,0 +1,205 @@
+// synchronous utility for filtering entries and calculating subwalks
+
+import { GLOBSTAR } from 'minimatch'
+import { Path } from 'path-scurry'
+import { MMPattern, Pattern } from './pattern.js'
+
+class HasWalkedCache {
+  store: Map>
+  constructor(store: Map> = new Map()) {
+    this.store = store
+  }
+  copy() {
+    return new HasWalkedCache(new Map(this.store))
+  }
+  hasWalked(target: Path, pattern: Pattern) {
+    return this.store.get(target)?.has(pattern.globString())
+  }
+  storeWalked(target: Path, pattern: Pattern) {
+    const cached = this.store.get(target)
+    if (cached) cached.add(pattern.globString())
+    else this.store.set(target, new Set([pattern.globString()]))
+  }
+}
+
+class MatchRecord {
+  store: Map = new Map()
+  add(target: Path, absolute: boolean, ifDir: boolean) {
+    const n = (absolute ? 2 : 0) | (ifDir ? 1 : 0)
+    const current = this.store.get(target) || 0
+    this.store.set(target, n & current)
+  }
+  // match, absolute, ifdir
+  entries(): [Path, boolean, boolean][] {
+    return [...this.store.entries()].map(([path, n]) => [
+      path,
+      !!(n & 2),
+      !!(n & 1),
+    ])
+  }
+}
+
+class SubWalks {
+  store: Map = new Map()
+  patterns: Map = new Map()
+  add(target: Path, pattern: Pattern) {
+    if (!target.canReaddir()) return
+    if (target.isSymbolicLink() && pattern.isGlobstar()) return
+    const subs = this.store.get(target)
+    if (subs) subs.push(pattern)
+    else this.store.set(target, [pattern])
+  }
+  get(target: Path): Pattern[] {
+    return this.store.get(target) || []
+  }
+  entries(): [Path, Pattern[]][] {
+    return this.keys().map(k => [k, this.store.get(k) as Pattern[]])
+  }
+  keys(): Path[] {
+    return [...this.store.keys()].filter(t => {
+      if (!t.canReaddir()) return false
+      if (
+        t.isSymbolicLink() &&
+        !this.store.get(t)?.some(p => p.isRegExp())
+      ) {
+        return false
+      }
+      return true
+    })
+  }
+}
+
+export class Processor {
+  hasWalked: HasWalkedCache
+  matches = new MatchRecord()
+  subwalks = new SubWalks()
+  patterns?: Pattern[]
+
+  constructor(hasWalked?: HasWalkedCache) {
+    this.hasWalked = hasWalked ? hasWalked.copy() : new HasWalkedCache()
+  }
+
+  processPatterns(target: Path, patterns: Pattern[]) {
+    this.patterns = patterns
+    const processingSet: [Path, Pattern][] = patterns.map(p => [target, p])
+
+    // map of paths to the magic-starting subwalks they need to walk
+    // first item in patterns is the filter
+
+    for (let [t, pattern] of processingSet) {
+      if (this.hasWalked.hasWalked(t, pattern)) continue
+      this.hasWalked.storeWalked(t, pattern)
+
+      const root = pattern.root()
+      const absolute = pattern.isAbsolute()
+
+      // start absolute patterns at root
+      if (root) {
+        t = t.resolve(root)
+        const rest = pattern.rest()
+        if (!rest) {
+          this.matches.add(t, true, false)
+          continue
+        } else {
+          pattern = rest
+        }
+      }
+
+      // walk down strings
+      let p: MMPattern
+      let rest: Pattern | null
+      let changed = false
+      while (
+        typeof (p = pattern.pattern()) === 'string' &&
+        (rest = pattern.rest())
+      ) {
+        t = t.resolve(p)
+        pattern = rest
+        changed = true
+      }
+      rest = pattern.rest()
+      if (changed) {
+        if (this.hasWalked.hasWalked(t, pattern)) continue
+        this.hasWalked.storeWalked(t, pattern)
+      }
+
+      // now we have either a final string, or a pattern starting with magic,
+      // mounted on t.
+      if (typeof p === 'string') {
+        // must be final entry
+        const ifDir = p === '..' || p === '' || p === '.'
+        this.matches.add(t.resolve(p), absolute, ifDir)
+        continue
+      } else if (p === GLOBSTAR) {
+        // if no rest, match and subwalk pattern
+        // if rest, process rest and subwalk pattern
+        this.subwalks.add(t, pattern)
+        if (!rest) {
+          this.matches.add(t, absolute, false)
+        } else {
+          if (!this.hasWalked.hasWalked(t, rest)) {
+            processingSet.push([t, rest])
+          }
+        }
+      } else if (p instanceof RegExp) {
+        this.subwalks.add(t, pattern)
+      }
+    }
+
+    return this
+  }
+
+  subwalkTargets(): Path[] {
+    return this.subwalks.keys()
+  }
+
+  child() {
+    return new Processor(this.hasWalked)
+  }
+
+  // return a new Processor containing the subwalks for each
+  // child entry, and a set of matches, and
+  // a hasWalked cache that's a copy of this one
+  // then we're going to call
+  filterEntries(parent: Path, entries: Path[]): Processor {
+    const patterns = this.subwalks.get(parent)
+    // put matches and entry walks into the results processor
+    const results = this.child()
+    for (const e of entries) {
+      for (const pattern of patterns) {
+        const absolute = pattern.isAbsolute()
+        const p = pattern.pattern()
+        const rest = pattern.rest()
+        let doSub: Pattern | undefined = undefined
+        if (p === GLOBSTAR) {
+          if (e.name.startsWith('.')) continue
+          if (!rest) {
+            results.matches.add(e, absolute, false)
+          }
+          if (e.isDirectory()) {
+            doSub = pattern
+          }
+        } else if (p instanceof RegExp) {
+          if (!p.test(e.name)) continue
+          if (!rest) {
+            results.matches.add(e, absolute, false)
+          } else {
+            doSub = rest
+          }
+        } else {
+          // should never happen?
+          if (!e.isNamed(p)) continue
+          if (!rest) {
+            results.matches.add(e, absolute, false)
+          } else {
+            doSub = rest
+          }
+        }
+        if (doSub) {
+          results.subwalks.add(e, doSub)
+        }
+      }
+    }
+    return results
+  }
+}
diff --git a/src/walker.ts b/src/walker.ts
index 6b37d343..475a2af8 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -28,6 +28,56 @@ import { Path } from 'path-scurry'
 
 // a single minimatch set entry with 1 or more parts
 import { MMPattern, Pattern } from './pattern.js'
+import { Processor } from './processor.js'
+
+class HasWalkedCache {
+  store: Map>
+  constructor(store: Map> = new Map()) {
+    this.store = store
+  }
+  copy() {
+    return new HasWalkedCache(new Map(this.store))
+  }
+  hasWalked(target: Path, pattern: Pattern) {
+    return this.store.get(target)?.has(pattern.globString())
+  }
+  storeWalked(target: Path, pattern: Pattern) {
+    const cached = this.store.get(target)
+    if (cached) cached.add(pattern.globString())
+    else this.store.set(target, new Set([pattern.globString()]))
+  }
+}
+
+// bitflag of 
+class MatchRecord {
+  store: Map = new Map()
+  add(target: Path, absolute: boolean, ifDir: boolean) {
+    const n = (absolute ? 2 : 0) | (ifDir ? 1 : 0)
+    const current = this.store.get(target) || 0
+    this.store.set(target, n & current)
+  }
+  // match, absolute, ifdir
+  entries(): [Path, boolean, boolean][] {
+    return [...this.store.entries()].map(([path, n]) => [
+      path,
+      !!(n & 2),
+      !!(n & 1),
+    ])
+  }
+}
+
+class SubWalks {
+  store: Map = new Map()
+  patterns: Map = new Map()
+  add(target: Path, pattern: Pattern) {
+    const subs = this.store.get(target)
+    if (subs) subs.push(pattern)
+    else this.store.set(target, [pattern])
+  }
+  entries() {
+    return this.store.entries()
+  }
+}
 
 export interface GlobWalkerOpts {
   absolute?: boolean
@@ -262,32 +312,21 @@ export abstract class GlobUtil {
   processPatterns(
     target: Path,
     patterns: Pattern[]
-  ): [Map, Map] {
-    const processingSet = new Set<[Path, Pattern]>(
-      patterns
-        // .filter(p => !this.hasWalked(target, p))
-        .map(p => [target, p])
-    )
-
-    const hasWalkedCache = new Map>()
-    const hasWalked = (target: Path, pattern: Pattern) =>
-      hasWalkedCache.get(target)?.has(pattern.globString())
-    const storeWalked = (target: Path, pattern: Pattern) => {
-      const cached = hasWalkedCache.get(target)
-      if (cached) cached.add(pattern.globString())
-      else hasWalkedCache.set(target, new Set([pattern.globString()]))
-    }
+  ): [SubWalks, MatchRecord] {
+    const processingSet: [Path, Pattern][] = patterns.map(p => [target, p])
+
+    const hasWalkedCache = new HasWalkedCache()
 
     // found matches, path => [absolute, ifdir]
-    const matches = new Map()
+    const matches = new MatchRecord()
 
     // map of paths to the magic-starting subwalks they need to walk
     // first item in patterns is the filter
-    const subwalks = new Map()
+    const subwalks = new SubWalks()
 
     for (let [t, pattern] of processingSet) {
-      if (hasWalked(t, pattern)) continue
-      storeWalked(t, pattern)
+      if (hasWalkedCache.hasWalked(t, pattern)) continue
+      hasWalkedCache.storeWalked(t, pattern)
 
       const root = pattern.root()
       const absolute = pattern.isAbsolute()
@@ -297,7 +336,7 @@ export abstract class GlobUtil {
         t = t.resolve(root)
         const rest = pattern.rest()
         if (!rest) {
-          matches.set(t, [true, false])
+          matches.add(t, true, false)
           continue
         } else {
           pattern = rest
@@ -318,8 +357,8 @@ export abstract class GlobUtil {
       }
       rest = pattern.rest()
       if (changed) {
-        if (hasWalked(t, pattern)) continue
-        storeWalked(t, pattern)
+        if (hasWalkedCache.hasWalked(t, pattern)) continue
+        hasWalkedCache.storeWalked(t, pattern)
       }
 
       // now we have either a final string, or a pattern starting with magic,
@@ -327,29 +366,21 @@ export abstract class GlobUtil {
       if (typeof p === 'string') {
         // must be final entry
         const ifDir = p === '..' || p === '' || p === '.'
-        matches.set(t.resolve(p), [absolute, ifDir])
+        matches.add(t.resolve(p), absolute, ifDir)
         continue
       } else if (p === GLOBSTAR) {
         // if no rest, match and subwalk pattern
         // if rest, process rest and subwalk pattern
-        const subs = subwalks.get(t)
-        if (!subs) {
-          subwalks.set(t, [pattern])
-        } else {
-          subs.push(pattern)
-        }
+        subwalks.add(t, pattern)
         if (!rest) {
-          matches.set(t, [absolute, false])
+          matches.add(t, absolute, false)
         } else {
-          if (!hasWalked(t, rest)) processingSet.add([t, rest])
+          if (!hasWalkedCache.hasWalked(t, rest)) {
+            processingSet.push([t, rest])
+          }
         }
       } else if (p instanceof RegExp) {
-        const subs = subwalks.get(t)
-        if (!subs) {
-          subwalks.set(t, [pattern])
-        } else {
-          subs.push(pattern)
-        }
+        subwalks.add(t, pattern)
       }
     }
     return [subwalks, matches]
@@ -360,15 +391,20 @@ export abstract class GlobUtil {
       this.onResume(() => this.walkCB(target, patterns, cb))
       return
     }
-    this.walkCB2(target, patterns, cb)
+    this.walkCB2(target, patterns, new Processor(), cb)
   }
 
-  walkCB2(target: Path, patterns: Pattern[], cb: () => any) {
+  walkCB2(
+    target: Path,
+    patterns: Pattern[],
+    processor: Processor,
+    cb: () => any
+  ) {
     if (this.paused) {
-      this.onResume(() => this.walkCB2(target, patterns, cb))
+      this.onResume(() => this.walkCB2(target, patterns, processor, cb))
       return
     }
-    const [subwalks, matches] = this.processPatterns(target, patterns)
+    processor.processPatterns(target, patterns)
 
     // done processing.  all of the above is sync, can be abstracted out.
     // subwalks is a map of paths to the entry filters they need
@@ -378,31 +414,19 @@ export abstract class GlobUtil {
       if (--tasks === 0) cb()
     }
 
-    for (const [m, [absolute, ifDir]] of matches.entries()) {
+    for (const [m, absolute, ifDir] of processor.matches.entries()) {
       tasks++
       this.match(m, absolute, ifDir).then(() => next())
     }
 
-    for (const [t, patterns] of subwalks.entries()) {
-      // if we can't read it, no sense trying
-      if (!t.canReaddir()) {
-        continue
-      }
-
-      // if they're all globstar, and it's a symlink, skip it.
-      if (
-        t.isSymbolicLink() &&
-        !patterns.some(p => p.pattern() instanceof RegExp)
-      ) {
-        continue
-      }
-
+    for (const t of processor.subwalkTargets()) {
       tasks++
       const childrenCached = t.readdirCached()
-      if (t.calledReaddir()) this.walkCB3(childrenCached, patterns, next)
+      if (t.calledReaddir())
+        this.walkCB3(t, childrenCached, processor, next)
       else {
         t.readdirCB(
-          (_, entries) => this.walkCB3(entries, patterns, next),
+          (_, entries) => this.walkCB3(t, entries, processor, next),
           true
         )
       }
@@ -411,70 +435,26 @@ export abstract class GlobUtil {
     next()
   }
 
-  filterEntries(
+  walkCB3(
+    target: Path,
     entries: Path[],
-    patterns: Pattern[]
-  ): [Map, Map] {
-    const subwalks = new Map()
-    const matches = new Map()
-    for (const e of entries) {
-      for (const pattern of patterns) {
-        const absolute = pattern.isAbsolute()
-        const p = pattern.pattern()
-        const rest = pattern.rest()
-        let doSub: Pattern | undefined = undefined
-        if (p === GLOBSTAR) {
-          if (e.name.startsWith('.')) continue
-          if (!rest) {
-            matches.set(e, [absolute, false])
-          }
-          if (e.isDirectory()) {
-            doSub = pattern
-          }
-        } else if (p instanceof RegExp) {
-          if (!p.test(e.name)) continue
-          if (!rest) {
-            matches.set(e, [absolute, false])
-          } else {
-            doSub = rest
-          }
-        } else {
-          // should never happen?
-          if (!e.isNamed(p)) continue
-          if (!rest) {
-            matches.set(e, [absolute, false])
-          } else {
-            doSub = rest
-          }
-        }
-        if (doSub /* && !this.hasWalked(e, doSub) */) {
-          const subs = subwalks.get(e)
-          if (!subs) {
-            subwalks.set(e, [doSub])
-          } else {
-            subs.push(doSub)
-          }
-        }
-      }
-    }
-    return [subwalks, matches]
-  }
-
-  walkCB3(entries: Path[], patterns: Pattern[], cb: () => any) {
-    const [subwalks, matches] = this.filterEntries(entries, patterns)
+    processor: Processor,
+    cb: () => any
+  ) {
+    processor = processor.filterEntries(target, entries)
 
     let tasks = 1
     const next = () => {
       if (--tasks === 0) cb()
     }
 
-    for (const [m, [absolute, ifDir]] of matches.entries()) {
+    for (const [m, absolute, ifDir] of processor.matches.entries()) {
       tasks++
       this.match(m, absolute, ifDir).then(() => next())
     }
-    for (const [target, patterns] of subwalks.entries()) {
+    for (const [target, patterns] of processor.subwalks.entries()) {
       tasks++
-      this.walkCB2(target, patterns, next)
+      this.walkCB2(target, patterns, processor.child(), next)
     }
 
     next()
@@ -485,22 +465,22 @@ export abstract class GlobUtil {
       this.onResume(() => this.walkCBSync(target, patterns, cb))
       return
     }
-    if (target.isUnknown()) {
-      target.lstat().then(t => {
-        if (!t) cb()
-        else this.walkCB2Sync(t, patterns, cb)
-      })
-    } else {
-      this.walkCB2Sync(target, patterns, cb)
-    }
+    this.walkCB2Sync(target, patterns, new Processor(), cb)
   }
 
-  walkCB2Sync(target: Path, patterns: Pattern[], cb: () => any) {
+  walkCB2Sync(
+    target: Path,
+    patterns: Pattern[],
+    processor: Processor,
+    cb: () => any
+  ) {
     if (this.paused) {
-      this.onResume(() => this.walkCB2(target, patterns, cb))
+      this.onResume(() =>
+        this.walkCB2Sync(target, patterns, processor, cb)
+      )
       return
     }
-    const [subwalks, matches] = this.processPatterns(target, patterns)
+    processor.processPatterns(target, patterns)
 
     // done processing.  all of the above is sync, can be abstracted out.
     // subwalks is a map of paths to the entry filters they need
@@ -510,47 +490,38 @@ export abstract class GlobUtil {
       if (--tasks === 0) cb()
     }
 
-    for (const [m, [absolute, ifDir]] of matches.entries()) {
-      tasks++
+    for (const [m, absolute, ifDir] of processor.matches.entries()) {
       this.matchSync(m, absolute, ifDir)
     }
 
-    for (const [t, patterns] of subwalks.entries()) {
-      // if we can't read it, no sense trying
-      if (!t.canReaddir()) continue
-      // if they're all globstar, and it's a symlink, skip it.
-      if (
-        t.isSymbolicLink() &&
-        !patterns.some(p => p.pattern() instanceof RegExp)
-      ) {
-        continue
-      }
-
+    for (const t of processor.subwalkTargets()) {
       tasks++
-      const childrenCached = t.readdirCached()
-      if (t.calledReaddir())
-        this.walkCB3Sync(childrenCached, patterns, next)
-      else this.walkCB3Sync(t.readdirSync(), patterns, next)
+      const children = t.readdirSync()
+      this.walkCB3Sync(t, children, processor, next)
     }
 
     next()
   }
 
-  walkCB3Sync(entries: Path[], patterns: Pattern[], cb: () => any) {
-    const [subwalks, matches] = this.filterEntries(entries, patterns)
+  walkCB3Sync(
+    target: Path,
+    entries: Path[],
+    processor: Processor,
+    cb: () => any
+  ) {
+    processor = processor.filterEntries(target, entries)
 
     let tasks = 1
     const next = () => {
       if (--tasks === 0) cb()
     }
 
-    for (const [m, [absolute, ifDir]] of matches.entries()) {
-      tasks++
+    for (const [m, absolute, ifDir] of processor.matches.entries()) {
       this.matchSync(m, absolute, ifDir)
     }
-    for (const [target, patterns] of subwalks.entries()) {
+    for (const [target, patterns] of processor.subwalks.entries()) {
       tasks++
-      this.walkCB2Sync(target, patterns, next)
+      this.walkCB2Sync(target, patterns, processor.child(), next)
     }
 
     next()

From 6cf04ee4976d462f92430f3744a46909c9f8ec2d Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 12:10:22 -0800
Subject: [PATCH 078/163] abstract out the processing of patterns and readdir
 entries

---
 benchmark.sh      | 75 ++++++++++++++++--------------------
 package-lock.json | 14 +++----
 package.json      |  2 +-
 patterns.sh       | 39 +++++++++++++++++++
 prof.sh           | 13 +++++--
 src/pattern.ts    | 23 -----------
 src/processor.ts  | 97 +++++++++++++++++++++++++++--------------------
 7 files changed, 146 insertions(+), 117 deletions(-)
 create mode 100644 patterns.sh

diff --git a/benchmark.sh b/benchmark.sh
index 6855ba7a..7da18ba1 100644
--- a/benchmark.sh
+++ b/benchmark.sh
@@ -2,45 +2,7 @@
 export CDPATH=
 set -e
 
-patterns=(
-  # some of these aren't particularly "representative" of real-world
-  # glob patterns, but they're here to highlight pathological perf
-  # cases that I found while working on the rewrite of this library.
-  '**'
-  '**/*.txt'
-  '**/!(0|9).txt'
-  '{**/*.txt,**/?/**/*.txt,**/?/**/?/**/*.txt,**/?/**/?/**/?/**/*.txt,**/?/**/?/**/?/**/?/**/*.txt}'
-  './{**/?{/**/?{/**/?{/**/?,,,,},,,,},,,,},,,}/**/*.txt'
-
-  './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,,,,},,,,},,,,},,,,},,,,}/*.txt'
-  './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
-  './*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
-  './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt'
-  './**/?/**/?/**/?/**/?/**/*.txt'
-  './**/0/**/../[01]/**/0/../**/0/*.txt'
-  '**/????/????/????/????/*.txt'
-  './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt'
-  '**/*/**/*/**/*/**/*/**'
-  # '5555/0000/**/*.txt'
-  '**/5555/0000/*.txt'
-  # '*/*/9/**/**/**/**/*/**/**/*.txt'
-  './**/*/**/*/**/*/**/*/**/*.txt'
-  './**/0/**/0/**/0/**/0/**/*.txt'
-  './**/0/**/0/**/*.txt'
-  '**/*.txt'
-  # './**/*.txt'
-  './**/**/**/**/**/**/**/**/*.txt'
-  '**/*/*.txt'
-  '**/*/**/*.txt'
-  '**/[0-9]/**/*.txt'
-  # '0/@([5-9]/*.txt|8/**)'
-  # '[0-9]/[0-9]/[0-9]/[0-9]/[0-9].txt'
-  # /**/**/**/**//////**/**//*.txt'
-  # '**/[5-9]/*.txt'
-  # '[678]/**/2.txt'
-  # '0/!(1|2)@(4|5)/**/**/**/**/*.txt'
-  # '0/!(1|2|@(4|5))/**/**/**/**/*.txt'
-)
+. patterns.sh
 
 bash make-benchmark-fixture.sh
 wd=$PWD
@@ -50,6 +12,7 @@ cd "$wd/bench-working-dir"
 cat > "$wd/bench-working-dir/package.json" <&1 | grep real | awk -F $'\t' '{ print $2 }' || true
+  rm -f stderr stdout
+  tt "$@" 2>stderr >stdout || true
+  echo $(cat stderr | grep real | awk -F $'\t' '{ print $2 }' || true)' '\
+    $(cat stdout)
+  rm -f stderr stdout
 }
 
+# warm up the fs cache so we don't get a spurious slow first result
+bash -c 'for i in **; do :; done'
+
+
 for p in "${patterns[@]}"; do
   echo
   echo "--- pattern: '$p' ---"
@@ -111,6 +82,20 @@ for p in "${patterns[@]}"; do
   #     console.log(files.length)
   #   })' "$wd/bench-working-dir/node_modules/glob8" "$p"
 
+  echo -n $'node fast-glob sync           \t'
+  cat > "$wd"/bench-working-dir/fast-glob-sync.cjs < "$wd"/bench-working-dir/fast-glob-async.cjs < console.log(r.length))
+CJS
+  t node "$wd/bench-working-dir/fast-glob-async.cjs" "$p"
+
   echo -n $'node globby sync              \t'
   cat > "$wd"/bench-working-dir/globby-sync.mjs < "$wd/bench-working-dir/stream-sync.mjs" < c++)
+    .on('end', () => console.log(c))
 MJS
   t node "$wd/bench-working-dir/stream-sync.mjs" "$p"
 
   echo -n $'node current glob stream      \t'
   cat > "$wd/bench-working-dir/stream.mjs" < c.push(f))
+    .on('end', () => console.log(new Set(c).size))
 MJS
   t node "$wd/bench-working-dir/stream.mjs" "$p"
 
diff --git a/package-lock.json b/package-lock.json
index eb9dbb4b..198bbd14 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "minimatch": "^6.2.0",
+        "minimatch": "^7.0.0",
         "minipass": "^4.0.3",
         "path-scurry": "^1.4.0"
       },
@@ -2920,9 +2920,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz",
-      "integrity": "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.0.0.tgz",
+      "integrity": "sha512-Wog4y1P2q/0sF+0vw+6dWgqVmo/XPJg+2OtVmR6IVvNGDhcfAPjFacjZCUlGCoU/tbzH6EOeSt2P3llRAqRNiA==",
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
@@ -8568,9 +8568,9 @@
       }
     },
     "minimatch": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz",
-      "integrity": "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.0.0.tgz",
+      "integrity": "sha512-Wog4y1P2q/0sF+0vw+6dWgqVmo/XPJg+2OtVmR6IVvNGDhcfAPjFacjZCUlGCoU/tbzH6EOeSt2P3llRAqRNiA==",
       "requires": {
         "brace-expansion": "^2.0.1"
       }
diff --git a/package.json b/package.json
index b3988249..06f27698 100644
--- a/package.json
+++ b/package.json
@@ -59,7 +59,7 @@
   },
   "dependencies": {
     "fs.realpath": "^1.0.0",
-    "minimatch": "^6.2.0",
+    "minimatch": "^7.0.0",
     "minipass": "^4.0.3",
     "path-scurry": "^1.4.0"
   },
diff --git a/patterns.sh b/patterns.sh
new file mode 100644
index 00000000..1e0ed769
--- /dev/null
+++ b/patterns.sh
@@ -0,0 +1,39 @@
+patterns=(
+  # some of these aren't particularly "representative" of real-world
+  # glob patterns, but they're here to highlight pathological perf
+  # cases that I found while working on the rewrite of this library.
+  '**'
+  '**/*.txt'
+  '**/!(0|9).txt'
+  '{**/*.txt,**/?/**/*.txt,**/?/**/?/**/*.txt,**/?/**/?/**/?/**/*.txt,**/?/**/?/**/?/**/?/**/*.txt}'
+  './{**/?{/**/?{/**/?{/**/?,,,,},,,,},,,,},,,}/**/*.txt'
+
+  './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,,,,},,,,},,,,},,,,},,,,}/*.txt'
+  './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
+  './*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
+  './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt'
+  './**/?/**/?/**/?/**/?/**/*.txt'
+  './**/0/**/../[01]/**/0/../**/0/*.txt'
+  '**/????/????/????/????/*.txt'
+  './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt'
+  '**/*/**/*/**/*/**/*/**'
+  # '5555/0000/**/*.txt'
+  '**/5555/0000/*.txt'
+  # '*/*/9/**/**/**/**/*/**/**/*.txt'
+  './**/*/**/*/**/*/**/*/**/*.txt'
+  './**/0/**/0/**/0/**/0/**/*.txt'
+  './**/0/**/0/**/*.txt'
+  '**/*.txt'
+  # './**/*.txt'
+  './**/**/**/**/**/**/**/**/*.txt'
+  '**/*/*.txt'
+  '**/*/**/*.txt'
+  '**/[0-9]/**/*.txt'
+  # '0/@([5-9]/*.txt|8/**)'
+  # '[0-9]/[0-9]/[0-9]/[0-9]/[0-9].txt'
+  # /**/**/**/**//////**/**//*.txt'
+  # '**/[5-9]/*.txt'
+  # '[678]/**/2.txt'
+  # '0/!(1|2)@(4|5)/**/**/**/**/*.txt'
+  # '0/!(1|2|@(4|5))/**/**/**/**/*.txt'
+)
diff --git a/prof.sh b/prof.sh
index 78ce3fa9..366a5859 100644
--- a/prof.sh
+++ b/prof.sh
@@ -3,6 +3,8 @@ export CDPATH=
 set -e
 set -x
 
+. patterns.sh
+
 bash -x make-benchmark-fixture.sh
 wd=$PWD
 tmp="$wd/bench-working-dir"
@@ -12,11 +14,16 @@ export __GLOB_PROFILE__=1
 
 cat > "profscript.mjs" < console.log(m.length))
+const patterns = process.argv.slice(2)
+for (const p of patterns) {
+  glob.sync("./fixture/" + p)
+}
+await Promise.all(patterns.map(async p => {
+  await glob("./fixture/" + p)
+}))
 MJS
 
-node --prof profscript.mjs &> profile.out
+node --prof profscript.mjs "${patterns[@]}" &> profile.out
 mkdir -p profiles
 d=./profiles/$(date +%s)
 mv isolate*.log ${d}.log
diff --git a/src/pattern.ts b/src/pattern.ts
index 0c583e8e..fb42b62f 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -7,9 +7,6 @@ type MMRegExp = RegExp & {
 }
 export type MMPattern = string | MMRegExp | typeof GLOBSTAR
 
-import LRUCache from 'lru-cache'
-const cache = new LRUCache({ max: 256 })
-
 // an array of length >= 1
 type PatternList = [p: MMPattern, ...rest: MMPattern[]]
 type UNCPatternList = [
@@ -29,15 +26,6 @@ const isPatternList = (pl: MMPattern[]): pl is PatternList =>
   pl.length >= 1
 const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1
 
-const cacheKey = (index: number, patternList: PatternList): string =>
-  index +
-  '\n' +
-  patternList
-    .map(p =>
-      typeof p === 'string' ? p : p instanceof RegExp ? String(p) : '**'
-    )
-    .join('\n')
-
 export class Pattern {
   readonly patternList: PatternList
   readonly globList: GlobList
@@ -83,17 +71,6 @@ export class Pattern {
       this.#index += 2
     }
 
-    // this is not so much to save on performance but more to ensure
-    // that if we get the same pattern, we'll have the same Pattern object,
-    // since these objects are used in cache entries to prevent rewalking.
-    // It won't cause any incorrect behavior on a cache miss, but it may
-    // adversely affect performance in really weird cases, like lots of
-    // **/.. patterns and such.
-    // const key = cacheKey(index, patternList)
-    // const cached = cache.get(key)
-    // if (cached) return cached
-    // cache.set(key, this)
-
     // normalize root entries of absolute patterns on initial creation.
     if (this.#index === 0) {
       // c: => ['c:/']
diff --git a/src/processor.ts b/src/processor.ts
index 70671112..5cf2d967 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -1,24 +1,25 @@
 // synchronous utility for filtering entries and calculating subwalks
 
-import { GLOBSTAR } from 'minimatch'
+import { GLOBSTAR, MMRegExp } from 'minimatch'
 import { Path } from 'path-scurry'
 import { MMPattern, Pattern } from './pattern.js'
 
 class HasWalkedCache {
-  store: Map>
-  constructor(store: Map> = new Map()) {
+  store: Map>
+  constructor(store: Map> = new Map()) {
     this.store = store
   }
   copy() {
     return new HasWalkedCache(new Map(this.store))
   }
   hasWalked(target: Path, pattern: Pattern) {
-    return this.store.get(target)?.has(pattern.globString())
+    return this.store.get(target.fullpath())?.has(pattern.globString())
   }
   storeWalked(target: Path, pattern: Pattern) {
-    const cached = this.store.get(target)
+    const fullpath = target.fullpath()
+    const cached = this.store.get(fullpath)
     if (cached) cached.add(pattern.globString())
-    else this.store.set(target, new Set([pattern.globString()]))
+    else this.store.set(fullpath, new Set([pattern.globString()]))
   }
 }
 
@@ -41,7 +42,6 @@ class MatchRecord {
 
 class SubWalks {
   store: Map = new Map()
-  patterns: Map = new Map()
   add(target: Path, pattern: Pattern) {
     if (!target.canReaddir()) return
     if (target.isSymbolicLink() && pattern.isGlobstar()) return
@@ -70,13 +70,15 @@ class SubWalks {
 }
 
 export class Processor {
-  hasWalked: HasWalkedCache
+  hasWalkedCache: HasWalkedCache
   matches = new MatchRecord()
   subwalks = new SubWalks()
   patterns?: Pattern[]
 
-  constructor(hasWalked?: HasWalkedCache) {
-    this.hasWalked = hasWalked ? hasWalked.copy() : new HasWalkedCache()
+  constructor(hasWalkedCache?: HasWalkedCache) {
+    this.hasWalkedCache = hasWalkedCache
+      ? hasWalkedCache// .copy()
+      : new HasWalkedCache()
   }
 
   processPatterns(target: Path, patterns: Pattern[]) {
@@ -87,8 +89,8 @@ export class Processor {
     // first item in patterns is the filter
 
     for (let [t, pattern] of processingSet) {
-      if (this.hasWalked.hasWalked(t, pattern)) continue
-      this.hasWalked.storeWalked(t, pattern)
+      if (this.hasWalkedCache.hasWalked(t, pattern)) continue
+      this.hasWalkedCache.storeWalked(t, pattern)
 
       const root = pattern.root()
       const absolute = pattern.isAbsolute()
@@ -119,8 +121,8 @@ export class Processor {
       }
       rest = pattern.rest()
       if (changed) {
-        if (this.hasWalked.hasWalked(t, pattern)) continue
-        this.hasWalked.storeWalked(t, pattern)
+        if (this.hasWalkedCache.hasWalked(t, pattern)) continue
+        this.hasWalkedCache.storeWalked(t, pattern)
       }
 
       // now we have either a final string, or a pattern starting with magic,
@@ -137,7 +139,7 @@ export class Processor {
         if (!rest) {
           this.matches.add(t, absolute, false)
         } else {
-          if (!this.hasWalked.hasWalked(t, rest)) {
+          if (!this.hasWalkedCache.hasWalked(t, rest)) {
             processingSet.push([t, rest])
           }
         }
@@ -154,12 +156,12 @@ export class Processor {
   }
 
   child() {
-    return new Processor(this.hasWalked)
+    return new Processor(this.hasWalkedCache)
   }
 
   // return a new Processor containing the subwalks for each
   // child entry, and a set of matches, and
-  // a hasWalked cache that's a copy of this one
+  // a hasWalkedCache that's a copy of this one
   // then we're going to call
   filterEntries(parent: Path, entries: Path[]): Processor {
     const patterns = this.subwalks.get(parent)
@@ -170,36 +172,49 @@ export class Processor {
         const absolute = pattern.isAbsolute()
         const p = pattern.pattern()
         const rest = pattern.rest()
-        let doSub: Pattern | undefined = undefined
         if (p === GLOBSTAR) {
-          if (e.name.startsWith('.')) continue
-          if (!rest) {
-            results.matches.add(e, absolute, false)
-          }
-          if (e.isDirectory()) {
-            doSub = pattern
-          }
+          results.testGlobstar(e, pattern, absolute)
         } else if (p instanceof RegExp) {
-          if (!p.test(e.name)) continue
-          if (!rest) {
-            results.matches.add(e, absolute, false)
-          } else {
-            doSub = rest
-          }
+          results.testRegExp(e, p, rest, absolute)
         } else {
-          // should never happen?
-          if (!e.isNamed(p)) continue
-          if (!rest) {
-            results.matches.add(e, absolute, false)
-          } else {
-            doSub = rest
-          }
-        }
-        if (doSub) {
-          results.subwalks.add(e, doSub)
+          results.testString(e, p, rest, absolute)
         }
       }
     }
     return results
   }
+
+  testGlobstar(e: Path, pattern: Pattern, absolute: boolean) {
+    if (e.name.startsWith('.')) return
+    if (!pattern.hasMore()) {
+      this.matches.add(e, absolute, false)
+    }
+    if (e.isDirectory()) {
+      this.subwalks.add(e, pattern)
+    }
+  }
+
+  testRegExp(
+    e: Path,
+    p: MMRegExp,
+    rest: Pattern | null,
+    absolute: boolean
+  ) {
+    if (!p.test(e.name)) return
+    if (!rest) {
+      this.matches.add(e, absolute, false)
+    } else {
+      this.subwalks.add(e, rest)
+    }
+  }
+
+  testString(e: Path, p: string, rest: Pattern | null, absolute: boolean) {
+    // should never happen?
+    if (!e.isNamed(p)) return
+    if (!rest) {
+      this.matches.add(e, absolute, false)
+    } else {
+      this.subwalks.add(e, rest)
+    }
+  }
 }

From 3a00ac9cfa0d9ccf0190f35dd85123ff0e87084b Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 13:08:25 -0800
Subject: [PATCH 079/163] pull in the matcher, use simpler regexen

---
 package-lock.json |  14 ++
 package.json      |   2 +
 src/compiler.ts   | 521 ++++++++++++++++++++++++++++++++++++++++++++++
 src/glob.ts       |  75 ++-----
 src/has-magic.ts  |  20 --
 src/index.ts      |   3 -
 src/matcher.ts    | 338 ++++++++++++++++++++++++++++++
 src/pattern.ts    | 245 ++++++----------------
 src/processor.ts  |  87 ++++----
 src/timer.ts      |  24 +++
 src/walker.ts     |   5 +-
 11 files changed, 1035 insertions(+), 299 deletions(-)
 create mode 100644 src/compiler.ts
 delete mode 100644 src/has-magic.ts
 create mode 100644 src/matcher.ts
 create mode 100644 src/timer.ts

diff --git a/package-lock.json b/package-lock.json
index 198bbd14..3ad54c18 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,12 +9,14 @@
       "version": "9.0.0-0",
       "license": "ISC",
       "dependencies": {
+        "brace-expansion": "^2.0.1",
         "fs.realpath": "^1.0.0",
         "minimatch": "^7.0.0",
         "minipass": "^4.0.3",
         "path-scurry": "^1.4.0"
       },
       "devDependencies": {
+        "@types/brace-expansion": "^1.1.0",
         "@types/mkdirp": "^1.0.2",
         "@types/node": "^18.11.18",
         "@types/tap": "^15.0.7",
@@ -628,6 +630,12 @@
       "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
       "dev": true
     },
+    "node_modules/@types/brace-expansion": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@types/brace-expansion/-/brace-expansion-1.1.0.tgz",
+      "integrity": "sha512-SaU/Kgp6z40CiF9JxlsrSrBEa+8YIry9IiCPhhYSNekeEhIAkY7iyu9aZ+5dSQIdo7mf86MUVvxWYm5GAzB/0g==",
+      "dev": true
+    },
     "node_modules/@types/istanbul-lib-coverage": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
@@ -6817,6 +6825,12 @@
       "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
       "dev": true
     },
+    "@types/brace-expansion": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@types/brace-expansion/-/brace-expansion-1.1.0.tgz",
+      "integrity": "sha512-SaU/Kgp6z40CiF9JxlsrSrBEa+8YIry9IiCPhhYSNekeEhIAkY7iyu9aZ+5dSQIdo7mf86MUVvxWYm5GAzB/0g==",
+      "dev": true
+    },
     "@types/istanbul-lib-coverage": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
diff --git a/package.json b/package.json
index 06f27698..003db05b 100644
--- a/package.json
+++ b/package.json
@@ -58,12 +58,14 @@
     "endOfLine": "lf"
   },
   "dependencies": {
+    "brace-expansion": "^2.0.1",
     "fs.realpath": "^1.0.0",
     "minimatch": "^7.0.0",
     "minipass": "^4.0.3",
     "path-scurry": "^1.4.0"
   },
   "devDependencies": {
+    "@types/brace-expansion": "^1.1.0",
     "@types/mkdirp": "^1.0.2",
     "@types/node": "^18.11.18",
     "@types/tap": "^15.0.7",
diff --git a/src/compiler.ts b/src/compiler.ts
new file mode 100644
index 00000000..c2f7aa95
--- /dev/null
+++ b/src/compiler.ts
@@ -0,0 +1,521 @@
+import { GLOBSTAR, MatcherOpts, MMPattern } from './matcher.js'
+
+const charUnescape = (s: string) => s.replace(/\\([^-\]])/g, '$1')
+const braceEscape = (s: string) => s.replace(/[[\]\\]/g, '\\$&')
+const globSpecialChars = new Set(['?', '*', '+', '@', '!', '[', '('])
+const escapeInClass = new Set(['-', ']'])
+const regExpEscape = (s: string) =>
+  s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
+
+export const compile = (
+  pattern: string,
+  options: MatcherOpts
+): MMPattern => {
+  if (pattern === '**') return GLOBSTAR
+  if (pattern === '') return ''
+
+  let m: RegExpMatchArray | null
+  let fastTest: null | ((f: string) => boolean) = null
+  if ((m = pattern.match(starRE))) {
+    fastTest = options.dot ? starTestDot : starTest
+  } else if ((m = pattern.match(starDotExtRE))) {
+    fastTest = (
+      options.nocase
+        ? options.dot
+          ? starDotExtTestNocaseDot
+          : starDotExtTestNocase
+        : options.dot
+        ? starDotExtTestDot
+        : starDotExtTest
+    )(m[1])
+  } else if ((m = pattern.match(qmarksRE))) {
+    fastTest = (
+      options.nocase
+        ? options.dot
+          ? qmarksTestNocaseDot
+          : qmarksTestNocase
+        : options.dot
+        ? qmarksTestDot
+        : qmarksTest
+    )(m)
+  } else if ((m = pattern.match(starDotStarRE))) {
+    fastTest = options.dot ? starDotStarTestDot : starDotStarTest
+  } else if ((m = pattern.match(dotStarRE))) {
+    fastTest = dotStarTest
+  }
+
+  if (fastTest) {
+    return Object.assign(/$./, {
+      _glob: pattern,
+      test: fastTest,
+    })
+  } else {
+    // ok we have to actually compile it
+    const re = compilePattern(pattern, options)
+    return typeof re === 'string'
+      ? re
+      : Object.assign(re, {
+          _glob: pattern,
+        })
+  }
+}
+
+const compilePattern = (
+  pattern: string,
+  options: MatcherOpts
+): MMPattern => {
+  const ast = tokenize(pattern, options)
+  if (ast.length === 1 && ast[0][TokenField.TYPE] === TokenType.STRING) {
+    return ast[0][TokenField.VALUE]
+  }
+  const re = assemble(ast, options, true)
+  try {
+    return new RegExp(re, options.nocase ? 'i' : '')
+  } catch (er) {
+    return /$./
+  }
+}
+
+// Optimized checking for the most common glob patterns.
+const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/
+const starDotExtTest = (ext: string) => (f: string) =>
+  !f.startsWith('.') && f.endsWith(ext)
+const starDotExtTestDot = (ext: string) => (f: string) => f.endsWith(ext)
+const starDotExtTestNocase = (ext: string) => {
+  ext = ext.toLowerCase()
+  return (f: string) => !f.startsWith('.') && f.toLowerCase().endsWith(ext)
+}
+const starDotExtTestNocaseDot = (ext: string) => {
+  ext = ext.toLowerCase()
+  return (f: string) => f.toLowerCase().endsWith(ext)
+}
+const starDotStarRE = /^\*+\.\*+$/
+const starDotStarTest = (f: string) =>
+  !f.startsWith('.') && f.includes('.')
+const starDotStarTestDot = (f: string) =>
+  f !== '.' && f !== '..' && f.includes('.')
+const dotStarRE = /^\.\*+$/
+const dotStarTest = (f: string) =>
+  f !== '.' && f !== '..' && f.startsWith('.')
+const starRE = /^\*+$/
+const starTest = (f: string) => f.length !== 0 && !f.startsWith('.')
+const starTestDot = (f: string) =>
+  f.length !== 0 && f !== '.' && f !== '..'
+const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/
+const qmarksTestNocase = ([$0, ext = '']: RegExpMatchArray) => {
+  const noext = qmarksTestNoExt([$0])
+  if (!ext) return noext
+  ext = ext.toLowerCase()
+  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)
+}
+const qmarksTestNocaseDot = ([$0, ext = '']: RegExpMatchArray) => {
+  const noext = qmarksTestNoExtDot([$0])
+  if (!ext) return noext
+  ext = ext.toLowerCase()
+  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)
+}
+const qmarksTestDot = ([$0, ext = '']: RegExpMatchArray) => {
+  const noext = qmarksTestNoExtDot([$0])
+  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)
+}
+const qmarksTest = ([$0, ext = '']: RegExpMatchArray) => {
+  const noext = qmarksTestNoExt([$0])
+  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)
+}
+const qmarksTestNoExt = ([$0]: RegExpMatchArray) => {
+  const len = $0.length
+  return (f: string) => f.length === len && !f.startsWith('.')
+}
+const qmarksTestNoExtDot = ([$0]: RegExpMatchArray) => {
+  const len = $0.length
+  return (f: string) => f.length === len && f !== '.' && f !== '..'
+}
+
+// TOKENIZING
+
+type AST = Token[]
+type ExtToken = [t: TokenType.EXT, value: ExtGlobType, children: AST[]]
+const isExtToken = (t: Token): t is ExtToken =>
+  t[TokenField.TYPE] === TokenType.EXT
+type StringToken = [t: TokenType.STRING, value: string]
+const isStringToken = (t: Token): t is StringToken =>
+  t[TokenField.TYPE] === TokenType.STRING
+type StarToken = [t: TokenType.STAR, value: '*']
+const isStarToken = (t: Token): t is StarToken =>
+  t[TokenField.TYPE] === TokenType.STAR
+type QmarkToken = [t: TokenType.QMARK, value: '?']
+const isQmarkToken = (t: Token): t is QmarkToken =>
+  t[TokenField.TYPE] === TokenType.QMARK
+type ClassToken = [t: TokenType.CLASS, value: string]
+const isClassToken = (t: Token): t is ClassToken =>
+  t[TokenField.TYPE] === TokenType.CLASS
+type Token = ExtToken | StringToken | StarToken | QmarkToken | ClassToken
+
+enum TokenField {
+  TYPE,
+  VALUE,
+  CHILDREN,
+}
+enum TokenType {
+  STRING,
+  STAR,
+  EXT,
+  QMARK,
+  CLASS,
+}
+
+type ExtGlobType = '?' | '*' | '+' | '@' | '!'
+const extGlobTypes: Set = new Set(['?', '*', '+', '@', '!'])
+const isExtGlobType = (s: string): s is ExtGlobType =>
+  extGlobTypes.has(s as ExtGlobType)
+
+const extTypes: { [k in ExtGlobType]: { open: string; close: string } } = {
+  '!': { open: '(?:(?!(?:', close: ').*?))' },
+  '?': { open: '(?:', close: ')?' },
+  '+': { open: '(?:', close: ')+' },
+  '*': { open: '(?:', close: ')*' },
+  '@': { open: '(?:', close: ')' },
+}
+
+const tokenize = (
+  pattern: string,
+  options: MatcherOpts,
+  ast: AST = []
+): AST => {
+  // tokenize the string up into chunks first
+  // sort of like an AST of the pattern
+  // each node is [type, value, [...children]]
+  // root, or children of extglobs, are an array of nodes
+  // so 'i\?jk?*.@(xy[a-c]|!(foo|ba*r))baz*bo' becomes:
+  // [
+  //  [STRING, 'i?jk'],
+  //  [QMARK, '?'],
+  //  [STAR, '*'],
+  //  [STRING, '.'],
+  //  [EXT, '@', [
+  //    [[STRING, 'xy'], [CLASS, 'a-c']],
+  //    [[EXT, '!', [
+  //      [[STRING, 'foo']],
+  //      [[STRING, 'ba'], [STAR, '*'], [STRING, 'r']]
+  //    ]]],
+  //  ]],
+  //  [STRING, 'baz'],
+  //  [STAR, '*'],
+  //  [STRING, 'bo'],
+  // ]
+  //
+  // which turns into the regexp:
+  // ^i\?jk..*?\.(?:xy[a-c]|(?:(?!(?:foo|ba.*?r).*$)))baz.*?bo$
+  // Place the "no dot allowed" if the AST starts at position 0,
+  // and is a *, ?, or class at the start
+  let i: number = 0
+  const length = pattern.length
+  while (i < length) {
+    let c = pattern.charAt(i)
+    // take our best guess as to what it is
+    // the other tokenizers will append to the AST and return
+    // the amount of string that was consumed.
+    if (
+      !options.noext &&
+      isExtGlobType(c) &&
+      pattern.charAt(i + 1) === '('
+    ) {
+      const consumed = tokenizeExt(pattern, options, i, ast)
+      if (consumed) {
+        i += consumed
+        c = pattern.charAt(i)
+        continue
+      }
+    }
+    if (c === '[') {
+      const consumed = tokenizeClass(pattern, options, i, ast)
+      if (consumed) {
+        i += consumed
+        continue
+      }
+    }
+    if (c === '*') {
+      ast.push([TokenType.STAR, '*'])
+    } else if (c === '?') {
+      ast.push([TokenType.QMARK, '?'])
+    } else {
+      const consumed = tokenizeNonMagic(pattern, options, i, ast)
+      if (consumed) {
+        i += consumed
+        c = pattern.charAt(i)
+        continue
+      }
+    }
+    i++
+  }
+  return ast
+}
+
+const tokenizeExt = (
+  pattern: string,
+  options: MatcherOpts,
+  i: number,
+  ast: AST
+): number => {
+  const extType = pattern.charAt(i)
+  if (!isExtGlobType(extType)) {
+    throw new Error('invalid extglob type: ' + extType)
+  }
+  const matchStack: string[] = []
+  const pipes: number[] = []
+  let p: number
+  const length = pattern.length
+  let end = -1
+  let escaping = false
+
+  // first split out the top-level set of strings
+  // if we can't do that, it's not a valid extglob
+  for (p = i + 2; p < length; p++) {
+    const c = pattern.charAt(p)
+    if (escaping) {
+      escaping = false
+      continue
+    }
+    if (c === '\\') {
+      escaping = true
+      continue
+    }
+    if (c === ']') {
+      if (matchStack[0] === '[' && pattern.charAt(p - 1) !== '[') {
+        matchStack.shift()
+      }
+    } else if (c === ')') {
+      if (!matchStack.length) {
+        // finished!
+        end = p
+        break
+      } else if (matchStack[0] === '(') {
+        matchStack.shift()
+      }
+    } else if (c === '(') {
+      if (matchStack[0] !== '[' && isExtGlobType(pattern.charAt(p - 1))) {
+        matchStack.unshift(c)
+      }
+    } else if (c === '|' && matchStack.length === 0) {
+      pipes.push(p)
+    }
+  }
+
+  if (!end || matchStack.length) {
+    return 0
+  }
+
+  // i + 1, pipes, and end define the outside boundaries of the subs
+  const subPatterns: string[] = []
+  let start = i + 2
+  for (const pipe of pipes) {
+    subPatterns.push(pattern.substring(start, pipe))
+    start = pipe + 1
+  }
+  subPatterns.push(pattern.substring(start, end))
+
+  const subTokenized = subPatterns.map(p => tokenize(p, options))
+  ast.push([TokenType.EXT, extType, subTokenized])
+  return end - i + 1
+}
+
+const tokenizeClass = (
+  pattern: string,
+  _: MatcherOpts,
+  i: number,
+  ast: AST
+): number => {
+  // walk until we find the closing ] that is not escaped or the first char
+  // return 0 if it's not a valid class (basically, just if it's left open)
+  let p: number
+  let escaping = false
+  const length = pattern.length
+  let s = ''
+  for (p = i + 1; p < length; p++) {
+    const c = pattern.charAt(p)
+    if (c === '\\' && !escaping) {
+      escaping = true
+      continue
+    }
+    if (p === i + 1 && c === ']') {
+      s += c
+      continue
+    }
+    if (escaping) {
+      escaping = false
+      if (escapeInClass.has(c)) {
+        s += '\\'
+      }
+      s += c
+      continue
+    }
+    if (c === ']') {
+      ast.push([TokenType.CLASS, s])
+      return p - i + 1
+    }
+    s += c
+  }
+  return 0
+}
+
+const tokenizeNonMagic = (
+  pattern: string,
+  _: MatcherOpts,
+  i: number,
+  ast: AST
+): number => {
+  let escaping = false
+  let p = i
+  let sawFirst = false
+  const length = pattern.length
+  let s = ''
+  for (p = i; p < length; p++) {
+    let c = pattern.charAt(p)
+    if (c === '\\' && !escaping) {
+      escaping = true
+      continue
+    }
+
+    if (escaping) {
+      escaping = false
+      s += c
+      continue
+    }
+
+    // this is only called when we KNOW the first char is not magic,
+    // so no need to stop for that at the outset.
+    if (!sawFirst) {
+      sawFirst = true
+      s += c
+      continue
+    }
+
+    if (globSpecialChars.has(c)) {
+      break
+    }
+
+    s += c
+  }
+
+  ast.push([TokenType.STRING, s])
+  return p - i
+}
+
+// COMPILATION
+
+export const assemble = (
+  ast: AST,
+  options: MatcherOpts,
+  isTop = false,
+  isStart = true
+): string => {
+  const negativeExts: number[] = []
+  const re: string[] = []
+  let stillStart = isStart
+  let maybeEmpty = true
+  for (let i = 0; i < ast.length; i++) {
+    const token = ast[i]
+    if (isStringToken(token)) {
+      if (token[TokenField.VALUE] !== '') {
+        maybeEmpty = false
+      }
+      re.push(assembleNonMagic(token, options))
+    } else if (isClassToken(token)) {
+      maybeEmpty = false
+      re.push(assembleClass(token, options))
+    } else if (isExtToken(token)) {
+      if (token[TokenField.VALUE] === '!') {
+        negativeExts.push(i)
+      }
+      re.push(assembleExt(token, options, stillStart))
+    } else if (isQmarkToken(token)) {
+      maybeEmpty = false
+      re.push(assembleQmark(token, options))
+    } else if (isStarToken(token)) {
+      re.push(assembleStar(token, options))
+      /* c8 ignore start */
+    } else {
+      throw new TypeError('unknown token type: ' + token)
+    }
+    /* c8 ignore stop */
+    stillStart = false
+  }
+
+  if (isTop) {
+    re.push('$')
+  }
+
+  // a negative extglob is:
+  // ((?!(sub|patterns)).*?)
+  // so we need to do it in two passes.
+  for (let i = negativeExts.length - 1; i >= 0; i--) {
+    const n = negativeExts[i]
+    re[n] += assembleNegativeExtClose(re, n)
+  }
+  if (isTop) {
+    if (!options.dot && needDotProtection(ast)) {
+      re.unshift('(?!^\\.)')
+    }
+    if (maybeEmpty) {
+      re.unshift('(?=.)')
+    }
+    re.unshift('^')
+  } else if (isStart) {
+    if (!options.dot && needDotProtection(ast)) {
+      re.unshift('(?!^\\.)')
+    }
+  }
+  return re.join('')
+}
+
+const needDotProtection = (ast: AST) => {
+  const first = ast[0]
+  return isClassToken(first) || isStarToken(first) || isQmarkToken(first)
+}
+
+const assembleQmark = (_: QmarkToken, __: MatcherOpts) => '.'
+const assembleStar = (_: StarToken, __: MatcherOpts) => '.*?'
+const assembleNonMagic = (token: StringToken, _: MatcherOpts) =>
+  regExpEscape(token[TokenField.VALUE])
+
+const assembleClass = (token: ClassToken, _: MatcherOpts) => {
+  // TODO: posix classes
+  const cls = braceEscape(charUnescape(token[TokenField.VALUE]))
+  const re = `[${cls}]`
+  // handle out of order classes, like `[z-a]`, which throw
+  // in javascript, but just match nothing in glob syntax.
+  try {
+    RegExp(re)
+    return re
+  } catch (_) {
+    return '$.'
+  }
+}
+
+const assembleExt = (
+  token: ExtToken,
+  options: MatcherOpts,
+  isStart: boolean
+): string => {
+  const t = token[TokenField.VALUE]
+  const open = extTypes[t].open
+  const close = t === '!' ? '' : extTypes[t].close
+  const subs = token[TokenField.CHILDREN]
+  const body = subs
+    .map(ast => assemble(ast, options, false, isStart))
+    .join('|')
+  return open + body + close
+}
+
+const assembleNegativeExtClose = (re: string[], n: number): string => {
+  // walk the AST from i onwards, collecting the regexp
+  // then add the end bit:
+  // ((?!(sub|patterns)).*?)
+  //                  ^-- from here on
+  let s: string = ')'
+  for (let i = n + 1; i < re.length; i++) {
+    s += re[i]
+  }
+  s += ').*?)'
+  return s
+}
diff --git a/src/glob.ts b/src/glob.ts
index 731f4230..c1e14af3 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -1,4 +1,3 @@
-import { Minimatch, MinimatchOptions } from 'minimatch'
 import Minipass from 'minipass'
 import {
   Path,
@@ -8,23 +7,22 @@ import {
   PathScurryWin32,
 } from 'path-scurry'
 import { Ignore } from './ignore.js'
+import { Matcher, MatcherOpts } from './matcher.js'
 import { Pattern } from './pattern.js'
 import { GlobStream, GlobWalker, Matches } from './walker.js'
 
-type MatchSet = Minimatch['set']
-type GlobSet = Exclude
-type GlobParts = Exclude
-
 // if no process global, just call it linux.
 // so we default to case-sensitive, / separators
+/* c8 ignore start */
 const defaultPlatform =
   typeof process === 'object' &&
   process &&
   typeof process.platform === 'string'
     ? process.platform
     : 'linux'
+/* c8 ignore stop */
 
-export interface GlobOptions extends MinimatchOptions {
+export interface GlobOptions extends MatcherOpts {
   ignore?: string | string[] | Ignore
   follow?: boolean
   mark?: boolean
@@ -77,13 +75,8 @@ export class Glob {
   nodir: boolean
   nounique: boolean
   cwd: string
-  matchSet: MatchSet
-  globSet: GlobSet
-  globParts: GlobParts
   realpath: boolean
-  nonull: boolean
   absolute: boolean
-  matchBase: boolean
   windowsPathsNoEscape: boolean
   noglobstar: boolean
   matches?: Matches
@@ -94,6 +87,7 @@ export class Glob {
   opts: Opts
   platform?: typeof process.platform
   patterns: Pattern[]
+  matcher: Matcher
 
   constructor(pattern: string | string[], opts: Opts) {
     this.withFileTypes = !!opts.withFileTypes as FileTypes
@@ -113,51 +107,30 @@ export class Glob {
     this.nounique = !!opts.nounique
     this.cwd = opts.cwd || ''
     this.realpath = !!opts.realpath
-    this.nonull = !!opts.nonull
     this.absolute = !!opts.absolute
 
     this.noglobstar = !!opts.noglobstar
-    this.matchBase = !!opts.matchBase
 
     // if we're returning Path objects, we can't do nonull, because
     // the pattern is a string, not a Path
-    if (this.withFileTypes) {
-      if (this.nonull) {
-        throw new TypeError(
-          'cannot set nonull:true and withFileTypes:true'
-        )
-      }
-      if (this.absolute) {
-        throw new Error('cannot set absolute:true and withFileTypes:true')
-      }
+    if (this.withFileTypes && this.absolute) {
+      throw new Error('cannot set absolute:true and withFileTypes:true')
     }
 
-    // if we want unique entries, we need a single set to hold them all
-    if (!this.nounique) {
-      this.matches = new Set() as Matches
-      this.seen = new Set()
-      this.walked = new Map()
-    }
+    this.matches = new Set() as Matches
+    this.seen = new Set()
+    this.walked = new Map()
 
     if (typeof pattern === 'string') {
       pattern = [pattern]
     }
 
-    this.windowsPathsNoEscape =
-      !!opts.windowsPathsNoEscape ||
-      (opts as GlobOptions).allowWindowsEscape === false
+    this.windowsPathsNoEscape = !!opts.windowsPathsNoEscape
 
     if (this.windowsPathsNoEscape) {
       pattern = pattern.map(p => p.replace(/\\/g, '/'))
     }
 
-    if (this.matchBase) {
-      if (opts.noglobstar) {
-        throw new TypeError('base matching requires globstar')
-      }
-      pattern = pattern.map(p => (p.includes('/') ? p : `**/${p}`))
-    }
-
     this.pattern = pattern
 
     this.platform = opts.platform || defaultPlatform
@@ -175,34 +148,16 @@ export class Glob {
       this.scurry = new Scurry(this.cwd, { nocase: opts.nocase })
     }
 
-    const mmo: MinimatchOptions = {
+    const mmo: MatcherOpts = {
       // default nocase based on platform
       nocase: this.scurry.nocase,
+      platform: this.platform,
       ...opts,
-      nonegate: true,
-      nocomment: true,
-      nocaseMagicOnly: true,
     }
 
     // console.error('glob pattern arg', this.pattern)
-    const mms = this.pattern.map(p => new Minimatch(p, mmo))
-    const [matchSet, globSet, globParts] = mms.reduce(
-      (set: [MatchSet, GlobSet, GlobParts], m) => {
-        // console.error('globparts', m.globParts)
-        set[0].push(...m.set)
-        set[1].push(...m.globSet)
-        set[2].push(...m.globParts)
-        return set
-      },
-      [[], [], []]
-    )
-    this.patterns = matchSet.map((set, i) => {
-      // console.error('globParts', globParts[i])
-      return new Pattern(set, globParts[i], 0)
-    })
-    this.matchSet = matchSet
-    this.globSet = globSet
-    this.globParts = globParts
+    this.matcher = new Matcher(this.pattern, mmo)
+    this.patterns = this.matcher.patterns
   }
 
   async walk(): Promise> {
diff --git a/src/has-magic.ts b/src/has-magic.ts
deleted file mode 100644
index 7a88cb0c..00000000
--- a/src/has-magic.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Glob, GlobOptions } from './glob.js'
-
-export const hasMagic = (
-  pattern: string | string[],
-  options: GlobOptions = {}
-): boolean => {
-  if (!Array.isArray(pattern)) {
-    pattern = [pattern]
-  }
-  return pattern.some(p => {
-    const g = new Glob(p, options)
-    if (g.matchSet.length === 0) {
-      return false
-    }
-    if (g.matchSet.length > 1) {
-      return true
-    }
-    return g.matchSet[0].some(p => typeof p !== 'string')
-  })
-}
diff --git a/src/index.ts b/src/index.ts
index a64972de..e24d1a17 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,6 +1,5 @@
 import Minipass from 'minipass'
 import { Glob, GlobOptions } from './glob.js'
-import { hasMagic } from './has-magic.js'
 
 export const globStreamSync = (
   pattern: string | string[],
@@ -37,13 +36,11 @@ export const glob = Object.assign(
     globStream,
     globStreamSync,
     Glob,
-    hasMagic,
   }
 )
 
 /* c8 ignore start */
 export { Glob } from './glob.js'
 export type { GlobOptions } from './glob.js'
-export { hasMagic } from './has-magic.js'
 export default glob
 /* c8 ignore stop */
diff --git a/src/matcher.ts b/src/matcher.ts
new file mode 100644
index 00000000..4cd49d8b
--- /dev/null
+++ b/src/matcher.ts
@@ -0,0 +1,338 @@
+// this is a much more "mini" minimatch, optimized for use in a recursive
+// glob walk.  So we build up the 2d array of pattern portions, and do
+// the preprocessing to make the glob patterns as efficient as possible,
+// but do *not* generate the big honkin complicated regexp to test an
+// entire path string.
+
+import expand from 'brace-expansion'
+
+export const GLOBSTAR = Symbol('**')
+
+import { GlobList, Compiled, Pattern } from './pattern.js'
+
+export type MMPattern = string | RegExp | typeof GLOBSTAR
+
+export interface MatcherOpts {
+  dot?: boolean
+  nocase?: boolean
+  noext?: boolean
+  noglobstar?: boolean
+  nobrace?: boolean
+  windowsPathsNoEscape?: boolean
+  platform?: typeof process.platform
+}
+
+/* c8 ignore start */
+// TODO: make this non-optional, pass in via Glob options
+const defaultPlatform: typeof process.platform =
+  typeof process === 'object' &&
+  !!process &&
+  typeof process.platform === 'string'
+    ? process.platform
+    : 'linux'
+/* c8 ignore stop */
+
+export class Matcher {
+  options: MatcherOpts
+  globLists: GlobList[]
+  patterns: Pattern[]
+
+  dot: boolean
+  nocase: boolean
+  noext: boolean
+  noglobstar: boolean
+  nobrace: boolean
+  windowsPathsNoEscape: boolean
+  platform: typeof process.platform
+  isWindows: boolean
+
+  constructor(patterns: string | string[], opts: MatcherOpts = {}) {
+    const {
+      dot = false,
+      nocase,
+      noext = false,
+      noglobstar = false,
+      nobrace = false,
+      windowsPathsNoEscape = false,
+      platform = defaultPlatform,
+    } = opts
+    this.dot = dot
+    this.noext = noext
+    this.noglobstar = noglobstar
+    this.nobrace = nobrace
+    this.windowsPathsNoEscape = windowsPathsNoEscape
+    this.platform = platform
+    this.nocase =
+      nocase !== undefined
+        ? nocase
+        : this.platform === 'win32' || this.platform === 'darwin'
+    this.isWindows = this.platform === 'win32'
+
+    opts = {
+      dot: this.dot,
+      nocase: this.nocase,
+      noext: this.noext,
+      noglobstar: this.noglobstar,
+      nobrace: this.nobrace,
+      windowsPathsNoEscape: this.windowsPathsNoEscape,
+      platform: this.platform,
+    }
+    this.options = opts
+
+    if (!patterns) throw new TypeError('pattern required')
+    if (!Array.isArray(patterns)) patterns = [patterns]
+    if (opts.windowsPathsNoEscape) {
+      patterns = patterns.map(p => p.replace(/\\/g, '/'))
+    }
+    this.globLists = this.preprocess(
+      patterns
+        .map(p => braceExpand(p, this.options))
+        .reduce((ps, p) => ps.concat(p), [])
+        .map(p => this.splitGlobString(p))
+        .filter(gl => !!gl.length)
+    ) as GlobList[]
+
+    const compiled: Compiled = new Map()
+    this.patterns = this.globLists.map(
+      gl => new Pattern(gl, 0, compiled, opts)
+    )
+  }
+
+  splitGlobString(globString: string) {
+    const parts = globString.split('/')
+    // canonincalize UNC paths and drives, make the first
+    // pattern the whole root ending in / for absolute patterns.
+    if (this.isUNC(parts)) {
+      const [p0, p1, p2] = parts
+      parts.shift()
+      parts.shift()
+      parts.shift()
+      parts.unshift([p0, p1, p2, ''].join('/').toUpperCase())
+    } else if (this.isDrive(parts)) {
+      const drive = parts[0].toUpperCase() + '/'
+      parts.shift()
+      parts.unshift(drive)
+    } else if (parts[0] === '') {
+      parts[0] = '/'
+    }
+
+    // now strip any empty parts
+    return parts.filter((p, i) => !!p || i === parts.length - 1)
+  }
+
+  isDrive(pl: string[]): boolean {
+    return (
+      this.isWindows &&
+      typeof pl[0] === 'string' &&
+      /^[a-z]:$/i.test(pl[0])
+    )
+  }
+
+  isUNC(pl: string[]): boolean {
+    return (
+      this.isWindows &&
+      pl[0] === '' &&
+      pl[1] === '' &&
+      typeof pl[2] === 'string' &&
+      !!pl[2] &&
+      typeof pl[3] === 'string' &&
+      !!pl[3]
+    )
+  }
+
+  preprocess(globParts: string[][]) {
+    // if we're not in globstar mode, then turn all ** into *
+    if (this.noglobstar) {
+      for (let i = 0; i < globParts.length; i++) {
+        for (let j = 0; j < globParts[i].length; j++) {
+          if (globParts[i][j] === '**') {
+            globParts[i][j] = '*'
+          }
+        }
+      }
+    }
+
+    globParts = this.firstPhasePreProcess(globParts)
+    globParts = this.secondPhasePreProcess(globParts)
+
+    return globParts
+  }
+
+  // First phase: single-pattern processing
+  // 
 is 1 or more portions
+  //  is 1 or more portions
+  // 

is any portion other than ., .., '', or ** + // is . or '' + // + // **/.. is *brutal* for filesystem walking performance, because + // it effectively resets the recursive walk each time it occurs, + // and ** cannot be reduced out by a .. pattern part like a regexp + // or most strings (other than .., ., and '') can be. + // + //

/**/../

/ -> {

/../

/,

/**/

/} + //

// -> 
/
+  // 
/

/../ ->

/
+  // **/**/ -> **/
+  //
+  // **/*/ -> */**/ <== not valid because ** doesn't follow
+  // this WOULD be allowed if ** did follow symlinks, or * didn't
+  firstPhasePreProcess(globParts: string[][]) {
+    let didSomething = false
+    do {
+      didSomething = false
+      // 
/**/../

/ -> {

/../

/,

/**/

/} + for (let parts of globParts) { + let gs: number = -1 + while (-1 !== (gs = parts.indexOf('**', gs + 1))) { + let gss: number = gs + while (parts[gss + 1] === '**') { + //

/**/**/ -> 
/**/
+            gss++
+          }
+          // eg, if gs is 2 and gss is 4, that means we have 3 **
+          // parts, and can remove 2 of them.
+          if (gss > gs) {
+            parts.splice(gs + 1, gss - gs)
+          }
+
+          let next = parts[gs + 1]
+          const p = parts[gs + 2]
+          if (next !== '..') continue
+          if (!p || p === '.' || p === '..') continue
+          didSomething = true
+          // edit parts in place, and push the new one
+          parts.splice(gs, 1)
+          const other = parts.slice(0)
+          other[gs] = '**'
+          globParts.push(other)
+          gs--
+        }
+
+        // 
// -> 
/
+        for (let i = 1; i < parts.length - 1; i++) {
+          const p = parts[i]
+          // don't squeeze out UNC patterns
+          if (i === 1 && p === '' && parts[0] === '') continue
+          if (p === '.' || p === '') {
+            didSomething = true
+            parts.splice(i, 1)
+            i--
+          }
+        }
+        if (parts[0] === '.') {
+          didSomething = true
+          parts.shift()
+        }
+
+        // 
/

/../ ->

/
+        let dd: number = 0
+        while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
+          const p = parts[dd - 1]
+          if (p && p !== '.' && p !== '..' && p !== '**') {
+            didSomething = true
+            parts.splice(dd - 1, 2)
+            if (parts.length === 0) parts.push('')
+            dd -= 2
+          }
+        }
+      }
+    } while (didSomething)
+
+    return globParts
+  }
+
+  // second phase: multi-pattern dedupes
+  // {
/*/,
/

/} ->

/*/
+  // {
/,
/} -> 
/
+  // {
/**/,
/} -> 
/**/
+  //
+  // {
/**/,
/**/

/} ->

/**/
+  // ^-- not valid because ** doens't follow symlinks
+  secondPhasePreProcess(globParts: string[][]): string[][] {
+    for (let i = 0; i < globParts.length - 1; i++) {
+      for (let j = i + 1; j < globParts.length; j++) {
+        const matched = this.partsMatch(globParts[i], globParts[j])
+        if (!matched) continue
+        globParts[i] = matched
+        globParts[j] = []
+      }
+    }
+    return globParts.filter(gs => gs.length)
+  }
+
+  partsMatch(a: string[], b: string[]): false | string[] {
+    let ai = 0
+    let bi = 0
+    let result: string[] = []
+    let which: string = ''
+    while (ai < a.length && bi < b.length) {
+      if (a[ai] === b[bi]) {
+        result.push(which === 'b' ? b[bi] : a[ai])
+        ai++
+        bi++
+      } else if (a[ai] === '**' && b[bi] === a[ai + 1]) {
+        result.push(a[ai])
+        ai++
+      } else if (b[bi] === '**' && a[ai] === b[bi + 1]) {
+        result.push(b[bi])
+        bi++
+      } else if (
+        a[ai] === '*' &&
+        b[bi] &&
+        !b[bi].startsWith('.') &&
+        b[bi] !== '**'
+      ) {
+        if (which === 'b') return false
+        which = 'a'
+        result.push(a[ai])
+        ai++
+        bi++
+      } else if (
+        b[bi] === '*' &&
+        a[ai] &&
+        (this.dot || !a[ai].startsWith('.')) &&
+        a[ai] !== '**'
+      ) {
+        if (which === 'a') return false
+        which = 'b'
+        result.push(b[bi])
+        ai++
+        bi++
+      } else {
+        return false
+      }
+    }
+    // if we fall out of the loop, it means they two are identical
+    // as long as their lengths match
+    return a.length === b.length && result
+  }
+}
+
+export const braceExpand = (
+  pattern: string,
+  options: MatcherOpts = {}
+) => {
+  assertValidPattern(pattern)
+
+  // Thanks to Yeting Li  for
+  // improving this regexp to avoid a ReDOS vulnerability.
+  if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
+    // shortcut. no need to expand.
+    return [pattern]
+  }
+
+  return expand(pattern)
+}
+
+const MAX_PATTERN_LENGTH = 1024 * 64
+const assertValidPattern: (pattern: any) => void = (
+  pattern: any
+): asserts pattern is string => {
+  if (typeof pattern !== 'string') {
+    throw new TypeError('invalid pattern')
+  }
+
+  if (pattern.length > MAX_PATTERN_LENGTH) {
+    throw new TypeError('pattern is too long')
+  }
+}
diff --git a/src/pattern.ts b/src/pattern.ts
index fb42b62f..bcf00838 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -1,140 +1,82 @@
 // this is just a very light wrapper around 2 arrays with an offset index
+// Pattern objects are effectively an immutable view over an array of
+// glob strings, which can return the compiled part on demand as needed.
 
-import { GLOBSTAR } from 'minimatch'
-type MMRegExp = RegExp & {
-  _glob?: string
-  _src?: string
-}
-export type MMPattern = string | MMRegExp | typeof GLOBSTAR
-
-// an array of length >= 1
-type PatternList = [p: MMPattern, ...rest: MMPattern[]]
-type UNCPatternList = [
-  p0: '',
-  p1: '',
-  p2: string,
-  p3: string,
-  ...rest: MMPattern[]
-]
-type DrivePatternList = [p0: string, ...rest: MMPattern[]]
-type AbsolutePatternList = [p0: '', ...rest: MMPattern[]]
-type GlobList = [p: string, ...rest: string[]]
+import { GLOBSTAR, MatcherOpts, MMPattern } from './matcher.js'
+import { compile } from './compiler.js'
+export type GlobList = [p: string, ...rest: string[]]
+export const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1
 
-// TODO: this should be a parameter
-const isWin = process.platform === 'win32'
-const isPatternList = (pl: MMPattern[]): pl is PatternList =>
-  pl.length >= 1
-const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1
+export type Compiled = Map
 
 export class Pattern {
-  readonly patternList: PatternList
-  readonly globList: GlobList
-  readonly #index: number
+  #options: MatcherOpts
+  #globList: GlobList
   readonly length: number
+  #index: number
+  #compiled: Compiled
+
+  // memoizing
+  #pattern?: MMPattern
   #rest?: Pattern | null
   #globString?: string
-  #isDrive?: boolean
-  #isUNC?: boolean
-  #isAbsolute?: boolean
 
   constructor(
-    patternList: MMPattern[],
-    globList: string[],
-    index: number
+    globList: GlobList,
+    index: number,
+    compiled: Compiled,
+    options: MatcherOpts
   ) {
-    if (!isPatternList(patternList)) {
-      throw new TypeError('empty pattern list')
-    }
     if (!isGlobList(globList)) {
       throw new TypeError('empty glob list')
     }
-    if (globList.length !== patternList.length) {
-      throw new TypeError('mismatched pattern list and glob list lengths')
-    }
-    this.length = patternList.length
-    if (index >= this.length) {
+    this.#globList = globList
+    if (index >= globList.length) {
       throw new TypeError('index out of range')
     }
-    this.patternList = patternList
-    this.globList = globList
+    this.length = globList.length
+    this.#options = options
     this.#index = index
-
-    // if the current item is not globstar, and the next item is .., skip ahead
-    if (
-      this.patternList[this.#index] !== GLOBSTAR &&
-      this.patternList[this.#index] !== '..' &&
-      this.patternList[this.#index] !== '.' &&
-      this.patternList[this.#index] !== '' &&
-      this.patternList[this.#index + 1] === '..' &&
-      this.length > this.#index + 2
-    ) {
-      this.#index += 2
-    }
-
-    // normalize root entries of absolute patterns on initial creation.
-    if (this.#index === 0) {
-      // c: => ['c:/']
-      // C:/ => ['C:/']
-      // C:/x => ['C:/', 'x']
-      // //host/share => ['//host/share/']
-      // //host/share/ => ['//host/share/']
-      // //host/share/x => ['//host/share/', 'x']
-      // /etc => ['/', 'etc']
-      // / => ['/']
-      if (this.isUNC()) {
-        const [p1, p2, p3, ...prest] = this.patternList
-        const [g1, g2, g3, ...grest] = this.globList
-        if (prest[0] === '') {
-          // ends in /
-          prest.shift()
-          grest.shift()
-        }
-        const p = [p1, p2, p3, ''].join('/')
-        const g = [g1, g2, g3, ''].join('/')
-        this.patternList = [p, ...prest]
-        this.globList = [g, ...grest]
-        this.length = this.patternList.length
-      } else if (this.isDrive() || this.isAbsolute()) {
-        const [p1, ...prest] = this.patternList
-        const [g1, ...grest] = this.globList
-        if (prest[0] === '') {
-          // ends in /
-          prest.shift()
-          grest.shift()
-        }
-        const p = (p1 as string) + '/'
-        const g = g1 + '/'
-        this.patternList = [p, ...prest]
-        this.globList = [g, ...grest]
-        this.length = this.patternList.length
-      }
-    } else {
-      // discard any empty path portions, except the last one.
-      while (this.#index < this.length - 1 && this.pattern() === '') {
-        this.#index++
-      }
-    }
+    this.#compiled = compiled
   }
 
-  pattern(): MMPattern {
-    return this.patternList[this.#index]
+  glob(): string {
+    return this.#globList[this.#index]
   }
 
-  isString(): boolean {
-    return typeof this.patternList[this.#index] === 'string'
-  }
   isGlobstar(): boolean {
-    return this.patternList[this.#index] === GLOBSTAR
-  }
-  isGlobstarDotDot(): boolean {
-    return this.isGlobstar() && this.globList[this.#index + 1] === '..'
+    return this.pattern() === GLOBSTAR
   }
   isRegExp(): boolean {
-    return this.patternList[this.#index] instanceof RegExp
+    return this.pattern() instanceof RegExp
+  }
+  isString(): boolean {
+    return typeof this.pattern() === 'string'
   }
 
-  glob(): string {
-    return this.globList[this.#index]
+  pattern(): MMPattern {
+    if (this.#pattern !== undefined) {
+      return this.#pattern
+    }
+    const glob = this.glob()
+    if (glob.endsWith('/')) {
+      return (this.#pattern = glob)
+    }
+    const cached = this.#compiled.get(glob)
+    if (cached !== undefined) {
+      return (this.#pattern = cached)
+    }
+    const pattern = compile(glob, this.#options)
+    this.#compiled.set(glob, pattern)
+    return (this.#pattern = pattern)
+  }
+
+  isAbsolute(): boolean {
+    return this.#globList[0].endsWith('/')
+  }
+
+  root(): string {
+    return this.#index === 0 && this.isAbsolute() ? this.#globList[0] : ''
   }
 
   globString(): string {
@@ -142,78 +84,29 @@ export class Pattern {
       this.#globString ||
       (this.#index === 0
         ? this.isAbsolute()
-          ? this.globList[0] + this.globList.slice(1).join('/')
-          : this.globList.join('/')
-        : this.globList.slice(this.#index).join('/')))
-  }
-
-  hasMore(): boolean {
-    return this.length > this.#index + 1
+          ? this.#globList[0] + this.#globList.slice(1).join('/')
+          : this.#globList.join('/')
+        : this.#globList.slice(this.#index).join('/')))
   }
 
   rest(): Pattern | null {
     if (this.#rest !== undefined) return this.#rest
-    if (!this.hasMore()) return (this.#rest = null)
-    this.#rest = new Pattern(
-      this.patternList,
-      this.globList,
-      this.#index + 1
+    if (this.#index >= this.length - 1) return (this.#rest = null)
+    const rest = new Pattern(
+      this.#globList,
+      this.#index + 1,
+      this.#compiled,
+      this.#options
     )
-    this.#rest.#isAbsolute = this.#isAbsolute
-    this.#rest.#isUNC = this.#isUNC
-    this.#rest.#isDrive = this.#isDrive
-    return this.#rest
-  }
-
-  // pattern like: //host/share/...
-  // split = [ '', '', 'host', 'share', ... ]
-  isUNC(pl = this.patternList): pl is UNCPatternList {
-    return this.#isUNC !== undefined
-      ? this.#isUNC
-      : (this.#isUNC =
-          isWin &&
-          this.#index === 0 &&
-          pl[0] === '' &&
-          pl[1] === '' &&
-          typeof pl[2] === 'string' &&
-          !!pl[2] &&
-          typeof pl[3] === 'string' &&
-          !!pl[3])
-  }
-
-  // pattern like C:/...
-  // split = ['C:', ...]
-  // XXX: would be nice to handle patterns like `c:*` to test the cwd
-  // in c: for *, but I don't know of a way to even figure out what that
-  // cwd is without actually chdir'ing into it?
-  isDrive(pl = this.patternList): pl is DrivePatternList {
-    return this.#isDrive !== undefined
-      ? this.#isDrive
-      : (this.#isDrive =
-          isWin &&
-          this.#index === 0 &&
-          this.length > 1 &&
-          typeof pl[0] === 'string' &&
-          /^[a-z]:$/i.test(pl[0]))
+    this.#rest = rest
+    return rest
   }
 
-  // pattern = '/' or '/...' or '/x/...'
-  // split = ['', ''] or ['', ...] or ['', 'x', ...]
-  // Drive and UNC both considered absolute on windows
-  isAbsolute(pl = this.patternList): pl is AbsolutePatternList {
-    return this.#isAbsolute !== undefined
-      ? this.#isAbsolute
-      : (this.#isAbsolute =
-          (pl[0] === '' && pl.length > 1) ||
-          this.isDrive(pl) ||
-          this.isUNC(pl))
+  hasMore(): this is PatternWithMore {
+    return this.#index < this.length - 1
   }
+}
 
-  // consume the root of the pattern, and return it
-  root(): string {
-    const p = this.patternList[0]
-    return typeof p === 'string' && this.isAbsolute() && this.#index === 0
-      ? p
-      : ''
-  }
+interface PatternWithMore extends Pattern {
+  rest(): Pattern
 }
diff --git a/src/processor.ts b/src/processor.ts
index 5cf2d967..b9494483 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -1,8 +1,8 @@
 // synchronous utility for filtering entries and calculating subwalks
 
-import { GLOBSTAR, MMRegExp } from 'minimatch'
 import { Path } from 'path-scurry'
-import { MMPattern, Pattern } from './pattern.js'
+import { GLOBSTAR, MMPattern } from './matcher.js'
+import { Pattern } from './pattern.js'
 
 class HasWalkedCache {
   store: Map>
@@ -77,7 +77,7 @@ export class Processor {
 
   constructor(hasWalkedCache?: HasWalkedCache) {
     this.hasWalkedCache = hasWalkedCache
-      ? hasWalkedCache// .copy()
+      ? hasWalkedCache.copy()
       : new HasWalkedCache()
   }
 
@@ -167,54 +167,67 @@ export class Processor {
     const patterns = this.subwalks.get(parent)
     // put matches and entry walks into the results processor
     const results = this.child()
-    for (const e of entries) {
-      for (const pattern of patterns) {
-        const absolute = pattern.isAbsolute()
-        const p = pattern.pattern()
-        const rest = pattern.rest()
-        if (p === GLOBSTAR) {
-          results.testGlobstar(e, pattern, absolute)
-        } else if (p instanceof RegExp) {
-          results.testRegExp(e, p, rest, absolute)
-        } else {
-          results.testString(e, p, rest, absolute)
-        }
+    for (const pattern of patterns) {
+      const p = pattern.pattern()
+      const rest = pattern.rest()
+      const absolute = pattern.isAbsolute()
+      if (p === GLOBSTAR) {
+        results.filterGlobstar(entries, pattern, absolute)
+      } else if (typeof p === 'string') {
+        results.filterString(entries, p, rest, absolute)
+      } else {
+        results.filterRegExp(entries, p, rest, absolute)
       }
     }
     return results
   }
 
-  testGlobstar(e: Path, pattern: Pattern, absolute: boolean) {
-    if (e.name.startsWith('.')) return
-    if (!pattern.hasMore()) {
-      this.matches.add(e, absolute, false)
-    }
-    if (e.isDirectory()) {
-      this.subwalks.add(e, pattern)
+  filterGlobstar(entries: Path[], pattern: Pattern, absolute: boolean) {
+    const hasMore = pattern.hasMore()
+    for (const e of entries) {
+      if (!e.name.startsWith('.')) {
+        if (!hasMore) {
+          this.matches.add(e, absolute, false)
+        }
+        if (e.isDirectory()) {
+          this.subwalks.add(e, pattern)
+        }
+      }
     }
   }
 
-  testRegExp(
-    e: Path,
-    p: MMRegExp,
+  filterRegExp(
+    entries: Path[],
+    p: RegExp,
     rest: Pattern | null,
     absolute: boolean
   ) {
-    if (!p.test(e.name)) return
-    if (!rest) {
-      this.matches.add(e, absolute, false)
-    } else {
-      this.subwalks.add(e, rest)
+    for (const e of entries) {
+      if (p.test(e.name)) {
+        if (!rest) {
+          this.matches.add(e, absolute, false)
+        } else {
+          this.subwalks.add(e, rest)
+        }
+      }
     }
   }
 
-  testString(e: Path, p: string, rest: Pattern | null, absolute: boolean) {
-    // should never happen?
-    if (!e.isNamed(p)) return
-    if (!rest) {
-      this.matches.add(e, absolute, false)
-    } else {
-      this.subwalks.add(e, rest)
+  filterString(
+    entries: Path[],
+    p: string,
+    rest: Pattern | null,
+    absolute: boolean
+  ) {
+    for (const e of entries) {
+      // should never happen?
+      if (e.isNamed(p)) {
+        if (!rest) {
+          this.matches.add(e, absolute, false)
+        } else {
+          this.subwalks.add(e, rest)
+        }
+      }
     }
   }
 }
diff --git a/src/timer.ts b/src/timer.ts
new file mode 100644
index 00000000..30691001
--- /dev/null
+++ b/src/timer.ts
@@ -0,0 +1,24 @@
+const profile = process.env.__GLOB_PROFILE__ === '1'
+const times = new Map()
+if (profile) {
+  process.on('exit', () => {
+    const print = [...times.entries()].sort(
+      ([_ak, av], [_bk, bv]) => av - bv
+    )
+    console.error(Object.fromEntries(print))
+  })
+}
+export class Timer {
+  name: string
+  start: number
+  constructor(name: string) {
+    this.name = name
+    this.start = profile ? performance.now() : 0
+  }
+  end() {
+    if (profile) {
+      const n = times.get(this.name) || 0
+      times.set(this.name, n + performance.now() - this.start)
+    }
+  }
+}
diff --git a/src/walker.ts b/src/walker.ts
index 475a2af8..4263a0b4 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -22,12 +22,11 @@
 //  rely on the Pattern objects being unique, I guess?
 
 // import LRUCache from 'lru-cache'
-import { GLOBSTAR } from 'minimatch'
 import Minipass from 'minipass'
 import { Path } from 'path-scurry'
 
-// a single minimatch set entry with 1 or more parts
-import { MMPattern, Pattern } from './pattern.js'
+import { MMPattern, GLOBSTAR } from './matcher.js'
+import { Pattern } from './pattern.js'
 import { Processor } from './processor.js'
 
 class HasWalkedCache {

From e22d6afa692ffd8df5a824ba7864c30e95c00854 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 15:02:05 -0800
Subject: [PATCH 080/163] fix a few bugs with stream emits and improve
 performance more

---
 src/processor.ts | 27 ++++++++++++++++-----------
 src/walker.ts    | 18 ++++++++++++------
 2 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/src/processor.ts b/src/processor.ts
index b9494483..5fe51ea8 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -77,7 +77,7 @@ export class Processor {
 
   constructor(hasWalkedCache?: HasWalkedCache) {
     this.hasWalkedCache = hasWalkedCache
-      ? hasWalkedCache.copy()
+      ? hasWalkedCache //.copy()
       : new HasWalkedCache()
   }
 
@@ -111,14 +111,15 @@ export class Processor {
       let p: MMPattern
       let rest: Pattern | null
       let changed = false
-      while (
-        typeof (p = pattern.pattern()) === 'string' &&
-        (rest = pattern.rest())
-      ) {
-        t = t.resolve(p)
-        pattern = rest
-        changed = true
-      }
+      //while (
+      //  typeof (p = pattern.pattern()) === 'string' &&
+      //  (rest = pattern.rest())
+      //) {
+      //  t = t.resolve(p)
+      //  pattern = rest
+      //  changed = true
+      //}
+      p = pattern.pattern()
       rest = pattern.rest()
       if (changed) {
         if (this.hasWalkedCache.hasWalked(t, pattern)) continue
@@ -129,8 +130,12 @@ export class Processor {
       // mounted on t.
       if (typeof p === 'string') {
         // must be final entry
-        const ifDir = p === '..' || p === '' || p === '.'
-        this.matches.add(t.resolve(p), absolute, ifDir)
+        if (!rest) {
+          const ifDir = p === '..' || p === '' || p === '.'
+          this.matches.add(t.resolve(p), absolute, ifDir)
+        } else {
+          this.subwalks.add(t, pattern)
+        }
         continue
       } else if (p === GLOBSTAR) {
         // if no rest, match and subwalk pattern
diff --git a/src/walker.ts b/src/walker.ts
index 4263a0b4..b0837913 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -1,8 +1,8 @@
 // TODO: provide all the same iteration patterns that PathScurry has
 // - [x] walk
 // - [x] walkSync
-// - [ ] stream
-// - [ ] streamSync
+// - [x] stream
+// - [x] streamSync
 // - [ ] iterator
 // - [ ] iteratorSync
 
@@ -25,7 +25,7 @@
 import Minipass from 'minipass'
 import { Path } from 'path-scurry'
 
-import { MMPattern, GLOBSTAR } from './matcher.js'
+import { GLOBSTAR, MMPattern } from './matcher.js'
 import { Pattern } from './pattern.js'
 import { Processor } from './processor.js'
 
@@ -144,10 +144,10 @@ export abstract class GlobUtil {
   }
   resume() {
     this.paused = false
-    let fn: (() => any) | undefined = undefined
-    while (!this.paused && (fn = this.#onResume.shift())) {
+    const fns = this.#onResume.slice()
+    this.#onResume.length = 0
+    for (const fn of fns) {
       fn()
-      if (this.paused) break
     }
   }
   onResume(fn: () => any) {
@@ -281,6 +281,7 @@ export abstract class GlobUtil {
   abstract matchEmit(p: string | Path): void
 
   matchFinish(e: Path, absolute: boolean) {
+    if (this.seen.has(e)) return
     this.seen.add(e)
     const mark = this.opts.mark && e.isDirectory() ? '/' : ''
     // ok, we have what we need!
@@ -414,6 +415,7 @@ export abstract class GlobUtil {
     }
 
     for (const [m, absolute, ifDir] of processor.matches.entries()) {
+      if (this.seen.has(m)) continue
       tasks++
       this.match(m, absolute, ifDir).then(() => next())
     }
@@ -448,6 +450,7 @@ export abstract class GlobUtil {
     }
 
     for (const [m, absolute, ifDir] of processor.matches.entries()) {
+      if (this.seen.has(m)) continue
       tasks++
       this.match(m, absolute, ifDir).then(() => next())
     }
@@ -490,6 +493,7 @@ export abstract class GlobUtil {
     }
 
     for (const [m, absolute, ifDir] of processor.matches.entries()) {
+      if (this.seen.has(m)) continue
       this.matchSync(m, absolute, ifDir)
     }
 
@@ -516,6 +520,7 @@ export abstract class GlobUtil {
     }
 
     for (const [m, absolute, ifDir] of processor.matches.entries()) {
+      if (this.seen.has(m)) continue
       this.matchSync(m, absolute, ifDir)
     }
     for (const [target, patterns] of processor.subwalks.entries()) {
@@ -586,6 +591,7 @@ export class GlobStream<
 
   matchEmit(e: Result): void
   matchEmit(e: Path | string): void {
+    if (e === '') e = '.'
     if (!this.results.write(e)) this.pause()
   }
 

From b892705089d04dbf05899dc8170edb0f63f93d6c Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 17:11:17 -0800
Subject: [PATCH 081/163] Revert "pull in the matcher, use simpler regexen"

This reverts commit 4c2c2c26ba887c61436093eacf0bd261ec9ac6b5.

It's a cool approach, but it didn't improve performance, and means
losing easy ways to implement Ignore and hasMagic.
---
 package-lock.json |  14 --
 package.json      |   2 -
 src/compiler.ts   | 521 ----------------------------------------------
 src/glob.ts       |  75 +++++--
 src/has-magic.ts  |  20 ++
 src/index.ts      |   3 +
 src/matcher.ts    | 338 ------------------------------
 src/pattern.ts    | 245 ++++++++++++++++------
 src/processor.ts  |  87 ++++----
 src/timer.ts      |  24 ---
 src/walker.ts     |   5 +-
 11 files changed, 299 insertions(+), 1035 deletions(-)
 delete mode 100644 src/compiler.ts
 create mode 100644 src/has-magic.ts
 delete mode 100644 src/matcher.ts
 delete mode 100644 src/timer.ts

diff --git a/package-lock.json b/package-lock.json
index 3ad54c18..198bbd14 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,14 +9,12 @@
       "version": "9.0.0-0",
       "license": "ISC",
       "dependencies": {
-        "brace-expansion": "^2.0.1",
         "fs.realpath": "^1.0.0",
         "minimatch": "^7.0.0",
         "minipass": "^4.0.3",
         "path-scurry": "^1.4.0"
       },
       "devDependencies": {
-        "@types/brace-expansion": "^1.1.0",
         "@types/mkdirp": "^1.0.2",
         "@types/node": "^18.11.18",
         "@types/tap": "^15.0.7",
@@ -630,12 +628,6 @@
       "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
       "dev": true
     },
-    "node_modules/@types/brace-expansion": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@types/brace-expansion/-/brace-expansion-1.1.0.tgz",
-      "integrity": "sha512-SaU/Kgp6z40CiF9JxlsrSrBEa+8YIry9IiCPhhYSNekeEhIAkY7iyu9aZ+5dSQIdo7mf86MUVvxWYm5GAzB/0g==",
-      "dev": true
-    },
     "node_modules/@types/istanbul-lib-coverage": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
@@ -6825,12 +6817,6 @@
       "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
       "dev": true
     },
-    "@types/brace-expansion": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@types/brace-expansion/-/brace-expansion-1.1.0.tgz",
-      "integrity": "sha512-SaU/Kgp6z40CiF9JxlsrSrBEa+8YIry9IiCPhhYSNekeEhIAkY7iyu9aZ+5dSQIdo7mf86MUVvxWYm5GAzB/0g==",
-      "dev": true
-    },
     "@types/istanbul-lib-coverage": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
diff --git a/package.json b/package.json
index 003db05b..06f27698 100644
--- a/package.json
+++ b/package.json
@@ -58,14 +58,12 @@
     "endOfLine": "lf"
   },
   "dependencies": {
-    "brace-expansion": "^2.0.1",
     "fs.realpath": "^1.0.0",
     "minimatch": "^7.0.0",
     "minipass": "^4.0.3",
     "path-scurry": "^1.4.0"
   },
   "devDependencies": {
-    "@types/brace-expansion": "^1.1.0",
     "@types/mkdirp": "^1.0.2",
     "@types/node": "^18.11.18",
     "@types/tap": "^15.0.7",
diff --git a/src/compiler.ts b/src/compiler.ts
deleted file mode 100644
index c2f7aa95..00000000
--- a/src/compiler.ts
+++ /dev/null
@@ -1,521 +0,0 @@
-import { GLOBSTAR, MatcherOpts, MMPattern } from './matcher.js'
-
-const charUnescape = (s: string) => s.replace(/\\([^-\]])/g, '$1')
-const braceEscape = (s: string) => s.replace(/[[\]\\]/g, '\\$&')
-const globSpecialChars = new Set(['?', '*', '+', '@', '!', '[', '('])
-const escapeInClass = new Set(['-', ']'])
-const regExpEscape = (s: string) =>
-  s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
-
-export const compile = (
-  pattern: string,
-  options: MatcherOpts
-): MMPattern => {
-  if (pattern === '**') return GLOBSTAR
-  if (pattern === '') return ''
-
-  let m: RegExpMatchArray | null
-  let fastTest: null | ((f: string) => boolean) = null
-  if ((m = pattern.match(starRE))) {
-    fastTest = options.dot ? starTestDot : starTest
-  } else if ((m = pattern.match(starDotExtRE))) {
-    fastTest = (
-      options.nocase
-        ? options.dot
-          ? starDotExtTestNocaseDot
-          : starDotExtTestNocase
-        : options.dot
-        ? starDotExtTestDot
-        : starDotExtTest
-    )(m[1])
-  } else if ((m = pattern.match(qmarksRE))) {
-    fastTest = (
-      options.nocase
-        ? options.dot
-          ? qmarksTestNocaseDot
-          : qmarksTestNocase
-        : options.dot
-        ? qmarksTestDot
-        : qmarksTest
-    )(m)
-  } else if ((m = pattern.match(starDotStarRE))) {
-    fastTest = options.dot ? starDotStarTestDot : starDotStarTest
-  } else if ((m = pattern.match(dotStarRE))) {
-    fastTest = dotStarTest
-  }
-
-  if (fastTest) {
-    return Object.assign(/$./, {
-      _glob: pattern,
-      test: fastTest,
-    })
-  } else {
-    // ok we have to actually compile it
-    const re = compilePattern(pattern, options)
-    return typeof re === 'string'
-      ? re
-      : Object.assign(re, {
-          _glob: pattern,
-        })
-  }
-}
-
-const compilePattern = (
-  pattern: string,
-  options: MatcherOpts
-): MMPattern => {
-  const ast = tokenize(pattern, options)
-  if (ast.length === 1 && ast[0][TokenField.TYPE] === TokenType.STRING) {
-    return ast[0][TokenField.VALUE]
-  }
-  const re = assemble(ast, options, true)
-  try {
-    return new RegExp(re, options.nocase ? 'i' : '')
-  } catch (er) {
-    return /$./
-  }
-}
-
-// Optimized checking for the most common glob patterns.
-const starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/
-const starDotExtTest = (ext: string) => (f: string) =>
-  !f.startsWith('.') && f.endsWith(ext)
-const starDotExtTestDot = (ext: string) => (f: string) => f.endsWith(ext)
-const starDotExtTestNocase = (ext: string) => {
-  ext = ext.toLowerCase()
-  return (f: string) => !f.startsWith('.') && f.toLowerCase().endsWith(ext)
-}
-const starDotExtTestNocaseDot = (ext: string) => {
-  ext = ext.toLowerCase()
-  return (f: string) => f.toLowerCase().endsWith(ext)
-}
-const starDotStarRE = /^\*+\.\*+$/
-const starDotStarTest = (f: string) =>
-  !f.startsWith('.') && f.includes('.')
-const starDotStarTestDot = (f: string) =>
-  f !== '.' && f !== '..' && f.includes('.')
-const dotStarRE = /^\.\*+$/
-const dotStarTest = (f: string) =>
-  f !== '.' && f !== '..' && f.startsWith('.')
-const starRE = /^\*+$/
-const starTest = (f: string) => f.length !== 0 && !f.startsWith('.')
-const starTestDot = (f: string) =>
-  f.length !== 0 && f !== '.' && f !== '..'
-const qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/
-const qmarksTestNocase = ([$0, ext = '']: RegExpMatchArray) => {
-  const noext = qmarksTestNoExt([$0])
-  if (!ext) return noext
-  ext = ext.toLowerCase()
-  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)
-}
-const qmarksTestNocaseDot = ([$0, ext = '']: RegExpMatchArray) => {
-  const noext = qmarksTestNoExtDot([$0])
-  if (!ext) return noext
-  ext = ext.toLowerCase()
-  return (f: string) => noext(f) && f.toLowerCase().endsWith(ext)
-}
-const qmarksTestDot = ([$0, ext = '']: RegExpMatchArray) => {
-  const noext = qmarksTestNoExtDot([$0])
-  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)
-}
-const qmarksTest = ([$0, ext = '']: RegExpMatchArray) => {
-  const noext = qmarksTestNoExt([$0])
-  return !ext ? noext : (f: string) => noext(f) && f.endsWith(ext)
-}
-const qmarksTestNoExt = ([$0]: RegExpMatchArray) => {
-  const len = $0.length
-  return (f: string) => f.length === len && !f.startsWith('.')
-}
-const qmarksTestNoExtDot = ([$0]: RegExpMatchArray) => {
-  const len = $0.length
-  return (f: string) => f.length === len && f !== '.' && f !== '..'
-}
-
-// TOKENIZING
-
-type AST = Token[]
-type ExtToken = [t: TokenType.EXT, value: ExtGlobType, children: AST[]]
-const isExtToken = (t: Token): t is ExtToken =>
-  t[TokenField.TYPE] === TokenType.EXT
-type StringToken = [t: TokenType.STRING, value: string]
-const isStringToken = (t: Token): t is StringToken =>
-  t[TokenField.TYPE] === TokenType.STRING
-type StarToken = [t: TokenType.STAR, value: '*']
-const isStarToken = (t: Token): t is StarToken =>
-  t[TokenField.TYPE] === TokenType.STAR
-type QmarkToken = [t: TokenType.QMARK, value: '?']
-const isQmarkToken = (t: Token): t is QmarkToken =>
-  t[TokenField.TYPE] === TokenType.QMARK
-type ClassToken = [t: TokenType.CLASS, value: string]
-const isClassToken = (t: Token): t is ClassToken =>
-  t[TokenField.TYPE] === TokenType.CLASS
-type Token = ExtToken | StringToken | StarToken | QmarkToken | ClassToken
-
-enum TokenField {
-  TYPE,
-  VALUE,
-  CHILDREN,
-}
-enum TokenType {
-  STRING,
-  STAR,
-  EXT,
-  QMARK,
-  CLASS,
-}
-
-type ExtGlobType = '?' | '*' | '+' | '@' | '!'
-const extGlobTypes: Set = new Set(['?', '*', '+', '@', '!'])
-const isExtGlobType = (s: string): s is ExtGlobType =>
-  extGlobTypes.has(s as ExtGlobType)
-
-const extTypes: { [k in ExtGlobType]: { open: string; close: string } } = {
-  '!': { open: '(?:(?!(?:', close: ').*?))' },
-  '?': { open: '(?:', close: ')?' },
-  '+': { open: '(?:', close: ')+' },
-  '*': { open: '(?:', close: ')*' },
-  '@': { open: '(?:', close: ')' },
-}
-
-const tokenize = (
-  pattern: string,
-  options: MatcherOpts,
-  ast: AST = []
-): AST => {
-  // tokenize the string up into chunks first
-  // sort of like an AST of the pattern
-  // each node is [type, value, [...children]]
-  // root, or children of extglobs, are an array of nodes
-  // so 'i\?jk?*.@(xy[a-c]|!(foo|ba*r))baz*bo' becomes:
-  // [
-  //  [STRING, 'i?jk'],
-  //  [QMARK, '?'],
-  //  [STAR, '*'],
-  //  [STRING, '.'],
-  //  [EXT, '@', [
-  //    [[STRING, 'xy'], [CLASS, 'a-c']],
-  //    [[EXT, '!', [
-  //      [[STRING, 'foo']],
-  //      [[STRING, 'ba'], [STAR, '*'], [STRING, 'r']]
-  //    ]]],
-  //  ]],
-  //  [STRING, 'baz'],
-  //  [STAR, '*'],
-  //  [STRING, 'bo'],
-  // ]
-  //
-  // which turns into the regexp:
-  // ^i\?jk..*?\.(?:xy[a-c]|(?:(?!(?:foo|ba.*?r).*$)))baz.*?bo$
-  // Place the "no dot allowed" if the AST starts at position 0,
-  // and is a *, ?, or class at the start
-  let i: number = 0
-  const length = pattern.length
-  while (i < length) {
-    let c = pattern.charAt(i)
-    // take our best guess as to what it is
-    // the other tokenizers will append to the AST and return
-    // the amount of string that was consumed.
-    if (
-      !options.noext &&
-      isExtGlobType(c) &&
-      pattern.charAt(i + 1) === '('
-    ) {
-      const consumed = tokenizeExt(pattern, options, i, ast)
-      if (consumed) {
-        i += consumed
-        c = pattern.charAt(i)
-        continue
-      }
-    }
-    if (c === '[') {
-      const consumed = tokenizeClass(pattern, options, i, ast)
-      if (consumed) {
-        i += consumed
-        continue
-      }
-    }
-    if (c === '*') {
-      ast.push([TokenType.STAR, '*'])
-    } else if (c === '?') {
-      ast.push([TokenType.QMARK, '?'])
-    } else {
-      const consumed = tokenizeNonMagic(pattern, options, i, ast)
-      if (consumed) {
-        i += consumed
-        c = pattern.charAt(i)
-        continue
-      }
-    }
-    i++
-  }
-  return ast
-}
-
-const tokenizeExt = (
-  pattern: string,
-  options: MatcherOpts,
-  i: number,
-  ast: AST
-): number => {
-  const extType = pattern.charAt(i)
-  if (!isExtGlobType(extType)) {
-    throw new Error('invalid extglob type: ' + extType)
-  }
-  const matchStack: string[] = []
-  const pipes: number[] = []
-  let p: number
-  const length = pattern.length
-  let end = -1
-  let escaping = false
-
-  // first split out the top-level set of strings
-  // if we can't do that, it's not a valid extglob
-  for (p = i + 2; p < length; p++) {
-    const c = pattern.charAt(p)
-    if (escaping) {
-      escaping = false
-      continue
-    }
-    if (c === '\\') {
-      escaping = true
-      continue
-    }
-    if (c === ']') {
-      if (matchStack[0] === '[' && pattern.charAt(p - 1) !== '[') {
-        matchStack.shift()
-      }
-    } else if (c === ')') {
-      if (!matchStack.length) {
-        // finished!
-        end = p
-        break
-      } else if (matchStack[0] === '(') {
-        matchStack.shift()
-      }
-    } else if (c === '(') {
-      if (matchStack[0] !== '[' && isExtGlobType(pattern.charAt(p - 1))) {
-        matchStack.unshift(c)
-      }
-    } else if (c === '|' && matchStack.length === 0) {
-      pipes.push(p)
-    }
-  }
-
-  if (!end || matchStack.length) {
-    return 0
-  }
-
-  // i + 1, pipes, and end define the outside boundaries of the subs
-  const subPatterns: string[] = []
-  let start = i + 2
-  for (const pipe of pipes) {
-    subPatterns.push(pattern.substring(start, pipe))
-    start = pipe + 1
-  }
-  subPatterns.push(pattern.substring(start, end))
-
-  const subTokenized = subPatterns.map(p => tokenize(p, options))
-  ast.push([TokenType.EXT, extType, subTokenized])
-  return end - i + 1
-}
-
-const tokenizeClass = (
-  pattern: string,
-  _: MatcherOpts,
-  i: number,
-  ast: AST
-): number => {
-  // walk until we find the closing ] that is not escaped or the first char
-  // return 0 if it's not a valid class (basically, just if it's left open)
-  let p: number
-  let escaping = false
-  const length = pattern.length
-  let s = ''
-  for (p = i + 1; p < length; p++) {
-    const c = pattern.charAt(p)
-    if (c === '\\' && !escaping) {
-      escaping = true
-      continue
-    }
-    if (p === i + 1 && c === ']') {
-      s += c
-      continue
-    }
-    if (escaping) {
-      escaping = false
-      if (escapeInClass.has(c)) {
-        s += '\\'
-      }
-      s += c
-      continue
-    }
-    if (c === ']') {
-      ast.push([TokenType.CLASS, s])
-      return p - i + 1
-    }
-    s += c
-  }
-  return 0
-}
-
-const tokenizeNonMagic = (
-  pattern: string,
-  _: MatcherOpts,
-  i: number,
-  ast: AST
-): number => {
-  let escaping = false
-  let p = i
-  let sawFirst = false
-  const length = pattern.length
-  let s = ''
-  for (p = i; p < length; p++) {
-    let c = pattern.charAt(p)
-    if (c === '\\' && !escaping) {
-      escaping = true
-      continue
-    }
-
-    if (escaping) {
-      escaping = false
-      s += c
-      continue
-    }
-
-    // this is only called when we KNOW the first char is not magic,
-    // so no need to stop for that at the outset.
-    if (!sawFirst) {
-      sawFirst = true
-      s += c
-      continue
-    }
-
-    if (globSpecialChars.has(c)) {
-      break
-    }
-
-    s += c
-  }
-
-  ast.push([TokenType.STRING, s])
-  return p - i
-}
-
-// COMPILATION
-
-export const assemble = (
-  ast: AST,
-  options: MatcherOpts,
-  isTop = false,
-  isStart = true
-): string => {
-  const negativeExts: number[] = []
-  const re: string[] = []
-  let stillStart = isStart
-  let maybeEmpty = true
-  for (let i = 0; i < ast.length; i++) {
-    const token = ast[i]
-    if (isStringToken(token)) {
-      if (token[TokenField.VALUE] !== '') {
-        maybeEmpty = false
-      }
-      re.push(assembleNonMagic(token, options))
-    } else if (isClassToken(token)) {
-      maybeEmpty = false
-      re.push(assembleClass(token, options))
-    } else if (isExtToken(token)) {
-      if (token[TokenField.VALUE] === '!') {
-        negativeExts.push(i)
-      }
-      re.push(assembleExt(token, options, stillStart))
-    } else if (isQmarkToken(token)) {
-      maybeEmpty = false
-      re.push(assembleQmark(token, options))
-    } else if (isStarToken(token)) {
-      re.push(assembleStar(token, options))
-      /* c8 ignore start */
-    } else {
-      throw new TypeError('unknown token type: ' + token)
-    }
-    /* c8 ignore stop */
-    stillStart = false
-  }
-
-  if (isTop) {
-    re.push('$')
-  }
-
-  // a negative extglob is:
-  // ((?!(sub|patterns)).*?)
-  // so we need to do it in two passes.
-  for (let i = negativeExts.length - 1; i >= 0; i--) {
-    const n = negativeExts[i]
-    re[n] += assembleNegativeExtClose(re, n)
-  }
-  if (isTop) {
-    if (!options.dot && needDotProtection(ast)) {
-      re.unshift('(?!^\\.)')
-    }
-    if (maybeEmpty) {
-      re.unshift('(?=.)')
-    }
-    re.unshift('^')
-  } else if (isStart) {
-    if (!options.dot && needDotProtection(ast)) {
-      re.unshift('(?!^\\.)')
-    }
-  }
-  return re.join('')
-}
-
-const needDotProtection = (ast: AST) => {
-  const first = ast[0]
-  return isClassToken(first) || isStarToken(first) || isQmarkToken(first)
-}
-
-const assembleQmark = (_: QmarkToken, __: MatcherOpts) => '.'
-const assembleStar = (_: StarToken, __: MatcherOpts) => '.*?'
-const assembleNonMagic = (token: StringToken, _: MatcherOpts) =>
-  regExpEscape(token[TokenField.VALUE])
-
-const assembleClass = (token: ClassToken, _: MatcherOpts) => {
-  // TODO: posix classes
-  const cls = braceEscape(charUnescape(token[TokenField.VALUE]))
-  const re = `[${cls}]`
-  // handle out of order classes, like `[z-a]`, which throw
-  // in javascript, but just match nothing in glob syntax.
-  try {
-    RegExp(re)
-    return re
-  } catch (_) {
-    return '$.'
-  }
-}
-
-const assembleExt = (
-  token: ExtToken,
-  options: MatcherOpts,
-  isStart: boolean
-): string => {
-  const t = token[TokenField.VALUE]
-  const open = extTypes[t].open
-  const close = t === '!' ? '' : extTypes[t].close
-  const subs = token[TokenField.CHILDREN]
-  const body = subs
-    .map(ast => assemble(ast, options, false, isStart))
-    .join('|')
-  return open + body + close
-}
-
-const assembleNegativeExtClose = (re: string[], n: number): string => {
-  // walk the AST from i onwards, collecting the regexp
-  // then add the end bit:
-  // ((?!(sub|patterns)).*?)
-  //                  ^-- from here on
-  let s: string = ')'
-  for (let i = n + 1; i < re.length; i++) {
-    s += re[i]
-  }
-  s += ').*?)'
-  return s
-}
diff --git a/src/glob.ts b/src/glob.ts
index c1e14af3..731f4230 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -1,3 +1,4 @@
+import { Minimatch, MinimatchOptions } from 'minimatch'
 import Minipass from 'minipass'
 import {
   Path,
@@ -7,22 +8,23 @@ import {
   PathScurryWin32,
 } from 'path-scurry'
 import { Ignore } from './ignore.js'
-import { Matcher, MatcherOpts } from './matcher.js'
 import { Pattern } from './pattern.js'
 import { GlobStream, GlobWalker, Matches } from './walker.js'
 
+type MatchSet = Minimatch['set']
+type GlobSet = Exclude
+type GlobParts = Exclude
+
 // if no process global, just call it linux.
 // so we default to case-sensitive, / separators
-/* c8 ignore start */
 const defaultPlatform =
   typeof process === 'object' &&
   process &&
   typeof process.platform === 'string'
     ? process.platform
     : 'linux'
-/* c8 ignore stop */
 
-export interface GlobOptions extends MatcherOpts {
+export interface GlobOptions extends MinimatchOptions {
   ignore?: string | string[] | Ignore
   follow?: boolean
   mark?: boolean
@@ -75,8 +77,13 @@ export class Glob {
   nodir: boolean
   nounique: boolean
   cwd: string
+  matchSet: MatchSet
+  globSet: GlobSet
+  globParts: GlobParts
   realpath: boolean
+  nonull: boolean
   absolute: boolean
+  matchBase: boolean
   windowsPathsNoEscape: boolean
   noglobstar: boolean
   matches?: Matches
@@ -87,7 +94,6 @@ export class Glob {
   opts: Opts
   platform?: typeof process.platform
   patterns: Pattern[]
-  matcher: Matcher
 
   constructor(pattern: string | string[], opts: Opts) {
     this.withFileTypes = !!opts.withFileTypes as FileTypes
@@ -107,30 +113,51 @@ export class Glob {
     this.nounique = !!opts.nounique
     this.cwd = opts.cwd || ''
     this.realpath = !!opts.realpath
+    this.nonull = !!opts.nonull
     this.absolute = !!opts.absolute
 
     this.noglobstar = !!opts.noglobstar
+    this.matchBase = !!opts.matchBase
 
     // if we're returning Path objects, we can't do nonull, because
     // the pattern is a string, not a Path
-    if (this.withFileTypes && this.absolute) {
-      throw new Error('cannot set absolute:true and withFileTypes:true')
+    if (this.withFileTypes) {
+      if (this.nonull) {
+        throw new TypeError(
+          'cannot set nonull:true and withFileTypes:true'
+        )
+      }
+      if (this.absolute) {
+        throw new Error('cannot set absolute:true and withFileTypes:true')
+      }
     }
 
-    this.matches = new Set() as Matches
-    this.seen = new Set()
-    this.walked = new Map()
+    // if we want unique entries, we need a single set to hold them all
+    if (!this.nounique) {
+      this.matches = new Set() as Matches
+      this.seen = new Set()
+      this.walked = new Map()
+    }
 
     if (typeof pattern === 'string') {
       pattern = [pattern]
     }
 
-    this.windowsPathsNoEscape = !!opts.windowsPathsNoEscape
+    this.windowsPathsNoEscape =
+      !!opts.windowsPathsNoEscape ||
+      (opts as GlobOptions).allowWindowsEscape === false
 
     if (this.windowsPathsNoEscape) {
       pattern = pattern.map(p => p.replace(/\\/g, '/'))
     }
 
+    if (this.matchBase) {
+      if (opts.noglobstar) {
+        throw new TypeError('base matching requires globstar')
+      }
+      pattern = pattern.map(p => (p.includes('/') ? p : `**/${p}`))
+    }
+
     this.pattern = pattern
 
     this.platform = opts.platform || defaultPlatform
@@ -148,16 +175,34 @@ export class Glob {
       this.scurry = new Scurry(this.cwd, { nocase: opts.nocase })
     }
 
-    const mmo: MatcherOpts = {
+    const mmo: MinimatchOptions = {
       // default nocase based on platform
       nocase: this.scurry.nocase,
-      platform: this.platform,
       ...opts,
+      nonegate: true,
+      nocomment: true,
+      nocaseMagicOnly: true,
     }
 
     // console.error('glob pattern arg', this.pattern)
-    this.matcher = new Matcher(this.pattern, mmo)
-    this.patterns = this.matcher.patterns
+    const mms = this.pattern.map(p => new Minimatch(p, mmo))
+    const [matchSet, globSet, globParts] = mms.reduce(
+      (set: [MatchSet, GlobSet, GlobParts], m) => {
+        // console.error('globparts', m.globParts)
+        set[0].push(...m.set)
+        set[1].push(...m.globSet)
+        set[2].push(...m.globParts)
+        return set
+      },
+      [[], [], []]
+    )
+    this.patterns = matchSet.map((set, i) => {
+      // console.error('globParts', globParts[i])
+      return new Pattern(set, globParts[i], 0)
+    })
+    this.matchSet = matchSet
+    this.globSet = globSet
+    this.globParts = globParts
   }
 
   async walk(): Promise> {
diff --git a/src/has-magic.ts b/src/has-magic.ts
new file mode 100644
index 00000000..7a88cb0c
--- /dev/null
+++ b/src/has-magic.ts
@@ -0,0 +1,20 @@
+import { Glob, GlobOptions } from './glob.js'
+
+export const hasMagic = (
+  pattern: string | string[],
+  options: GlobOptions = {}
+): boolean => {
+  if (!Array.isArray(pattern)) {
+    pattern = [pattern]
+  }
+  return pattern.some(p => {
+    const g = new Glob(p, options)
+    if (g.matchSet.length === 0) {
+      return false
+    }
+    if (g.matchSet.length > 1) {
+      return true
+    }
+    return g.matchSet[0].some(p => typeof p !== 'string')
+  })
+}
diff --git a/src/index.ts b/src/index.ts
index e24d1a17..a64972de 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,6 @@
 import Minipass from 'minipass'
 import { Glob, GlobOptions } from './glob.js'
+import { hasMagic } from './has-magic.js'
 
 export const globStreamSync = (
   pattern: string | string[],
@@ -36,11 +37,13 @@ export const glob = Object.assign(
     globStream,
     globStreamSync,
     Glob,
+    hasMagic,
   }
 )
 
 /* c8 ignore start */
 export { Glob } from './glob.js'
 export type { GlobOptions } from './glob.js'
+export { hasMagic } from './has-magic.js'
 export default glob
 /* c8 ignore stop */
diff --git a/src/matcher.ts b/src/matcher.ts
deleted file mode 100644
index 4cd49d8b..00000000
--- a/src/matcher.ts
+++ /dev/null
@@ -1,338 +0,0 @@
-// this is a much more "mini" minimatch, optimized for use in a recursive
-// glob walk.  So we build up the 2d array of pattern portions, and do
-// the preprocessing to make the glob patterns as efficient as possible,
-// but do *not* generate the big honkin complicated regexp to test an
-// entire path string.
-
-import expand from 'brace-expansion'
-
-export const GLOBSTAR = Symbol('**')
-
-import { GlobList, Compiled, Pattern } from './pattern.js'
-
-export type MMPattern = string | RegExp | typeof GLOBSTAR
-
-export interface MatcherOpts {
-  dot?: boolean
-  nocase?: boolean
-  noext?: boolean
-  noglobstar?: boolean
-  nobrace?: boolean
-  windowsPathsNoEscape?: boolean
-  platform?: typeof process.platform
-}
-
-/* c8 ignore start */
-// TODO: make this non-optional, pass in via Glob options
-const defaultPlatform: typeof process.platform =
-  typeof process === 'object' &&
-  !!process &&
-  typeof process.platform === 'string'
-    ? process.platform
-    : 'linux'
-/* c8 ignore stop */
-
-export class Matcher {
-  options: MatcherOpts
-  globLists: GlobList[]
-  patterns: Pattern[]
-
-  dot: boolean
-  nocase: boolean
-  noext: boolean
-  noglobstar: boolean
-  nobrace: boolean
-  windowsPathsNoEscape: boolean
-  platform: typeof process.platform
-  isWindows: boolean
-
-  constructor(patterns: string | string[], opts: MatcherOpts = {}) {
-    const {
-      dot = false,
-      nocase,
-      noext = false,
-      noglobstar = false,
-      nobrace = false,
-      windowsPathsNoEscape = false,
-      platform = defaultPlatform,
-    } = opts
-    this.dot = dot
-    this.noext = noext
-    this.noglobstar = noglobstar
-    this.nobrace = nobrace
-    this.windowsPathsNoEscape = windowsPathsNoEscape
-    this.platform = platform
-    this.nocase =
-      nocase !== undefined
-        ? nocase
-        : this.platform === 'win32' || this.platform === 'darwin'
-    this.isWindows = this.platform === 'win32'
-
-    opts = {
-      dot: this.dot,
-      nocase: this.nocase,
-      noext: this.noext,
-      noglobstar: this.noglobstar,
-      nobrace: this.nobrace,
-      windowsPathsNoEscape: this.windowsPathsNoEscape,
-      platform: this.platform,
-    }
-    this.options = opts
-
-    if (!patterns) throw new TypeError('pattern required')
-    if (!Array.isArray(patterns)) patterns = [patterns]
-    if (opts.windowsPathsNoEscape) {
-      patterns = patterns.map(p => p.replace(/\\/g, '/'))
-    }
-    this.globLists = this.preprocess(
-      patterns
-        .map(p => braceExpand(p, this.options))
-        .reduce((ps, p) => ps.concat(p), [])
-        .map(p => this.splitGlobString(p))
-        .filter(gl => !!gl.length)
-    ) as GlobList[]
-
-    const compiled: Compiled = new Map()
-    this.patterns = this.globLists.map(
-      gl => new Pattern(gl, 0, compiled, opts)
-    )
-  }
-
-  splitGlobString(globString: string) {
-    const parts = globString.split('/')
-    // canonincalize UNC paths and drives, make the first
-    // pattern the whole root ending in / for absolute patterns.
-    if (this.isUNC(parts)) {
-      const [p0, p1, p2] = parts
-      parts.shift()
-      parts.shift()
-      parts.shift()
-      parts.unshift([p0, p1, p2, ''].join('/').toUpperCase())
-    } else if (this.isDrive(parts)) {
-      const drive = parts[0].toUpperCase() + '/'
-      parts.shift()
-      parts.unshift(drive)
-    } else if (parts[0] === '') {
-      parts[0] = '/'
-    }
-
-    // now strip any empty parts
-    return parts.filter((p, i) => !!p || i === parts.length - 1)
-  }
-
-  isDrive(pl: string[]): boolean {
-    return (
-      this.isWindows &&
-      typeof pl[0] === 'string' &&
-      /^[a-z]:$/i.test(pl[0])
-    )
-  }
-
-  isUNC(pl: string[]): boolean {
-    return (
-      this.isWindows &&
-      pl[0] === '' &&
-      pl[1] === '' &&
-      typeof pl[2] === 'string' &&
-      !!pl[2] &&
-      typeof pl[3] === 'string' &&
-      !!pl[3]
-    )
-  }
-
-  preprocess(globParts: string[][]) {
-    // if we're not in globstar mode, then turn all ** into *
-    if (this.noglobstar) {
-      for (let i = 0; i < globParts.length; i++) {
-        for (let j = 0; j < globParts[i].length; j++) {
-          if (globParts[i][j] === '**') {
-            globParts[i][j] = '*'
-          }
-        }
-      }
-    }
-
-    globParts = this.firstPhasePreProcess(globParts)
-    globParts = this.secondPhasePreProcess(globParts)
-
-    return globParts
-  }
-
-  // First phase: single-pattern processing
-  // 
 is 1 or more portions
-  //  is 1 or more portions
-  // 

is any portion other than ., .., '', or ** - // is . or '' - // - // **/.. is *brutal* for filesystem walking performance, because - // it effectively resets the recursive walk each time it occurs, - // and ** cannot be reduced out by a .. pattern part like a regexp - // or most strings (other than .., ., and '') can be. - // - //

/**/../

/ -> {

/../

/,

/**/

/} - //

// -> 
/
-  // 
/

/../ ->

/
-  // **/**/ -> **/
-  //
-  // **/*/ -> */**/ <== not valid because ** doesn't follow
-  // this WOULD be allowed if ** did follow symlinks, or * didn't
-  firstPhasePreProcess(globParts: string[][]) {
-    let didSomething = false
-    do {
-      didSomething = false
-      // 
/**/../

/ -> {

/../

/,

/**/

/} - for (let parts of globParts) { - let gs: number = -1 - while (-1 !== (gs = parts.indexOf('**', gs + 1))) { - let gss: number = gs - while (parts[gss + 1] === '**') { - //

/**/**/ -> 
/**/
-            gss++
-          }
-          // eg, if gs is 2 and gss is 4, that means we have 3 **
-          // parts, and can remove 2 of them.
-          if (gss > gs) {
-            parts.splice(gs + 1, gss - gs)
-          }
-
-          let next = parts[gs + 1]
-          const p = parts[gs + 2]
-          if (next !== '..') continue
-          if (!p || p === '.' || p === '..') continue
-          didSomething = true
-          // edit parts in place, and push the new one
-          parts.splice(gs, 1)
-          const other = parts.slice(0)
-          other[gs] = '**'
-          globParts.push(other)
-          gs--
-        }
-
-        // 
// -> 
/
-        for (let i = 1; i < parts.length - 1; i++) {
-          const p = parts[i]
-          // don't squeeze out UNC patterns
-          if (i === 1 && p === '' && parts[0] === '') continue
-          if (p === '.' || p === '') {
-            didSomething = true
-            parts.splice(i, 1)
-            i--
-          }
-        }
-        if (parts[0] === '.') {
-          didSomething = true
-          parts.shift()
-        }
-
-        // 
/

/../ ->

/
-        let dd: number = 0
-        while (-1 !== (dd = parts.indexOf('..', dd + 1))) {
-          const p = parts[dd - 1]
-          if (p && p !== '.' && p !== '..' && p !== '**') {
-            didSomething = true
-            parts.splice(dd - 1, 2)
-            if (parts.length === 0) parts.push('')
-            dd -= 2
-          }
-        }
-      }
-    } while (didSomething)
-
-    return globParts
-  }
-
-  // second phase: multi-pattern dedupes
-  // {
/*/,
/

/} ->

/*/
-  // {
/,
/} -> 
/
-  // {
/**/,
/} -> 
/**/
-  //
-  // {
/**/,
/**/

/} ->

/**/
-  // ^-- not valid because ** doens't follow symlinks
-  secondPhasePreProcess(globParts: string[][]): string[][] {
-    for (let i = 0; i < globParts.length - 1; i++) {
-      for (let j = i + 1; j < globParts.length; j++) {
-        const matched = this.partsMatch(globParts[i], globParts[j])
-        if (!matched) continue
-        globParts[i] = matched
-        globParts[j] = []
-      }
-    }
-    return globParts.filter(gs => gs.length)
-  }
-
-  partsMatch(a: string[], b: string[]): false | string[] {
-    let ai = 0
-    let bi = 0
-    let result: string[] = []
-    let which: string = ''
-    while (ai < a.length && bi < b.length) {
-      if (a[ai] === b[bi]) {
-        result.push(which === 'b' ? b[bi] : a[ai])
-        ai++
-        bi++
-      } else if (a[ai] === '**' && b[bi] === a[ai + 1]) {
-        result.push(a[ai])
-        ai++
-      } else if (b[bi] === '**' && a[ai] === b[bi + 1]) {
-        result.push(b[bi])
-        bi++
-      } else if (
-        a[ai] === '*' &&
-        b[bi] &&
-        !b[bi].startsWith('.') &&
-        b[bi] !== '**'
-      ) {
-        if (which === 'b') return false
-        which = 'a'
-        result.push(a[ai])
-        ai++
-        bi++
-      } else if (
-        b[bi] === '*' &&
-        a[ai] &&
-        (this.dot || !a[ai].startsWith('.')) &&
-        a[ai] !== '**'
-      ) {
-        if (which === 'a') return false
-        which = 'b'
-        result.push(b[bi])
-        ai++
-        bi++
-      } else {
-        return false
-      }
-    }
-    // if we fall out of the loop, it means they two are identical
-    // as long as their lengths match
-    return a.length === b.length && result
-  }
-}
-
-export const braceExpand = (
-  pattern: string,
-  options: MatcherOpts = {}
-) => {
-  assertValidPattern(pattern)
-
-  // Thanks to Yeting Li  for
-  // improving this regexp to avoid a ReDOS vulnerability.
-  if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
-    // shortcut. no need to expand.
-    return [pattern]
-  }
-
-  return expand(pattern)
-}
-
-const MAX_PATTERN_LENGTH = 1024 * 64
-const assertValidPattern: (pattern: any) => void = (
-  pattern: any
-): asserts pattern is string => {
-  if (typeof pattern !== 'string') {
-    throw new TypeError('invalid pattern')
-  }
-
-  if (pattern.length > MAX_PATTERN_LENGTH) {
-    throw new TypeError('pattern is too long')
-  }
-}
diff --git a/src/pattern.ts b/src/pattern.ts
index bcf00838..fb42b62f 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -1,82 +1,140 @@
 // this is just a very light wrapper around 2 arrays with an offset index
-// Pattern objects are effectively an immutable view over an array of
-// glob strings, which can return the compiled part on demand as needed.
 
-import { GLOBSTAR, MatcherOpts, MMPattern } from './matcher.js'
-import { compile } from './compiler.js'
-export type GlobList = [p: string, ...rest: string[]]
-export const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1
+import { GLOBSTAR } from 'minimatch'
+type MMRegExp = RegExp & {
+  _glob?: string
+  _src?: string
+}
+export type MMPattern = string | MMRegExp | typeof GLOBSTAR
+
+// an array of length >= 1
+type PatternList = [p: MMPattern, ...rest: MMPattern[]]
+type UNCPatternList = [
+  p0: '',
+  p1: '',
+  p2: string,
+  p3: string,
+  ...rest: MMPattern[]
+]
+type DrivePatternList = [p0: string, ...rest: MMPattern[]]
+type AbsolutePatternList = [p0: '', ...rest: MMPattern[]]
+type GlobList = [p: string, ...rest: string[]]
 
-export type Compiled = Map
+// TODO: this should be a parameter
+const isWin = process.platform === 'win32'
+const isPatternList = (pl: MMPattern[]): pl is PatternList =>
+  pl.length >= 1
+const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1
 
 export class Pattern {
-  #options: MatcherOpts
-  #globList: GlobList
+  readonly patternList: PatternList
+  readonly globList: GlobList
+  readonly #index: number
   readonly length: number
-  #index: number
-  #compiled: Compiled
-
-  // memoizing
-  #pattern?: MMPattern
   #rest?: Pattern | null
   #globString?: string
+  #isDrive?: boolean
+  #isUNC?: boolean
+  #isAbsolute?: boolean
 
   constructor(
-    globList: GlobList,
-    index: number,
-    compiled: Compiled,
-    options: MatcherOpts
+    patternList: MMPattern[],
+    globList: string[],
+    index: number
   ) {
+    if (!isPatternList(patternList)) {
+      throw new TypeError('empty pattern list')
+    }
     if (!isGlobList(globList)) {
       throw new TypeError('empty glob list')
     }
-    this.#globList = globList
-    if (index >= globList.length) {
+    if (globList.length !== patternList.length) {
+      throw new TypeError('mismatched pattern list and glob list lengths')
+    }
+    this.length = patternList.length
+    if (index >= this.length) {
       throw new TypeError('index out of range')
     }
-    this.length = globList.length
-    this.#options = options
+    this.patternList = patternList
+    this.globList = globList
     this.#index = index
-    this.#compiled = compiled
-  }
 
-  glob(): string {
-    return this.#globList[this.#index]
-  }
+    // if the current item is not globstar, and the next item is .., skip ahead
+    if (
+      this.patternList[this.#index] !== GLOBSTAR &&
+      this.patternList[this.#index] !== '..' &&
+      this.patternList[this.#index] !== '.' &&
+      this.patternList[this.#index] !== '' &&
+      this.patternList[this.#index + 1] === '..' &&
+      this.length > this.#index + 2
+    ) {
+      this.#index += 2
+    }
 
-  isGlobstar(): boolean {
-    return this.pattern() === GLOBSTAR
-  }
-  isRegExp(): boolean {
-    return this.pattern() instanceof RegExp
-  }
-  isString(): boolean {
-    return typeof this.pattern() === 'string'
+    // normalize root entries of absolute patterns on initial creation.
+    if (this.#index === 0) {
+      // c: => ['c:/']
+      // C:/ => ['C:/']
+      // C:/x => ['C:/', 'x']
+      // //host/share => ['//host/share/']
+      // //host/share/ => ['//host/share/']
+      // //host/share/x => ['//host/share/', 'x']
+      // /etc => ['/', 'etc']
+      // / => ['/']
+      if (this.isUNC()) {
+        const [p1, p2, p3, ...prest] = this.patternList
+        const [g1, g2, g3, ...grest] = this.globList
+        if (prest[0] === '') {
+          // ends in /
+          prest.shift()
+          grest.shift()
+        }
+        const p = [p1, p2, p3, ''].join('/')
+        const g = [g1, g2, g3, ''].join('/')
+        this.patternList = [p, ...prest]
+        this.globList = [g, ...grest]
+        this.length = this.patternList.length
+      } else if (this.isDrive() || this.isAbsolute()) {
+        const [p1, ...prest] = this.patternList
+        const [g1, ...grest] = this.globList
+        if (prest[0] === '') {
+          // ends in /
+          prest.shift()
+          grest.shift()
+        }
+        const p = (p1 as string) + '/'
+        const g = g1 + '/'
+        this.patternList = [p, ...prest]
+        this.globList = [g, ...grest]
+        this.length = this.patternList.length
+      }
+    } else {
+      // discard any empty path portions, except the last one.
+      while (this.#index < this.length - 1 && this.pattern() === '') {
+        this.#index++
+      }
+    }
   }
 
   pattern(): MMPattern {
-    if (this.#pattern !== undefined) {
-      return this.#pattern
-    }
-    const glob = this.glob()
-    if (glob.endsWith('/')) {
-      return (this.#pattern = glob)
-    }
-    const cached = this.#compiled.get(glob)
-    if (cached !== undefined) {
-      return (this.#pattern = cached)
-    }
-    const pattern = compile(glob, this.#options)
-    this.#compiled.set(glob, pattern)
-    return (this.#pattern = pattern)
+    return this.patternList[this.#index]
   }
 
-  isAbsolute(): boolean {
-    return this.#globList[0].endsWith('/')
+  isString(): boolean {
+    return typeof this.patternList[this.#index] === 'string'
+  }
+  isGlobstar(): boolean {
+    return this.patternList[this.#index] === GLOBSTAR
+  }
+  isGlobstarDotDot(): boolean {
+    return this.isGlobstar() && this.globList[this.#index + 1] === '..'
+  }
+  isRegExp(): boolean {
+    return this.patternList[this.#index] instanceof RegExp
   }
 
-  root(): string {
-    return this.#index === 0 && this.isAbsolute() ? this.#globList[0] : ''
+  glob(): string {
+    return this.globList[this.#index]
   }
 
   globString(): string {
@@ -84,29 +142,78 @@ export class Pattern {
       this.#globString ||
       (this.#index === 0
         ? this.isAbsolute()
-          ? this.#globList[0] + this.#globList.slice(1).join('/')
-          : this.#globList.join('/')
-        : this.#globList.slice(this.#index).join('/')))
+          ? this.globList[0] + this.globList.slice(1).join('/')
+          : this.globList.join('/')
+        : this.globList.slice(this.#index).join('/')))
+  }
+
+  hasMore(): boolean {
+    return this.length > this.#index + 1
   }
 
   rest(): Pattern | null {
     if (this.#rest !== undefined) return this.#rest
-    if (this.#index >= this.length - 1) return (this.#rest = null)
-    const rest = new Pattern(
-      this.#globList,
-      this.#index + 1,
-      this.#compiled,
-      this.#options
+    if (!this.hasMore()) return (this.#rest = null)
+    this.#rest = new Pattern(
+      this.patternList,
+      this.globList,
+      this.#index + 1
     )
-    this.#rest = rest
-    return rest
+    this.#rest.#isAbsolute = this.#isAbsolute
+    this.#rest.#isUNC = this.#isUNC
+    this.#rest.#isDrive = this.#isDrive
+    return this.#rest
   }
 
-  hasMore(): this is PatternWithMore {
-    return this.#index < this.length - 1
+  // pattern like: //host/share/...
+  // split = [ '', '', 'host', 'share', ... ]
+  isUNC(pl = this.patternList): pl is UNCPatternList {
+    return this.#isUNC !== undefined
+      ? this.#isUNC
+      : (this.#isUNC =
+          isWin &&
+          this.#index === 0 &&
+          pl[0] === '' &&
+          pl[1] === '' &&
+          typeof pl[2] === 'string' &&
+          !!pl[2] &&
+          typeof pl[3] === 'string' &&
+          !!pl[3])
+  }
+
+  // pattern like C:/...
+  // split = ['C:', ...]
+  // XXX: would be nice to handle patterns like `c:*` to test the cwd
+  // in c: for *, but I don't know of a way to even figure out what that
+  // cwd is without actually chdir'ing into it?
+  isDrive(pl = this.patternList): pl is DrivePatternList {
+    return this.#isDrive !== undefined
+      ? this.#isDrive
+      : (this.#isDrive =
+          isWin &&
+          this.#index === 0 &&
+          this.length > 1 &&
+          typeof pl[0] === 'string' &&
+          /^[a-z]:$/i.test(pl[0]))
   }
-}
 
-interface PatternWithMore extends Pattern {
-  rest(): Pattern
+  // pattern = '/' or '/...' or '/x/...'
+  // split = ['', ''] or ['', ...] or ['', 'x', ...]
+  // Drive and UNC both considered absolute on windows
+  isAbsolute(pl = this.patternList): pl is AbsolutePatternList {
+    return this.#isAbsolute !== undefined
+      ? this.#isAbsolute
+      : (this.#isAbsolute =
+          (pl[0] === '' && pl.length > 1) ||
+          this.isDrive(pl) ||
+          this.isUNC(pl))
+  }
+
+  // consume the root of the pattern, and return it
+  root(): string {
+    const p = this.patternList[0]
+    return typeof p === 'string' && this.isAbsolute() && this.#index === 0
+      ? p
+      : ''
+  }
 }
diff --git a/src/processor.ts b/src/processor.ts
index 5fe51ea8..a6ec4046 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -1,8 +1,8 @@
 // synchronous utility for filtering entries and calculating subwalks
 
+import { GLOBSTAR, MMRegExp } from 'minimatch'
 import { Path } from 'path-scurry'
-import { GLOBSTAR, MMPattern } from './matcher.js'
-import { Pattern } from './pattern.js'
+import { MMPattern, Pattern } from './pattern.js'
 
 class HasWalkedCache {
   store: Map>
@@ -77,7 +77,7 @@ export class Processor {
 
   constructor(hasWalkedCache?: HasWalkedCache) {
     this.hasWalkedCache = hasWalkedCache
-      ? hasWalkedCache //.copy()
+      ? hasWalkedCache.copy()
       : new HasWalkedCache()
   }
 
@@ -172,67 +172,54 @@ export class Processor {
     const patterns = this.subwalks.get(parent)
     // put matches and entry walks into the results processor
     const results = this.child()
-    for (const pattern of patterns) {
-      const p = pattern.pattern()
-      const rest = pattern.rest()
-      const absolute = pattern.isAbsolute()
-      if (p === GLOBSTAR) {
-        results.filterGlobstar(entries, pattern, absolute)
-      } else if (typeof p === 'string') {
-        results.filterString(entries, p, rest, absolute)
-      } else {
-        results.filterRegExp(entries, p, rest, absolute)
+    for (const e of entries) {
+      for (const pattern of patterns) {
+        const absolute = pattern.isAbsolute()
+        const p = pattern.pattern()
+        const rest = pattern.rest()
+        if (p === GLOBSTAR) {
+          results.testGlobstar(e, pattern, absolute)
+        } else if (p instanceof RegExp) {
+          results.testRegExp(e, p, rest, absolute)
+        } else {
+          results.testString(e, p, rest, absolute)
+        }
       }
     }
     return results
   }
 
-  filterGlobstar(entries: Path[], pattern: Pattern, absolute: boolean) {
-    const hasMore = pattern.hasMore()
-    for (const e of entries) {
-      if (!e.name.startsWith('.')) {
-        if (!hasMore) {
-          this.matches.add(e, absolute, false)
-        }
-        if (e.isDirectory()) {
-          this.subwalks.add(e, pattern)
-        }
-      }
+  testGlobstar(e: Path, pattern: Pattern, absolute: boolean) {
+    if (e.name.startsWith('.')) return
+    if (!pattern.hasMore()) {
+      this.matches.add(e, absolute, false)
+    }
+    if (e.isDirectory()) {
+      this.subwalks.add(e, pattern)
     }
   }
 
-  filterRegExp(
-    entries: Path[],
-    p: RegExp,
+  testRegExp(
+    e: Path,
+    p: MMRegExp,
     rest: Pattern | null,
     absolute: boolean
   ) {
-    for (const e of entries) {
-      if (p.test(e.name)) {
-        if (!rest) {
-          this.matches.add(e, absolute, false)
-        } else {
-          this.subwalks.add(e, rest)
-        }
-      }
+    if (!p.test(e.name)) return
+    if (!rest) {
+      this.matches.add(e, absolute, false)
+    } else {
+      this.subwalks.add(e, rest)
     }
   }
 
-  filterString(
-    entries: Path[],
-    p: string,
-    rest: Pattern | null,
-    absolute: boolean
-  ) {
-    for (const e of entries) {
-      // should never happen?
-      if (e.isNamed(p)) {
-        if (!rest) {
-          this.matches.add(e, absolute, false)
-        } else {
-          this.subwalks.add(e, rest)
-        }
-      }
+  testString(e: Path, p: string, rest: Pattern | null, absolute: boolean) {
+    // should never happen?
+    if (!e.isNamed(p)) return
+    if (!rest) {
+      this.matches.add(e, absolute, false)
+    } else {
+      this.subwalks.add(e, rest)
     }
   }
 }
diff --git a/src/timer.ts b/src/timer.ts
deleted file mode 100644
index 30691001..00000000
--- a/src/timer.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-const profile = process.env.__GLOB_PROFILE__ === '1'
-const times = new Map()
-if (profile) {
-  process.on('exit', () => {
-    const print = [...times.entries()].sort(
-      ([_ak, av], [_bk, bv]) => av - bv
-    )
-    console.error(Object.fromEntries(print))
-  })
-}
-export class Timer {
-  name: string
-  start: number
-  constructor(name: string) {
-    this.name = name
-    this.start = profile ? performance.now() : 0
-  }
-  end() {
-    if (profile) {
-      const n = times.get(this.name) || 0
-      times.set(this.name, n + performance.now() - this.start)
-    }
-  }
-}
diff --git a/src/walker.ts b/src/walker.ts
index b0837913..ad35d1f2 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -22,11 +22,12 @@
 //  rely on the Pattern objects being unique, I guess?
 
 // import LRUCache from 'lru-cache'
+import { GLOBSTAR } from 'minimatch'
 import Minipass from 'minipass'
 import { Path } from 'path-scurry'
 
-import { GLOBSTAR, MMPattern } from './matcher.js'
-import { Pattern } from './pattern.js'
+// a single minimatch set entry with 1 or more parts
+import { MMPattern, Pattern } from './pattern.js'
 import { Processor } from './processor.js'
 
 class HasWalkedCache {

From 0321240d43794612551fb0718c26addc4571b233 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 22:45:33 -0800
Subject: [PATCH 082/163] add AbortSignal support

---
 src/glob.ts    |  1 +
 src/readdir.ts | 96 --------------------------------------------------
 src/walker.ts  | 11 ++++++
 3 files changed, 12 insertions(+), 96 deletions(-)
 delete mode 100644 src/readdir.ts

diff --git a/src/glob.ts b/src/glob.ts
index 731f4230..d8ae19ea 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -36,6 +36,7 @@ export interface GlobOptions extends MinimatchOptions {
   withFileTypes?: boolean
   scurry?: PathScurry
   platform?: typeof process.platform
+  signal?: AbortSignal
 }
 
 export type GlobOptionsWithFileTypesTrue = GlobOptions & {
diff --git a/src/readdir.ts b/src/readdir.ts
deleted file mode 100644
index 63e4b3df..00000000
--- a/src/readdir.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-// this is a caching readdir that cuts down on excess syscalls,
-// if the same directory needs to be read multiple times.
-
-import { Dirent } from 'fs'
-
-import {
-  readdir as origReaddir,
-  readdirSync as origReaddirSync,
-  statSync,
-} from 'fs'
-import { basename, dirname, resolve } from 'path'
-
-// when we read a directory, put its entries in here as well
-export interface GlobCache {
-  [path: string]: Dirent[] | false
-}
-
-export class Readdir {
-  cache: GlobCache
-  pcache: { [path: string]: Promise | undefined }
-
-  constructor(cache: GlobCache = Object.create(null)) {
-    this.pcache = Object.create(null)
-    this.cache = cache
-  }
-
-  // look up the Dirent for the path, if it exists
-  lookup(resolved: string): Dirent | undefined {
-    const dir = dirname(resolved)
-    const entities = this.cache[dir]
-    if (entities && Array.isArray(entities)) {
-      return entities.find(e => e.name === basename(resolved))
-    }
-  }
-
-  isDirectory(path: string): boolean {
-    const resolved = resolve(path)
-    const cached = this.cache[resolved]
-    return Array.isArray(cached)
-      ? true
-      : !!this.lookup(resolved)?.isDirectory()
-  }
-
-  async readdir(path: string): Promise {
-    const cacheEntry = this.cache[path]
-    if (cacheEntry !== undefined) {
-      return cacheEntry
-    }
-
-    // const lu = this.lookup(path)
-    // if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) {
-    //   return (this.cache[path] = false)
-    // }
-
-    const pc = this.pcache[path]
-    if (pc) {
-      return pc
-    }
-
-    return (this.pcache[path] = new Promise(res => {
-      origReaddir(path, { withFileTypes: true }, (_, entities) => {
-        this.pcache[path] = undefined
-        res((this.cache[path] = entities || false))
-      })
-    }))
-  }
-
-  readdirSync(path: string): Dirent[] | false {
-    // if (path.startsWith('//')) {
-    //   console.error('WAT', path)
-    // }
-    const cacheEntry = this.cache[path]
-    if (Array.isArray(cacheEntry) || cacheEntry === false) {
-      return cacheEntry
-    }
-
-    // const lu = this.lookup(path)
-    // if (lu && !lu.isDirectory() && !lu.isSymbolicLink()) {
-    //   return (this.cache[path] = false)
-    // }
-
-    // try to avoid getting an error object created if we can
-    // stack traces are expensive, and we don't use them.
-    try {
-      const st = statSync(path, { throwIfNoEntry: false })
-      if (!st || !st.isDirectory()) {
-        return (this.cache[path] = false)
-      }
-      return (this.cache[path] = origReaddirSync(path, {
-        withFileTypes: true,
-      }))
-    } catch (_) {
-      return (this.cache[path] = false)
-    }
-  }
-}
diff --git a/src/walker.ts b/src/walker.ts
index ad35d1f2..a992b731 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -85,6 +85,7 @@ export interface GlobWalkerOpts {
   nodir?: boolean
   mark?: boolean
   withFileTypes?: boolean
+  signal?: AbortSignal
 }
 export type GWOFileTypesTrue = GlobWalkerOpts & {
   withFileTypes: true
@@ -130,6 +131,7 @@ export abstract class GlobUtil {
   opts: O
   seen: Set = new Set()
   paused: boolean = false
+  aborted: boolean = false
   #onResume: (() => any)[] = []
 
   constructor(patterns: Pattern[], path: Path, opts: O)
@@ -137,6 +139,9 @@ export abstract class GlobUtil {
     this.patterns = patterns
     this.path = path
     this.opts = opts
+    if (opts.signal) {
+      opts.signal.addEventListener('abort', () => this.abort())
+    }
   }
 
   // backpressure mechanism
@@ -144,6 +149,7 @@ export abstract class GlobUtil {
     this.paused = true
   }
   resume() {
+    if (this.aborted) return
     this.paused = false
     const fns = this.#onResume.slice()
     this.#onResume.length = 0
@@ -152,9 +158,14 @@ export abstract class GlobUtil {
     }
   }
   onResume(fn: () => any) {
+    if (this.aborted) return
     if (!this.paused) fn()
     else this.#onResume.push(fn)
   }
+  abort() {
+    this.paused = true
+    this.aborted = true
+  }
 
   // do the requisite realpath/stat checking, and return true/false
   // to say whether to include the match or filter it out.

From f63a01b1b5b0a36f57a7d673d82bdbbf1e3dd7a5 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 22:51:28 -0800
Subject: [PATCH 083/163] benchmark updates

Only benchmark against fast-glob, we're already faster than globby ;)

Frankly, I don't really see this lib ever getting faster than fast-glob.
Fast-glob sacrifices some correctness for speed, and I'm just not
willing to do that.  (Nothing wrong with that choice, it's just not the
choice I choose.)  In all but the most extreme edge case patterns, the
speed is comparable, and both libraries already do really just the bare
minimum of file system operations, but this one is doing a bit more
extra computation to manage objects whereas fast-glob just kinda yolos
out of a bunch of weird cases.  Hard to say that's not the right call,
"complete coherence with Bash 5" is an arbitrary esthetic choice.

I do think speed of this library *could* get faster than fast-glob, if
the whole Processor/Pattern OOP implementation was scrapped in favor of
just using string/pattern arrays wherever possible, but frankly that was
so much harder to reason about, I don't think it's really worth the
effort. The point in node-glob's favor is that the underlying filesystem
walking lib is a bit more aggressive with caching and more highly tuned
than @nodelib/fs.walk.

Interestingly, the speed delta does *not* seem to come from the costs of
evaluating and testing patterns against filenames (ie, the actual
matching speed) but almost entirely from the fact that node-glob just
has more objects and in some cases does more filesystem operations.
Which means that fast-glob could probably add comparable correctness and
maintain its speed advantage by switching from picomatch/micromatch to
minimatch. I haven't profiled it in detail, which means it's possible
that this assertion is dead wrong, but my reason for thinking so is that
switching out Minimatch for a much more efficient matcher implementation
did not meaningfully impact performance. It improved a little, like 2%,
but not nearly enough to be worth the maintenance overhead, or adding
the work of re-implementing ignores and other features that it lacked.

And, being between 5x and 500x faster than the previous version of
node-glob is probably more than enough for any of its current users, and
puts it well in the range where I can justify pulling glob support back
into rimraf, which is the real goal here.
---
 benchmark.sh | 83 ++++++++++++++++++++++++++++------------------------
 patterns.sh  | 20 ++++++++-----
 2 files changed, 58 insertions(+), 45 deletions(-)

diff --git a/benchmark.sh b/benchmark.sh
index 7da18ba1..a2d49e78 100644
--- a/benchmark.sh
+++ b/benchmark.sh
@@ -69,18 +69,7 @@ for p in "${patterns[@]}"; do
   #     console.log(files.length)
   #   })' "$wd/bench-working-dir/node_modules/glob7" "$p"
 
-  # echo -n $'node glob v8 sync             \t'
-  # t node -e '
-  #   var glob=require(process.argv[1])
-  #   console.log(glob.sync(process.argv[2]).length)
-  # ' "$wd/bench-working-dir/node_modules/glob8" "$p"
-
-  # echo -n $'node glob v8 async            \t'
-  # t node -e '
-  #   var glob=require(process.argv[1])
-  #   glob(process.argv[2], (er, files) => {
-  #     console.log(files.length)
-  #   })' "$wd/bench-working-dir/node_modules/glob8" "$p"
+  echo '~~ sync ~~'
 
   echo -n $'node fast-glob sync           \t'
   cat > "$wd"/bench-working-dir/fast-glob-sync.cjs < "$wd"/bench-working-dir/fast-glob-async.cjs < console.log(r.length))
-CJS
-  t node "$wd/bench-working-dir/fast-glob-async.cjs" "$p"
-
   echo -n $'node globby sync              \t'
   cat > "$wd"/bench-working-dir/globby-sync.mjs < "$wd"/bench-working-dir/globby-async.mjs < {
-      console.log(files.length)
-    })
-MJS
-  t node "$wd/bench-working-dir/globby-async.mjs" "$p"
-
 #  echo -n $'node current glob.sync cjs    \t'
 #  cat > "$wd/bench-working-dir/sync.cjs" < "$wd/bench-working-dir/glob-8-sync.cjs" < "$wd/bench-working-dir/sync.mjs" < "$wd/bench-working-dir/async.mjs" < console.log(files.length))
-MJS
-  t node "$wd/bench-working-dir/async.mjs" "$p"
-
   echo -n $'node current glob syncStream  \t'
   cat > "$wd/bench-working-dir/stream-sync.mjs" < "$wd"/bench-working-dir/fast-glob-async.cjs < console.log(r.length))
+CJS
+  t node "$wd/bench-working-dir/fast-glob-async.cjs" "$p"
+
+  echo -n $'node globby async             \t'
+  cat > "$wd"/bench-working-dir/globby-async.mjs < {
+      console.log(files.length)
+    })
+MJS
+  t node "$wd/bench-working-dir/globby-async.mjs" "$p"
+
+#   echo -n $'node glob v8 async            \t'
+#   cat > "$wd/bench-working-dir/glob-8-async.cjs" <
+#       console.log(results.length)
+#     )
+# CJS
+#   t node "$wd/bench-working-dir/glob-8-async.cjs" "$p"
+
+  echo -n $'node current glob async mjs   \t'
+  cat > "$wd/bench-working-dir/async.mjs" < console.log(files.length))
+MJS
+  t node "$wd/bench-working-dir/async.mjs" "$p"
+
   echo -n $'node current glob stream      \t'
   cat > "$wd/bench-working-dir/stream.mjs" < c.push(f))
-    .on('end', () => console.log(new Set(c).size))
+    .on('data', () => c++)
+    .on('end', () => console.log(c))
 MJS
   t node "$wd/bench-working-dir/stream.mjs" "$p"
 
diff --git a/patterns.sh b/patterns.sh
index 1e0ed769..de28078a 100644
--- a/patterns.sh
+++ b/patterns.sh
@@ -2,27 +2,33 @@ patterns=(
   # some of these aren't particularly "representative" of real-world
   # glob patterns, but they're here to highlight pathological perf
   # cases that I found while working on the rewrite of this library.
+  './**/0/**/0/**/0/**/0/**/*.txt'
+  './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt'
+  './**/0/**/0/**/*.txt'
+
   '**'
   '**/*.txt'
-  '**/!(0|9).txt'
   '{**/*.txt,**/?/**/*.txt,**/?/**/?/**/*.txt,**/?/**/?/**/?/**/*.txt,**/?/**/?/**/?/**/?/**/*.txt}'
+  '**/5555/0000/*.txt'
+
+  './**/0/**/../[01]/**/0/../**/0/*.txt'
+  '**/????/????/????/????/*.txt'
+
+
   './{**/?{/**/?{/**/?{/**/?,,,,},,,,},,,,},,,}/**/*.txt'
 
+
+  '**/!(0|9).txt'
+
   './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,,,,},,,,},,,,},,,,},,,,}/*.txt'
   './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
   './*/**/../*/**/../*/**/../*/**/../*/**/*.txt'
   './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt'
   './**/?/**/?/**/?/**/?/**/*.txt'
-  './**/0/**/../[01]/**/0/../**/0/*.txt'
-  '**/????/????/????/????/*.txt'
-  './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt'
   '**/*/**/*/**/*/**/*/**'
   # '5555/0000/**/*.txt'
-  '**/5555/0000/*.txt'
   # '*/*/9/**/**/**/**/*/**/**/*.txt'
   './**/*/**/*/**/*/**/*/**/*.txt'
-  './**/0/**/0/**/0/**/0/**/*.txt'
-  './**/0/**/0/**/*.txt'
   '**/*.txt'
   # './**/*.txt'
   './**/**/**/**/**/**/**/**/*.txt'

From 01c3d45c506e48faf26df42da935b922bd0106cb Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 23:00:52 -0800
Subject: [PATCH 084/163] add iterator/asyncIterator support

---
 src/glob.ts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/glob.ts b/src/glob.ts
index d8ae19ea..14ab010d 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -250,4 +250,18 @@ export class Glob {
       this.opts
     ).streamSync()
   }
+
+  iteratorSync(): Generator, void, void> {
+    return this.streamSync()[Symbol.iterator]()
+  }
+  [Symbol.iterator]() {
+    return this.iteratorSync()
+  }
+
+  iterator(): AsyncGenerator, void, void> {
+    return this.stream()[Symbol.asyncIterator]()
+  }
+  [Symbol.asyncIterator]() {
+    return this.iterator()
+  }
 }

From 2716452fb5908842b33afc62100fa85e81ef7b3a Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 23:01:04 -0800
Subject: [PATCH 085/163] correct test-regen npm script

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 06f27698..17f58ef1 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,7 @@
     "typedoc": "typedoc --tsconfig tsconfig-esm.json ./src/*.ts",
     "prepublish": "npm run benchclean",
     "profclean": "rm -f v8.log profile.txt",
-    "test-regen": "npm run profclean && TEST_REGEN=1 node --no-warnings --loader ts-node/esm test/00-setup.js",
+    "test-regen": "npm run profclean && TEST_REGEN=1 node --no-warnings --loader ts-node/esm test/00-setup.ts",
     "prebench": "npm run prepare",
     "bench": "bash benchmark.sh",
     "preprof": "npm run prepare",

From 5865bd30462726b13384c17c9946584ac5d60be1 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 23:08:06 -0800
Subject: [PATCH 086/163] Match bash's weird ** following behavior

A globstar will follow ONE symlink, but will not follow any further
symbolic links that it finds along the way.
---
 src/pattern.ts   |  19 +++++-
 src/processor.ts |  37 +++++------
 src/walker.ts    | 156 +----------------------------------------------
 3 files changed, 38 insertions(+), 174 deletions(-)

diff --git a/src/pattern.ts b/src/pattern.ts
index fb42b62f..8b8b9eaa 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -36,11 +36,13 @@ export class Pattern {
   #isDrive?: boolean
   #isUNC?: boolean
   #isAbsolute?: boolean
+  #globstarFollowed: number[]
 
   constructor(
     patternList: MMPattern[],
     globList: string[],
-    index: number
+    index: number,
+    globstarFollowed: number[] = []
   ) {
     if (!isPatternList(patternList)) {
       throw new TypeError('empty pattern list')
@@ -58,6 +60,7 @@ export class Pattern {
     this.patternList = patternList
     this.globList = globList
     this.#index = index
+    this.#globstarFollowed = globstarFollowed
 
     // if the current item is not globstar, and the next item is .., skip ahead
     if (
@@ -157,7 +160,8 @@ export class Pattern {
     this.#rest = new Pattern(
       this.patternList,
       this.globList,
-      this.#index + 1
+      this.#index + 1,
+      this.#globstarFollowed
     )
     this.#rest.#isAbsolute = this.#isAbsolute
     this.#rest.#isUNC = this.#isUNC
@@ -165,6 +169,17 @@ export class Pattern {
     return this.#rest
   }
 
+  followGlobstar(): boolean {
+    if (!this.isGlobstar()) {
+      return false
+    }
+    if (this.#globstarFollowed.includes(this.#index)) {
+      return false
+    }
+    this.#globstarFollowed.push(this.#index)
+    return true
+  }
+
   // pattern like: //host/share/...
   // split = [ '', '', 'host', 'share', ... ]
   isUNC(pl = this.patternList): pl is UNCPatternList {
diff --git a/src/processor.ts b/src/processor.ts
index a6ec4046..34455b77 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -43,8 +43,9 @@ class MatchRecord {
 class SubWalks {
   store: Map = new Map()
   add(target: Path, pattern: Pattern) {
-    if (!target.canReaddir()) return
-    if (target.isSymbolicLink() && pattern.isGlobstar()) return
+    if (!target.canReaddir()) {
+      return
+    }
     const subs = this.store.get(target)
     if (subs) subs.push(pattern)
     else this.store.set(target, [pattern])
@@ -56,16 +57,7 @@ class SubWalks {
     return this.keys().map(k => [k, this.store.get(k) as Pattern[]])
   }
   keys(): Path[] {
-    return [...this.store.keys()].filter(t => {
-      if (!t.canReaddir()) return false
-      if (
-        t.isSymbolicLink() &&
-        !this.store.get(t)?.some(p => p.isRegExp())
-      ) {
-        return false
-      }
-      return true
-    })
+    return [...this.store.keys()].filter(t => t.canReaddir())
   }
 }
 
@@ -89,7 +81,9 @@ export class Processor {
     // first item in patterns is the filter
 
     for (let [t, pattern] of processingSet) {
-      if (this.hasWalkedCache.hasWalked(t, pattern)) continue
+      if (this.hasWalkedCache.hasWalked(t, pattern)) {
+        continue
+      }
       this.hasWalkedCache.storeWalked(t, pattern)
 
       const root = pattern.root()
@@ -140,9 +134,14 @@ export class Processor {
       } else if (p === GLOBSTAR) {
         // if no rest, match and subwalk pattern
         // if rest, process rest and subwalk pattern
-        this.subwalks.add(t, pattern)
+        // if it's a symlink, but we didn't get here by way of a
+        // globstar match (meaning it's the first time THIS globstar
+        // has traversed a symlink), then we follow it. Otherwise, stop.
+        if (!t.isSymbolicLink() || pattern.followGlobstar()) {
+          this.subwalks.add(t, pattern)
+        }
         if (!rest) {
-          this.matches.add(t, absolute, false)
+          this.matches.add(t, absolute, true)
         } else {
           if (!this.hasWalkedCache.hasWalked(t, rest)) {
             processingSet.push([t, rest])
@@ -194,9 +193,13 @@ export class Processor {
     if (!pattern.hasMore()) {
       this.matches.add(e, absolute, false)
     }
-    if (e.isDirectory()) {
-      this.subwalks.add(e, pattern)
+    // record that this globstar is following a symlink, so we
+    // can know to stop traversing when we encounter it again
+    // in processPatterns.
+    if (e.isSymbolicLink()) {
+      pattern.followGlobstar()
     }
+    this.subwalks.add(e, pattern)
   }
 
   testRegExp(
diff --git a/src/walker.ts b/src/walker.ts
index a992b731..5e9e4058 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -1,84 +1,10 @@
-// TODO: provide all the same iteration patterns that PathScurry has
-// - [x] walk
-// - [x] walkSync
-// - [x] stream
-// - [x] streamSync
-// - [ ] iterator
-// - [ ] iteratorSync
-
-//  **/.. is really annoyingly slow, especially when repeated, because .. can't eliminate it.
-//  but!  
/**/../ is equivalent to 
/..//**/ plus 
/.. or in other words:  
/**/./ plus 
/../
-//  so 
/**/../*/**/../ goes to: {
/../*/**/../, 
/**/*/**/../}
-//  which goes to: {
/../*/**/../, 
/*/**/**/../}
-//  {
/../*/**/../, 
/*/**/../} then do the second **/..
-//  {
/../*/**/, 
/../*/../, 
/*/../, 
/*/**/}
-//  {
/../*/**/, 
/../, 
/, 
/*/**/}
-//  reordering:
-//   1                     2                  3                4
-//  {
/../*/**/, 
/*/**/, 
/../, 
/}
-//
-//  When we walk 1, that'll end up walking over each child in 2 with **, and
-//  most of that pattern will be deduped out at some point, but we then can't
-//  rely on the Pattern objects being unique, I guess?
-
-// import LRUCache from 'lru-cache'
-import { GLOBSTAR } from 'minimatch'
 import Minipass from 'minipass'
 import { Path } from 'path-scurry'
 
 // a single minimatch set entry with 1 or more parts
-import { MMPattern, Pattern } from './pattern.js'
+import { Pattern } from './pattern.js'
 import { Processor } from './processor.js'
 
-class HasWalkedCache {
-  store: Map>
-  constructor(store: Map> = new Map()) {
-    this.store = store
-  }
-  copy() {
-    return new HasWalkedCache(new Map(this.store))
-  }
-  hasWalked(target: Path, pattern: Pattern) {
-    return this.store.get(target)?.has(pattern.globString())
-  }
-  storeWalked(target: Path, pattern: Pattern) {
-    const cached = this.store.get(target)
-    if (cached) cached.add(pattern.globString())
-    else this.store.set(target, new Set([pattern.globString()]))
-  }
-}
-
-// bitflag of 
-class MatchRecord {
-  store: Map = new Map()
-  add(target: Path, absolute: boolean, ifDir: boolean) {
-    const n = (absolute ? 2 : 0) | (ifDir ? 1 : 0)
-    const current = this.store.get(target) || 0
-    this.store.set(target, n & current)
-  }
-  // match, absolute, ifdir
-  entries(): [Path, boolean, boolean][] {
-    return [...this.store.entries()].map(([path, n]) => [
-      path,
-      !!(n & 2),
-      !!(n & 1),
-    ])
-  }
-}
-
-class SubWalks {
-  store: Map = new Map()
-  patterns: Map = new Map()
-  add(target: Path, pattern: Pattern) {
-    const subs = this.store.get(target)
-    if (subs) subs.push(pattern)
-    else this.store.set(target, [pattern])
-  }
-  entries() {
-    return this.store.entries()
-  }
-}
-
 export interface GlobWalkerOpts {
   absolute?: boolean
   realpath?: boolean
@@ -318,86 +244,6 @@ export abstract class GlobUtil {
     if (p) this.matchFinish(p, absolute)
   }
 
-  // TODO: this function is the hottest path here,
-  // need to optimize this.  Using a double-Map might
-  // not be the best idea. Maybe could get away with 2 arrays?
-  processPatterns(
-    target: Path,
-    patterns: Pattern[]
-  ): [SubWalks, MatchRecord] {
-    const processingSet: [Path, Pattern][] = patterns.map(p => [target, p])
-
-    const hasWalkedCache = new HasWalkedCache()
-
-    // found matches, path => [absolute, ifdir]
-    const matches = new MatchRecord()
-
-    // map of paths to the magic-starting subwalks they need to walk
-    // first item in patterns is the filter
-    const subwalks = new SubWalks()
-
-    for (let [t, pattern] of processingSet) {
-      if (hasWalkedCache.hasWalked(t, pattern)) continue
-      hasWalkedCache.storeWalked(t, pattern)
-
-      const root = pattern.root()
-      const absolute = pattern.isAbsolute()
-
-      // start absolute patterns at root
-      if (root) {
-        t = t.resolve(root)
-        const rest = pattern.rest()
-        if (!rest) {
-          matches.add(t, true, false)
-          continue
-        } else {
-          pattern = rest
-        }
-      }
-
-      // walk down strings
-      let p: MMPattern
-      let rest: Pattern | null
-      let changed = false
-      while (
-        typeof (p = pattern.pattern()) === 'string' &&
-        (rest = pattern.rest())
-      ) {
-        t = t.resolve(p)
-        pattern = rest
-        changed = true
-      }
-      rest = pattern.rest()
-      if (changed) {
-        if (hasWalkedCache.hasWalked(t, pattern)) continue
-        hasWalkedCache.storeWalked(t, pattern)
-      }
-
-      // now we have either a final string, or a pattern starting with magic,
-      // mounted on t.
-      if (typeof p === 'string') {
-        // must be final entry
-        const ifDir = p === '..' || p === '' || p === '.'
-        matches.add(t.resolve(p), absolute, ifDir)
-        continue
-      } else if (p === GLOBSTAR) {
-        // if no rest, match and subwalk pattern
-        // if rest, process rest and subwalk pattern
-        subwalks.add(t, pattern)
-        if (!rest) {
-          matches.add(t, absolute, false)
-        } else {
-          if (!hasWalkedCache.hasWalked(t, rest)) {
-            processingSet.push([t, rest])
-          }
-        }
-      } else if (p instanceof RegExp) {
-        subwalks.add(t, pattern)
-      }
-    }
-    return [subwalks, matches]
-  }
-
   walkCB(target: Path, patterns: Pattern[], cb: () => any) {
     if (this.paused) {
       this.onResume(() => this.walkCB(target, patterns, cb))

From 14cb4e878b1aca74f7ca4a799699c2a71863ffcd Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 23:08:53 -0800
Subject: [PATCH 087/163] walk down strings as long as they are known

The overhead of calling readdir() on a normal file is
brutal, compared to calling readdir() on something we
know is a dir, or having to lstat the final entry.
---
 src/processor.ts | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/src/processor.ts b/src/processor.ts
index 34455b77..8fe04039 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -101,18 +101,19 @@ export class Processor {
         }
       }
 
-      // walk down strings
       let p: MMPattern
       let rest: Pattern | null
       let changed = false
-      //while (
-      //  typeof (p = pattern.pattern()) === 'string' &&
-      //  (rest = pattern.rest())
-      //) {
-      //  t = t.resolve(p)
-      //  pattern = rest
-      //  changed = true
-      //}
+      while (
+        typeof (p = pattern.pattern()) === 'string' &&
+        (rest = pattern.rest())
+      ) {
+        const c = t.resolve(p)
+        if (c.isUnknown()) break
+        t = c
+        pattern = rest
+        changed = true
+      }
       p = pattern.pattern()
       rest = pattern.rest()
       if (changed) {

From 22a727bc420c46184923960d2b2a8dc4c56f83fd Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Feb 2023 23:09:40 -0800
Subject: [PATCH 088/163] some test updates

many more to fix, though.
---
 test/00-setup.ts     |   6 +-
 test/absolute.ts     |   4 +-
 test/bash-results.ts | 170 +++++++++++++++++++++----------------------
 test/cwd-test.ts     |  37 ++++++----
 4 files changed, 112 insertions(+), 105 deletions(-)

diff --git a/test/00-setup.ts b/test/00-setup.ts
index 6b41c31b..a5709ca8 100644
--- a/test/00-setup.ts
+++ b/test/00-setup.ts
@@ -4,7 +4,7 @@
 import { spawn } from 'child_process'
 import { createWriteStream, promises } from 'fs'
 import mkdirp from 'mkdirp'
-import { dirname, resolve } from 'path'
+import { join, dirname, resolve } from 'path'
 import t from 'tap'
 
 const { writeFile, symlink } = promises
@@ -153,9 +153,7 @@ export const bashResults:{ [path: string]: string[] } = ${
     // normalize discrepancies in ordering, duplication,
     // and ending slashes.
     return m
-      .map(function (m) {
-        return m.replace(/\/$/, '')
-      })
+      .map(m => join(m.replace(/\/$/, '').replace(/\/+/g, '/')))
       .sort(alphasort)
       .reduce(function (set: string[], f) {
         if (f !== set[set.length - 1]) set.push(f)
diff --git a/test/absolute.ts b/test/absolute.ts
index 5ff92d21..ec632326 100644
--- a/test/absolute.ts
+++ b/test/absolute.ts
@@ -16,7 +16,7 @@ for (const mark of marks) {
 
     t.test('Emits absolute matches if option set', async t => {
       var g = new Glob(pattern, { absolute: true })
-      const results = await g.process()
+      const results = await g.walk()
 
       t.equal(
         results.length,
@@ -30,7 +30,7 @@ for (const mark of marks) {
 
     t.test('returns absolute results synchronously', async t => {
       var g = new Glob(pattern, { absolute: true })
-      const results = g.processSync()
+      const results = g.walkSync()
 
       t.equal(
         results.length,
diff --git a/test/bash-results.ts b/test/bash-results.ts
index 665eba9f..69e08711 100644
--- a/test/bash-results.ts
+++ b/test/bash-results.ts
@@ -4,90 +4,90 @@ if (module === require.main) {
 }
 export const bashResults: { [path: string]: string[] } = {
   'a/c/d/*/b': ['a/c/d/c/b'],
-  'a//c//d//*//b': ['a//c//d//c/b'],
+  'a//c//d//*//b': ['a/c/d/c/b'],
   'a/*/d/*/b': ['a/c/d/c/b'],
-  'a/*/+(c|g)/./d': ['a/b/c/./d'],
+  'a/*/+(c|g)/./d': ['a/b/c/d'],
   'a/**/[cg]/../[cg]': [
-    'a/abcdef/g/../g',
-    'a/abcfed/g/../g',
-    'a/b/c/../c',
-    'a/c/../c',
-    'a/c/d/c/../c',
-    'a/symlink/a/b/c/../c',
+    'a/abcdef/g',
+    'a/abcfed/g',
+    'a/b/c',
+    'a/c',
+    'a/c/d/c',
+    'a/symlink/a/b/c',
   ],
   'a/{b,c,d,e,f}/**/g': [],
   'a/b/**': ['a/b', 'a/b/c', 'a/b/c/d'],
-  './**/g': ['./a/abcdef/g', './a/abcfed/g'],
+  './**/g': ['a/abcdef/g', 'a/abcfed/g'],
   'a/abc{fed,def}/g/h': ['a/abcdef/g/h', 'a/abcfed/g/h'],
   'a/abc{fed/g,def}/**/': ['a/abcdef', 'a/abcdef/g', 'a/abcfed/g'],
   'a/abc{fed/g,def}/**///**/': ['a/abcdef', 'a/abcdef/g', 'a/abcfed/g'],
-  './**/a': ['./a', './a/symlink/a', './a/symlink/a/b/c/a'],
+  './**/a': ['a', 'a/symlink/a', 'a/symlink/a/b/c/a'],
   './**/a/**/': [
-    './a',
-    './a/abcdef',
-    './a/abcdef/g',
-    './a/abcfed',
-    './a/abcfed/g',
-    './a/b',
-    './a/b/c',
-    './a/bc',
-    './a/bc/e',
-    './a/c',
-    './a/c/d',
-    './a/c/d/c',
-    './a/cb',
-    './a/cb/e',
-    './a/symlink',
-    './a/symlink/a',
-    './a/symlink/a/b',
-    './a/symlink/a/b/c',
-    './a/symlink/a/b/c/a',
-    './a/symlink/a/b/c/a/b',
-    './a/symlink/a/b/c/a/b/c',
-    './a/x',
-    './a/z',
+    'a',
+    'a/abcdef',
+    'a/abcdef/g',
+    'a/abcfed',
+    'a/abcfed/g',
+    'a/b',
+    'a/b/c',
+    'a/bc',
+    'a/bc/e',
+    'a/c',
+    'a/c/d',
+    'a/c/d/c',
+    'a/cb',
+    'a/cb/e',
+    'a/symlink',
+    'a/symlink/a',
+    'a/symlink/a/b',
+    'a/symlink/a/b/c',
+    'a/symlink/a/b/c/a',
+    'a/symlink/a/b/c/a/b',
+    'a/symlink/a/b/c/a/b/c',
+    'a/x',
+    'a/z',
   ],
   './**/a/**': [
-    './a',
-    './a/abcdef',
-    './a/abcdef/g',
-    './a/abcdef/g/h',
-    './a/abcfed',
-    './a/abcfed/g',
-    './a/abcfed/g/h',
-    './a/b',
-    './a/b/c',
-    './a/b/c/d',
-    './a/bc',
-    './a/bc/e',
-    './a/bc/e/f',
-    './a/c',
-    './a/c/d',
-    './a/c/d/c',
-    './a/c/d/c/b',
-    './a/cb',
-    './a/cb/e',
-    './a/cb/e/f',
-    './a/symlink',
-    './a/symlink/a',
-    './a/symlink/a/b',
-    './a/symlink/a/b/c',
-    './a/symlink/a/b/c/a',
-    './a/symlink/a/b/c/a/b',
-    './a/symlink/a/b/c/a/b/c',
-    './a/x',
-    './a/z',
+    'a',
+    'a/abcdef',
+    'a/abcdef/g',
+    'a/abcdef/g/h',
+    'a/abcfed',
+    'a/abcfed/g',
+    'a/abcfed/g/h',
+    'a/b',
+    'a/b/c',
+    'a/b/c/d',
+    'a/bc',
+    'a/bc/e',
+    'a/bc/e/f',
+    'a/c',
+    'a/c/d',
+    'a/c/d/c',
+    'a/c/d/c/b',
+    'a/cb',
+    'a/cb/e',
+    'a/cb/e/f',
+    'a/symlink',
+    'a/symlink/a',
+    'a/symlink/a/b',
+    'a/symlink/a/b/c',
+    'a/symlink/a/b/c/a',
+    'a/symlink/a/b/c/a/b',
+    'a/symlink/a/b/c/a/b/c',
+    'a/x',
+    'a/z',
   ],
   './**/a/**/a/**/': [
-    './a/symlink/a',
-    './a/symlink/a/b',
-    './a/symlink/a/b/c',
-    './a/symlink/a/b/c/a',
-    './a/symlink/a/b/c/a/b',
-    './a/symlink/a/b/c/a/b/c',
-    './a/symlink/a/b/c/a/b/c/a',
-    './a/symlink/a/b/c/a/b/c/a/b',
-    './a/symlink/a/b/c/a/b/c/a/b/c',
+    'a/symlink/a',
+    'a/symlink/a/b',
+    'a/symlink/a/b/c',
+    'a/symlink/a/b/c/a',
+    'a/symlink/a/b/c/a/b',
+    'a/symlink/a/b/c/a/b/c',
+    'a/symlink/a/b/c/a/b/c/a',
+    'a/symlink/a/b/c/a/b/c/a/b',
+    'a/symlink/a/b/c/a/b/c/a/b/c',
   ],
   '+(a|b|c)/a{/,bc*}/**': [
     'a/abcdef',
@@ -98,23 +98,14 @@ export const bashResults: { [path: string]: string[] } = {
     'a/abcfed/g/h',
   ],
   '*/*/*/f': ['a/bc/e/f', 'a/cb/e/f'],
-  './**/f': ['./a/bc/e/f', './a/cb/e/f'],
+  './**/f': ['a/bc/e/f', 'a/cb/e/f'],
   'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**': [
-    'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/a/b/c',
-    'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/a/b/c/a',
-    'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/a/b/c/a/b',
-    'a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/a/b/c/a/b/c',
+    'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c',
+    'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a',
+    'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b',
+    'a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c',
   ],
   '{./*/*,/tmp/glob-test/*}': [
-    './a/abcdef',
-    './a/abcfed',
-    './a/b',
-    './a/bc',
-    './a/c',
-    './a/cb',
-    './a/symlink',
-    './a/x',
-    './a/z',
     '/tmp/glob-test/asdf',
     '/tmp/glob-test/bar',
     '/tmp/glob-test/baz',
@@ -122,6 +113,15 @@ export const bashResults: { [path: string]: string[] } = {
     '/tmp/glob-test/quux',
     '/tmp/glob-test/qwer',
     '/tmp/glob-test/rewq',
+    'a/abcdef',
+    'a/abcfed',
+    'a/b',
+    'a/bc',
+    'a/c',
+    'a/cb',
+    'a/symlink',
+    'a/x',
+    'a/z',
   ],
   '{/tmp/glob-test/*,*}': [
     '/tmp/glob-test/asdf',
diff --git a/test/cwd-test.ts b/test/cwd-test.ts
index bf732279..ba932de8 100644
--- a/test/cwd-test.ts
+++ b/test/cwd-test.ts
@@ -1,4 +1,4 @@
-import { join, resolve } from 'path'
+import { resolve } from 'path'
 import t from 'tap'
 import { glob } from '../'
 
@@ -8,26 +8,35 @@ t.teardown(() => process.chdir(origCwd))
 
 t.test('changing cwd and searching for **/d', t => {
   const expect = Object.entries({
-    a: ['b/c/d', 'c/d'],
-    'a/b': ['c/d'],
-    '': ['a/b/c/d', 'a/c/d'],
+    a: new Set(['c/d', 'b/c/d']),
+    'a/b': new Set(['c/d']),
+    '': new Set(['a/b/c/d', 'a/c/d']),
   })
   t.plan(expect.length)
   for (const [cwd, matches] of expect) {
     t.test(cwd || '(empty string)', async t => {
-      t.same(await glob('**/d', { cwd }), matches)
+      t.same(new Set(await glob('**/d', { cwd })), matches)
       if (cwd) {
-        t.same(await glob('**/d', { cwd: cwd + '/' }), matches)
-        t.same(await glob('**/d', { cwd: cwd + '/.' }), matches)
-        t.same(await glob('**/d', { cwd: cwd + '/./' }), matches)
+        t.same(new Set(await glob('**/d', { cwd: cwd + '/' })), matches)
+        t.same(new Set(await glob('**/d', { cwd: cwd + '/.' })), matches)
+        t.same(new Set(await glob('**/d', { cwd: cwd + '/./' })), matches)
       } else {
-        t.same(await glob('**/d', { cwd: '.' }), matches)
-        t.same(await glob('**/d', { cwd: './' }), matches)
+        t.same(new Set(await glob('**/d', { cwd: '.' })), matches)
+        t.same(new Set(await glob('**/d', { cwd: './' })), matches)
       }
-      t.same(await glob('**/d', { cwd: resolve(cwd) }), matches)
-      t.same(await glob('**/d', { cwd: resolve(cwd) + '/' }), matches)
-      t.same(await glob('**/d', { cwd: resolve(cwd) + '/.' }), matches)
-      t.same(await glob('**/d', { cwd: resolve(cwd) + '/./' }), matches)
+      t.same(new Set(await glob('**/d', { cwd: resolve(cwd) })), matches)
+      t.same(
+        new Set(await glob('**/d', { cwd: resolve(cwd) + '/' })),
+        matches
+      )
+      t.same(
+        new Set(await glob('**/d', { cwd: resolve(cwd) + '/.' })),
+        matches
+      )
+      t.same(
+        new Set(await glob('**/d', { cwd: resolve(cwd) + '/./' })),
+        matches
+      )
     })
   }
 })

From 0ada648b71850bcb102d901cb26b0ad5d43c7ff5 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Wed, 22 Feb 2023 17:32:32 -0800
Subject: [PATCH 089/163] pass AbortSignal to minipass, use newest minimatch

---
 package-lock.json | 28 ++++++++++++++--------------
 package.json      |  4 ++--
 src/glob.ts       |  3 +++
 src/walker.ts     |  6 ++++--
 4 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 198bbd14..3b2bf04c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,8 +10,8 @@
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "minimatch": "^7.0.0",
-        "minipass": "^4.0.3",
+        "minimatch": "^7.1.0",
+        "minipass": "^4.2.0",
         "path-scurry": "^1.4.0"
       },
       "devDependencies": {
@@ -2920,9 +2920,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.0.0.tgz",
-      "integrity": "sha512-Wog4y1P2q/0sF+0vw+6dWgqVmo/XPJg+2OtVmR6IVvNGDhcfAPjFacjZCUlGCoU/tbzH6EOeSt2P3llRAqRNiA==",
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.0.tgz",
+      "integrity": "sha512-ZRvZsrVXiuB/QDlJx7WPymFyOHQUntQOEH3vFIwCzs/fDnH/siHZQAmI6Zamx1J9u9S66ucgKXU0CnqHfi8Z4g==",
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
@@ -2942,9 +2942,9 @@
       "peer": true
     },
     "node_modules/minipass": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.3.tgz",
-      "integrity": "sha512-OW2r4sQ0sI+z5ckEt5c1Tri4xTgZwYDxpE54eqWlQloQRoWtXjqt9udJ5Z4dSv7wK+nfFI7FRXyCpBSft+gpFw==",
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.0.tgz",
+      "integrity": "sha512-ExlilAIS7zJ2EWUMaVXi14H+FnZ18kr17kFkGemMqBx6jW0m8P6XfqwYVPEG53ENlgsED+alVP9ZxC3JzkK23Q==",
       "engines": {
         "node": ">=8"
       }
@@ -8568,9 +8568,9 @@
       }
     },
     "minimatch": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.0.0.tgz",
-      "integrity": "sha512-Wog4y1P2q/0sF+0vw+6dWgqVmo/XPJg+2OtVmR6IVvNGDhcfAPjFacjZCUlGCoU/tbzH6EOeSt2P3llRAqRNiA==",
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.0.tgz",
+      "integrity": "sha512-ZRvZsrVXiuB/QDlJx7WPymFyOHQUntQOEH3vFIwCzs/fDnH/siHZQAmI6Zamx1J9u9S66ucgKXU0CnqHfi8Z4g==",
       "requires": {
         "brace-expansion": "^2.0.1"
       }
@@ -8584,9 +8584,9 @@
       "peer": true
     },
     "minipass": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.3.tgz",
-      "integrity": "sha512-OW2r4sQ0sI+z5ckEt5c1Tri4xTgZwYDxpE54eqWlQloQRoWtXjqt9udJ5Z4dSv7wK+nfFI7FRXyCpBSft+gpFw=="
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.0.tgz",
+      "integrity": "sha512-ExlilAIS7zJ2EWUMaVXi14H+FnZ18kr17kFkGemMqBx6jW0m8P6XfqwYVPEG53ENlgsED+alVP9ZxC3JzkK23Q=="
     },
     "mkdirp": {
       "version": "2.0.0",
diff --git a/package.json b/package.json
index 17f58ef1..6ffe495e 100644
--- a/package.json
+++ b/package.json
@@ -59,8 +59,8 @@
   },
   "dependencies": {
     "fs.realpath": "^1.0.0",
-    "minimatch": "^7.0.0",
-    "minipass": "^4.0.3",
+    "minimatch": "^7.1.0",
+    "minipass": "^4.2.0",
     "path-scurry": "^1.4.0"
   },
   "devDependencies": {
diff --git a/src/glob.ts b/src/glob.ts
index 14ab010d..8a31a6ab 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -95,6 +95,7 @@ export class Glob {
   opts: Opts
   platform?: typeof process.platform
   patterns: Pattern[]
+  signal?: AbortSignal
 
   constructor(pattern: string | string[], opts: Opts) {
     this.withFileTypes = !!opts.withFileTypes as FileTypes
@@ -107,6 +108,7 @@ export class Glob {
       this.ignore = ignore
     }
     this.opts = opts
+    this.signal = opts.signal
     this.follow = !!opts.follow
     this.dot = !!opts.dot
     this.nodir = !!opts.nodir
@@ -183,6 +185,7 @@ export class Glob {
       nonegate: true,
       nocomment: true,
       nocaseMagicOnly: true,
+      optimizationLevel: 2,
     }
 
     // console.error('glob pattern arg', this.pattern)
diff --git a/src/walker.ts b/src/walker.ts
index 5e9e4058..bbe6794b 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -442,14 +442,16 @@ export class GlobStream<
 
   constructor(patterns: Pattern[], path: Path, opts: O) {
     super(patterns, path, opts)
-    this.results = new Minipass({ objectMode: true }) as MatchStream
+    this.results = new Minipass({
+      signal: this.opts.signal,
+      objectMode: true,
+    }) as MatchStream
     this.results.on('drain', () => this.resume())
     this.results.on('resume', () => this.resume())
   }
 
   matchEmit(e: Result): void
   matchEmit(e: Path | string): void {
-    if (e === '') e = '.'
     if (!this.results.write(e)) this.pause()
   }
 

From cf64aad8750bc27c4e9b75f743535f964d561ab7 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 23 Feb 2023 14:51:27 -0800
Subject: [PATCH 090/163] ever so slight perf improvement on globstar pattern
 walking

---
 src/processor.ts | 40 ++++++++++++++++++++++++++++++++++------
 src/walker.ts    |  8 ++++----
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/src/processor.ts b/src/processor.ts
index 8fe04039..69389a4f 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -141,11 +141,17 @@ export class Processor {
         if (!t.isSymbolicLink() || pattern.followGlobstar()) {
           this.subwalks.add(t, pattern)
         }
-        if (!rest) {
+        const rp = rest?.pattern()
+        const rrest = rest?.rest()
+        if (!rest || ((rp === '' || rp === '.') && !rrest)) {
           this.matches.add(t, absolute, true)
         } else {
-          if (!this.hasWalkedCache.hasWalked(t, rest)) {
-            processingSet.push([t, rest])
+          if (rp === '..') {
+            const tp = t.parent || t
+            if (!rrest) this.matches.add(tp, absolute, true)
+            else if (!this.hasWalkedCache.hasWalked(tp, rrest)) {
+              this.subwalks.add(tp, rrest)
+            }
           }
         }
       } else if (p instanceof RegExp) {
@@ -178,7 +184,7 @@ export class Processor {
         const p = pattern.pattern()
         const rest = pattern.rest()
         if (p === GLOBSTAR) {
-          results.testGlobstar(e, pattern, absolute)
+          results.testGlobstar(e, pattern, rest, absolute)
         } else if (p instanceof RegExp) {
           results.testRegExp(e, p, rest, absolute)
         } else {
@@ -189,7 +195,12 @@ export class Processor {
     return results
   }
 
-  testGlobstar(e: Path, pattern: Pattern, absolute: boolean) {
+  testGlobstar(
+    e: Path,
+    pattern: Pattern,
+    rest: Pattern | null,
+    absolute: boolean
+  ) {
     if (e.name.startsWith('.')) return
     if (!pattern.hasMore()) {
       this.matches.add(e, absolute, false)
@@ -200,7 +211,24 @@ export class Processor {
     if (e.isSymbolicLink()) {
       pattern.followGlobstar()
     }
-    this.subwalks.add(e, pattern)
+    if (e.canReaddir()) {
+      this.subwalks.add(e, pattern)
+    }
+    // if the NEXT thing matches this entry, then also add
+    // the rest.
+    if (rest) {
+      const rp = rest.pattern()
+      if (
+        typeof rp === 'string' &&
+        rp !== '..' &&
+        rp !== '' &&
+        rp !== '.'
+      ) {
+        this.testString(e, rp, rest.rest(), absolute)
+      } else if (rp instanceof RegExp) {
+        this.testRegExp(e, rp, rest.rest(), absolute)
+      }
+    }
   }
 
   testRegExp(
diff --git a/src/walker.ts b/src/walker.ts
index bbe6794b..aca9cc05 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -433,12 +433,12 @@ export class GlobStream<
   O extends GlobWalkerOpts = GlobWalkerOpts
 > extends GlobUtil {
   results: O extends GWOFileTypesTrue
-    ? Minipass
+    ? Minipass
     : O extends GWOFileTypesFalse
-    ? Minipass
+    ? Minipass
     : O extends GWOFileTypesUnset
-    ? Minipass
-    : Minipass
+    ? Minipass
+    : Minipass
 
   constructor(patterns: Pattern[], path: Path, opts: O) {
     super(patterns, path, opts)

From aa0dbd88701d47ddbbd711850c284059c211163c Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Fri, 24 Feb 2023 09:13:38 -0800
Subject: [PATCH 091/163] Better protection against repeated walks

---
 package-lock.json | 28 ++++++++++++++--------------
 package.json      |  4 ++--
 patterns.sh       |  4 +++-
 src/pattern.ts    |  4 ++++
 src/processor.ts  | 12 +++++++++---
 src/walker.ts     | 20 +++++++++++++++-----
 6 files changed, 47 insertions(+), 25 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 3b2bf04c..2281f8f2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,8 +10,8 @@
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "minimatch": "^7.1.0",
-        "minipass": "^4.2.0",
+        "minimatch": "^7.1.1",
+        "minipass": "^4.2.1",
         "path-scurry": "^1.4.0"
       },
       "devDependencies": {
@@ -2920,9 +2920,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.0.tgz",
-      "integrity": "sha512-ZRvZsrVXiuB/QDlJx7WPymFyOHQUntQOEH3vFIwCzs/fDnH/siHZQAmI6Zamx1J9u9S66ucgKXU0CnqHfi8Z4g==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.1.tgz",
+      "integrity": "sha512-jjK46CRPxSRHTwHYtg+7LJ4pmfg01JuCjYr24+PUi1zHtZ8rOABPA0cMHKBF4QNeKn1xYy4hiBOm57p56ClCjw==",
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
@@ -2942,9 +2942,9 @@
       "peer": true
     },
     "node_modules/minipass": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.0.tgz",
-      "integrity": "sha512-ExlilAIS7zJ2EWUMaVXi14H+FnZ18kr17kFkGemMqBx6jW0m8P6XfqwYVPEG53ENlgsED+alVP9ZxC3JzkK23Q==",
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.1.tgz",
+      "integrity": "sha512-KS4CHIsDfOZetnT+u6fwxyFADXLamtkPxkGScmmtTW//MlRrImV+LtbmbJpLQ86Hw7km/utbfEfndhGBrfwvlA==",
       "engines": {
         "node": ">=8"
       }
@@ -8568,9 +8568,9 @@
       }
     },
     "minimatch": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.0.tgz",
-      "integrity": "sha512-ZRvZsrVXiuB/QDlJx7WPymFyOHQUntQOEH3vFIwCzs/fDnH/siHZQAmI6Zamx1J9u9S66ucgKXU0CnqHfi8Z4g==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.1.tgz",
+      "integrity": "sha512-jjK46CRPxSRHTwHYtg+7LJ4pmfg01JuCjYr24+PUi1zHtZ8rOABPA0cMHKBF4QNeKn1xYy4hiBOm57p56ClCjw==",
       "requires": {
         "brace-expansion": "^2.0.1"
       }
@@ -8584,9 +8584,9 @@
       "peer": true
     },
     "minipass": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.0.tgz",
-      "integrity": "sha512-ExlilAIS7zJ2EWUMaVXi14H+FnZ18kr17kFkGemMqBx6jW0m8P6XfqwYVPEG53ENlgsED+alVP9ZxC3JzkK23Q=="
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.1.tgz",
+      "integrity": "sha512-KS4CHIsDfOZetnT+u6fwxyFADXLamtkPxkGScmmtTW//MlRrImV+LtbmbJpLQ86Hw7km/utbfEfndhGBrfwvlA=="
     },
     "mkdirp": {
       "version": "2.0.0",
diff --git a/package.json b/package.json
index 6ffe495e..a748c3be 100644
--- a/package.json
+++ b/package.json
@@ -59,8 +59,8 @@
   },
   "dependencies": {
     "fs.realpath": "^1.0.0",
-    "minimatch": "^7.1.0",
-    "minipass": "^4.2.0",
+    "minimatch": "^7.1.1",
+    "minipass": "^4.2.1",
     "path-scurry": "^1.4.0"
   },
   "devDependencies": {
diff --git a/patterns.sh b/patterns.sh
index de28078a..6dfb492e 100644
--- a/patterns.sh
+++ b/patterns.sh
@@ -1,4 +1,7 @@
 patterns=(
+  '**'
+  '**/..'
+
   # some of these aren't particularly "representative" of real-world
   # glob patterns, but they're here to highlight pathological perf
   # cases that I found while working on the rewrite of this library.
@@ -6,7 +9,6 @@ patterns=(
   './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt'
   './**/0/**/0/**/*.txt'
 
-  '**'
   '**/*.txt'
   '{**/*.txt,**/?/**/*.txt,**/?/**/?/**/*.txt,**/?/**/?/**/?/**/*.txt,**/?/**/?/**/?/**/?/**/*.txt}'
   '**/5555/0000/*.txt'
diff --git a/src/pattern.ts b/src/pattern.ts
index 8b8b9eaa..8dfab3ac 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -173,6 +173,10 @@ export class Pattern {
     if (!this.isGlobstar()) {
       return false
     }
+    // never follow a globstar if it's the first pattern in the list
+    if (this.#index === 0) {
+      return false
+    }
     if (this.#globstarFollowed.includes(this.#index)) {
       return false
     }
diff --git a/src/processor.ts b/src/processor.ts
index 69389a4f..45922d29 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -47,8 +47,11 @@ class SubWalks {
       return
     }
     const subs = this.store.get(target)
-    if (subs) subs.push(pattern)
-    else this.store.set(target, [pattern])
+    if (subs) {
+      if (!subs.find(p => p.globString() === pattern.globString())) {
+        subs.push(pattern)
+      }
+    } else this.store.set(target, [pattern])
   }
   get(target: Path): Pattern[] {
     return this.store.get(target) || []
@@ -144,7 +147,9 @@ export class Processor {
         const rp = rest?.pattern()
         const rrest = rest?.rest()
         if (!rest || ((rp === '' || rp === '.') && !rrest)) {
-          this.matches.add(t, absolute, true)
+          // only HAS to be a dir if it ends in **/ or **/.
+          // but ending in ** will match files as well.
+          this.matches.add(t, absolute, rp === '' || rp === '.')
         } else {
           if (rp === '..') {
             const tp = t.parent || t
@@ -220,6 +225,7 @@ export class Processor {
       const rp = rest.pattern()
       if (
         typeof rp === 'string' &&
+        // dots and empty were handled already
         rp !== '..' &&
         rp !== '' &&
         rp !== '.'
diff --git a/src/walker.ts b/src/walker.ts
index aca9cc05..c330880e 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -1,6 +1,10 @@
 import Minipass from 'minipass'
 import { Path } from 'path-scurry'
 
+// XXX can we somehow make it so that it NEVER processes a given path more than
+// once, enough that the match set tracking is no longer needed?  that'd speed
+// things up a lot.  Or maybe bring back nounique, and skip it in that case?
+
 // a single minimatch set entry with 1 or more parts
 import { Pattern } from './pattern.js'
 import { Processor } from './processor.js'
@@ -55,7 +59,7 @@ export abstract class GlobUtil {
   path: Path
   patterns: Pattern[]
   opts: O
-  seen: Set = new Set()
+  seen: Set = new Set()
   paused: boolean = false
   aborted: boolean = false
   #onResume: (() => any)[] = []
@@ -76,10 +80,10 @@ export abstract class GlobUtil {
   }
   resume() {
     if (this.aborted) return
+    //console.error(new Error('resume').stack, this.#onResume.length)
     this.paused = false
-    const fns = this.#onResume.slice()
-    this.#onResume.length = 0
-    for (const fn of fns) {
+    let fn: (() => any) | undefined = undefined
+    while (!this.paused && (fn = this.#onResume.shift())) {
       fn()
     }
   }
@@ -235,11 +239,14 @@ export abstract class GlobUtil {
   }
 
   async match(e: Path, absolute: boolean, ifDir: boolean): Promise {
+    if (this.seen.has(e)) return
     const p = await this.matchCheck(e, ifDir)
     if (p) this.matchFinish(p, absolute)
   }
 
   matchSync(e: Path, absolute: boolean, ifDir: boolean): void {
+    if (this.seen.has(e)) return
+    //console.error(e.fullpath(), absolute, ifDir, new Error('matchtrace').stack)
     const p = this.matchCheckSync(e, ifDir)
     if (p) this.matchFinish(p, absolute)
   }
@@ -334,6 +341,7 @@ export abstract class GlobUtil {
     processor: Processor,
     cb: () => any
   ) {
+    //console.error('walkcb2sync', this.paused, target.fullpath(), patterns.map(p => p.globString()))
     if (this.paused) {
       this.onResume(() =>
         this.walkCB2Sync(target, patterns, processor, cb)
@@ -452,7 +460,9 @@ export class GlobStream<
 
   matchEmit(e: Result): void
   matchEmit(e: Path | string): void {
-    if (!this.results.write(e)) this.pause()
+    // console.error('MATCH EMIT', [e])
+    this.results.write(e)
+    if (!this.results.flowing) this.pause()
   }
 
   stream(): MatchStream {

From 717600197fed1f68cb78456ea8762d5c305eb190 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Fri, 24 Feb 2023 16:59:47 -0800
Subject: [PATCH 092/163] minimatch@7.1.3

---
 package-lock.json | 14 +++++++-------
 package.json      |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 2281f8f2..0695c9f3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "minimatch": "^7.1.1",
+        "minimatch": "^7.1.3",
         "minipass": "^4.2.1",
         "path-scurry": "^1.4.0"
       },
@@ -2920,9 +2920,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.1.tgz",
-      "integrity": "sha512-jjK46CRPxSRHTwHYtg+7LJ4pmfg01JuCjYr24+PUi1zHtZ8rOABPA0cMHKBF4QNeKn1xYy4hiBOm57p56ClCjw==",
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.3.tgz",
+      "integrity": "sha512-kpcwpcyeYtgSzpOvUf+9RiaPgrqtR2NwuqejBV2VkWxR+KC8jMWTb76zSlVJXy6ypbY39u66Un4gTk0ryiXm2g==",
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
@@ -8568,9 +8568,9 @@
       }
     },
     "minimatch": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.1.tgz",
-      "integrity": "sha512-jjK46CRPxSRHTwHYtg+7LJ4pmfg01JuCjYr24+PUi1zHtZ8rOABPA0cMHKBF4QNeKn1xYy4hiBOm57p56ClCjw==",
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.3.tgz",
+      "integrity": "sha512-kpcwpcyeYtgSzpOvUf+9RiaPgrqtR2NwuqejBV2VkWxR+KC8jMWTb76zSlVJXy6ypbY39u66Un4gTk0ryiXm2g==",
       "requires": {
         "brace-expansion": "^2.0.1"
       }
diff --git a/package.json b/package.json
index a748c3be..e6b9ccb4 100644
--- a/package.json
+++ b/package.json
@@ -59,7 +59,7 @@
   },
   "dependencies": {
     "fs.realpath": "^1.0.0",
-    "minimatch": "^7.1.1",
+    "minimatch": "^7.1.3",
     "minipass": "^4.2.1",
     "path-scurry": "^1.4.0"
   },

From e1633161317407748a137017df822c078bb70334 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Fri, 24 Feb 2023 18:25:27 -0800
Subject: [PATCH 093/163] ignores

---
 changelog.md   | 66 ++++++++++++++++++++++------------
 src/glob.ts    | 47 ++++++++++--------------
 src/ignore.ts  | 98 +++++++++++++++++++++++++++++++++++++++++---------
 src/pattern.ts | 11 +++---
 src/walker.ts  | 62 +++++++++++++++++++++++---------
 5 files changed, 195 insertions(+), 89 deletions(-)

diff --git a/changelog.md b/changelog.md
index 00916443..6b0dea35 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,49 +1,69 @@
 ## 9.0
 
-This is a full rewrite.
+This is a full rewrite, with significant API and algorithm
+changes.
 
+## High-Level Feature and API Surface Changes
+
+- Only support node 16 and higher.
 - Promise API instead of callbacks.
 - Accept pattern as string or array of strings.
 - Hybrid module distribution.
-- `module.exports` in CommonJS mode is an object, not a function.
-  Use the exported `default` or `glob` members to access the
-  default function export in CommonJS modes.
+
+  **Note:** `module.exports` in CommonJS mode is an object, not a
+  function. Use the exported `default` or `glob` members to
+  access the default function export in CommonJS modes.
+
 - Full TypeScript support.
+- Exported `Glob` class is no longer an event emitter.
+- Exported `Glob` class has `walk()`, `walkSync()`, `stream()`,
+  `streamSync()`, `iterate()`, `iterateSync()` methods, and is
+  both an async and sync Generator.
+- First class support for UNC paths and drive letters on Windows.
+  Note that *glob patterns* must still use `/` as a path
+  separator, unless the `windowsPathsNoEscape` option is set, in
+  which case glob patterns cannot be escaped with `\`.
+- Paths are returned in the canonical formatting for the platform
+  in question.
+
+## Options Changes
+
 - Removed `root` option and mounting behavior.
 - Removed `stat` option. It's slow and pointless. (Could bring
-  back easily if there's demand.)
+  back easily if there's demand, but items are already statted in
+  cases where it's relevant, such as `nodir:true` or
+  `mark:true`.)
 - Simplified `cwd` behavior so it is far less magical, and relies
   less on platform-specific absolute path representations.
 - More efficient handling for absolute patterns. (That is,
   patterns that start with `/` on any platform, or start with a
-  drive letter on Windows.)
-- Removed nearly all stat calls, in favor of using `withFileTypes:true`
-  with `fs.readdir()`.
-- Replaced almost all caching with a
-  [PathScurry](http://npm.im/path-scurry) base implementation.
-- Removed EventEmitter behavior from exported `Glob` class.
-- Consolidated sync and async `Glob` class behavior into a single
-  class with `walk()`, `walkSync()`, `stream()`, and
-  `streamSync()` methods.
+  drive letter or UNC path on Windows.)
 - Removed `silent` and `strict` options. Any readdir errors are
   simply treated as "the directory could not be read", and it is
   treated as a normal file entry instead, like shells do.
 - Removed `fs` option. This module only operates on the real
   filesystem. (Could bring back if there's demand for it, but
   it'd be an update to PathScurry, not Glob.)
-- Only support node 16 and higher.
 - `nonull:true` is no longer supported.
-- `withFileTypes:true` option added, to get `Path` objects (like
-  a `Dirent`, but can also do a lot more).
-- Patterns starting with drive letters on Windows are now
-  properly treated as absolute paths, and the drive letter in an
-  absolute `{cwd}` option will be used as the root of patterns
-  that start with `/`.
-- `nounique:true` is no longer supported.  Result sets are always
+- `withFileTypes:true` option added, to get `Path` objects.
+  These are a bit like a Dirent, but can do a lot more. See
+  
+- `nounique:true` is no longer supported. Result sets are always
   unique.
-- `nosort:true` is no longer supported.  Result sets are never
+- `nosort:true` is no longer supported. Result sets are never
   sorted.
 
+## Performance and Algorithm Changes
+
+- Massive performance improvements.
+- Removed nearly all stat calls, in favor of using
+  `withFileTypes:true` with `fs.readdir()`.
+- Replaced most of the caching with a
+  [PathScurry](http://npm.im/path-scurry) based implementation.
+- More correct handling of `**` vs `./**`, following Bash
+  semantics, where a `**` is followed one time only if it is not
+  the first item in the pattern.
+
 ## 8.1
 
 - Add `windowsPathsNoEscape` option
diff --git a/src/glob.ts b/src/glob.ts
index 8a31a6ab..67972414 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -17,7 +17,7 @@ type GlobParts = Exclude
 
 // if no process global, just call it linux.
 // so we default to case-sensitive, / separators
-const defaultPlatform =
+const defaultPlatform: NodeJS.Platform =
   typeof process === 'object' &&
   process &&
   typeof process.platform === 'string'
@@ -29,13 +29,12 @@ export interface GlobOptions extends MinimatchOptions {
   follow?: boolean
   mark?: boolean
   nodir?: boolean
-  nounique?: boolean
   cwd?: string
   realpath?: boolean
   absolute?: boolean
   withFileTypes?: boolean
   scurry?: PathScurry
-  platform?: typeof process.platform
+  platform?: NodeJS.Platform
   signal?: AbortSignal
 }
 
@@ -76,7 +75,6 @@ export class Glob {
   dot: boolean
   mark: boolean
   nodir: boolean
-  nounique: boolean
   cwd: string
   matchSet: MatchSet
   globSet: GlobSet
@@ -93,27 +91,18 @@ export class Glob {
   nocase?: boolean
   scurry: PathScurry
   opts: Opts
-  platform?: typeof process.platform
+  globUtilOpts: Opts
+  platform: NodeJS.Platform
   patterns: Pattern[]
   signal?: AbortSignal
 
   constructor(pattern: string | string[], opts: Opts) {
     this.withFileTypes = !!opts.withFileTypes as FileTypes
-    const { ignore } = opts
-    if (typeof ignore === 'string') {
-      this.ignore = new Ignore([ignore])
-    } else if (Array.isArray(ignore)) {
-      this.ignore = new Ignore(ignore)
-    } else if (ignore && ignore instanceof Ignore) {
-      this.ignore = ignore
-    }
-    this.opts = opts
     this.signal = opts.signal
     this.follow = !!opts.follow
     this.dot = !!opts.dot
     this.nodir = !!opts.nodir
     this.mark = !!opts.mark
-    this.nounique = !!opts.nounique
     this.cwd = opts.cwd || ''
     this.realpath = !!opts.realpath
     this.nonull = !!opts.nonull
@@ -135,13 +124,6 @@ export class Glob {
       }
     }
 
-    // if we want unique entries, we need a single set to hold them all
-    if (!this.nounique) {
-      this.matches = new Set() as Matches
-      this.seen = new Set()
-      this.walked = new Map()
-    }
-
     if (typeof pattern === 'string') {
       pattern = [pattern]
     }
@@ -164,6 +146,7 @@ export class Glob {
     this.pattern = pattern
 
     this.platform = opts.platform || defaultPlatform
+    this.opts = { ...opts, platform: this.platform }
     if (opts.scurry) {
       this.scurry = opts.scurry
     } else {
@@ -177,15 +160,23 @@ export class Glob {
           : PathScurry
       this.scurry = new Scurry(this.cwd, { nocase: opts.nocase })
     }
+    this.nocase = this.scurry.nocase
+
+    this.globUtilOpts = {
+      ...opts,
+      platform: this.platform,
+      nocase: this.nocase,
+    }
 
     const mmo: MinimatchOptions = {
       // default nocase based on platform
-      nocase: this.scurry.nocase,
+      nocase: this.nocase,
       ...opts,
       nonegate: true,
       nocomment: true,
       nocaseMagicOnly: true,
       optimizationLevel: 2,
+      platform: this.platform,
     }
 
     // console.error('glob pattern arg', this.pattern)
@@ -202,7 +193,7 @@ export class Glob {
     )
     this.patterns = matchSet.map((set, i) => {
       // console.error('globParts', globParts[i])
-      return new Pattern(set, globParts[i], 0)
+      return new Pattern(set, globParts[i], 0, this.platform)
     })
     this.matchSet = matchSet
     this.globSet = globSet
@@ -217,7 +208,7 @@ export class Glob {
     const walker = new GlobWalker(
       this.patterns,
       this.scurry.cwd,
-      this.opts
+      { ...this.opts, platform: this.platform, nocase: this.nocase }
     )
     return this.finish(await walker.walk())
   }
@@ -226,7 +217,7 @@ export class Glob {
     const walker = new GlobWalker(
       this.patterns,
       this.scurry.cwd,
-      this.opts
+      { ...this.opts, platform: this.platform, nocase: this.nocase }
     )
     return this.finish(walker.walkSync())
   }
@@ -241,7 +232,7 @@ export class Glob {
     return new GlobStream(
       this.patterns,
       this.scurry.cwd,
-      this.opts
+      { ...this.opts, platform: this.platform, nocase: this.nocase }
     ).stream()
   }
 
@@ -250,7 +241,7 @@ export class Glob {
     return new GlobStream(
       this.patterns,
       this.scurry.cwd,
-      this.opts
+      { ...this.opts, platform: this.platform, nocase: this.nocase }
     ).streamSync()
   }
 
diff --git a/src/ignore.ts b/src/ignore.ts
index 37f4b461..a949f0a8 100644
--- a/src/ignore.ts
+++ b/src/ignore.ts
@@ -4,31 +4,95 @@
 // Ignores are always parsed in dot:true mode
 
 import { Minimatch } from 'minimatch'
+import { Path } from 'path-scurry'
+import { Pattern } from './pattern.js'
+import { GlobWalkerOpts } from './walker.js'
+
+const defaultPlatform: NodeJS.Platform =
+  typeof process === 'object' &&
+  process &&
+  typeof process.platform === 'string'
+    ? process.platform
+    : 'linux'
 
 export class Ignore {
-  matchers: Minimatch[]
-  gmatchers: Minimatch[]
+  platform: NodeJS.Platform
+  nocase: boolean
+  relative: Minimatch[]
+  relativeChildren: Minimatch[]
+  absolute: Minimatch[]
+  absoluteChildren: Minimatch[]
+
+  constructor(
+    ignored: string[],
+    { platform = defaultPlatform, nocase }: GlobWalkerOpts
+  ) {
+    this.platform = platform
+    this.nocase = !!nocase
+    this.relative = []
+    this.absolute = []
+    this.relativeChildren = []
+    this.absoluteChildren = []
+    const mmopts = {
+      platform: this.platform,
+      optimizationLevel: 2,
+      nocaseMagicOnly: true,
+      dot: true,
+      nocase,
+    }
 
-  constructor(patterns: string[]) {
-    this.matchers = []
-    this.gmatchers = []
-    for (const pattern of patterns) {
-      this.matchers.push(new Minimatch(pattern, { dot: true }))
-      if (pattern.substring(pattern.length - 3) === '/**') {
-        const gp = pattern.replace(/(\/\*\*)+$/, '')
-        this.gmatchers.push(new Minimatch(gp, { dot: true }))
+    // this is a little weird, but it gives us a clean set of optimized
+    // minimatch matchers, without getting tripped up if one of them
+    // ends in /** inside a brace section, and it's only inefficient at
+    // the start of the walk, not along it.
+    // It'd be nice if the Pattern class just had a .test() method, but
+    // handling globstars is a bit of a pita, and that code already lives
+    // in minimatch anyway.
+    // Another way would be if maybe Minimatch could take its set/globParts
+    // as an option, and then we could at least just use Pattern to test
+    // for absolute-ness.
+    // Yet another way, Minimatch could take an array of glob strings, and
+    // a cwd option, and do the right thing.
+    for (const ign of ignored) {
+      const mm = new Minimatch(ign, mmopts)
+      for (let i = 0; i < mm.set.length; i++) {
+        const parsed = mm.set[i]
+        const globParts = mm.globParts[i]
+        const p = new Pattern(parsed, globParts, 0, this.platform)
+        const m = new Minimatch(p.globString(), mmopts)
+        const children = globParts[globParts.length - 1] === '**'
+        const absolute = p.isAbsolute()
+        if (absolute) this.absolute.push(m)
+        else this.relative.push(m)
+        if (children) {
+          if (absolute) this.absoluteChildren.push(m)
+          else this.relativeChildren.push(m)
+        }
       }
     }
   }
 
-  ignored(p: string): boolean {
-    return (
-      this.matchers.some(m => m.match(p)) ||
-      this.gmatchers.some(m => m.match(p))
-    )
+  ignored(p: Path): boolean {
+    const fullpath = p.fullpath()
+    const relative = p.relative()
+    for (const m of this.absolute) {
+      if (m.match(fullpath)) return true
+    }
+    for (const m of this.relative) {
+      if (m.match(relative)) return true
+    }
+    return false
   }
 
-  childrenIgnored(p: string): boolean {
-    return this.gmatchers.some(m => m.match(p))
+  childrenIgnored(p: Path): boolean {
+    const fullpath = p.fullpath()
+    const relative = p.relative()
+    for (const m of this.absoluteChildren) {
+      if (m.match(fullpath)) return true
+    }
+    for (const m of this.relativeChildren) {
+      if (m.match(relative)) return true
+    }
+    return false
   }
 }
diff --git a/src/pattern.ts b/src/pattern.ts
index 8dfab3ac..d7fa33a2 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -1,6 +1,7 @@
 // this is just a very light wrapper around 2 arrays with an offset index
 
 import { GLOBSTAR } from 'minimatch'
+import { Path } from 'path-scurry'
 type MMRegExp = RegExp & {
   _glob?: string
   _src?: string
@@ -20,8 +21,6 @@ type DrivePatternList = [p0: string, ...rest: MMPattern[]]
 type AbsolutePatternList = [p0: '', ...rest: MMPattern[]]
 type GlobList = [p: string, ...rest: string[]]
 
-// TODO: this should be a parameter
-const isWin = process.platform === 'win32'
 const isPatternList = (pl: MMPattern[]): pl is PatternList =>
   pl.length >= 1
 const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1
@@ -31,6 +30,7 @@ export class Pattern {
   readonly globList: GlobList
   readonly #index: number
   readonly length: number
+  #platform: NodeJS.Platform
   #rest?: Pattern | null
   #globString?: string
   #isDrive?: boolean
@@ -42,6 +42,7 @@ export class Pattern {
     patternList: MMPattern[],
     globList: string[],
     index: number,
+    platform: NodeJS.Platform,
     globstarFollowed: number[] = []
   ) {
     if (!isPatternList(patternList)) {
@@ -61,6 +62,7 @@ export class Pattern {
     this.globList = globList
     this.#index = index
     this.#globstarFollowed = globstarFollowed
+    this.#platform = platform
 
     // if the current item is not globstar, and the next item is .., skip ahead
     if (
@@ -161,6 +163,7 @@ export class Pattern {
       this.patternList,
       this.globList,
       this.#index + 1,
+      this.#platform,
       this.#globstarFollowed
     )
     this.#rest.#isAbsolute = this.#isAbsolute
@@ -190,7 +193,7 @@ export class Pattern {
     return this.#isUNC !== undefined
       ? this.#isUNC
       : (this.#isUNC =
-          isWin &&
+          this.#platform === 'win32' &&
           this.#index === 0 &&
           pl[0] === '' &&
           pl[1] === '' &&
@@ -209,7 +212,7 @@ export class Pattern {
     return this.#isDrive !== undefined
       ? this.#isDrive
       : (this.#isDrive =
-          isWin &&
+          this.#platform === 'win32' &&
           this.#index === 0 &&
           this.length > 1 &&
           typeof pl[0] === 'string' &&
diff --git a/src/walker.ts b/src/walker.ts
index c330880e..ea54d5d7 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -1,5 +1,6 @@
 import Minipass from 'minipass'
 import { Path } from 'path-scurry'
+import { Ignore } from './ignore.js'
 
 // XXX can we somehow make it so that it NEVER processes a given path more than
 // once, enough that the match set tracking is no longer needed?  that'd speed
@@ -16,7 +17,11 @@ export interface GlobWalkerOpts {
   mark?: boolean
   withFileTypes?: boolean
   signal?: AbortSignal
+  ignore?: string | string[] | Ignore
+  platform?: NodeJS.Platform
+  nocase?: boolean
 }
+
 export type GWOFileTypesTrue = GlobWalkerOpts & {
   withFileTypes: true
 }
@@ -52,6 +57,16 @@ export type MatchStream =
     ? Minipass
     : Minipass
 
+const makeIgnore = (
+  ignore: string | string[] | Ignore,
+  opts: GlobWalkerOpts
+): Ignore =>
+  typeof ignore === 'string'
+    ? new Ignore([ignore], opts)
+    : Array.isArray(ignore)
+    ? new Ignore(ignore, opts)
+    : ignore
+
 /**
  * basic walking utilities that all the glob walker types use
  */
@@ -63,17 +78,28 @@ export abstract class GlobUtil {
   paused: boolean = false
   aborted: boolean = false
   #onResume: (() => any)[] = []
+  #ignore?: Ignore
 
   constructor(patterns: Pattern[], path: Path, opts: O)
   constructor(patterns: Pattern[], path: Path, opts: O) {
     this.patterns = patterns
     this.path = path
     this.opts = opts
+    if (opts.ignore) {
+      this.#ignore = makeIgnore(opts.ignore, opts)
+    }
     if (opts.signal) {
       opts.signal.addEventListener('abort', () => this.abort())
     }
   }
 
+  #ignored(path: Path): boolean {
+    return this.seen.has(path) || !!this.#ignore?.ignored(path)
+  }
+  #childrenIgnored(path: Path): boolean {
+    return !!this.#ignore?.childrenIgnored(path)
+  }
+
   // backpressure mechanism
   pause() {
     this.paused = true
@@ -104,7 +130,7 @@ export abstract class GlobUtil {
     if (this.opts.realpath) {
       rpc = e.realpathCached()
       if (rpc) {
-        if (this.seen.has(rpc) || (e.isDirectory() && this.opts.nodir)) {
+        if (this.#ignored(rpc) || (e.isDirectory() && this.opts.nodir)) {
           return undefined
         }
         e = rpc
@@ -119,7 +145,7 @@ export abstract class GlobUtil {
       const r = await e.realpath().then(e => e?.lstat())
       if (
         !r ||
-        this.seen.has(r) ||
+        this.#ignored(r) ||
         (!e.canReaddir() && ifDir) ||
         (e.isDirectory() && this.opts.nodir)
       ) {
@@ -130,7 +156,7 @@ export abstract class GlobUtil {
       const r = await e.realpath()
       if (
         !r ||
-        this.seen.has(r) ||
+        this.#ignored(r) ||
         (!e.canReaddir() && ifDir) ||
         (e.isDirectory() && this.opts.nodir)
       ) {
@@ -141,7 +167,7 @@ export abstract class GlobUtil {
       const r = await e.lstat()
       if (
         !r ||
-        this.seen.has(r) ||
+        this.#ignored(r) ||
         (!r.canReaddir() && ifDir) ||
         (r.isDirectory() && this.opts.nodir)
       ) {
@@ -149,7 +175,7 @@ export abstract class GlobUtil {
       }
       return r
     } else if (
-      this.seen.has(e) ||
+      this.#ignored(e) ||
       (!e.canReaddir() && ifDir) ||
       (e.isDirectory() && this.opts.nodir)
     ) {
@@ -164,7 +190,7 @@ export abstract class GlobUtil {
     if (this.opts.realpath) {
       rpc = e.realpathCached()
       if (rpc) {
-        if (this.seen.has(rpc) || (e.isDirectory() && this.opts.nodir)) {
+        if (this.#ignored(rpc) || (e.isDirectory() && this.opts.nodir)) {
           return undefined
         }
         e = rpc
@@ -179,7 +205,7 @@ export abstract class GlobUtil {
       const r = e.realpathSync()?.lstatSync()
       if (
         !r ||
-        this.seen.has(r) ||
+        this.#ignored(r) ||
         (!r.canReaddir() && ifDir) ||
         (e.isDirectory() && this.opts.nodir)
       ) {
@@ -190,7 +216,7 @@ export abstract class GlobUtil {
       const r = e.realpathSync()
       if (
         !r ||
-        this.seen.has(r) ||
+        this.#ignored(r) ||
         (!r.canReaddir() && ifDir) ||
         (e.isDirectory() && this.opts.nodir)
       ) {
@@ -201,7 +227,7 @@ export abstract class GlobUtil {
       const r = e.lstatSync()
       if (
         !r ||
-        this.seen.has(r) ||
+        this.#ignored(r) ||
         (!r.canReaddir() && ifDir) ||
         (r.isDirectory() && this.opts.nodir)
       ) {
@@ -209,7 +235,7 @@ export abstract class GlobUtil {
       }
       return r
     } else if (
-      this.seen.has(e) ||
+      this.#ignored(e) ||
       (!e.canReaddir() && ifDir) ||
       (e.isDirectory() && this.opts.nodir)
     ) {
@@ -223,7 +249,7 @@ export abstract class GlobUtil {
   abstract matchEmit(p: string | Path): void
 
   matchFinish(e: Path, absolute: boolean) {
-    if (this.seen.has(e)) return
+    if (this.#ignored(e)) return
     this.seen.add(e)
     const mark = this.opts.mark && e.isDirectory() ? '/' : ''
     // ok, we have what we need!
@@ -239,13 +265,13 @@ export abstract class GlobUtil {
   }
 
   async match(e: Path, absolute: boolean, ifDir: boolean): Promise {
-    if (this.seen.has(e)) return
+    if (this.#ignored(e)) return
     const p = await this.matchCheck(e, ifDir)
     if (p) this.matchFinish(p, absolute)
   }
 
   matchSync(e: Path, absolute: boolean, ifDir: boolean): void {
-    if (this.seen.has(e)) return
+    if (this.#ignored(e)) return
     //console.error(e.fullpath(), absolute, ifDir, new Error('matchtrace').stack)
     const p = this.matchCheckSync(e, ifDir)
     if (p) this.matchFinish(p, absolute)
@@ -265,6 +291,7 @@ export abstract class GlobUtil {
     processor: Processor,
     cb: () => any
   ) {
+    if (this.#childrenIgnored(target)) return cb()
     if (this.paused) {
       this.onResume(() => this.walkCB2(target, patterns, processor, cb))
       return
@@ -280,7 +307,7 @@ export abstract class GlobUtil {
     }
 
     for (const [m, absolute, ifDir] of processor.matches.entries()) {
-      if (this.seen.has(m)) continue
+      if (this.#ignored(m)) continue
       tasks++
       this.match(m, absolute, ifDir).then(() => next())
     }
@@ -315,7 +342,7 @@ export abstract class GlobUtil {
     }
 
     for (const [m, absolute, ifDir] of processor.matches.entries()) {
-      if (this.seen.has(m)) continue
+      if (this.#ignored(m)) continue
       tasks++
       this.match(m, absolute, ifDir).then(() => next())
     }
@@ -341,6 +368,7 @@ export abstract class GlobUtil {
     processor: Processor,
     cb: () => any
   ) {
+    if (this.#childrenIgnored(target)) return cb()
     //console.error('walkcb2sync', this.paused, target.fullpath(), patterns.map(p => p.globString()))
     if (this.paused) {
       this.onResume(() =>
@@ -359,7 +387,7 @@ export abstract class GlobUtil {
     }
 
     for (const [m, absolute, ifDir] of processor.matches.entries()) {
-      if (this.seen.has(m)) continue
+      if (this.#ignored(m)) continue
       this.matchSync(m, absolute, ifDir)
     }
 
@@ -386,7 +414,7 @@ export abstract class GlobUtil {
     }
 
     for (const [m, absolute, ifDir] of processor.matches.entries()) {
-      if (this.seen.has(m)) continue
+      if (this.#ignored(m)) continue
       this.matchSync(m, absolute, ifDir)
     }
     for (const [target, patterns] of processor.subwalks.entries()) {

From f2cb1b08259fb9188b098703f5ae60fb48dbc74f Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Fri, 24 Feb 2023 18:26:13 -0800
Subject: [PATCH 094/163] follows

---
 src/glob.ts      | 40 ++++++++++++++++++++--------------------
 src/processor.ts | 15 ++++++++++++---
 src/walker.ts    |  5 +++--
 3 files changed, 35 insertions(+), 25 deletions(-)

diff --git a/src/glob.ts b/src/glob.ts
index 67972414..737d6211 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -205,20 +205,20 @@ export class Glob {
     // coerce them into the right shape.  It will have already called
     // realpath() if the option was set to do so, so we know that's cached.
     // start out knowing the cwd, at least
-    const walker = new GlobWalker(
-      this.patterns,
-      this.scurry.cwd,
-      { ...this.opts, platform: this.platform, nocase: this.nocase }
-    )
+    const walker = new GlobWalker(this.patterns, this.scurry.cwd, {
+      ...this.opts,
+      platform: this.platform,
+      nocase: this.nocase,
+    })
     return this.finish(await walker.walk())
   }
 
   walkSync(): Results {
-    const walker = new GlobWalker(
-      this.patterns,
-      this.scurry.cwd,
-      { ...this.opts, platform: this.platform, nocase: this.nocase }
-    )
+    const walker = new GlobWalker(this.patterns, this.scurry.cwd, {
+      ...this.opts,
+      platform: this.platform,
+      nocase: this.nocase,
+    })
     return this.finish(walker.walkSync())
   }
 
@@ -229,20 +229,20 @@ export class Glob {
 
   stream(): Minipass>
   stream(): Minipass {
-    return new GlobStream(
-      this.patterns,
-      this.scurry.cwd,
-      { ...this.opts, platform: this.platform, nocase: this.nocase }
-    ).stream()
+    return new GlobStream(this.patterns, this.scurry.cwd, {
+      ...this.opts,
+      platform: this.platform,
+      nocase: this.nocase,
+    }).stream()
   }
 
   streamSync(): Minipass>
   streamSync(): Minipass {
-    return new GlobStream(
-      this.patterns,
-      this.scurry.cwd,
-      { ...this.opts, platform: this.platform, nocase: this.nocase }
-    ).streamSync()
+    return new GlobStream(this.patterns, this.scurry.cwd, {
+      ...this.opts,
+      platform: this.platform,
+      nocase: this.nocase,
+    }).streamSync()
   }
 
   iteratorSync(): Generator, void, void> {
diff --git a/src/processor.ts b/src/processor.ts
index 45922d29..30fcdff3 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -3,6 +3,7 @@
 import { GLOBSTAR, MMRegExp } from 'minimatch'
 import { Path } from 'path-scurry'
 import { MMPattern, Pattern } from './pattern.js'
+import { GlobWalkerOpts } from './walker.js'
 
 class HasWalkedCache {
   store: Map>
@@ -69,8 +70,12 @@ export class Processor {
   matches = new MatchRecord()
   subwalks = new SubWalks()
   patterns?: Pattern[]
+  follow: boolean
+  opts: GlobWalkerOpts
 
-  constructor(hasWalkedCache?: HasWalkedCache) {
+  constructor(opts: GlobWalkerOpts, hasWalkedCache?: HasWalkedCache) {
+    this.opts = opts
+    this.follow = !!opts.follow
     this.hasWalkedCache = hasWalkedCache
       ? hasWalkedCache.copy()
       : new HasWalkedCache()
@@ -141,7 +146,11 @@ export class Processor {
         // if it's a symlink, but we didn't get here by way of a
         // globstar match (meaning it's the first time THIS globstar
         // has traversed a symlink), then we follow it. Otherwise, stop.
-        if (!t.isSymbolicLink() || pattern.followGlobstar()) {
+        if (
+          !t.isSymbolicLink() ||
+          this.follow ||
+          pattern.followGlobstar()
+        ) {
           this.subwalks.add(t, pattern)
         }
         const rp = rest?.pattern()
@@ -172,7 +181,7 @@ export class Processor {
   }
 
   child() {
-    return new Processor(this.hasWalkedCache)
+    return new Processor(this.opts, this.hasWalkedCache)
   }
 
   // return a new Processor containing the subwalks for each
diff --git a/src/walker.ts b/src/walker.ts
index ea54d5d7..e7eb60be 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -20,6 +20,7 @@ export interface GlobWalkerOpts {
   ignore?: string | string[] | Ignore
   platform?: NodeJS.Platform
   nocase?: boolean
+  follow?: boolean
 }
 
 export type GWOFileTypesTrue = GlobWalkerOpts & {
@@ -282,7 +283,7 @@ export abstract class GlobUtil {
       this.onResume(() => this.walkCB(target, patterns, cb))
       return
     }
-    this.walkCB2(target, patterns, new Processor(), cb)
+    this.walkCB2(target, patterns, new Processor(this.opts), cb)
   }
 
   walkCB2(
@@ -359,7 +360,7 @@ export abstract class GlobUtil {
       this.onResume(() => this.walkCBSync(target, patterns, cb))
       return
     }
-    this.walkCB2Sync(target, patterns, new Processor(), cb)
+    this.walkCB2Sync(target, patterns, new Processor(this.opts), cb)
   }
 
   walkCB2Sync(

From 8f9b8748b2943356a39012c47b8aa0178ecbf1a9 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Fri, 24 Feb 2023 18:26:23 -0800
Subject: [PATCH 095/163] format changelog

---
 changelog.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/changelog.md b/changelog.md
index 6b0dea35..93f3f584 100644
--- a/changelog.md
+++ b/changelog.md
@@ -20,7 +20,7 @@ changes.
   `streamSync()`, `iterate()`, `iterateSync()` methods, and is
   both an async and sync Generator.
 - First class support for UNC paths and drive letters on Windows.
-  Note that *glob patterns* must still use `/` as a path
+  Note that _glob patterns_ must still use `/` as a path
   separator, unless the `windowsPathsNoEscape` option is set, in
   which case glob patterns cannot be escaped with `\`.
 - Paths are returned in the canonical formatting for the platform

From 5af05e76220a43e462cc704ad5e1fe6090759a78 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Fri, 24 Feb 2023 22:34:53 -0800
Subject: [PATCH 096/163] hasMagic returns false for brace expansion

As long as the brace-expanded patterns do not contain any magic characters,
treat these the same as if an array of non-magic patterns had been provided.
---
 changelog.md     |  2 ++
 src/has-magic.ts | 14 ++++----------
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/changelog.md b/changelog.md
index 93f3f584..64a83c3a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -25,6 +25,8 @@ changes.
   which case glob patterns cannot be escaped with `\`.
 - Paths are returned in the canonical formatting for the platform
   in question.
+- The `hasMagic` method will return false for patterns that only
+  contain brace expansion, but no other "magic" glob characters.
 
 ## Options Changes
 
diff --git a/src/has-magic.ts b/src/has-magic.ts
index 7a88cb0c..e2db2b43 100644
--- a/src/has-magic.ts
+++ b/src/has-magic.ts
@@ -7,14 +7,8 @@ export const hasMagic = (
   if (!Array.isArray(pattern)) {
     pattern = [pattern]
   }
-  return pattern.some(p => {
-    const g = new Glob(p, options)
-    if (g.matchSet.length === 0) {
-      return false
-    }
-    if (g.matchSet.length > 1) {
-      return true
-    }
-    return g.matchSet[0].some(p => typeof p !== 'string')
-  })
+  const g = new Glob(pattern, options)
+  return g.patterns.length === 0
+    ? false
+    : g.patterns.some(p => p.hasMagic())
 }

From cbd84c4b441d007263ca76d1d83863da7cb43dd1 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Fri, 24 Feb 2023 22:35:35 -0800
Subject: [PATCH 097/163] Pattern: make patternList and globList fields private

---
 src/pattern.ts | 80 +++++++++++++++++++++++++++-----------------------
 1 file changed, 44 insertions(+), 36 deletions(-)

diff --git a/src/pattern.ts b/src/pattern.ts
index d7fa33a2..c437f478 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -1,7 +1,6 @@
 // this is just a very light wrapper around 2 arrays with an offset index
 
 import { GLOBSTAR } from 'minimatch'
-import { Path } from 'path-scurry'
 type MMRegExp = RegExp & {
   _glob?: string
   _src?: string
@@ -26,11 +25,11 @@ const isPatternList = (pl: MMPattern[]): pl is PatternList =>
 const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1
 
 export class Pattern {
-  readonly patternList: PatternList
-  readonly globList: GlobList
+  readonly #patternList: PatternList
+  readonly #globList: GlobList
   readonly #index: number
   readonly length: number
-  #platform: NodeJS.Platform
+  readonly #platform: NodeJS.Platform
   #rest?: Pattern | null
   #globString?: string
   #isDrive?: boolean
@@ -58,19 +57,19 @@ export class Pattern {
     if (index >= this.length) {
       throw new TypeError('index out of range')
     }
-    this.patternList = patternList
-    this.globList = globList
+    this.#patternList = patternList
+    this.#globList = globList
     this.#index = index
     this.#globstarFollowed = globstarFollowed
     this.#platform = platform
 
     // if the current item is not globstar, and the next item is .., skip ahead
     if (
-      this.patternList[this.#index] !== GLOBSTAR &&
-      this.patternList[this.#index] !== '..' &&
-      this.patternList[this.#index] !== '.' &&
-      this.patternList[this.#index] !== '' &&
-      this.patternList[this.#index + 1] === '..' &&
+      this.#patternList[this.#index] !== GLOBSTAR &&
+      this.#patternList[this.#index] !== '..' &&
+      this.#patternList[this.#index] !== '.' &&
+      this.#patternList[this.#index] !== '' &&
+      this.#patternList[this.#index + 1] === '..' &&
       this.length > this.#index + 2
     ) {
       this.#index += 2
@@ -87,8 +86,8 @@ export class Pattern {
       // /etc => ['/', 'etc']
       // / => ['/']
       if (this.isUNC()) {
-        const [p1, p2, p3, ...prest] = this.patternList
-        const [g1, g2, g3, ...grest] = this.globList
+        const [p1, p2, p3, ...prest] = this.#patternList
+        const [g1, g2, g3, ...grest] = this.#globList
         if (prest[0] === '') {
           // ends in /
           prest.shift()
@@ -96,12 +95,12 @@ export class Pattern {
         }
         const p = [p1, p2, p3, ''].join('/')
         const g = [g1, g2, g3, ''].join('/')
-        this.patternList = [p, ...prest]
-        this.globList = [g, ...grest]
-        this.length = this.patternList.length
+        this.#patternList = [p, ...prest]
+        this.#globList = [g, ...grest]
+        this.length = this.#patternList.length
       } else if (this.isDrive() || this.isAbsolute()) {
-        const [p1, ...prest] = this.patternList
-        const [g1, ...grest] = this.globList
+        const [p1, ...prest] = this.#patternList
+        const [g1, ...grest] = this.#globList
         if (prest[0] === '') {
           // ends in /
           prest.shift()
@@ -109,9 +108,9 @@ export class Pattern {
         }
         const p = (p1 as string) + '/'
         const g = g1 + '/'
-        this.patternList = [p, ...prest]
-        this.globList = [g, ...grest]
-        this.length = this.patternList.length
+        this.#patternList = [p, ...prest]
+        this.#globList = [g, ...grest]
+        this.length = this.#patternList.length
       }
     } else {
       // discard any empty path portions, except the last one.
@@ -122,24 +121,24 @@ export class Pattern {
   }
 
   pattern(): MMPattern {
-    return this.patternList[this.#index]
+    return this.#patternList[this.#index]
   }
 
   isString(): boolean {
-    return typeof this.patternList[this.#index] === 'string'
+    return typeof this.#patternList[this.#index] === 'string'
   }
   isGlobstar(): boolean {
-    return this.patternList[this.#index] === GLOBSTAR
+    return this.#patternList[this.#index] === GLOBSTAR
   }
   isGlobstarDotDot(): boolean {
-    return this.isGlobstar() && this.globList[this.#index + 1] === '..'
+    return this.isGlobstar() && this.#globList[this.#index + 1] === '..'
   }
   isRegExp(): boolean {
-    return this.patternList[this.#index] instanceof RegExp
+    return this.#patternList[this.#index] instanceof RegExp
   }
 
   glob(): string {
-    return this.globList[this.#index]
+    return this.#globList[this.#index]
   }
 
   globString(): string {
@@ -147,9 +146,9 @@ export class Pattern {
       this.#globString ||
       (this.#index === 0
         ? this.isAbsolute()
-          ? this.globList[0] + this.globList.slice(1).join('/')
-          : this.globList.join('/')
-        : this.globList.slice(this.#index).join('/')))
+          ? this.#globList[0] + this.#globList.slice(1).join('/')
+          : this.#globList.join('/')
+        : this.#globList.slice(this.#index).join('/')))
   }
 
   hasMore(): boolean {
@@ -160,8 +159,8 @@ export class Pattern {
     if (this.#rest !== undefined) return this.#rest
     if (!this.hasMore()) return (this.#rest = null)
     this.#rest = new Pattern(
-      this.patternList,
-      this.globList,
+      this.#patternList,
+      this.#globList,
       this.#index + 1,
       this.#platform,
       this.#globstarFollowed
@@ -189,7 +188,7 @@ export class Pattern {
 
   // pattern like: //host/share/...
   // split = [ '', '', 'host', 'share', ... ]
-  isUNC(pl = this.patternList): pl is UNCPatternList {
+  isUNC(pl = this.#patternList): pl is UNCPatternList {
     return this.#isUNC !== undefined
       ? this.#isUNC
       : (this.#isUNC =
@@ -208,7 +207,7 @@ export class Pattern {
   // XXX: would be nice to handle patterns like `c:*` to test the cwd
   // in c: for *, but I don't know of a way to even figure out what that
   // cwd is without actually chdir'ing into it?
-  isDrive(pl = this.patternList): pl is DrivePatternList {
+  isDrive(pl = this.#patternList): pl is DrivePatternList {
     return this.#isDrive !== undefined
       ? this.#isDrive
       : (this.#isDrive =
@@ -222,7 +221,7 @@ export class Pattern {
   // pattern = '/' or '/...' or '/x/...'
   // split = ['', ''] or ['', ...] or ['', 'x', ...]
   // Drive and UNC both considered absolute on windows
-  isAbsolute(pl = this.patternList): pl is AbsolutePatternList {
+  isAbsolute(pl = this.#patternList): pl is AbsolutePatternList {
     return this.#isAbsolute !== undefined
       ? this.#isAbsolute
       : (this.#isAbsolute =
@@ -233,9 +232,18 @@ export class Pattern {
 
   // consume the root of the pattern, and return it
   root(): string {
-    const p = this.patternList[0]
+    const p = this.#patternList[0]
     return typeof p === 'string' && this.isAbsolute() && this.#index === 0
       ? p
       : ''
   }
+
+  hasMagic(): boolean {
+    for (let i = 0; i < this.length; i++) {
+      if (typeof this.#patternList[i] !== 'string') {
+        return true
+      }
+    }
+    return false
+  }
 }

From c3be35ae03314f4d74450eee6d15b6e4d85f1816 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Fri, 24 Feb 2023 22:36:43 -0800
Subject: [PATCH 098/163] correct ** vs ./** behavior

The previous implementation was only valid prior to minimatch preserving
the leading portions before an initial **, resulting in some incorrect
follows in some cases.  Now that we can determine whether the ** leads
the pattern, the corrected behavior is more easily implemented.
---
 src/processor.ts | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/src/processor.ts b/src/processor.ts
index 30fcdff3..cca4a855 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -146,12 +146,14 @@ export class Processor {
         // if it's a symlink, but we didn't get here by way of a
         // globstar match (meaning it's the first time THIS globstar
         // has traversed a symlink), then we follow it. Otherwise, stop.
-        if (
-          !t.isSymbolicLink() ||
-          this.follow ||
-          pattern.followGlobstar()
-        ) {
+        if (this.follow || !t.isSymbolicLink()) {
           this.subwalks.add(t, pattern)
+        } else if (
+          t.isSymbolicLink() &&
+          pattern.followGlobstar() &&
+          rest
+        ) {
+          this.subwalks.add(t, rest)
         }
         const rp = rest?.pattern()
         const rrest = rest?.rest()
@@ -219,12 +221,6 @@ export class Processor {
     if (!pattern.hasMore()) {
       this.matches.add(e, absolute, false)
     }
-    // record that this globstar is following a symlink, so we
-    // can know to stop traversing when we encounter it again
-    // in processPatterns.
-    if (e.isSymbolicLink()) {
-      pattern.followGlobstar()
-    }
     if (e.canReaddir()) {
       this.subwalks.add(e, pattern)
     }

From 8c2e0824f76b843d8477b6e3d90a3afecd54cc07 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sat, 25 Feb 2023 14:14:52 -0800
Subject: [PATCH 099/163] feature complete and tests passing

not 100% coverage yet, though
---
 changelog.md                      |  18 ++++
 src/glob.ts                       |   5 +-
 src/ignore.ts                     |  23 ++---
 src/pattern.ts                    |  39 ++++----
 src/processor.ts                  |  52 ++++++----
 src/walker.ts                     |  12 +--
 test/00-setup.ts                  |   7 +-
 test/bash-results.ts              |  29 ++++++
 test/has-magic.ts                 |   4 +-
 test/ignore.ts                    |  38 ++++----
 test/mark.ts                      |  58 +++++------
 test/match-base.ts                |  67 +++++++++++--
 test/new-glob-optional-options.ts |  10 --
 test/nocase-nomagic.ts            | 156 ------------------------------
 test/nonull.ts                    |  25 -----
 test/nosort.ts                    |  53 ----------
 test/realpath.ts                  | 102 +++++--------------
 test/slash-cwd.ts                 |   2 +-
 test/windows-paths-no-escape.ts   |   2 +-
 19 files changed, 256 insertions(+), 446 deletions(-)
 delete mode 100644 test/new-glob-optional-options.ts
 delete mode 100644 test/nocase-nomagic.ts
 delete mode 100644 test/nonull.ts
 delete mode 100644 test/nosort.ts

diff --git a/changelog.md b/changelog.md
index 64a83c3a..8c8174a4 100644
--- a/changelog.md
+++ b/changelog.md
@@ -27,6 +27,15 @@ changes.
   in question.
 - The `hasMagic` method will return false for patterns that only
   contain brace expansion, but no other "magic" glob characters.
+- Patterns ending in `/` will still be restricted to matching
+  directories, but will not have a `/` appended in the results.
+  In general, results will be in their default relative or
+  absolute forms, without any extraneous `/` and `.` characters,
+  unlike shell matches. (The `mark` option may still be used to
+  _always_ mark directory matches with a trailing `/` or `\`.)
+- An options argument is required for the `Glob` class
+  constructor. `{}` may be provided to accept all default
+  options.
 
 ## Options Changes
 
@@ -54,6 +63,15 @@ changes.
   unique.
 - `nosort:true` is no longer supported. Result sets are never
   sorted.
+- When the `nocase` option is used, the assumption is that it
+  reflects the case sensitivity of the _filesystem itself_.
+  Using case-insensitive matching on a case-sensitive filesystem,
+  or vice versa, may thus result in more or fewer matches than
+  expected. In general, it should only be used when the
+  filesystem is known to differ from the platform default.
+- `realpath:true` no longer implies `absolute:true`.  The
+  relative path to the realpath will be emitted when `absolute`
+  is not set.
 
 ## Performance and Algorithm Changes
 
diff --git a/src/glob.ts b/src/glob.ts
index 737d6211..5a9ee483 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -140,7 +140,7 @@ export class Glob {
       if (opts.noglobstar) {
         throw new TypeError('base matching requires globstar')
       }
-      pattern = pattern.map(p => (p.includes('/') ? p : `**/${p}`))
+      pattern = pattern.map(p => (p.includes('/') ? p : `./**/${p}`))
     }
 
     this.pattern = pattern
@@ -179,11 +179,9 @@ export class Glob {
       platform: this.platform,
     }
 
-    // console.error('glob pattern arg', this.pattern)
     const mms = this.pattern.map(p => new Minimatch(p, mmo))
     const [matchSet, globSet, globParts] = mms.reduce(
       (set: [MatchSet, GlobSet, GlobParts], m) => {
-        // console.error('globparts', m.globParts)
         set[0].push(...m.set)
         set[1].push(...m.globSet)
         set[2].push(...m.globParts)
@@ -192,7 +190,6 @@ export class Glob {
       [[], [], []]
     )
     this.patterns = matchSet.map((set, i) => {
-      // console.error('globParts', globParts[i])
       return new Pattern(set, globParts[i], 0, this.platform)
     })
     this.matchSet = matchSet
diff --git a/src/ignore.ts b/src/ignore.ts
index a949f0a8..e9433d44 100644
--- a/src/ignore.ts
+++ b/src/ignore.ts
@@ -36,7 +36,6 @@ export class Ignore {
     const mmopts = {
       platform: this.platform,
       optimizationLevel: 2,
-      nocaseMagicOnly: true,
       dot: true,
       nocase,
     }
@@ -74,25 +73,27 @@ export class Ignore {
 
   ignored(p: Path): boolean {
     const fullpath = p.fullpath()
-    const relative = p.relative()
-    for (const m of this.absolute) {
-      if (m.match(fullpath)) return true
-    }
+    const fullpaths = `${fullpath}/`
+    const relative = p.relative() || '.'
+    const relatives = `${relative}/`
     for (const m of this.relative) {
-      if (m.match(relative)) return true
+      if (m.match(relative) || m.match(relatives)) return true
+    }
+    for (const m of this.absolute) {
+      if (m.match(fullpath) || m.match(fullpaths)) return true
     }
     return false
   }
 
   childrenIgnored(p: Path): boolean {
-    const fullpath = p.fullpath()
-    const relative = p.relative()
-    for (const m of this.absoluteChildren) {
-      if (m.match(fullpath)) return true
-    }
+    const fullpath = p.fullpath() + '/'
+    const relative = (p.relative() || '.') + '/'
     for (const m of this.relativeChildren) {
       if (m.match(relative)) return true
     }
+    for (const m of this.absoluteChildren) {
+      if (m.match(fullpath)) true
+    }
     return false
   }
 }
diff --git a/src/pattern.ts b/src/pattern.ts
index c437f478..cec75e99 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -35,14 +35,13 @@ export class Pattern {
   #isDrive?: boolean
   #isUNC?: boolean
   #isAbsolute?: boolean
-  #globstarFollowed: number[]
+  #followGlobstar: boolean = true
 
   constructor(
     patternList: MMPattern[],
     globList: string[],
     index: number,
-    platform: NodeJS.Platform,
-    globstarFollowed: number[] = []
+    platform: NodeJS.Platform
   ) {
     if (!isPatternList(patternList)) {
       throw new TypeError('empty pattern list')
@@ -60,7 +59,6 @@ export class Pattern {
     this.#patternList = patternList
     this.#globList = globList
     this.#index = index
-    this.#globstarFollowed = globstarFollowed
     this.#platform = platform
 
     // if the current item is not globstar, and the next item is .., skip ahead
@@ -162,8 +160,7 @@ export class Pattern {
       this.#patternList,
       this.#globList,
       this.#index + 1,
-      this.#platform,
-      this.#globstarFollowed
+      this.#platform
     )
     this.#rest.#isAbsolute = this.#isAbsolute
     this.#rest.#isUNC = this.#isUNC
@@ -171,21 +168,6 @@ export class Pattern {
     return this.#rest
   }
 
-  followGlobstar(): boolean {
-    if (!this.isGlobstar()) {
-      return false
-    }
-    // never follow a globstar if it's the first pattern in the list
-    if (this.#index === 0) {
-      return false
-    }
-    if (this.#globstarFollowed.includes(this.#index)) {
-      return false
-    }
-    this.#globstarFollowed.push(this.#index)
-    return true
-  }
-
   // pattern like: //host/share/...
   // split = [ '', '', 'host', 'share', ... ]
   isUNC(pl = this.#patternList): pl is UNCPatternList {
@@ -246,4 +228,19 @@ export class Pattern {
     }
     return false
   }
+
+  checkFollowGlobstar(): boolean {
+    return !(
+      this.#index === 0 ||
+      !this.isGlobstar() ||
+      !this.#followGlobstar
+    )
+  }
+
+  markFollowGlobstar(): boolean {
+    if (this.#index === 0 || !this.isGlobstar() || !this.#followGlobstar)
+      return false
+    this.#followGlobstar = false
+    return true
+  }
 }
diff --git a/src/processor.ts b/src/processor.ts
index cca4a855..71f2279d 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -28,8 +28,8 @@ class MatchRecord {
   store: Map = new Map()
   add(target: Path, absolute: boolean, ifDir: boolean) {
     const n = (absolute ? 2 : 0) | (ifDir ? 1 : 0)
-    const current = this.store.get(target) || 0
-    this.store.set(target, n & current)
+    const current = this.store.get(target)
+    this.store.set(target, current === undefined ? n : n & current)
   }
   // match, absolute, ifdir
   entries(): [Path, boolean, boolean][] {
@@ -71,11 +71,13 @@ export class Processor {
   subwalks = new SubWalks()
   patterns?: Pattern[]
   follow: boolean
+  dot: boolean
   opts: GlobWalkerOpts
 
   constructor(opts: GlobWalkerOpts, hasWalkedCache?: HasWalkedCache) {
     this.opts = opts
     this.follow = !!opts.follow
+    this.dot = !!opts.dot
     this.hasWalkedCache = hasWalkedCache
       ? hasWalkedCache.copy()
       : new HasWalkedCache()
@@ -117,7 +119,8 @@ export class Processor {
         (rest = pattern.rest())
       ) {
         const c = t.resolve(p)
-        if (c.isUnknown()) break
+        // we can be reasonably sure that .. is a readable dir
+        if (c.isUnknown() && p !== '..') break
         t = c
         pattern = rest
         changed = true
@@ -129,8 +132,9 @@ export class Processor {
         this.hasWalkedCache.storeWalked(t, pattern)
       }
 
-      // now we have either a final string, or a pattern starting with magic,
-      // mounted on t.
+      // now we have either a final string for a known entry,
+      // more strings for an unknown entry,
+      // or a pattern starting with magic, mounted on t.
       if (typeof p === 'string') {
         // must be final entry
         if (!rest) {
@@ -146,14 +150,12 @@ export class Processor {
         // if it's a symlink, but we didn't get here by way of a
         // globstar match (meaning it's the first time THIS globstar
         // has traversed a symlink), then we follow it. Otherwise, stop.
-        if (this.follow || !t.isSymbolicLink()) {
-          this.subwalks.add(t, pattern)
-        } else if (
-          t.isSymbolicLink() &&
-          pattern.followGlobstar() &&
-          rest
+        if (
+          !t.isSymbolicLink() ||
+          this.follow ||
+          pattern.checkFollowGlobstar()
         ) {
-          this.subwalks.add(t, rest)
+          this.subwalks.add(t, pattern)
         }
         const rp = rest?.pattern()
         const rrest = rest?.rest()
@@ -217,12 +219,26 @@ export class Processor {
     rest: Pattern | null,
     absolute: boolean
   ) {
-    if (e.name.startsWith('.')) return
-    if (!pattern.hasMore()) {
-      this.matches.add(e, absolute, false)
-    }
-    if (e.canReaddir()) {
-      this.subwalks.add(e, pattern)
+    if (this.dot || !e.name.startsWith('.')) {
+      if (!pattern.hasMore()) {
+        this.matches.add(e, absolute, false)
+      }
+      if (e.canReaddir()) {
+        // if we're in follow mode or it's not a symlink, just keep
+        // testing the same pattern. If there's more after the globstar,
+        // then this symlink consumes the globstar. If not, then we can
+        // follow at most ONE symlink along the way, so we mark it, which
+        // also checks to ensure that it wasn't already marked.
+        if (this.follow || !e.isSymbolicLink()) {
+          this.subwalks.add(e, pattern)
+        } else if (e.isSymbolicLink()) {
+          if (rest && pattern.checkFollowGlobstar()) {
+            this.subwalks.add(e, rest)
+          } else if (pattern.markFollowGlobstar()) {
+            this.subwalks.add(e, pattern)
+          }
+        }
+      }
     }
     // if the NEXT thing matches this entry, then also add
     // the rest.
diff --git a/src/walker.ts b/src/walker.ts
index e7eb60be..0db3d68f 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -21,6 +21,7 @@ export interface GlobWalkerOpts {
   platform?: NodeJS.Platform
   nocase?: boolean
   follow?: boolean
+  dot?: boolean
 }
 
 export type GWOFileTypesTrue = GlobWalkerOpts & {
@@ -80,12 +81,14 @@ export abstract class GlobUtil {
   aborted: boolean = false
   #onResume: (() => any)[] = []
   #ignore?: Ignore
+  #sep: '\\' | '/'
 
   constructor(patterns: Pattern[], path: Path, opts: O)
   constructor(patterns: Pattern[], path: Path, opts: O) {
     this.patterns = patterns
     this.path = path
     this.opts = opts
+    this.#sep = opts.platform === 'win32' ? '\\' : '/'
     if (opts.ignore) {
       this.#ignore = makeIgnore(opts.ignore, opts)
     }
@@ -107,7 +110,6 @@ export abstract class GlobUtil {
   }
   resume() {
     if (this.aborted) return
-    //console.error(new Error('resume').stack, this.#onResume.length)
     this.paused = false
     let fn: (() => any) | undefined = undefined
     while (!this.paused && (fn = this.#onResume.shift())) {
@@ -252,7 +254,7 @@ export abstract class GlobUtil {
   matchFinish(e: Path, absolute: boolean) {
     if (this.#ignored(e)) return
     this.seen.add(e)
-    const mark = this.opts.mark && e.isDirectory() ? '/' : ''
+    const mark = this.opts.mark && e.isDirectory() ? this.#sep : ''
     // ok, we have what we need!
     if (this.opts.withFileTypes) {
       this.matchEmit(e)
@@ -261,7 +263,8 @@ export abstract class GlobUtil {
     } else if (this.opts.absolute || absolute) {
       this.matchEmit(e.fullpath() + mark)
     } else {
-      this.matchEmit(e.relative() + mark)
+      const rel = e.relative()
+      this.matchEmit(!rel && mark ? './' : rel + mark)
     }
   }
 
@@ -273,7 +276,6 @@ export abstract class GlobUtil {
 
   matchSync(e: Path, absolute: boolean, ifDir: boolean): void {
     if (this.#ignored(e)) return
-    //console.error(e.fullpath(), absolute, ifDir, new Error('matchtrace').stack)
     const p = this.matchCheckSync(e, ifDir)
     if (p) this.matchFinish(p, absolute)
   }
@@ -370,7 +372,6 @@ export abstract class GlobUtil {
     cb: () => any
   ) {
     if (this.#childrenIgnored(target)) return cb()
-    //console.error('walkcb2sync', this.paused, target.fullpath(), patterns.map(p => p.globString()))
     if (this.paused) {
       this.onResume(() =>
         this.walkCB2Sync(target, patterns, processor, cb)
@@ -489,7 +490,6 @@ export class GlobStream<
 
   matchEmit(e: Result): void
   matchEmit(e: Path | string): void {
-    // console.error('MATCH EMIT', [e])
     this.results.write(e)
     if (!this.results.flowing) this.pause()
   }
diff --git a/test/00-setup.ts b/test/00-setup.ts
index a5709ca8..76fc3de2 100644
--- a/test/00-setup.ts
+++ b/test/00-setup.ts
@@ -77,11 +77,10 @@ if (process.platform === 'win32' || !process.env.TEST_REGEN) {
       'a/abc{fed,def}/g/h',
       'a/abc{fed/g,def}/**/',
       'a/abc{fed/g,def}/**///**/',
-      // TODO: match bash behavior
       // When a ** is the FIRST item in a pattern, it has
-      // slightly dfferent symbolic link handling behavior.
-      // '**/a',
-      // '**/a/**',
+      // more restrictive symbolic link handling behavior.
+      '**/a',
+      '**/a/**',
       './**/a',
       './**/a/**/',
       './**/a/**',
diff --git a/test/bash-results.ts b/test/bash-results.ts
index 69e08711..14a1650f 100644
--- a/test/bash-results.ts
+++ b/test/bash-results.ts
@@ -21,6 +21,35 @@ export const bashResults: { [path: string]: string[] } = {
   'a/abc{fed,def}/g/h': ['a/abcdef/g/h', 'a/abcfed/g/h'],
   'a/abc{fed/g,def}/**/': ['a/abcdef', 'a/abcdef/g', 'a/abcfed/g'],
   'a/abc{fed/g,def}/**///**/': ['a/abcdef', 'a/abcdef/g', 'a/abcfed/g'],
+  '**/a': ['a', 'a/symlink/a'],
+  '**/a/**': [
+    'a',
+    'a/abcdef',
+    'a/abcdef/g',
+    'a/abcdef/g/h',
+    'a/abcfed',
+    'a/abcfed/g',
+    'a/abcfed/g/h',
+    'a/b',
+    'a/b/c',
+    'a/b/c/d',
+    'a/bc',
+    'a/bc/e',
+    'a/bc/e/f',
+    'a/c',
+    'a/c/d',
+    'a/c/d/c',
+    'a/c/d/c/b',
+    'a/cb',
+    'a/cb/e',
+    'a/cb/e/f',
+    'a/symlink',
+    'a/symlink/a',
+    'a/symlink/a/b',
+    'a/symlink/a/b/c',
+    'a/x',
+    'a/z',
+  ],
   './**/a': ['a', 'a/symlink/a', 'a/symlink/a/b/c/a'],
   './**/a/**/': [
     'a',
diff --git a/test/has-magic.ts b/test/has-magic.ts
index 5fc9ed45..4495550a 100644
--- a/test/has-magic.ts
+++ b/test/has-magic.ts
@@ -22,9 +22,9 @@ t.test('detect magic in glob patterns', async t => {
     glob.hasMagic('a/b/+(x|y)', { noext: true }),
     'no magic in a/b/+(x|y) noext'
   )
-  t.ok(glob.hasMagic('{a,b}'), 'magic in {a,b}')
+  t.notOk(glob.hasMagic('{a,b}'), 'no magic in {a,b}')
   t.notOk(
     glob.hasMagic('{a,b}', { nobrace: true }),
-    'magic in {a,b} nobrace:true'
+    'no magic in {a,b} nobrace:true'
   )
 })
diff --git a/test/ignore.ts b/test/ignore.ts
index 3d6cf874..158f82d4 100644
--- a/test/ignore.ts
+++ b/test/ignore.ts
@@ -45,6 +45,7 @@ const cases: Case[] = [
     '**',
     ['c/**', 'bc/**', 'symlink/**', 'abcdef/**'],
     [
+      '',
       'abcfed',
       'abcfed/g',
       'abcfed/g/h',
@@ -66,6 +67,7 @@ const cases: Case[] = [
     '**',
     ['b'],
     [
+      '',
       'abcdef',
       'abcdef/g',
       'abcdef/g/h',
@@ -97,6 +99,7 @@ const cases: Case[] = [
     '**',
     ['b', 'c'],
     [
+      '',
       'abcdef',
       'abcdef/g',
       'abcdef/g/h',
@@ -127,6 +130,7 @@ const cases: Case[] = [
     '**',
     ['b**'],
     [
+      '',
       'abcdef',
       'abcdef/g',
       'abcdef/g/h',
@@ -157,6 +161,7 @@ const cases: Case[] = [
     '**',
     ['b/**'],
     [
+      '',
       'abcdef',
       'abcdef/g',
       'abcdef/g/h',
@@ -186,6 +191,7 @@ const cases: Case[] = [
     '**',
     ['b**/**'],
     [
+      '',
       'abcdef',
       'abcdef/g',
       'abcdef/g/h',
@@ -212,6 +218,7 @@ const cases: Case[] = [
     '**',
     ['ab**ef/**'],
     [
+      '',
       'abcfed',
       'abcfed/g',
       'abcfed/g/h',
@@ -241,6 +248,7 @@ const cases: Case[] = [
     '**',
     ['abc{def,fed}/**'],
     [
+      '',
       'b',
       'b/c',
       'b/c/d',
@@ -267,6 +275,7 @@ const cases: Case[] = [
     '**',
     ['abc{def,fed}/*'],
     [
+      '',
       'abcdef',
       'abcdef/g/h',
       'abcfed',
@@ -343,25 +352,18 @@ t.test('race condition', async t => {
   t.jobs = 64
   for (const dot of [true, false]) {
     for (const ignore of ['fixtures/**', undefined]) {
-      for (const nonull of [true, false]) {
-        for (const cwd of [undefined, process.cwd(), '.']) {
-          const opt: GlobOptions = {
-            dot,
-            ignore,
-            nonull,
-          }
-          if (cwd) opt.cwd = cwd
-          const expect = ignore
-            ? nonull
-              ? ['fixtures/*']
-              : []
-            : ['fixtures/a']
-          t.test(JSON.stringify(opt), async t => {
-            t.plan(2)
-            t.same(glob.sync(pattern, opt).sort(), expect)
-            t.same((await glob(pattern, opt)).sort(), expect)
-          })
+      for (const cwd of [undefined, process.cwd(), '.']) {
+        const opt: GlobOptions = {
+          dot,
+          ignore,
         }
+        if (cwd) opt.cwd = cwd
+        const expect = ignore ? [] : ['fixtures/a']
+        t.test(JSON.stringify(opt), async t => {
+          t.plan(2)
+          t.same(glob.sync(pattern, opt).sort(), expect)
+          t.same((await glob(pattern, opt)).sort(), expect)
+        })
       }
     }
   }
diff --git a/test/mark.ts b/test/mark.ts
index 47996b94..07b829e9 100644
--- a/test/mark.ts
+++ b/test/mark.ts
@@ -2,6 +2,8 @@ import t from 'tap'
 import glob from '../'
 process.chdir(__dirname + '/fixtures')
 
+const alphasort = (a:string, b:string) => a.localeCompare(b, 'en')
+
 t.test('mark with cwd', async t => {
   const pattern = '*/*'
   const opt = { mark: true, cwd: 'a' }
@@ -12,15 +14,15 @@ t.test('mark with cwd', async t => {
     'bc/e/',
     'c/d/',
     'cb/e/',
-  ].sort()
+  ].sort(alphasort)
 
   const res = await glob(pattern, opt)
   if (process.platform !== 'win32') {
     expect.push('symlink/a/')
   }
 
-  t.same(res.sort(), expect)
-  t.same(glob.sync(pattern, opt).sort(), expect)
+  t.same(res.sort(alphasort), expect)
+  t.same(glob.sync(pattern, opt).sort(alphasort), expect)
 })
 
 t.test('mark, with **', async t => {
@@ -42,10 +44,10 @@ t.test('mark, with **', async t => {
     'a/cb/',
     'a/cb/e/',
     'a/cb/e/f',
-  ]
+  ].sort(alphasort)
 
-  t.same(await glob(pattern, opt), expect, 'async')
-  t.same(glob.sync(pattern, opt), expect, 'sync')
+  t.same((await glob(pattern, opt)).sort(alphasort), expect, 'async')
+  t.same(glob.sync(pattern, opt).sort(alphasort), expect, 'sync')
 })
 
 t.test('mark, no / on pattern', async t => {
@@ -64,10 +66,10 @@ t.test('mark, no / on pattern', async t => {
   if (process.platform !== 'win32') {
     expect.push('a/symlink/')
   }
-  expect.sort()
-  const results = await glob(pattern, opt)
+  expect.sort(alphasort)
+  const results = (await glob(pattern, opt)).sort(alphasort)
   t.same(results, expect)
-  t.same(glob.sync(pattern, opt), expect)
+  t.same(glob.sync(pattern, opt).sort(alphasort), expect)
 })
 
 t.test('mark=false, no / on pattern', async t => {
@@ -85,11 +87,11 @@ t.test('mark=false, no / on pattern', async t => {
   if (process.platform !== 'win32') {
     expect.push('a/symlink')
   }
-  expect.sort()
-  const results = await glob(pattern)
+  expect.sort(alphasort)
+  const results = (await glob(pattern)).sort(alphasort)
 
   t.same(results, expect)
-  t.same(glob.sync(pattern), expect)
+  t.same(glob.sync(pattern).sort(alphasort), expect)
 })
 
 t.test('mark=true, / on pattern', async t => {
@@ -109,32 +111,32 @@ t.test('mark=true, / on pattern', async t => {
   if (process.platform !== 'win32') {
     expect.push('a/symlink/')
   }
-  expect.sort()
-  const results = await glob(pattern, opt)
+  expect.sort(alphasort)
+  const results = (await glob(pattern, opt)).sort(alphasort)
   t.same(results, expect)
-  t.same(glob.sync(pattern, opt), expect)
+  t.same(glob.sync(pattern, opt).sort(alphasort), expect)
 })
 
 t.test('mark=false, / on pattern', async t => {
   const pattern = 'a/*/'
   const expect = [
-    'a/abcdef/',
-    'a/abcfed/',
-    'a/b/',
-    'a/bc/',
-    'a/c/',
-    'a/cb/',
-    'a/x/',
-    'a/z/',
+    'a/abcdef',
+    'a/abcfed',
+    'a/b',
+    'a/bc',
+    'a/c',
+    'a/cb',
+    'a/x',
+    'a/z',
   ]
   if (process.platform !== 'win32') {
-    expect.push('a/symlink/')
+    expect.push('a/symlink')
   }
-  expect.sort()
+  expect.sort(alphasort)
 
-  const results = await glob(pattern)
+  const results = (await glob(pattern)).sort(alphasort)
   t.same(results, expect)
-  t.same(glob.sync(pattern), expect)
+  t.same(glob.sync(pattern).sort(alphasort), expect)
 })
 
 const cwd = process
@@ -150,7 +152,7 @@ for (const mark of [true, false]) {
       const res = results[0].replace(/\\/g, '/')
       const syncResults = glob.sync(pattern, { mark: mark })
       const syncRes = syncResults[0].replace(/\\/g, '/')
-      if (slash || mark) {
+      if (mark) {
         t.equal(res, cwd + '/')
       } else {
         t.equal(res.indexOf(cwd), 0)
diff --git a/test/match-base.ts b/test/match-base.ts
index 0b3adb06..3cdfabb9 100644
--- a/test/match-base.ts
+++ b/test/match-base.ts
@@ -12,17 +12,34 @@ if (process.platform !== 'win32') {
   expect.push('a/symlink/a', 'a/symlink/a/b/c/a')
 }
 
+const alphasort = (a: string, b: string) => a.localeCompare(b, 'en')
+
+expect.sort(alphasort)
+
 t.test('chdir', async t => {
   const origCwd = process.cwd()
   process.chdir(fixtureDir)
   t.teardown(() => process.chdir(origCwd))
-  t.same(glob.sync(pattern, { matchBase: true }), expect)
-  t.same(await glob(pattern, { matchBase: true }), expect)
+  t.same(glob.sync(pattern, { matchBase: true }).sort(alphasort), expect)
+  t.same(
+    (await glob(pattern, { matchBase: true })).sort(alphasort),
+    expect
+  )
 })
 
 t.test('cwd', async t => {
-  t.same(glob.sync(pattern, { matchBase: true, cwd: fixtureDir }), expect)
-  t.same(await glob(pattern, { matchBase: true, cwd: fixtureDir }), expect)
+  t.same(
+    glob
+      .sync(pattern, { matchBase: true, cwd: fixtureDir })
+      .sort(alphasort),
+    expect
+  )
+  t.same(
+    (await glob(pattern, { matchBase: true, cwd: fixtureDir })).sort(
+      alphasort
+    ),
+    expect
+  )
 })
 
 t.test('noglobstar', async t => {
@@ -34,20 +51,50 @@ t.test('noglobstar', async t => {
 t.test('pattern includes /', async t => {
   const pattern = 'a/b*'
   const expect = ['a/b', 'a/bc']
-  t.same(glob.sync(pattern, { matchBase: true, cwd: fixtureDir }), expect)
-  t.same(await glob(pattern, { matchBase: true, cwd: fixtureDir }), expect)
+  t.same(
+    glob
+      .sync(pattern, { matchBase: true, cwd: fixtureDir })
+      .sort(alphasort),
+    expect
+  )
+  t.same(
+    (await glob(pattern, { matchBase: true, cwd: fixtureDir })).sort(
+      alphasort
+    ),
+    expect
+  )
 })
 
 t.test('one brace section of pattern includes /', async t => {
   const pattern = 'a{*,/b*}'
   const exp = ['a', 'a/b', 'a/bc']
-  t.same(glob.sync(pattern, { matchBase: true, cwd: fixtureDir }), exp)
-  t.same(await glob(pattern, { matchBase: true, cwd: fixtureDir }), exp)
+  t.same(
+    glob
+      .sync(pattern, { matchBase: true, cwd: fixtureDir })
+      .sort(alphasort),
+    exp
+  )
+  t.same(
+    (await glob(pattern, { matchBase: true, cwd: fixtureDir })).sort(
+      alphasort
+    ),
+    exp
+  )
 })
 
 t.test('one array member of pattern includes /', async t => {
   const pattern = ['a*', 'a/b*']
   const exp = expect.concat(['a/b', 'a/bc']).sort()
-  t.same(glob.sync(pattern, { matchBase: true, cwd: fixtureDir }), exp)
-  t.same(await glob(pattern, { matchBase: true, cwd: fixtureDir }), exp)
+  t.same(
+    glob
+      .sync(pattern, { matchBase: true, cwd: fixtureDir })
+      .sort(alphasort),
+    exp
+  )
+  t.same(
+    (await glob(pattern, { matchBase: true, cwd: fixtureDir })).sort(
+      alphasort
+    ),
+    exp
+  )
 })
diff --git a/test/new-glob-optional-options.ts b/test/new-glob-optional-options.ts
deleted file mode 100644
index a8055a56..00000000
--- a/test/new-glob-optional-options.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import t from 'tap'
-import { Glob } from '../'
-const f = __filename.replace(/\\/g, '/')
-
-t.test('new glob, with cb, and no options', async t => {
-  const gs = new Glob(f)
-  t.same(gs.processSync(), [f])
-  const g = new Glob(f)
-  t.same(await g.process(), [f])
-})
diff --git a/test/nocase-nomagic.ts b/test/nocase-nomagic.ts
deleted file mode 100644
index 34f571f3..00000000
--- a/test/nocase-nomagic.ts
+++ /dev/null
@@ -1,156 +0,0 @@
-import * as fs from 'fs'
-import t from 'tap'
-
-const cwd = process.cwd()
-const drive = /^[a-zA-Z]:[\\\/]/.test(cwd)
-  ? cwd.charAt(0).toLowerCase()
-  : 'c'
-
-const fakeStat = (
-  path: string
-): { isDirectory: () => boolean; isSymbolicLink: () => boolean } => {
-  let ret: { isDirectory: () => boolean; isSymbolicLink: () => false }
-  switch (path.toLowerCase().replace(/\\/g, '/')) {
-    case '/':
-    case drive + '/':
-    case drive:
-      ret = {
-        isSymbolicLink: () => false,
-        isDirectory: () => true,
-      }
-      break
-    case '/tmp':
-    case '/tmp/':
-    case drive + ':/tmp':
-    case drive + ':/tmp/':
-      ret = {
-        isSymbolicLink: () => false,
-        isDirectory: () => true,
-      }
-      break
-    case '/tmp/a':
-    case drive + ':/tmp/a':
-      ret = {
-        isSymbolicLink: () => false,
-        isDirectory: () => false,
-      }
-      break
-    default:
-      throw new Error('invalid: ' + path)
-  }
-  return ret
-}
-
-const join = (r: string, p: string) =>
-  r === '/' ? `${r}${p}` : `${r}/${p}`
-
-function fakeReaddir(path: string) {
-  let ret: string[]
-  switch (path.toLowerCase().replace(/\\/g, '/')) {
-    case '/tmp':
-    case '/tmp/':
-    case drive + ':/tmp':
-    case drive + ':/tmp/':
-      ret = ['a', 'A']
-      break
-    case '/':
-    case drive + ':':
-    case drive + ':/':
-      ret = ['tMp', 'tmp', 'tMP', 'TMP']
-      break
-    default:
-      throw new Error('not mocked')
-  }
-  return ret.map(name => ({ name, ...fakeStat(join(path, name)) }))
-}
-
-const mockFs = {
-  ...fs,
-  statSync: fakeStat,
-  readdir: (
-    path: string,
-    _options: { withFileTypes: true },
-    cb: (
-      er: null | NodeJS.ErrnoException,
-      entries?: ReturnType
-    ) => void
-  ) => {
-    try {
-      const f = fakeReaddir(path)
-      process.nextTick(() => cb(null, f))
-    } catch (_) {
-      fs.readdir(path, { withFileTypes: true }, cb)
-    }
-  },
-
-  readdirSync: (path: string, _options?: { withFileTypes: true }) => {
-    try {
-      return fakeReaddir(path)
-    } catch (_) {
-      return fs.readdirSync(path, { withFileTypes: true })
-    }
-  },
-}
-
-const { glob } = t.mock('../dist/cjs/index.js', { fs: mockFs })
-
-t.test('nocase, nomagic', async t => {
-  const raw = [
-    '/TMP/A',
-    '/TMP/a',
-    '/tMP/A',
-    '/tMP/a',
-    '/tMp/A',
-    '/tMp/a',
-    '/tmp/A',
-    '/tmp/a',
-  ]
-  const want =
-    process.platform === 'win32' ? raw.map(p => drive + ':' + p) : raw
-
-  await Promise.all(
-    ['/tmp/a', '/TmP/A'].map(async pattern => {
-      const rawRes: string[] = await glob(pattern, { nocase: true })
-      const g = new glob.Glob(pattern, { nocase: true })
-      const res =
-        process.platform === 'win32'
-          ? rawRes.map(r =>
-              r
-                .replace(/\\/g, '/')
-                .replace(new RegExp('^' + drive + ':', 'i'), drive + ':')
-            )
-          : rawRes
-      t.same(res.sort(), want, pattern)
-    })
-  )
-})
-
-t.test('nocase, with some magic', async t => {
-  const raw = [
-    '/TMP/A',
-    '/TMP/a',
-    '/tMP/A',
-    '/tMP/a',
-    '/tMp/A',
-    '/tMp/a',
-    '/tmp/A',
-    '/tmp/a',
-  ]
-  const want =
-    process.platform === 'win32' ? raw.map(p => drive + ':' + p) : raw
-
-  await Promise.all(
-    ['/tmp/*', '/tMp/*'].map(async pattern => {
-      const resRaw: string[] = glob.sync(pattern, { nocase: true })
-      const res =
-        process.platform === 'win32'
-          ? resRaw.map(r =>
-              r
-                .replace(/\\/g, '/')
-                .replace(new RegExp('^' + drive + ':', 'i'), drive + ':')
-            )
-          : resRaw
-      t.same(res.sort(), want)
-    })
-  )
-})
diff --git a/test/nonull.ts b/test/nonull.ts
deleted file mode 100644
index 2946a101..00000000
--- a/test/nonull.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import t from 'tap'
-import { glob } from '../'
-import type { GlobOptions } from '../src/index.js'
-process.chdir(__dirname)
-
-// [pattern, options, expect]
-const cases: [string, GlobOptions, string[]][] = [
-  ['a/*NOFILE*/**/', {}, ['a/*NOFILE*/**/']],
-  ['*/*', { cwd: 'NODIR' }, ['*/*']],
-  ['NOFILE', {}, ['NOFILE']],
-  ['NOFILE', { cwd: 'NODIR' }, ['NOFILE']],
-  // this is the weird one, because a/b actually does exist,
-  // and we've said we want to ignore it, but also it's the pattern,
-  // and nonull is set, so nonull takes precedence.
-  ['a/b', { ignore: 'a/**' }, ['a/b']],
-]
-
-for (const [pattern, options, expect] of cases) {
-  options.nonull = true
-  expect.sort()
-  t.test(pattern + ' ' + JSON.stringify(options), async t => {
-    t.same(glob.sync(pattern, options).sort(), expect, 'sync results')
-    t.same((await glob(pattern, options)).sort(), expect, 'async results')
-  })
-}
diff --git a/test/nosort.ts b/test/nosort.ts
deleted file mode 100644
index 00bbbb84..00000000
--- a/test/nosort.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import * as fs from 'fs'
-import { Dirent, readdir, readdirSync } from 'fs'
-import { resolve } from 'path'
-import t from 'tap'
-const { glob } = t.mock('../dist/cjs/index.js', {
-  fs: {
-    ...fs,
-    readdir: (
-      path: string,
-      o: { withFileTypes: true },
-      cb: (er: null | NodeJS.ErrnoException, entries?: Dirent[]) => void
-    ) => {
-      readdir(path, o, (er, entries) => {
-        if (entries) {
-          cb(
-            er,
-            entries.sort(({ name: b }, { name: a }) =>
-              a.localeCompare(b, 'en')
-            )
-          )
-        } else {
-          cb(er)
-        }
-      })
-    },
-    readdirSync: (path: string, o: { withFileTypes: true }) =>
-      readdirSync(path, o).sort(({ name: b }, { name: a }) =>
-        a.localeCompare(b, 'en')
-      ),
-  },
-})
-
-const pattern = 'a/[bz]*'
-t.test('nosort', async t => {
-  const opt = { nosort: true, cwd: resolve(__dirname, 'fixtures') }
-  const expect = ['a/z', 'a/bc', 'a/b']
-  t.same(glob.sync(pattern, opt), expect)
-  t.same(await glob(pattern, opt), expect)
-})
-
-t.test('nosort unset', async t => {
-  const opt = { cwd: resolve(__dirname, 'fixtures') }
-  const expect = ['a/b', 'a/bc', 'a/z']
-  t.same(glob.sync(pattern, opt), expect)
-  t.same(await glob(pattern, opt), expect)
-})
-
-t.test('nosort:false', async t => {
-  const opt = { nosort: false, cwd: resolve(__dirname, 'fixtures') }
-  const expect = ['a/b', 'a/bc', 'a/z']
-  t.same(glob.sync(pattern, opt), expect)
-  t.same(await glob(pattern, opt), expect)
-})
diff --git a/test/realpath.ts b/test/realpath.ts
index 543b76c5..9561bdc1 100644
--- a/test/realpath.ts
+++ b/test/realpath.ts
@@ -1,9 +1,12 @@
 import * as fs from 'fs'
+import * as fsp from 'fs/promises'
 import { resolve } from 'path'
 import t from 'tap'
 import glob from '../'
 import type { GlobOptions } from '../src/index.js'
 
+const alphasort = (a: string, b: string) => a.localeCompare(b, 'en')
+
 // pattern to find a bunch of duplicates
 const pattern = 'a/symlink/{*,**/*/*/*,*/*/**,*/*/*/*/*/*}'
 const fixtureDir = resolve(__dirname, 'fixtures')
@@ -33,41 +36,7 @@ if (process.platform === 'win32') {
     [{ cwd: 'a' }, [], 'no one here but us chickens'],
 
     [
-      { nonull: true },
-      ['no one here but us chickens', 'no one here but us sheep'],
-      'no one here but us {chickens,sheep}',
-    ],
-
-    [
-      { nounique: true },
-      [
-        'a/symlink',
-        'a/symlink',
-        'a/symlink',
-        'a/symlink/a',
-        'a/symlink/a',
-        'a/symlink/a',
-        'a/symlink/a/b',
-        'a/symlink/a/b',
-      ],
-    ],
-
-    [
-      { nounique: true, mark: true },
-      [
-        'a/symlink/',
-        'a/symlink/',
-        'a/symlink/',
-        'a/symlink/a/',
-        'a/symlink/a/',
-        'a/symlink/a/',
-        'a/symlink/a/b/',
-        'a/symlink/a/b/',
-      ],
-    ],
-
-    [
-      { nounique: true, mark: true, follow: true },
+      { mark: true, follow: true },
       [
         // this one actually just has HELLA entries, don't list them all here
         // plus it differs based on the platform.  follow:true is kinda cray.
@@ -78,40 +47,13 @@ if (process.platform === 'win32') {
     ],
   ]
 
-  for (const [opt, raw, p = pattern] of cases) {
-    const expect = !(opt.nonull && raw[0].match(/^no one here/))
-      ? raw.map(function (d) {
-          d = (opt.cwd ? resolve(opt.cwd) : fixtureDir) + '/' + d
-          return d.replace(/\\/g, '/')
-        })
-      : raw
-
+  for (const [opt, expect, p = pattern] of cases) {
+    expect.sort(alphasort)
     t.test(p + ' ' + JSON.stringify(opt), async t => {
       opt.realpath = true
-      if (!(opt.follow && opt.nounique)) {
-        t.same(glob.sync(p, opt), expect, 'sync')
-        const a = await glob(p, opt)
-        t.same(a, expect, 'async')
-      } else {
-        // follow with nounique is wild, just verify it has a lot of entries,
-        // and that all the expected ones are found.
-        const s = glob.sync(p, opt)
-        const a = await glob(p, opt)
-        t.ok(s.length > 5, 'more than 5 entries found sync', {
-          found: s.length,
-          expect: '>5',
-          matches: s,
-        })
-        t.ok(a.length > 5, 'more than 5 entries found async', {
-          found: a.length,
-          expect: '>5',
-          matches: a,
-        })
-        for (const e of expect) {
-          t.ok(s.includes(e), 'found ' + e + ' sync')
-          t.ok(a.includes(e), 'found ' + e + ' async')
-        }
-      }
+      t.same(glob.sync(p, opt).sort(alphasort), expect, 'sync')
+      const a = await glob(p, opt)
+      t.same(a.sort(alphasort), expect, 'async')
     })
   }
 
@@ -120,27 +62,31 @@ if (process.platform === 'win32') {
     const { glob } = t.mock('../dist/cjs/index.js', {
       fs: {
         ...fs,
-        realpath: (_: string, cb: (er: Error) => void) =>
-          cb(new Error('no realpath for you async')),
-        realpathSync: () => {
-          throw new Error('no error for you sync')
+        realpathSync: Object.assign(fs.realpathSync, {
+          native: () => {
+            throw new Error('no error for you sync')
+          },
+        }),
+      },
+      'fs/promises': {
+        ...fsp,
+        realpath: async () => {
+          throw new Error('no error for you async')
         },
       },
     })
     const pattern = 'a/symlink/a/b/c/a/b/**'
-    const expect = ['a/symlink/a/b/c/a/b/', 'a/symlink/a/b/c/a/b/c'].map(
-      e => resolve(fixtureDir, e)
-    )
+    const expect = ['a/symlink', 'a/symlink/a/b'].sort(alphasort)
     t.test('setting cwd explicitly', async t => {
       const opt = { realpath: true, cwd: fixtureDir }
-      t.same(glob.sync(pattern, opt), expect)
-      t.same(await glob(pattern, opt), expect)
+      t.same(glob.sync(pattern, opt).sort(alphasort), expect)
+      t.same((await glob(pattern, opt)).sort(alphasort), expect)
     })
     t.test('looking in cwd', async t => {
       process.chdir(fixtureDir)
       const opt = { realpath: true }
-      t.same(glob.sync(pattern, opt), expect)
-      t.same(await glob(pattern, opt), expect)
+      t.same(glob.sync(pattern, opt).sort(alphasort), expect)
+      t.same((await glob(pattern, opt)).sort(alphasort), expect)
     })
   })
 }
diff --git a/test/slash-cwd.ts b/test/slash-cwd.ts
index d54f048b..ffb8c82a 100644
--- a/test/slash-cwd.ts
+++ b/test/slash-cwd.ts
@@ -5,7 +5,7 @@ import glob from '../'
 import type { GlobOptions } from '../src/index.js'
 
 const pattern = '../{*.md,test}/'
-const expect = ['../test/']
+const expect = ['']
 const cwd = __dirname
 const opt: GlobOptions = { cwd }
 process.chdir(__dirname + '/..')
diff --git a/test/windows-paths-no-escape.ts b/test/windows-paths-no-escape.ts
index 997162a9..6ed8ceda 100644
--- a/test/windows-paths-no-escape.ts
+++ b/test/windows-paths-no-escape.ts
@@ -20,7 +20,7 @@ for (const p of platforms) {
     })
     t.equal(process.platform, p, 'gut check: actually set platform')
     const pattern = '/a/b/c/x\\[a-b\\]y\\*'
-    const def = new Glob(pattern)
+    const def = new Glob(pattern, {})
     const winpath = new Glob(pattern, {
       windowsPathsNoEscape: true,
     })

From 3e68a7b908d6477350530b70a55c9f80130f775b Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sat, 25 Feb 2023 14:44:09 -0800
Subject: [PATCH 100/163] some windows test affordances

---
 test/cwd-test.ts |  8 +++---
 test/ignore.ts   | 70 +++++++++++++++++++++++++-----------------------
 test/mark.ts     | 32 +++++++++++-----------
 3 files changed, 57 insertions(+), 53 deletions(-)

diff --git a/test/cwd-test.ts b/test/cwd-test.ts
index ba932de8..369f1096 100644
--- a/test/cwd-test.ts
+++ b/test/cwd-test.ts
@@ -1,6 +1,8 @@
 import { resolve } from 'path'
 import t from 'tap'
 import { glob } from '../'
+import { sep } from 'path'
+const j = (a: string[]) => a.map(s => s.split('/').join(sep))
 
 const origCwd = process.cwd()
 process.chdir(__dirname + '/fixtures')
@@ -8,9 +10,9 @@ t.teardown(() => process.chdir(origCwd))
 
 t.test('changing cwd and searching for **/d', t => {
   const expect = Object.entries({
-    a: new Set(['c/d', 'b/c/d']),
-    'a/b': new Set(['c/d']),
-    '': new Set(['a/b/c/d', 'a/c/d']),
+    a: new Set(j(['c/d', 'b/c/d'])),
+    'a/b': new Set(j(['c/d'])),
+    '': new Set(j(['a/b/c/d', 'a/c/d'])),
   })
   t.plan(expect.length)
   for (const [cwd, matches] of expect) {
diff --git a/test/ignore.ts b/test/ignore.ts
index 158f82d4..3ab1f996 100644
--- a/test/ignore.ts
+++ b/test/ignore.ts
@@ -5,6 +5,10 @@ import t from 'tap'
 import glob from '../'
 import type { GlobOptions } from '../src/index.js'
 
+import { sep } from 'path'
+const alphasort = (a:string, b:string) => a.localeCompare(b, 'en')
+const j = (a: string[]) => a.map(s => s.split('/').join(sep)).sort(alphasort)
+
 // [pattern, ignore, expect, opt (object) or cwd (string)]
 type Case = [
   pattern: string,
@@ -16,24 +20,24 @@ const cases: Case[] = [
   [
     '*',
     null,
-    ['abcdef', 'abcfed', 'b', 'bc', 'c', 'cb', 'symlink', 'x', 'z'],
+    j(['abcdef', 'abcfed', 'b', 'bc', 'c', 'cb', 'symlink', 'x', 'z']),
     'a',
   ],
   [
     '*',
     'b',
-    ['abcdef', 'abcfed', 'bc', 'c', 'cb', 'symlink', 'x', 'z'],
+    j(['abcdef', 'abcfed', 'bc', 'c', 'cb', 'symlink', 'x', 'z']),
     'a',
   ],
-  ['*', 'b*', ['abcdef', 'abcfed', 'c', 'cb', 'symlink', 'x', 'z'], 'a'],
-  ['b/**', 'b/c/d', ['b', 'b/c'], 'a'],
-  ['b/**', 'd', ['b', 'b/c', 'b/c/d'], 'a'],
+  ['*', 'b*', j(['abcdef', 'abcfed', 'c', 'cb', 'symlink', 'x', 'z']), 'a'],
+  ['b/**', 'b/c/d', j(['b', 'b/c']), 'a'],
+  ['b/**', 'd', j(['b', 'b/c', 'b/c/d']), 'a'],
   ['b/**', 'b/c/**', ['b'], 'a'],
-  ['**/d', 'b/c/d', ['c/d'], 'a'],
+  ['**/d', 'b/c/d', j(['c/d']), 'a'],
   [
     'a/**/[gh]',
     ['a/abcfed/g/h'],
-    ['a/abcdef/g', 'a/abcdef/g/h', 'a/abcfed/g'],
+    j(['a/abcdef/g', 'a/abcdef/g/h', 'a/abcfed/g']),
   ],
   [
     '*',
@@ -44,7 +48,7 @@ const cases: Case[] = [
   [
     '**',
     ['c/**', 'bc/**', 'symlink/**', 'abcdef/**'],
-    [
+    j([
       '',
       'abcfed',
       'abcfed/g',
@@ -57,16 +61,16 @@ const cases: Case[] = [
       'cb/e/f',
       'x',
       'z',
-    ],
+    ]),
     'a',
   ],
   ['a/**', ['a/**'], []],
   ['a/**', ['a/**/**'], []],
-  ['a/b/**', ['a/b'], ['a/b/c', 'a/b/c/d']],
+  ['a/b/**', ['a/b'], j(['a/b/c', 'a/b/c/d'])],
   [
     '**',
     ['b'],
-    [
+    j([
       '',
       'abcdef',
       'abcdef/g',
@@ -92,13 +96,13 @@ const cases: Case[] = [
       'symlink/a/b/c',
       'x',
       'z',
-    ],
+    ]),
     'a',
   ],
   [
     '**',
     ['b', 'c'],
-    [
+    j([
       '',
       'abcdef',
       'abcdef/g',
@@ -123,13 +127,13 @@ const cases: Case[] = [
       'symlink/a/b/c',
       'x',
       'z',
-    ],
+    ]),
     'a',
   ],
   [
     '**',
     ['b**'],
-    [
+    j([
       '',
       'abcdef',
       'abcdef/g',
@@ -154,13 +158,13 @@ const cases: Case[] = [
       'symlink/a/b/c',
       'x',
       'z',
-    ],
+    ]),
     'a',
   ],
   [
     '**',
     ['b/**'],
-    [
+    j([
       '',
       'abcdef',
       'abcdef/g',
@@ -184,13 +188,13 @@ const cases: Case[] = [
       'symlink/a/b/c',
       'x',
       'z',
-    ],
+    ]),
     'a',
   ],
   [
     '**',
     ['b**/**'],
-    [
+    j([
       '',
       'abcdef',
       'abcdef/g',
@@ -211,13 +215,13 @@ const cases: Case[] = [
       'symlink/a/b/c',
       'x',
       'z',
-    ],
+    ]),
     'a',
   ],
   [
     '**',
     ['ab**ef/**'],
-    [
+    j([
       '',
       'abcfed',
       'abcfed/g',
@@ -241,13 +245,13 @@ const cases: Case[] = [
       'symlink/a/b/c',
       'x',
       'z',
-    ],
+    ]),
     'a',
   ],
   [
     '**',
     ['abc{def,fed}/**'],
-    [
+    j([
       '',
       'b',
       'b/c',
@@ -268,13 +272,13 @@ const cases: Case[] = [
       'symlink/a/b/c',
       'x',
       'z',
-    ],
+    ]),
     'a',
   ],
   [
     '**',
     ['abc{def,fed}/*'],
-    [
+    j([
       '',
       'abcdef',
       'abcdef/g/h',
@@ -299,23 +303,23 @@ const cases: Case[] = [
       'symlink/a/b/c',
       'x',
       'z',
-    ],
+    ]),
     'a',
   ],
-  ['c/**', ['c/*'], ['c', 'c/d/c', 'c/d/c/b'], 'a'],
-  ['a/c/**', ['a/c/*'], ['a/c', 'a/c/d/c', 'a/c/d/c/b']],
+  ['c/**', ['c/*'], j(['c', 'c/d/c', 'c/d/c/b']), 'a'],
+  ['a/c/**', ['a/c/*'], j(['a/c', 'a/c/d/c', 'a/c/d/c/b'])],
   ['a/c/**', ['a/c/**', 'a/c/*', 'a/c/*/c'], []],
-  ['a/**/.y', ['a/x/**'], ['a/z/.y']],
-  ['a/**/.y', ['a/x/**'], ['a/z/.y'], { dot: true }],
-  ['a/**/b', ['a/x/**'], ['a/b', 'a/c/d/c/b', 'a/symlink/a/b']],
+  ['a/**/.y', ['a/x/**'], j(['a/z/.y'])],
+  ['a/**/.y', ['a/x/**'], j(['a/z/.y']), { dot: true }],
+  ['a/**/b', ['a/x/**'], j(['a/b', 'a/c/d/c/b', 'a/symlink/a/b'])],
   [
     'a/**/b',
     ['a/x/**'],
-    ['a/b', 'a/c/d/c/b', 'a/symlink/a/b', 'a/z/.y/b'],
+    j(['a/b', 'a/c/d/c/b', 'a/symlink/a/b', 'a/z/.y/b']),
     { dot: true },
   ],
   ['*/.abcdef', 'a/**', []],
-  ['a/*/.y/b', 'a/x/**', ['a/z/.y/b']],
+  ['a/*/.y/b', 'a/x/**', j(['a/z/.y/b'])],
 ]
 
 process.chdir(__dirname + '/fixtures')
diff --git a/test/mark.ts b/test/mark.ts
index 07b829e9..d1e3a151 100644
--- a/test/mark.ts
+++ b/test/mark.ts
@@ -3,6 +3,8 @@ import glob from '../'
 process.chdir(__dirname + '/fixtures')
 
 const alphasort = (a:string, b:string) => a.localeCompare(b, 'en')
+import { sep } from 'path'
+const j = (a: string[]) => a.map(s=>s.split('/').join(sep)).sort(alphasort)
 
 t.test('mark with cwd', async t => {
   const pattern = '*/*'
@@ -14,15 +16,15 @@ t.test('mark with cwd', async t => {
     'bc/e/',
     'c/d/',
     'cb/e/',
-  ].sort(alphasort)
+  ]
 
   const res = await glob(pattern, opt)
   if (process.platform !== 'win32') {
     expect.push('symlink/a/')
   }
 
-  t.same(res.sort(alphasort), expect)
-  t.same(glob.sync(pattern, opt).sort(alphasort), expect)
+  t.same(res.sort(alphasort), j(expect))
+  t.same(glob.sync(pattern, opt).sort(alphasort), j(expect))
 })
 
 t.test('mark, with **', async t => {
@@ -46,8 +48,8 @@ t.test('mark, with **', async t => {
     'a/cb/e/f',
   ].sort(alphasort)
 
-  t.same((await glob(pattern, opt)).sort(alphasort), expect, 'async')
-  t.same(glob.sync(pattern, opt).sort(alphasort), expect, 'sync')
+  t.same((await glob(pattern, opt)).sort(alphasort), j(expect), 'async')
+  t.same(glob.sync(pattern, opt).sort(alphasort), j(expect), 'sync')
 })
 
 t.test('mark, no / on pattern', async t => {
@@ -66,10 +68,9 @@ t.test('mark, no / on pattern', async t => {
   if (process.platform !== 'win32') {
     expect.push('a/symlink/')
   }
-  expect.sort(alphasort)
   const results = (await glob(pattern, opt)).sort(alphasort)
-  t.same(results, expect)
-  t.same(glob.sync(pattern, opt).sort(alphasort), expect)
+  t.same(results, j(expect))
+  t.same(glob.sync(pattern, opt).sort(alphasort), j(expect))
 })
 
 t.test('mark=false, no / on pattern', async t => {
@@ -87,11 +88,10 @@ t.test('mark=false, no / on pattern', async t => {
   if (process.platform !== 'win32') {
     expect.push('a/symlink')
   }
-  expect.sort(alphasort)
   const results = (await glob(pattern)).sort(alphasort)
 
-  t.same(results, expect)
-  t.same(glob.sync(pattern).sort(alphasort), expect)
+  t.same(results, j(expect))
+  t.same(glob.sync(pattern).sort(alphasort), j(expect))
 })
 
 t.test('mark=true, / on pattern', async t => {
@@ -111,10 +111,9 @@ t.test('mark=true, / on pattern', async t => {
   if (process.platform !== 'win32') {
     expect.push('a/symlink/')
   }
-  expect.sort(alphasort)
   const results = (await glob(pattern, opt)).sort(alphasort)
-  t.same(results, expect)
-  t.same(glob.sync(pattern, opt).sort(alphasort), expect)
+  t.same(results, j(expect))
+  t.same(glob.sync(pattern, opt).sort(alphasort), j(expect))
 })
 
 t.test('mark=false, / on pattern', async t => {
@@ -132,11 +131,10 @@ t.test('mark=false, / on pattern', async t => {
   if (process.platform !== 'win32') {
     expect.push('a/symlink')
   }
-  expect.sort(alphasort)
 
   const results = (await glob(pattern)).sort(alphasort)
-  t.same(results, expect)
-  t.same(glob.sync(pattern).sort(alphasort), expect)
+  t.same(results, j(expect))
+  t.same(glob.sync(pattern).sort(alphasort), j(expect))
 })
 
 const cwd = process

From 3aa1abd025b2dd29cdc4cf92a9f64ef28c962af9 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sat, 25 Feb 2023 14:45:49 -0800
Subject: [PATCH 101/163] more windows test affordances

---
 test/match-base.ts | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/test/match-base.ts b/test/match-base.ts
index 3cdfabb9..80995d9a 100644
--- a/test/match-base.ts
+++ b/test/match-base.ts
@@ -2,6 +2,9 @@ import t from 'tap'
 import glob from '../'
 
 import { resolve } from 'path'
+import { sep } from 'path'
+const alphasort = (a:string, b:string) => a.localeCompare(b, 'en')
+const j = (a: string[]) => a.map(s => s.split('/').join(sep)).sort(alphasort)
 
 const fixtureDir = resolve(__dirname, 'fixtures')
 
@@ -12,18 +15,14 @@ if (process.platform !== 'win32') {
   expect.push('a/symlink/a', 'a/symlink/a/b/c/a')
 }
 
-const alphasort = (a: string, b: string) => a.localeCompare(b, 'en')
-
-expect.sort(alphasort)
-
 t.test('chdir', async t => {
   const origCwd = process.cwd()
   process.chdir(fixtureDir)
   t.teardown(() => process.chdir(origCwd))
-  t.same(glob.sync(pattern, { matchBase: true }).sort(alphasort), expect)
+  t.same(glob.sync(pattern, { matchBase: true }).sort(alphasort), j(expect))
   t.same(
     (await glob(pattern, { matchBase: true })).sort(alphasort),
-    expect
+    j(expect)
   )
 })
 
@@ -32,13 +31,13 @@ t.test('cwd', async t => {
     glob
       .sync(pattern, { matchBase: true, cwd: fixtureDir })
       .sort(alphasort),
-    expect
+    j(expect)
   )
   t.same(
     (await glob(pattern, { matchBase: true, cwd: fixtureDir })).sort(
       alphasort
     ),
-    expect
+    j(expect)
   )
 })
 
@@ -55,13 +54,13 @@ t.test('pattern includes /', async t => {
     glob
       .sync(pattern, { matchBase: true, cwd: fixtureDir })
       .sort(alphasort),
-    expect
+    j(expect)
   )
   t.same(
     (await glob(pattern, { matchBase: true, cwd: fixtureDir })).sort(
       alphasort
     ),
-    expect
+    j(expect)
   )
 })
 
@@ -72,13 +71,13 @@ t.test('one brace section of pattern includes /', async t => {
     glob
       .sync(pattern, { matchBase: true, cwd: fixtureDir })
       .sort(alphasort),
-    exp
+    j(exp)
   )
   t.same(
     (await glob(pattern, { matchBase: true, cwd: fixtureDir })).sort(
       alphasort
     ),
-    exp
+    j(exp)
   )
 })
 
@@ -89,12 +88,12 @@ t.test('one array member of pattern includes /', async t => {
     glob
       .sync(pattern, { matchBase: true, cwd: fixtureDir })
       .sort(alphasort),
-    exp
+    j(exp)
   )
   t.same(
     (await glob(pattern, { matchBase: true, cwd: fixtureDir })).sort(
       alphasort
     ),
-    exp
+    j(exp)
   )
 })

From 75f74b0d481da9d1b85f74e8ba35dc3646fefb3c Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sat, 25 Feb 2023 15:42:44 -0800
Subject: [PATCH 102/163] more windows test slashes

---
 test/ignore.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/ignore.ts b/test/ignore.ts
index 3ab1f996..4f8a9b31 100644
--- a/test/ignore.ts
+++ b/test/ignore.ts
@@ -362,7 +362,7 @@ t.test('race condition', async t => {
           ignore,
         }
         if (cwd) opt.cwd = cwd
-        const expect = ignore ? [] : ['fixtures/a']
+        const expect = ignore ? [] : j(['fixtures/a'])
         t.test(JSON.stringify(opt), async t => {
           t.plan(2)
           t.same(glob.sync(pattern, opt).sort(), expect)

From b12e6baa664fa23ac2901ca9a4f3d56df1e6b787 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sat, 25 Feb 2023 15:47:20 -0800
Subject: [PATCH 103/163] slashes on nodir test

---
 test/nodir.ts | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/test/nodir.ts b/test/nodir.ts
index 2c4fc676..cd4dfa9b 100644
--- a/test/nodir.ts
+++ b/test/nodir.ts
@@ -1,16 +1,20 @@
-import { resolve } from 'path'
+import { resolve, sep } from 'path'
 import t from 'tap'
 import glob from '../'
 import type { GlobOptions } from '../src/index.js'
 process.chdir(__dirname + '/fixtures')
 
+const alphasort = (a: string, b: string) => a.localeCompare(b, 'en')
+const j = (a: string[]) =>
+  a.map(s => s.split('/').join(sep)).sort(alphasort)
+
 // [pattern, options, expect]
 const root = resolve('a')
 const cases: [string, GlobOptions, string[]][] = [
   [
     '*/**',
     { cwd: 'a' },
-    [
+    j([
       'abcdef/g/h',
       'abcfed/g/h',
       'b/c/d',
@@ -18,12 +22,12 @@ const cases: [string, GlobOptions, string[]][] = [
       'c/d/c/b',
       'cb/e/f',
       'symlink/a/b/c',
-    ],
+    ]),
   ],
   [
     'a/*b*/**',
     {},
-    ['a/abcdef/g/h', 'a/abcfed/g/h', 'a/b/c/d', 'a/bc/e/f', 'a/cb/e/f'],
+    j(['a/abcdef/g/h', 'a/abcfed/g/h', 'a/b/c/d', 'a/bc/e/f', 'a/cb/e/f']),
   ],
   ['a/*b*/**/', {}, []],
   ['*/*', { cwd: 'a' }, []],

From 5f21b46bc21c27ce39e166c064455d8f1ed62863 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sat, 25 Feb 2023 22:14:11 -0800
Subject: [PATCH 104/163] adding lots of tests, clean up types

Also, this fixes a but preventing `**/..` from working properly when
it's the last in the pattern.
---
 changelog.md                     |   7 +-
 package-lock.json                |  14 +--
 package.json                     |   6 +-
 src/glob.ts                      |  74 ++++++++------
 src/ignore.ts                    |  21 ++--
 src/index.ts                     | 147 +++++++++++++++++++++-------
 src/pattern.ts                   |  35 ++-----
 src/processor.ts                 |  20 +++-
 src/walker.ts                    |  33 ++++---
 test/00-setup.ts                 |  10 ++
 test/absolute-must-be-strings.ts |   8 ++
 test/bash-results.ts             |  54 +++++++++++
 test/broken-symlink.ts           |   5 +-
 test/cwd-noent.ts                |  80 +++++++++++++++
 test/ignore.ts                   |  22 ++++-
 test/mark.ts                     |   5 +-
 test/match-base.ts               |  10 +-
 test/match-parent.ts             |  25 +++++
 test/match-root.ts               |   8 ++
 test/pattern.ts                  |  64 ++++++++++++
 test/platform.ts                 |  57 +++++++++++
 test/realpath.ts                 |   8 +-
 test/stream.ts                   | 161 +++++++++++++++++++++++++++++++
 23 files changed, 723 insertions(+), 151 deletions(-)
 create mode 100644 test/absolute-must-be-strings.ts
 create mode 100644 test/cwd-noent.ts
 create mode 100644 test/match-parent.ts
 create mode 100644 test/match-root.ts
 create mode 100644 test/pattern.ts
 create mode 100644 test/platform.ts
 create mode 100644 test/stream.ts

diff --git a/changelog.md b/changelog.md
index 8c8174a4..c4bdc0a6 100644
--- a/changelog.md
+++ b/changelog.md
@@ -9,11 +9,6 @@ changes.
 - Promise API instead of callbacks.
 - Accept pattern as string or array of strings.
 - Hybrid module distribution.
-
-  **Note:** `module.exports` in CommonJS mode is an object, not a
-  function. Use the exported `default` or `glob` members to
-  access the default function export in CommonJS modes.
-
 - Full TypeScript support.
 - Exported `Glob` class is no longer an event emitter.
 - Exported `Glob` class has `walk()`, `walkSync()`, `stream()`,
@@ -69,7 +64,7 @@ changes.
   or vice versa, may thus result in more or fewer matches than
   expected. In general, it should only be used when the
   filesystem is known to differ from the platform default.
-- `realpath:true` no longer implies `absolute:true`.  The
+- `realpath:true` no longer implies `absolute:true`. The
   relative path to the realpath will be emitted when `absolute`
   is not set.
 
diff --git a/package-lock.json b/package-lock.json
index 0695c9f3..c483f109 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "minimatch": "^7.1.3",
+        "minimatch": "^7.1.4",
         "minipass": "^4.2.1",
         "path-scurry": "^1.4.0"
       },
@@ -2920,9 +2920,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.3.tgz",
-      "integrity": "sha512-kpcwpcyeYtgSzpOvUf+9RiaPgrqtR2NwuqejBV2VkWxR+KC8jMWTb76zSlVJXy6ypbY39u66Un4gTk0ryiXm2g==",
+      "version": "7.1.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.4.tgz",
+      "integrity": "sha512-dZdn8jDUB4Y3eu7hABT6IgLTMQ9cVf+vhhXjLAkuN40wRkweVxEpvnGYLYZUhNB0P+BbTOZDzo+1rCitOQWc3g==",
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
@@ -8568,9 +8568,9 @@
       }
     },
     "minimatch": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.3.tgz",
-      "integrity": "sha512-kpcwpcyeYtgSzpOvUf+9RiaPgrqtR2NwuqejBV2VkWxR+KC8jMWTb76zSlVJXy6ypbY39u66Un4gTk0ryiXm2g==",
+      "version": "7.1.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.4.tgz",
+      "integrity": "sha512-dZdn8jDUB4Y3eu7hABT6IgLTMQ9cVf+vhhXjLAkuN40wRkweVxEpvnGYLYZUhNB0P+BbTOZDzo+1rCitOQWc3g==",
       "requires": {
         "brace-expansion": "^2.0.1"
       }
diff --git a/package.json b/package.json
index e6b9ccb4..21ad2b8d 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
-  "description": "a little globber",
+  "description": "the most correct and second fastest glob implementation in JavaScript",
   "version": "9.0.0-0",
   "repository": {
     "type": "git",
@@ -17,7 +17,7 @@
       },
       "require": {
         "types": "./dist/cjs/index-cjs.d.ts",
-        "default": "./dist/cjs/index-cjs.js"
+        "default": "./dist/cjs/index.js"
       }
     }
   },
@@ -59,7 +59,7 @@
   },
   "dependencies": {
     "fs.realpath": "^1.0.0",
-    "minimatch": "^7.1.3",
+    "minimatch": "^7.1.4",
     "minipass": "^4.2.1",
     "path-scurry": "^1.4.0"
   },
diff --git a/src/glob.ts b/src/glob.ts
index 5a9ee483..bf2f3f9b 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -24,18 +24,26 @@ const defaultPlatform: NodeJS.Platform =
     ? process.platform
     : 'linux'
 
-export interface GlobOptions extends MinimatchOptions {
-  ignore?: string | string[] | Ignore
+export interface GlobOptions {
+  absolute?: boolean
+  allowWindowsEscape?: boolean
+  cwd?: string
+  dot?: boolean
   follow?: boolean
+  ignore?: string | string[] | Ignore
   mark?: boolean
+  matchBase?: boolean
+  nobrace?: boolean
+  nocase?: boolean
   nodir?: boolean
-  cwd?: string
+  noext?: boolean
+  noglobstar?: boolean
+  platform?: NodeJS.Platform
   realpath?: boolean
-  absolute?: boolean
-  withFileTypes?: boolean
   scurry?: PathScurry
-  platform?: NodeJS.Platform
   signal?: AbortSignal
+  windowsPathsNoEscape?: boolean
+  withFileTypes?: boolean
 }
 
 export type GlobOptionsWithFileTypesTrue = GlobOptions & {
@@ -57,7 +65,7 @@ type Result = Opts extends GlobOptionsWithFileTypesTrue
   : Opts extends GlobOptionsWithFileTypesUnset
   ? string
   : string | Path
-type Results = Result[]
+export type Results = Result[]
 
 type FileTypes = Opts extends GlobOptionsWithFileTypesTrue
   ? true
@@ -80,7 +88,6 @@ export class Glob {
   globSet: GlobSet
   globParts: GlobParts
   realpath: boolean
-  nonull: boolean
   absolute: boolean
   matchBase: boolean
   windowsPathsNoEscape: boolean
@@ -95,6 +102,8 @@ export class Glob {
   platform: NodeJS.Platform
   patterns: Pattern[]
   signal?: AbortSignal
+  nobrace: boolean
+  noext: boolean
 
   constructor(pattern: string | string[], opts: Opts) {
     this.withFileTypes = !!opts.withFileTypes as FileTypes
@@ -104,24 +113,16 @@ export class Glob {
     this.nodir = !!opts.nodir
     this.mark = !!opts.mark
     this.cwd = opts.cwd || ''
+    this.nobrace = !!opts.nobrace
+    this.noext = !!opts.noext
     this.realpath = !!opts.realpath
-    this.nonull = !!opts.nonull
     this.absolute = !!opts.absolute
 
     this.noglobstar = !!opts.noglobstar
     this.matchBase = !!opts.matchBase
 
-    // if we're returning Path objects, we can't do nonull, because
-    // the pattern is a string, not a Path
-    if (this.withFileTypes) {
-      if (this.nonull) {
-        throw new TypeError(
-          'cannot set nonull:true and withFileTypes:true'
-        )
-      }
-      if (this.absolute) {
-        throw new Error('cannot set absolute:true and withFileTypes:true')
-      }
+    if (this.withFileTypes && this.absolute) {
+      throw new Error('cannot set absolute:true and withFileTypes:true')
     }
 
     if (typeof pattern === 'string') {
@@ -149,6 +150,12 @@ export class Glob {
     this.opts = { ...opts, platform: this.platform }
     if (opts.scurry) {
       this.scurry = opts.scurry
+      if (
+        opts.nocase !== undefined &&
+        opts.nocase !== opts.scurry.nocase
+      ) {
+        throw new Error('nocase option contradicts provided scurry option')
+      }
     } else {
       const Scurry =
         opts.platform === 'win32'
@@ -170,13 +177,18 @@ export class Glob {
 
     const mmo: MinimatchOptions = {
       // default nocase based on platform
-      nocase: this.nocase,
       ...opts,
-      nonegate: true,
-      nocomment: true,
+      dot: this.dot,
+      matchBase: this.matchBase,
+      nobrace: this.nobrace,
+      nocase: this.nocase,
       nocaseMagicOnly: true,
+      nocomment: true,
+      noext: this.noext,
+      nonegate: true,
       optimizationLevel: 2,
       platform: this.platform,
+      windowsPathsNoEscape: this.windowsPathsNoEscape,
     }
 
     const mms = this.pattern.map(p => new Minimatch(p, mmo))
@@ -224,8 +236,8 @@ export class Glob {
     return [...matches]
   }
 
-  stream(): Minipass>
-  stream(): Minipass {
+  stream(): Minipass, Result>
+  stream(): Minipass {
     return new GlobStream(this.patterns, this.scurry.cwd, {
       ...this.opts,
       platform: this.platform,
@@ -233,8 +245,8 @@ export class Glob {
     }).stream()
   }
 
-  streamSync(): Minipass>
-  streamSync(): Minipass {
+  streamSync(): Minipass, Result>
+  streamSync(): Minipass {
     return new GlobStream(this.patterns, this.scurry.cwd, {
       ...this.opts,
       platform: this.platform,
@@ -242,17 +254,17 @@ export class Glob {
     }).streamSync()
   }
 
-  iteratorSync(): Generator, void, void> {
+  iterateSync(): Generator, void, void> {
     return this.streamSync()[Symbol.iterator]()
   }
   [Symbol.iterator]() {
-    return this.iteratorSync()
+    return this.iterateSync()
   }
 
-  iterator(): AsyncGenerator, void, void> {
+  iterate(): AsyncGenerator, void, void> {
     return this.stream()[Symbol.asyncIterator]()
   }
   [Symbol.asyncIterator]() {
-    return this.iterator()
+    return this.iterate()
   }
 }
diff --git a/src/ignore.ts b/src/ignore.ts
index e9433d44..d2fbb0d8 100644
--- a/src/ignore.ts
+++ b/src/ignore.ts
@@ -16,8 +16,6 @@ const defaultPlatform: NodeJS.Platform =
     : 'linux'
 
 export class Ignore {
-  platform: NodeJS.Platform
-  nocase: boolean
   relative: Minimatch[]
   relativeChildren: Minimatch[]
   absolute: Minimatch[]
@@ -25,19 +23,26 @@ export class Ignore {
 
   constructor(
     ignored: string[],
-    { platform = defaultPlatform, nocase }: GlobWalkerOpts
+    {
+      nobrace,
+      nocase,
+      noext,
+      noglobstar,
+      platform = defaultPlatform,
+    }: GlobWalkerOpts
   ) {
-    this.platform = platform
-    this.nocase = !!nocase
     this.relative = []
     this.absolute = []
     this.relativeChildren = []
     this.absoluteChildren = []
     const mmopts = {
-      platform: this.platform,
-      optimizationLevel: 2,
       dot: true,
+      nobrace,
       nocase,
+      noext,
+      noglobstar,
+      optimizationLevel: 2,
+      platform,
     }
 
     // this is a little weird, but it gives us a clean set of optimized
@@ -57,7 +62,7 @@ export class Ignore {
       for (let i = 0; i < mm.set.length; i++) {
         const parsed = mm.set[i]
         const globParts = mm.globParts[i]
-        const p = new Pattern(parsed, globParts, 0, this.platform)
+        const p = new Pattern(parsed, globParts, 0, platform)
         const m = new Minimatch(p.globString(), mmopts)
         const children = globParts[globParts.length - 1] === '**'
         const absolute = p.isAbsolute()
diff --git a/src/index.ts b/src/index.ts
index a64972de..ed539dc7 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,49 +1,124 @@
-import Minipass from 'minipass'
-import { Glob, GlobOptions } from './glob.js'
+import {
+  Glob,
+  GlobOptions,
+  GlobOptionsWithFileTypesFalse,
+  GlobOptionsWithFileTypesTrue,
+  GlobOptionsWithFileTypesUnset,
+  Results,
+} from './glob.js'
 import { hasMagic } from './has-magic.js'
+import {
+  GWOFileTypesFalse,
+  GWOFileTypesTrue,
+  GWOFileTypesUnset,
+  MatchStream,
+} from './walker.js'
 
-export const globStreamSync = (
+export function globStreamSync(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesTrue
+): MatchStream
+export function globStreamSync(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesFalse
+): MatchStream
+export function globStreamSync(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesUnset
+): MatchStream
+export function globStreamSync(
+  pattern: string | string[],
+  options: GlobOptions
+): MatchStream
+export function globStreamSync(
   pattern: string | string[],
   options: GlobOptions = {}
-): Minipass =>
-  new Glob(pattern, { ...options, withFileTypes: false }).streamSync()
+) {
+  return new Glob(pattern, options).streamSync()
+}
 
-export const globStream = Object.assign(
-  (
-    pattern: string | string[],
-    options: GlobOptions = {}
-  ): Minipass =>
-    new Glob(pattern, { ...options, withFileTypes: false }).stream(),
-  { sync: globStreamSync }
-)
+export function globStream(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesFalse
+): MatchStream
+export function globStream(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesTrue
+): MatchStream
+export function globStream(
+  pattern: string | string[],
+  options?: GlobOptionsWithFileTypesUnset | undefined
+): MatchStream
+export function globStream(
+  pattern: string | string[],
+  options: GlobOptions
+): MatchStream
+export function globStream(
+  pattern: string | string[],
+  options: GlobOptions = {}
+) {
+  return new Glob(pattern, options).stream()
+}
 
-export const globSync = Object.assign(
-  (pattern: string | string[], options: GlobOptions = {}): string[] =>
-    new Glob(pattern, { ...options, withFileTypes: false }).walkSync(),
-  { stream: globStreamSync }
-)
+export function globSync(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesFalse
+): Results
+export function globSync(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesTrue
+): Results
+export function globSync(
+  pattern: string | string[],
+  options?: GlobOptionsWithFileTypesUnset | undefined
+): Results
+export function globSync(
+  pattern: string | string[],
+  options: GlobOptions
+): Results
+export function globSync(
+  pattern: string | string[],
+  options: GlobOptions = {}
+) {
+  return new Glob(pattern, options).walkSync()
+}
 
-export const glob = Object.assign(
-  async (
-    pattern: string | string[],
-    options: GlobOptions = {}
-  ): Promise =>
-    new Glob(pattern, { ...options, withFileTypes: false }).walk(),
-  {
-    sync: globSync,
-    globSync,
-    stream: globStream,
-    streamSync: globStreamSync,
-    globStream,
-    globStreamSync,
-    Glob,
-    hasMagic,
-  }
-)
+export async function glob(
+  pattern: string | string[],
+  options?: GlobOptionsWithFileTypesUnset | undefined
+): Promise>
+export async function glob(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesTrue
+): Promise>
+export async function glob(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesFalse
+): Promise>
+export async function glob(
+  pattern: string | string[],
+  options: GlobOptions
+): Promise>
+export async function glob(
+  pattern: string | string[],
+  options: GlobOptions = {}
+) {
+  return new Glob(pattern, options).walk()
+}
 
 /* c8 ignore start */
 export { Glob } from './glob.js'
 export type { GlobOptions } from './glob.js'
 export { hasMagic } from './has-magic.js'
-export default glob
 /* c8 ignore stop */
+export default Object.assign(glob, {
+  glob: glob,
+  sync: globSync,
+  globSync,
+  stream: globStream,
+  streamSync: globStreamSync,
+  globStream,
+  globStreamSync,
+  Glob,
+  hasMagic,
+})
diff --git a/src/pattern.ts b/src/pattern.ts
index cec75e99..676d61c3 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -53,7 +53,7 @@ export class Pattern {
       throw new TypeError('mismatched pattern list and glob list lengths')
     }
     this.length = patternList.length
-    if (index >= this.length) {
+    if (index < 0 || index >= this.length) {
       throw new TypeError('index out of range')
     }
     this.#patternList = patternList
@@ -61,18 +61,6 @@ export class Pattern {
     this.#index = index
     this.#platform = platform
 
-    // if the current item is not globstar, and the next item is .., skip ahead
-    if (
-      this.#patternList[this.#index] !== GLOBSTAR &&
-      this.#patternList[this.#index] !== '..' &&
-      this.#patternList[this.#index] !== '.' &&
-      this.#patternList[this.#index] !== '' &&
-      this.#patternList[this.#index + 1] === '..' &&
-      this.length > this.#index + 2
-    ) {
-      this.#index += 2
-    }
-
     // normalize root entries of absolute patterns on initial creation.
     if (this.#index === 0) {
       // c: => ['c:/']
@@ -84,15 +72,16 @@ export class Pattern {
       // /etc => ['/', 'etc']
       // / => ['/']
       if (this.isUNC()) {
-        const [p1, p2, p3, ...prest] = this.#patternList
-        const [g1, g2, g3, ...grest] = this.#globList
+        // '' / '' / 'host' / 'share'
+        const [p0, p1, p2, p3, ...prest] = this.#patternList
+        const [g0, g1, g2, g3, ...grest] = this.#globList
         if (prest[0] === '') {
           // ends in /
           prest.shift()
           grest.shift()
         }
-        const p = [p1, p2, p3, ''].join('/')
-        const g = [g1, g2, g3, ''].join('/')
+        const p = [p0, p1, p2, p3, ''].join('/')
+        const g = [g0, g1, g2, g3, ''].join('/')
         this.#patternList = [p, ...prest]
         this.#globList = [g, ...grest]
         this.length = this.#patternList.length
@@ -110,11 +99,6 @@ export class Pattern {
         this.#globList = [g, ...grest]
         this.length = this.#patternList.length
       }
-    } else {
-      // discard any empty path portions, except the last one.
-      while (this.#index < this.length - 1 && this.pattern() === '') {
-        this.#index++
-      }
     }
   }
 
@@ -128,17 +112,10 @@ export class Pattern {
   isGlobstar(): boolean {
     return this.#patternList[this.#index] === GLOBSTAR
   }
-  isGlobstarDotDot(): boolean {
-    return this.isGlobstar() && this.#globList[this.#index + 1] === '..'
-  }
   isRegExp(): boolean {
     return this.#patternList[this.#index] instanceof RegExp
   }
 
-  glob(): string {
-    return this.#globList[this.#index]
-  }
-
   globString(): string {
     return (this.#globString =
       this.#globString ||
diff --git a/src/processor.ts b/src/processor.ts
index 71f2279d..c2e6aab0 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -55,7 +55,13 @@ class SubWalks {
     } else this.store.set(target, [pattern])
   }
   get(target: Path): Pattern[] {
-    return this.store.get(target) || []
+    const subs = this.store.get(target)
+    /* c8 ignore start */
+    if (!subs) {
+      throw new Error('attempting to walk unknown path')
+    }
+    /* c8 ignore stop */
+    return subs
   }
   entries(): [Path, Pattern[]][] {
     return this.keys().map(k => [k, this.store.get(k) as Pattern[]])
@@ -91,9 +97,6 @@ export class Processor {
     // first item in patterns is the filter
 
     for (let [t, pattern] of processingSet) {
-      if (this.hasWalkedCache.hasWalked(t, pattern)) {
-        continue
-      }
       this.hasWalkedCache.storeWalked(t, pattern)
 
       const root = pattern.root()
@@ -165,7 +168,11 @@ export class Processor {
           this.matches.add(t, absolute, rp === '' || rp === '.')
         } else {
           if (rp === '..') {
+            // this would mean you're matching **/.. at the fs root,
+            // and no thanks, I'm not gonna test that specific case.
+            /* c8 ignore start */
             const tp = t.parent || t
+            /* c8 ignore stop */
             if (!rrest) this.matches.add(tp, absolute, true)
             else if (!this.hasWalkedCache.hasWalked(tp, rrest)) {
               this.subwalks.add(tp, rrest)
@@ -252,6 +259,11 @@ export class Processor {
         rp !== '.'
       ) {
         this.testString(e, rp, rest.rest(), absolute)
+      } else if (rp === '..') {
+        /* c8 ignore start */
+        const ep = e.parent || e
+        /* c8 ignore stop */
+        this.subwalks.add(ep, rest)
       } else if (rp instanceof RegExp) {
         this.testRegExp(e, rp, rest.rest(), absolute)
       }
diff --git a/src/walker.ts b/src/walker.ts
index 0db3d68f..382746c7 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -12,16 +12,23 @@ import { Processor } from './processor.js'
 
 export interface GlobWalkerOpts {
   absolute?: boolean
-  realpath?: boolean
-  nodir?: boolean
-  mark?: boolean
-  withFileTypes?: boolean
-  signal?: AbortSignal
+  allowWindowsEscape?: boolean
+  cwd?: string
+  dot?: boolean
+  follow?: boolean
   ignore?: string | string[] | Ignore
-  platform?: NodeJS.Platform
+  mark?: boolean
+  matchBase?: boolean
+  nobrace?: boolean
   nocase?: boolean
-  follow?: boolean
-  dot?: boolean
+  nodir?: boolean
+  noext?: boolean
+  noglobstar?: boolean
+  platform?: NodeJS.Platform
+  realpath?: boolean
+  signal?: AbortSignal
+  windowsPathsNoEscape?: boolean
+  withFileTypes?: boolean
 }
 
 export type GWOFileTypesTrue = GlobWalkerOpts & {
@@ -52,12 +59,12 @@ export type Matches = O extends GWOFileTypesTrue
 
 export type MatchStream =
   O extends GWOFileTypesTrue
-    ? Minipass
+    ? Minipass
     : O extends GWOFileTypesFalse
-    ? Minipass
+    ? Minipass
     : O extends GWOFileTypesUnset
-    ? Minipass
-    : Minipass
+    ? Minipass
+    : Minipass
 
 const makeIgnore = (
   ignore: string | string[] | Ignore,
@@ -516,6 +523,8 @@ export class GlobStream<
       : this.path
     if (target) {
       this.walkCBSync(target, this.patterns, () => this.results.end())
+    } else {
+      this.results.end()
     }
     return this.results
   }
diff --git a/test/00-setup.ts b/test/00-setup.ts
index 76fc3de2..e8e91947 100644
--- a/test/00-setup.ts
+++ b/test/00-setup.ts
@@ -93,6 +93,16 @@ if (process.platform === 'win32' || !process.env.TEST_REGEN) {
       '{/tmp/glob-test/*,*}', // evil owl face!  how you taunt me!
       'a/!(symlink)/**',
       'a/symlink/a/**/*',
+      // this one we don't quite match bash, because when bash
+      // applies the .. to the symlink walked by **, it effectively
+      // resets the symlink walk limit, and that is just a step too
+      // far for an edge case no one knows or cares about, even for
+      // an obsessive perfectionist like me.
+      // './a/**/../*/**',
+      'a/!(symlink)/**/..',
+      'a/!(symlink)/**/../',
+      'a/!(symlink)/**/../*',
+      'a/!(symlink)/**/../*/*',
     ]
 
   const bashOutput: { [k: string]: string[] } = {}
diff --git a/test/absolute-must-be-strings.ts b/test/absolute-must-be-strings.ts
new file mode 100644
index 00000000..cc18e034
--- /dev/null
+++ b/test/absolute-must-be-strings.ts
@@ -0,0 +1,8 @@
+import { Glob } from '../'
+import t from 'tap'
+t.throws(() => {
+  new Glob('.', {
+    withFileTypes: true,
+    absolute: true,
+  })
+})
diff --git a/test/bash-results.ts b/test/bash-results.ts
index 14a1650f..76d5641e 100644
--- a/test/bash-results.ts
+++ b/test/bash-results.ts
@@ -190,4 +190,58 @@ export const bashResults: { [path: string]: string[] } = {
     'a/symlink/a/b/c',
     'a/symlink/a/b/c/a',
   ],
+  'a/!(symlink)/**/..': [
+    'a',
+    'a/abcdef',
+    'a/abcfed',
+    'a/b',
+    'a/bc',
+    'a/c',
+    'a/c/d',
+    'a/cb',
+  ],
+  'a/!(symlink)/**/../': [
+    'a',
+    'a/abcdef',
+    'a/abcfed',
+    'a/b',
+    'a/bc',
+    'a/c',
+    'a/c/d',
+    'a/cb',
+  ],
+  'a/!(symlink)/**/../*': [
+    'a/abcdef',
+    'a/abcdef/g',
+    'a/abcfed',
+    'a/abcfed/g',
+    'a/b',
+    'a/b/c',
+    'a/bc',
+    'a/bc/e',
+    'a/c',
+    'a/c/d',
+    'a/c/d/c',
+    'a/cb',
+    'a/cb/e',
+    'a/symlink',
+    'a/x',
+    'a/z',
+  ],
+  'a/!(symlink)/**/../*/*': [
+    'a/abcdef/g',
+    'a/abcdef/g/h',
+    'a/abcfed/g',
+    'a/abcfed/g/h',
+    'a/b/c',
+    'a/b/c/d',
+    'a/bc/e',
+    'a/bc/e/f',
+    'a/c/d',
+    'a/c/d/c',
+    'a/c/d/c/b',
+    'a/cb/e',
+    'a/cb/e/f',
+    'a/symlink/a',
+  ],
 }
diff --git a/test/broken-symlink.ts b/test/broken-symlink.ts
index ca1ca89e..044834ff 100644
--- a/test/broken-symlink.ts
+++ b/test/broken-symlink.ts
@@ -1,7 +1,7 @@
 import { relative } from 'path'
 import t from 'tap'
 import { glob } from '../'
-import type { GlobOptions } from '../src/index.js'
+import { GlobOptionsWithFileTypesUnset } from '../src/glob.js'
 
 if (process.platform === 'win32') {
   t.plan(0, 'skip on windows')
@@ -32,9 +32,8 @@ const patterns = [
   `${dir}/a/broken-link/!(asdf)`,
 ]
 
-const opts: (GlobOptions | undefined)[] = [
+const opts: (GlobOptionsWithFileTypesUnset | undefined)[] = [
   undefined,
-  { nonull: true },
   { mark: true },
   { follow: true },
 ]
diff --git a/test/cwd-noent.ts b/test/cwd-noent.ts
new file mode 100644
index 00000000..7438b117
--- /dev/null
+++ b/test/cwd-noent.ts
@@ -0,0 +1,80 @@
+import { resolve } from 'path'
+import t from 'tap'
+import { Glob } from '../'
+const cwd = resolve(__dirname, 'fixtures/does-not-exist')
+
+t.test('walk', async t => {
+  const g = new Glob('**', { cwd })
+  t.same(await g.walk(), [])
+})
+
+t.test('walkSync', t => {
+  const g = new Glob('**', { cwd })
+  t.same(g.walkSync(), [])
+  t.end()
+})
+
+t.test('stream', async t => {
+  const g = new Glob('**', { cwd })
+  const s = g.stream()
+  s.on('data', () => t.fail('should not get entries'))
+  t.same(await s.collect(), [])
+})
+
+t.test('streamSync', t => {
+  const g = new Glob('**', { cwd })
+  const s = g.streamSync()
+  const c: string[] = []
+  s.on('data', p => {
+    t.fail('should not get entries')
+    c.push(p)
+  })
+  s.on('end', () => {
+    t.same(c, [])
+    t.end()
+  })
+})
+
+t.test('iterate', async t => {
+  const g = new Glob('**', { cwd })
+  const s = g.iterate()
+  const c: string[] = []
+  for await (const p of s) {
+    c.push(p)
+    t.fail('should not get entries')
+  }
+  t.same(c, [])
+})
+
+t.test('iterateSync', async t => {
+  const g = new Glob('**', { cwd })
+  const s = g.iterateSync()
+  const c: string[] = []
+  for (const p of s) {
+    c.push(p)
+    t.fail('should not get entries')
+  }
+  t.same(c, [])
+  t.end()
+})
+
+t.test('for await', async t => {
+  const g = new Glob('**', { cwd })
+  const c: string[] = []
+  for await (const p of g) {
+    c.push(p)
+    t.fail('should not get entries')
+  }
+  t.same(c, [])
+})
+
+t.test('iterateSync', async t => {
+  const g = new Glob('**', { cwd })
+  const c: string[] = []
+  for (const p of g) {
+    c.push(p)
+    t.fail('should not get entries')
+  }
+  t.same(c, [])
+  t.end()
+})
diff --git a/test/ignore.ts b/test/ignore.ts
index 4f8a9b31..c6163c9d 100644
--- a/test/ignore.ts
+++ b/test/ignore.ts
@@ -6,8 +6,11 @@ import glob from '../'
 import type { GlobOptions } from '../src/index.js'
 
 import { sep } from 'path'
-const alphasort = (a:string, b:string) => a.localeCompare(b, 'en')
-const j = (a: string[]) => a.map(s => s.split('/').join(sep)).sort(alphasort)
+const alphasort = (a: string, b: string) => a.localeCompare(b, 'en')
+const j = (a: string[]) =>
+  a.map(s => s.split('/').join(sep)).sort(alphasort)
+
+process.chdir(__dirname + '/fixtures')
 
 // [pattern, ignore, expect, opt (object) or cwd (string)]
 type Case = [
@@ -29,10 +32,16 @@ const cases: Case[] = [
     j(['abcdef', 'abcfed', 'bc', 'c', 'cb', 'symlink', 'x', 'z']),
     'a',
   ],
-  ['*', 'b*', j(['abcdef', 'abcfed', 'c', 'cb', 'symlink', 'x', 'z']), 'a'],
+  [
+    '*',
+    'b*',
+    j(['abcdef', 'abcfed', 'c', 'cb', 'symlink', 'x', 'z']),
+    'a',
+  ],
   ['b/**', 'b/c/d', j(['b', 'b/c']), 'a'],
   ['b/**', 'd', j(['b', 'b/c', 'b/c/d']), 'a'],
   ['b/**', 'b/c/**', ['b'], 'a'],
+  ['b/**', (process.cwd() + '/a/b/c/**').split(sep).join('/'), ['b'], 'a'],
   ['**/d', 'b/c/d', j(['c/d']), 'a'],
   [
     'a/**/[gh]',
@@ -320,10 +329,13 @@ const cases: Case[] = [
   ],
   ['*/.abcdef', 'a/**', []],
   ['a/*/.y/b', 'a/x/**', j(['a/z/.y/b'])],
+  [
+    'a/*/.y/b',
+    (process.cwd() + '/a/x/**').split(sep).join('/'),
+    j(['a/z/.y/b']),
+  ],
 ]
 
-process.chdir(__dirname + '/fixtures')
-
 for (const c of cases) {
   const [pattern, ignore, ex, optCwd] = c
   const expect = (
diff --git a/test/mark.ts b/test/mark.ts
index d1e3a151..298bd924 100644
--- a/test/mark.ts
+++ b/test/mark.ts
@@ -2,9 +2,10 @@ import t from 'tap'
 import glob from '../'
 process.chdir(__dirname + '/fixtures')
 
-const alphasort = (a:string, b:string) => a.localeCompare(b, 'en')
+const alphasort = (a: string, b: string) => a.localeCompare(b, 'en')
 import { sep } from 'path'
-const j = (a: string[]) => a.map(s=>s.split('/').join(sep)).sort(alphasort)
+const j = (a: string[]) =>
+  a.map(s => s.split('/').join(sep)).sort(alphasort)
 
 t.test('mark with cwd', async t => {
   const pattern = '*/*'
diff --git a/test/match-base.ts b/test/match-base.ts
index 80995d9a..bd53f83f 100644
--- a/test/match-base.ts
+++ b/test/match-base.ts
@@ -3,8 +3,9 @@ import glob from '../'
 
 import { resolve } from 'path'
 import { sep } from 'path'
-const alphasort = (a:string, b:string) => a.localeCompare(b, 'en')
-const j = (a: string[]) => a.map(s => s.split('/').join(sep)).sort(alphasort)
+const alphasort = (a: string, b: string) => a.localeCompare(b, 'en')
+const j = (a: string[]) =>
+  a.map(s => s.split('/').join(sep)).sort(alphasort)
 
 const fixtureDir = resolve(__dirname, 'fixtures')
 
@@ -19,7 +20,10 @@ t.test('chdir', async t => {
   const origCwd = process.cwd()
   process.chdir(fixtureDir)
   t.teardown(() => process.chdir(origCwd))
-  t.same(glob.sync(pattern, { matchBase: true }).sort(alphasort), j(expect))
+  t.same(
+    glob.sync(pattern, { matchBase: true }).sort(alphasort),
+    j(expect)
+  )
   t.same(
     (await glob(pattern, { matchBase: true })).sort(alphasort),
     j(expect)
diff --git a/test/match-parent.ts b/test/match-parent.ts
new file mode 100644
index 00000000..f49db67b
--- /dev/null
+++ b/test/match-parent.ts
@@ -0,0 +1,25 @@
+import t from 'tap'
+import { PathScurry } from 'path-scurry'
+import { Glob } from '../'
+const scurry = new PathScurry()
+t.test('/', t => {
+  const g = new Glob('/', { withFileTypes: true, scurry })
+  const m = g.walkSync()
+  t.equal(m.length, 1)
+  t.equal(m[0], scurry.cwd.resolve('/'))
+  t.end()
+})
+t.test('/..', t => {
+  const g = new Glob('/..', { withFileTypes: true, scurry })
+  const m = g.walkSync()
+  t.equal(m.length, 1)
+  t.equal(m[0], scurry.cwd.resolve('/'))
+  t.end()
+})
+t.test('/../../../../../', t => {
+  const g = new Glob('/../../../../../', { withFileTypes: true, scurry })
+  const m = g.walkSync()
+  t.equal(m.length, 1)
+  t.equal(m[0], scurry.cwd.resolve('/'))
+  t.end()
+})
diff --git a/test/match-root.ts b/test/match-root.ts
new file mode 100644
index 00000000..df8a5ef8
--- /dev/null
+++ b/test/match-root.ts
@@ -0,0 +1,8 @@
+import t from 'tap'
+import { PathScurry } from 'path-scurry'
+import { Glob } from '../'
+const scurry = new PathScurry()
+const g = new Glob('/', { withFileTypes: true, scurry })
+const m = g.walkSync()
+t.equal(m.length, 1)
+t.equal(m[0], scurry.cwd.resolve('/'))
diff --git a/test/pattern.ts b/test/pattern.ts
new file mode 100644
index 00000000..6b3cb22d
--- /dev/null
+++ b/test/pattern.ts
@@ -0,0 +1,64 @@
+import { GLOBSTAR } from 'minimatch'
+import t from 'tap'
+import { Glob } from '../'
+import { Pattern } from '../dist/cjs/pattern'
+
+t.same(
+  new Glob(
+    [
+      '//host/share///x/*',
+      '//host/share/',
+      '//host/share',
+      '//?/z:/x/*',
+      '//?/z:/',
+      '//?/z:',
+      'c:/x/*',
+      'c:/',
+    ],
+    { platform: 'win32' }
+  ).patterns.map(p => [p.globString(), p.root()]),
+  [
+    ['//host/share/x/*', '//host/share/'],
+    ['//host/share/', '//host/share/'],
+    ['//host/share/', '//host/share/'],
+    ['//?/z:/x/*', '//?/z:/'],
+    ['//?/z:/', '//?/z:/'],
+    ['//?/z:/', '//?/z:/'],
+    ['c:/x/*', 'c:/'],
+    ['c:/', 'c:/'],
+  ]
+)
+t.throws(() => {
+  new Pattern([], ['x'], 0, process.platform)
+})
+
+t.throws(() => {
+  new Pattern(['x'], [], 0, process.platform)
+})
+
+t.throws(() => {
+  new Pattern(['x'], ['x'], 2, process.platform)
+})
+
+t.throws(() => {
+  new Pattern(['x'], ['x'], -1, process.platform)
+})
+
+t.throws(() => {
+  new Pattern(['x', 'x'], ['x', 'x', 'x'], 0, process.platform)
+})
+
+const s = new Pattern(['x'], ['x'], 0, process.platform)
+const g = new Pattern([GLOBSTAR], ['**'], 0, process.platform)
+const r = new Pattern([/./], ['?'], 0, process.platform)
+t.equal(s.isString(), true)
+t.equal(g.isString(), false)
+t.equal(r.isString(), false)
+
+t.equal(s.isGlobstar(), false)
+t.equal(g.isGlobstar(), true)
+t.equal(r.isGlobstar(), false)
+
+t.equal(s.isRegExp(), false)
+t.equal(g.isRegExp(), false)
+t.equal(r.isRegExp(), true)
diff --git a/test/platform.ts b/test/platform.ts
new file mode 100644
index 00000000..5c087b32
--- /dev/null
+++ b/test/platform.ts
@@ -0,0 +1,57 @@
+import t from 'tap'
+
+import {
+  PathScurry,
+  PathScurryDarwin,
+  PathScurryPosix,
+  PathScurryWin32,
+} from 'path-scurry'
+import { Glob } from '../'
+
+t.test('default platform is process.platform', t => {
+  const g = new Glob('.', {})
+  t.equal(g.platform, process.platform)
+  t.end()
+})
+
+t.test('default linux when not found', async t => {
+  const prop = Object.getOwnPropertyDescriptor(process, 'platform')
+  if (!prop) throw new Error('no platform?')
+  t.teardown(() => {
+    Object.defineProperty(process, 'platform', prop)
+  })
+  Object.defineProperty(process, 'platform', {
+    value: null,
+    configurable: true,
+  })
+  const { Glob } = t.mock('../', {})
+  const g = new Glob('.', {})
+  t.equal(g.platform, 'linux')
+  t.end()
+})
+
+t.test('set platform, get appropriate scurry object', t => {
+  t.equal(
+    new Glob('.', { platform: 'darwin' }).scurry.constructor,
+    PathScurryDarwin
+  )
+  t.equal(
+    new Glob('.', { platform: 'linux' }).scurry.constructor,
+    PathScurryPosix
+  )
+  t.equal(
+    new Glob('.', { platform: 'win32' }).scurry.constructor,
+    PathScurryWin32
+  )
+  t.equal(new Glob('.', {}).scurry.constructor, PathScurry)
+  t.end()
+})
+
+t.test('set scurry, sets nocase and scurry', t => {
+  const scurry = new PathScurryWin32('.')
+  t.throws(() => new Glob('.', { scurry, nocase: false }))
+  const g = new Glob('.', { scurry })
+  t.equal(g.scurry, scurry)
+  t.equal(g.nocase, true)
+  t.end()
+})
diff --git a/test/realpath.ts b/test/realpath.ts
index 9561bdc1..f0e9da2f 100644
--- a/test/realpath.ts
+++ b/test/realpath.ts
@@ -3,7 +3,7 @@ import * as fsp from 'fs/promises'
 import { resolve } from 'path'
 import t from 'tap'
 import glob from '../'
-import type { GlobOptions } from '../src/index.js'
+import { GlobOptionsWithFileTypesUnset } from '../src/glob'
 
 const alphasort = (a: string, b: string) => a.localeCompare(b, 'en')
 
@@ -19,7 +19,11 @@ if (process.platform === 'win32') {
   // options, results
   // realpath:true set on each option
 
-  type Case = [options: GlobOptions, results: string[], pattern?: string]
+  type Case = [
+    options: GlobOptionsWithFileTypesUnset,
+    results: string[],
+    pattern?: string
+  ]
   const cases: Case[] = [
     [{}, ['a/symlink', 'a/symlink/a', 'a/symlink/a/b']],
 
diff --git a/test/stream.ts b/test/stream.ts
new file mode 100644
index 00000000..37ca8072
--- /dev/null
+++ b/test/stream.ts
@@ -0,0 +1,161 @@
+import { resolve, sep } from 'path'
+import t from 'tap'
+import { Glob } from '../'
+const fixture = resolve(__dirname, 'fixtures/a')
+const j = (a: string[]) => a.map(a => a.split('/').join(sep))
+const expect = j([
+  '',
+  'z',
+  'x',
+  'symlink',
+  'cb',
+  'c',
+  'bc',
+  'b',
+  'abcfed',
+  'abcdef',
+  'symlink/a',
+  'symlink/a/b',
+  'symlink/a/b/c',
+  'cb/e',
+  'cb/e/f',
+  'c/d',
+  'c/d/c',
+  'c/d/c/b',
+  'bc/e',
+  'bc/e/f',
+  'b/c',
+  'b/c/d',
+  'abcfed/g',
+  'abcfed/g/h',
+  'abcdef/g',
+  'abcdef/g/h',
+])
+
+t.test('stream', t => {
+  let sync: boolean = true
+  const s = new Glob('./**', { cwd: fixture })
+  const stream = s.stream()
+  const e = new Set(expect)
+  stream.on('data', c => {
+    t.equal(e.has(c), true, JSON.stringify(c))
+    e.delete(c)
+  })
+  stream.on('end', () => {
+    t.equal(e.size, 0, 'saw all entries')
+    t.equal(sync, false, 'did not finish in one tick')
+    const d = new Glob('./**', s)
+    const dream = d.stream()
+    const f = new Set(expect)
+    dream.on('data', c => {
+      t.equal(f.has(c), true, JSON.stringify(c))
+      f.delete(c)
+    })
+    dream.on('end', () => {
+      t.equal(f.size, 0, 'saw all entries')
+      t.end()
+    })
+  })
+  sync = false
+})
+
+t.test('streamSync', t => {
+  let sync: boolean = true
+  const s = new Glob('./**', { cwd: fixture })
+  const stream = s.streamSync()
+  const e = new Set(expect)
+  stream.on('data', c => {
+    t.equal(e.has(c), true, JSON.stringify(c))
+    e.delete(c)
+  })
+  stream.on('end', () => {
+    t.equal(e.size, 0, 'saw all entries')
+    const d = new Glob('./**', s)
+    const dream = d.streamSync()
+    const f = new Set(expect)
+    dream.on('data', c => {
+      t.equal(f.has(c), true, JSON.stringify(c))
+      f.delete(c)
+    })
+    dream.on('end', () => {
+      t.equal(f.size, 0, 'saw all entries')
+      t.equal(sync, true, 'finished synchronously')
+      t.end()
+    })
+  })
+  sync = false
+})
+
+t.test('iterate', async t => {
+  const s = new Glob('./**', { cwd: fixture })
+  const e = new Set(expect)
+  for await (const c of s.iterate()) {
+    t.equal(e.has(c), true, JSON.stringify(c))
+    e.delete(c)
+  }
+  t.equal(e.size, 0, 'saw all entries')
+
+  const f = new Set(expect)
+  const d = new Glob('./**', s)
+  for await (const c of d.iterate()) {
+    t.equal(f.has(c), true, JSON.stringify(c))
+    f.delete(c)
+  }
+  t.equal(f.size, 0, 'saw all entries')
+})
+
+t.test('iterateSync', t => {
+  const s = new Glob('./**', { cwd: fixture })
+  const e = new Set(expect)
+  for (const c of s.iterateSync()) {
+    t.equal(e.has(c), true, JSON.stringify(c))
+    e.delete(c)
+  }
+  t.equal(e.size, 0, 'saw all entries')
+
+  const f = new Set(expect)
+  const d = new Glob('./**', s)
+  for (const c of d.iterateSync()) {
+    t.equal(f.has(c), true, JSON.stringify(c))
+    f.delete(c)
+  }
+  t.equal(f.size, 0, 'saw all entries')
+  t.end()
+})
+
+t.test('for await', async t => {
+  const s = new Glob('./**', { cwd: fixture })
+  const e = new Set(expect)
+  for await (const c of s) {
+    t.equal(e.has(c), true, JSON.stringify(c))
+    e.delete(c)
+  }
+  t.equal(e.size, 0, 'saw all entries')
+
+  const f = new Set(expect)
+  const d = new Glob('./**', s)
+  for await (const c of d) {
+    t.equal(f.has(c), true, JSON.stringify(c))
+    f.delete(c)
+  }
+  t.equal(f.size, 0, 'saw all entries')
+})
+
+t.test('for of', t => {
+  const s = new Glob('./**', { cwd: fixture })
+  const e = new Set(expect)
+  for (const c of s) {
+    t.equal(e.has(c), true, JSON.stringify(c))
+    e.delete(c)
+  }
+  t.equal(e.size, 0, 'saw all entries')
+
+  const f = new Set(expect)
+  const d = new Glob('./**', s)
+  for (const c of d) {
+    t.equal(f.has(c), true, JSON.stringify(c))
+    f.delete(c)
+  }
+  t.equal(f.size, 0, 'saw all entries')
+  t.end()
+})

From d34c8d519a65242914d8348303dfc482c3ea3c28 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sun, 26 Feb 2023 00:27:07 -0800
Subject: [PATCH 105/163] full test coverage, clean up signals and remove
 extranous code

---
 package-lock.json        |  14 +--
 package.json             |   2 +-
 src/index.ts             |  54 ++++++++++-
 src/walker.ts            | 191 ++++++++++++---------------------------
 test/bash-comparison.ts  |   2 +-
 test/broken-symlink.ts   |   2 +-
 test/follow.ts           |   4 +-
 test/ignore.ts           |   4 +-
 test/mark.ts             |  33 +++++--
 test/match-base.ts       |  12 +--
 test/nodir.ts            |   2 +-
 test/platform.ts         |  16 ++++
 test/realpath.ts         |   6 +-
 test/signal.ts           |  89 ++++++++++++++++++
 test/slash-cwd.ts        |   2 +-
 test/stream.ts           | 112 +++++++++++++++++++++--
 test/windows-paths-fs.ts |   4 +-
 17 files changed, 371 insertions(+), 178 deletions(-)
 create mode 100644 test/signal.ts

diff --git a/package-lock.json b/package-lock.json
index c483f109..d4232beb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,7 @@
       "dependencies": {
         "fs.realpath": "^1.0.0",
         "minimatch": "^7.1.4",
-        "minipass": "^4.2.1",
+        "minipass": "^4.2.4",
         "path-scurry": "^1.4.0"
       },
       "devDependencies": {
@@ -2942,9 +2942,9 @@
       "peer": true
     },
     "node_modules/minipass": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.1.tgz",
-      "integrity": "sha512-KS4CHIsDfOZetnT+u6fwxyFADXLamtkPxkGScmmtTW//MlRrImV+LtbmbJpLQ86Hw7km/utbfEfndhGBrfwvlA==",
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.4.tgz",
+      "integrity": "sha512-lwycX3cBMTvcejsHITUgYj6Gy6A7Nh4Q6h9NP4sTHY1ccJlC7yKzDmiShEHsJ16Jf1nKGDEaiHxiltsJEvk0nQ==",
       "engines": {
         "node": ">=8"
       }
@@ -8584,9 +8584,9 @@
       "peer": true
     },
     "minipass": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.1.tgz",
-      "integrity": "sha512-KS4CHIsDfOZetnT+u6fwxyFADXLamtkPxkGScmmtTW//MlRrImV+LtbmbJpLQ86Hw7km/utbfEfndhGBrfwvlA=="
+      "version": "4.2.4",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.4.tgz",
+      "integrity": "sha512-lwycX3cBMTvcejsHITUgYj6Gy6A7Nh4Q6h9NP4sTHY1ccJlC7yKzDmiShEHsJ16Jf1nKGDEaiHxiltsJEvk0nQ=="
     },
     "mkdirp": {
       "version": "2.0.0",
diff --git a/package.json b/package.json
index 21ad2b8d..16cd230d 100644
--- a/package.json
+++ b/package.json
@@ -60,7 +60,7 @@
   "dependencies": {
     "fs.realpath": "^1.0.0",
     "minimatch": "^7.1.4",
-    "minipass": "^4.2.1",
+    "minipass": "^4.2.4",
     "path-scurry": "^1.4.0"
   },
   "devDependencies": {
diff --git a/src/index.ts b/src/index.ts
index ed539dc7..670087ed 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -12,6 +12,7 @@ import {
   GWOFileTypesTrue,
   GWOFileTypesUnset,
   MatchStream,
+  Result,
 } from './walker.js'
 
 export function globStreamSync(
@@ -106,19 +107,64 @@ export async function glob(
   return new Glob(pattern, options).walk()
 }
 
+export function globIterate(
+  pattern: string | string[],
+  options?: GlobOptionsWithFileTypesUnset | undefined
+): AsyncGenerator, void, void>
+export function globIterate(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesTrue
+): AsyncGenerator, void, void>
+export function globIterate(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesFalse
+): AsyncGenerator, void, void>
+export function globIterate(
+  pattern: string | string[],
+  options: GlobOptions
+): AsyncGenerator, void, void>
+export function globIterate(
+  pattern: string | string[],
+  options: GlobOptions = {}
+) {
+  return new Glob(pattern, options).iterate()
+}
+
+export function globIterateSync(
+  pattern: string | string[],
+  options?: GlobOptionsWithFileTypesUnset | undefined
+): Generator, void, void>
+export function globIterateSync(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesTrue
+): Generator, void, void>
+export function globIterateSync(
+  pattern: string | string[],
+  options: GlobOptionsWithFileTypesFalse
+): Generator, void, void>
+export function globIterateSync(
+  pattern: string | string[],
+  options: GlobOptions
+): Generator, void, void>
+export function globIterateSync(
+  pattern: string | string[],
+  options: GlobOptions = {}
+) {
+  return new Glob(pattern, options).iterateSync()
+}
+
 /* c8 ignore start */
 export { Glob } from './glob.js'
 export type { GlobOptions } from './glob.js'
 export { hasMagic } from './has-magic.js'
 /* c8 ignore stop */
 export default Object.assign(glob, {
-  glob: glob,
-  sync: globSync,
+  glob,
   globSync,
-  stream: globStream,
-  streamSync: globStreamSync,
   globStream,
   globStreamSync,
+  globIterate,
+  globIterateSync,
   Glob,
   hasMagic,
 })
diff --git a/src/walker.ts b/src/walker.ts
index 382746c7..16f1749a 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -74,7 +74,9 @@ const makeIgnore = (
     ? new Ignore([ignore], opts)
     : Array.isArray(ignore)
     ? new Ignore(ignore, opts)
-    : ignore
+    : /* c8 ignore start */
+      ignore
+/* c8 ignore stop */
 
 /**
  * basic walking utilities that all the glob walker types use
@@ -89,6 +91,7 @@ export abstract class GlobUtil {
   #onResume: (() => any)[] = []
   #ignore?: Ignore
   #sep: '\\' | '/'
+  signal?: AbortSignal
 
   constructor(patterns: Pattern[], path: Path, opts: O)
   constructor(patterns: Pattern[], path: Path, opts: O) {
@@ -100,7 +103,10 @@ export abstract class GlobUtil {
       this.#ignore = makeIgnore(opts.ignore, opts)
     }
     if (opts.signal) {
-      opts.signal.addEventListener('abort', () => this.abort())
+      this.signal = opts.signal
+      this.signal.addEventListener('abort', () => {
+        this.#onResume.length = 0
+      })
     }
   }
 
@@ -116,7 +122,9 @@ export abstract class GlobUtil {
     this.paused = true
   }
   resume() {
-    if (this.aborted) return
+    /* c8 ignore start */
+    if (this.signal?.aborted) return
+    /* c8 ignore stop */
     this.paused = false
     let fn: (() => any) | undefined = undefined
     while (!this.paused && (fn = this.#onResume.shift())) {
@@ -124,135 +132,46 @@ export abstract class GlobUtil {
     }
   }
   onResume(fn: () => any) {
-    if (this.aborted) return
+    if (this.signal?.aborted) return
+    /* c8 ignore start */
     if (!this.paused) fn()
+    /* c8 ignore stop */
     else this.#onResume.push(fn)
   }
-  abort() {
-    this.paused = true
-    this.aborted = true
-  }
 
-  // do the requisite realpath/stat checking, and return true/false
-  // to say whether to include the match or filter it out.
+  // do the requisite realpath/stat checking, and return the path
+  // to add or undefined to filter it out.
   async matchCheck(e: Path, ifDir: boolean): Promise {
+    if (ifDir && this.opts.nodir) return undefined
     let rpc: Path | undefined
     if (this.opts.realpath) {
-      rpc = e.realpathCached()
-      if (rpc) {
-        if (this.#ignored(rpc) || (e.isDirectory() && this.opts.nodir)) {
-          return undefined
-        }
-        e = rpc
-      }
-    }
-    if (e.isDirectory() && this.opts.nodir) {
-      return undefined
+      rpc = e.realpathCached() || (await e.realpath())
+      if (!rpc) return undefined
+      e = rpc
     }
-    const needRealPath = !rpc && this.opts.realpath
     const needStat = e.isUnknown()
-    if (needRealPath && needStat) {
-      const r = await e.realpath().then(e => e?.lstat())
-      if (
-        !r ||
-        this.#ignored(r) ||
-        (!e.canReaddir() && ifDir) ||
-        (e.isDirectory() && this.opts.nodir)
-      ) {
-        return undefined
-      }
-      return r
-    } else if (needRealPath) {
-      const r = await e.realpath()
-      if (
-        !r ||
-        this.#ignored(r) ||
-        (!e.canReaddir() && ifDir) ||
-        (e.isDirectory() && this.opts.nodir)
-      ) {
-        return undefined
-      }
-      return r
-    } else if (needStat) {
-      const r = await e.lstat()
-      if (
-        !r ||
-        this.#ignored(r) ||
-        (!r.canReaddir() && ifDir) ||
-        (r.isDirectory() && this.opts.nodir)
-      ) {
-        return undefined
-      }
-      return r
-    } else if (
-      this.#ignored(e) ||
-      (!e.canReaddir() && ifDir) ||
-      (e.isDirectory() && this.opts.nodir)
-    ) {
-      return undefined
-    } else {
-      return e
-    }
+    return this.matchCheckTest(needStat ? await e.lstat() : e, ifDir)
+  }
+
+  matchCheckTest(e: Path | undefined, ifDir: boolean): Path | undefined {
+    return e &&
+      !this.#ignored(e) &&
+      (!ifDir || e.canReaddir()) &&
+      (!this.opts.nodir || !e.isDirectory())
+      ? e
+      : undefined
   }
 
   matchCheckSync(e: Path, ifDir: boolean): Path | undefined {
+    if (ifDir && this.opts.nodir) return undefined
     let rpc: Path | undefined
     if (this.opts.realpath) {
-      rpc = e.realpathCached()
-      if (rpc) {
-        if (this.#ignored(rpc) || (e.isDirectory() && this.opts.nodir)) {
-          return undefined
-        }
-        e = rpc
-      }
-    }
-    if (e.isDirectory() && this.opts.nodir) {
-      return undefined
+      rpc = e.realpathCached() || e.realpathSync()
+      if (!rpc) return undefined
+      e = rpc
     }
-    const needRealPath = !rpc && this.opts.realpath
     const needStat = e.isUnknown()
-    if (needRealPath && needStat) {
-      const r = e.realpathSync()?.lstatSync()
-      if (
-        !r ||
-        this.#ignored(r) ||
-        (!r.canReaddir() && ifDir) ||
-        (e.isDirectory() && this.opts.nodir)
-      ) {
-        return undefined
-      }
-      return r
-    } else if (needRealPath) {
-      const r = e.realpathSync()
-      if (
-        !r ||
-        this.#ignored(r) ||
-        (!r.canReaddir() && ifDir) ||
-        (e.isDirectory() && this.opts.nodir)
-      ) {
-        return undefined
-      }
-      return r
-    } else if (needStat) {
-      const r = e.lstatSync()
-      if (
-        !r ||
-        this.#ignored(r) ||
-        (!r.canReaddir() && ifDir) ||
-        (r.isDirectory() && this.opts.nodir)
-      ) {
-        return undefined
-      }
-      return r
-    } else if (
-      this.#ignored(e) ||
-      (!e.canReaddir() && ifDir) ||
-      (e.isDirectory() && this.opts.nodir)
-    ) {
-      return undefined
-    } else {
-      return e
-    }
+    return this.matchCheckTest(needStat ? e.lstatSync() : e, ifDir)
   }
 
   abstract matchEmit(p: Result): void
@@ -265,8 +184,6 @@ export abstract class GlobUtil {
     // ok, we have what we need!
     if (this.opts.withFileTypes) {
       this.matchEmit(e)
-    } else if (this.opts.nodir && e.isDirectory()) {
-      return
     } else if (this.opts.absolute || absolute) {
       this.matchEmit(e.fullpath() + mark)
     } else {
@@ -276,22 +193,19 @@ export abstract class GlobUtil {
   }
 
   async match(e: Path, absolute: boolean, ifDir: boolean): Promise {
-    if (this.#ignored(e)) return
     const p = await this.matchCheck(e, ifDir)
     if (p) this.matchFinish(p, absolute)
   }
 
   matchSync(e: Path, absolute: boolean, ifDir: boolean): void {
-    if (this.#ignored(e)) return
     const p = this.matchCheckSync(e, ifDir)
     if (p) this.matchFinish(p, absolute)
   }
 
   walkCB(target: Path, patterns: Pattern[], cb: () => any) {
-    if (this.paused) {
-      this.onResume(() => this.walkCB(target, patterns, cb))
-      return
-    }
+    /* c8 ignore start */
+    if (this.signal?.aborted) cb()
+    /* c8 ignore stop */
     this.walkCB2(target, patterns, new Processor(this.opts), cb)
   }
 
@@ -302,6 +216,7 @@ export abstract class GlobUtil {
     cb: () => any
   ) {
     if (this.#childrenIgnored(target)) return cb()
+    if (this.signal?.aborted) cb()
     if (this.paused) {
       this.onResume(() => this.walkCB2(target, patterns, processor, cb))
       return
@@ -365,10 +280,9 @@ export abstract class GlobUtil {
   }
 
   walkCBSync(target: Path, patterns: Pattern[], cb: () => any) {
-    if (this.paused) {
-      this.onResume(() => this.walkCBSync(target, patterns, cb))
-      return
-    }
+    /* c8 ignore start */
+    if (this.signal?.aborted) cb()
+    /* c8 ignore stop */
     this.walkCB2Sync(target, patterns, new Processor(this.opts), cb)
   }
 
@@ -379,6 +293,7 @@ export abstract class GlobUtil {
     cb: () => any
   ) {
     if (this.#childrenIgnored(target)) return cb()
+    if (this.signal?.aborted) cb()
     if (this.paused) {
       this.onResume(() =>
         this.walkCB2Sync(target, patterns, processor, cb)
@@ -457,19 +372,31 @@ export class GlobWalker<
   }
 
   async walk(): Promise> {
+    if (this.signal?.aborted) throw this.signal.reason
     const t = this.path.isUnknown() ? await this.path.lstat() : this.path
     if (t) {
-      await new Promise(res => {
-        this.walkCB(t, this.patterns, () => res(this.matches))
+      await new Promise((res, rej) => {
+        this.walkCB(t, this.patterns, () => {
+          if (this.signal?.aborted) {
+            rej(this.signal.reason)
+          } else {
+            res(this.matches)
+          }
+        })
       })
     }
     return this.matches
   }
 
   walkSync(): Matches {
+    if (this.signal?.aborted) throw this.signal.reason
     const t = this.path.isUnknown() ? this.path.lstatSync() : this.path
     // nothing for the callback to do, because this never pauses
-    if (t) this.walkCBSync(t, this.patterns, () => {})
+    if (t) {
+      this.walkCBSync(t, this.patterns, () => {
+        if (this.signal?.aborted) throw this.signal.reason
+      })
+    }
     return this.matches
   }
 }
@@ -488,7 +415,7 @@ export class GlobStream<
   constructor(patterns: Pattern[], path: Path, opts: O) {
     super(patterns, path, opts)
     this.results = new Minipass({
-      signal: this.opts.signal,
+      signal: this.signal,
       objectMode: true,
     }) as MatchStream
     this.results.on('drain', () => this.resume())
diff --git a/test/bash-comparison.ts b/test/bash-comparison.ts
index 976e827c..8406dbbc 100644
--- a/test/bash-comparison.ts
+++ b/test/bash-comparison.ts
@@ -50,7 +50,7 @@ globs.forEach(function (pattern) {
   })
 
   t.test(pattern + ' sync', async t => {
-    const matches = cleanResults(glob.sync(pattern))
+    const matches = cleanResults(glob.globSync(pattern))
     t.same(matches, expect, 'should match shell (sync)')
   })
 })
diff --git a/test/broken-symlink.ts b/test/broken-symlink.ts
index 044834ff..b854829a 100644
--- a/test/broken-symlink.ts
+++ b/test/broken-symlink.ts
@@ -58,7 +58,7 @@ t.test('sync test', t => {
     t.test(pattern, t => {
       t.plan(opts.length)
       for (const opt of opts) {
-        const res = glob.sync(pattern, opt)
+        const res = glob.globSync(pattern, opt)
         t.not(res.indexOf(link), -1, 'opt=' + JSON.stringify(opt))
       }
     })
diff --git a/test/follow.ts b/test/follow.ts
index 53d377f6..101b3667 100644
--- a/test/follow.ts
+++ b/test/follow.ts
@@ -10,8 +10,8 @@ process.chdir(__dirname + '/fixtures')
 
 t.test('follow symlinks', async t => {
   const pattern = 'a/symlink/**'
-  const syncNoFollow = glob.sync(pattern)
-  const syncFollow = glob.sync(pattern, { follow: true })
+  const syncNoFollow = glob.globSync(pattern)
+  const syncFollow = glob.globSync(pattern, { follow: true })
   const [noFollow, follow] = await Promise.all([
     glob(pattern),
     glob(pattern, { follow: true }),
diff --git a/test/ignore.ts b/test/ignore.ts
index c6163c9d..86381a0f 100644
--- a/test/ignore.ts
+++ b/test/ignore.ts
@@ -357,7 +357,7 @@ for (const c of cases) {
   t.test(name, async t => {
     const res = await glob(pattern, opt)
     t.same(res.sort(), expect, 'async')
-    const resSync = glob.sync(pattern, opt)
+    const resSync = glob.globSync(pattern, opt)
     t.same(resSync.sort(), expect, 'sync')
   })
 }
@@ -377,7 +377,7 @@ t.test('race condition', async t => {
         const expect = ignore ? [] : j(['fixtures/a'])
         t.test(JSON.stringify(opt), async t => {
           t.plan(2)
-          t.same(glob.sync(pattern, opt).sort(), expect)
+          t.same(glob.globSync(pattern, opt).sort(), expect)
           t.same((await glob(pattern, opt)).sort(), expect)
         })
       }
diff --git a/test/mark.ts b/test/mark.ts
index 298bd924..620aa2f3 100644
--- a/test/mark.ts
+++ b/test/mark.ts
@@ -25,7 +25,7 @@ t.test('mark with cwd', async t => {
   }
 
   t.same(res.sort(alphasort), j(expect))
-  t.same(glob.sync(pattern, opt).sort(alphasort), j(expect))
+  t.same(glob.globSync(pattern, opt).sort(alphasort), j(expect))
 })
 
 t.test('mark, with **', async t => {
@@ -50,7 +50,7 @@ t.test('mark, with **', async t => {
   ].sort(alphasort)
 
   t.same((await glob(pattern, opt)).sort(alphasort), j(expect), 'async')
-  t.same(glob.sync(pattern, opt).sort(alphasort), j(expect), 'sync')
+  t.same(glob.globSync(pattern, opt).sort(alphasort), j(expect), 'sync')
 })
 
 t.test('mark, no / on pattern', async t => {
@@ -71,7 +71,7 @@ t.test('mark, no / on pattern', async t => {
   }
   const results = (await glob(pattern, opt)).sort(alphasort)
   t.same(results, j(expect))
-  t.same(glob.sync(pattern, opt).sort(alphasort), j(expect))
+  t.same(glob.globSync(pattern, opt).sort(alphasort), j(expect))
 })
 
 t.test('mark=false, no / on pattern', async t => {
@@ -92,7 +92,7 @@ t.test('mark=false, no / on pattern', async t => {
   const results = (await glob(pattern)).sort(alphasort)
 
   t.same(results, j(expect))
-  t.same(glob.sync(pattern).sort(alphasort), j(expect))
+  t.same(glob.globSync(pattern).sort(alphasort), j(expect))
 })
 
 t.test('mark=true, / on pattern', async t => {
@@ -114,7 +114,7 @@ t.test('mark=true, / on pattern', async t => {
   }
   const results = (await glob(pattern, opt)).sort(alphasort)
   t.same(results, j(expect))
-  t.same(glob.sync(pattern, opt).sort(alphasort), j(expect))
+  t.same(glob.globSync(pattern, opt).sort(alphasort), j(expect))
 })
 
 t.test('mark=false, / on pattern', async t => {
@@ -135,7 +135,7 @@ t.test('mark=false, / on pattern', async t => {
 
   const results = (await glob(pattern)).sort(alphasort)
   t.same(results, j(expect))
-  t.same(glob.sync(pattern).sort(alphasort), j(expect))
+  t.same(glob.globSync(pattern).sort(alphasort), j(expect))
 })
 
 const cwd = process
@@ -149,7 +149,7 @@ for (const mark of [true, false]) {
       const results = await glob(pattern, { mark })
       t.equal(results.length, 1)
       const res = results[0].replace(/\\/g, '/')
-      const syncResults = glob.sync(pattern, { mark: mark })
+      const syncResults = glob.globSync(pattern, { mark: mark })
       const syncRes = syncResults[0].replace(/\\/g, '/')
       if (mark) {
         t.equal(res, cwd + '/')
@@ -160,3 +160,22 @@ for (const mark of [true, false]) {
     })
   }
 }
+
+for (const mark of [true, false]) {
+  for (const slash of [true, false]) {
+    t.test('. mark:' + mark + ' slash:' + slash, async t => {
+      const pattern = '.' + (slash ? '/' : '')
+      const results = await glob(pattern, { mark })
+      t.equal(results.length, 1)
+      const res = results[0].replace(/\\/g, '/')
+      const syncResults = glob.globSync(pattern, { mark: mark })
+      const syncRes = syncResults[0].replace(/\\/g, '/')
+      if (mark) {
+        t.equal(res, './')
+      } else {
+        t.equal(res, '')
+      }
+      t.equal(syncRes, res, 'sync should match async')
+    })
+  }
+}
diff --git a/test/match-base.ts b/test/match-base.ts
index bd53f83f..1284c762 100644
--- a/test/match-base.ts
+++ b/test/match-base.ts
@@ -21,7 +21,7 @@ t.test('chdir', async t => {
   process.chdir(fixtureDir)
   t.teardown(() => process.chdir(origCwd))
   t.same(
-    glob.sync(pattern, { matchBase: true }).sort(alphasort),
+    glob.globSync(pattern, { matchBase: true }).sort(alphasort),
     j(expect)
   )
   t.same(
@@ -33,7 +33,7 @@ t.test('chdir', async t => {
 t.test('cwd', async t => {
   t.same(
     glob
-      .sync(pattern, { matchBase: true, cwd: fixtureDir })
+      .globSync(pattern, { matchBase: true, cwd: fixtureDir })
       .sort(alphasort),
     j(expect)
   )
@@ -47,7 +47,7 @@ t.test('cwd', async t => {
 
 t.test('noglobstar', async t => {
   t.rejects(glob(pattern, { matchBase: true, noglobstar: true }))
-  t.throws(() => glob.sync(pattern, { matchBase: true, noglobstar: true }))
+  t.throws(() => glob.globSync(pattern, { matchBase: true, noglobstar: true }))
   t.end()
 })
 
@@ -56,7 +56,7 @@ t.test('pattern includes /', async t => {
   const expect = ['a/b', 'a/bc']
   t.same(
     glob
-      .sync(pattern, { matchBase: true, cwd: fixtureDir })
+      .globSync(pattern, { matchBase: true, cwd: fixtureDir })
       .sort(alphasort),
     j(expect)
   )
@@ -73,7 +73,7 @@ t.test('one brace section of pattern includes /', async t => {
   const exp = ['a', 'a/b', 'a/bc']
   t.same(
     glob
-      .sync(pattern, { matchBase: true, cwd: fixtureDir })
+      .globSync(pattern, { matchBase: true, cwd: fixtureDir })
       .sort(alphasort),
     j(exp)
   )
@@ -90,7 +90,7 @@ t.test('one array member of pattern includes /', async t => {
   const exp = expect.concat(['a/b', 'a/bc']).sort()
   t.same(
     glob
-      .sync(pattern, { matchBase: true, cwd: fixtureDir })
+      .globSync(pattern, { matchBase: true, cwd: fixtureDir })
       .sort(alphasort),
     j(exp)
   )
diff --git a/test/nodir.ts b/test/nodir.ts
index cd4dfa9b..a6616e79 100644
--- a/test/nodir.ts
+++ b/test/nodir.ts
@@ -44,7 +44,7 @@ for (const [pattern, options, expectRaw] of cases) {
   if (process.platform !== 'win32') {
   }
   t.test(pattern + ' ' + JSON.stringify(options), async t => {
-    t.same(glob.sync(pattern, options).sort(), expect, 'sync results')
+    t.same(glob.globSync(pattern, options).sort(), expect, 'sync results')
     t.same((await glob(pattern, options)).sort(), expect, 'async results')
   })
 }
diff --git a/test/platform.ts b/test/platform.ts
index 5c087b32..c1a67b77 100644
--- a/test/platform.ts
+++ b/test/platform.ts
@@ -1,3 +1,4 @@
+import { resolve } from 'path'
 import t from 'tap'
 
 import {
@@ -7,6 +8,9 @@ import {
   PathScurryWin32,
 } from 'path-scurry'
 import { Glob } from '../'
+import { glob } from '../dist/cjs'
+import {GlobWalker} from '../dist/cjs/walker'
+import {Pattern} from '../dist/cjs/pattern'
 
 t.test('default platform is process.platform', t => {
   const g = new Glob('.', {})
@@ -55,3 +59,15 @@ t.test('set scurry, sets nocase and scurry', t => {
   t.equal(g.nocase, true)
   t.end()
 })
+
+t.test('instantiate to hit a coverage line', async t => {
+  const s = new PathScurry(resolve(__dirname, 'fixtures/a/b'))
+  const p = new Pattern([/./, /./], ['?', '?'], 0, process.platform)
+  new GlobWalker([p], s.cwd, {
+    platform: 'win32',
+  })
+  new GlobWalker([p], s.cwd, {
+    platform: 'linux',
+  })
+  t.pass('this is fine')
+})
diff --git a/test/realpath.ts b/test/realpath.ts
index f0e9da2f..64a1731d 100644
--- a/test/realpath.ts
+++ b/test/realpath.ts
@@ -55,7 +55,7 @@ if (process.platform === 'win32') {
     expect.sort(alphasort)
     t.test(p + ' ' + JSON.stringify(opt), async t => {
       opt.realpath = true
-      t.same(glob.sync(p, opt).sort(alphasort), expect, 'sync')
+      t.same(glob.globSync(p, opt).sort(alphasort), expect, 'sync')
       const a = await glob(p, opt)
       t.same(a.sort(alphasort), expect, 'async')
     })
@@ -83,13 +83,13 @@ if (process.platform === 'win32') {
     const expect = ['a/symlink', 'a/symlink/a/b'].sort(alphasort)
     t.test('setting cwd explicitly', async t => {
       const opt = { realpath: true, cwd: fixtureDir }
-      t.same(glob.sync(pattern, opt).sort(alphasort), expect)
+      t.same(glob.globSync(pattern, opt).sort(alphasort), expect)
       t.same((await glob(pattern, opt)).sort(alphasort), expect)
     })
     t.test('looking in cwd', async t => {
       process.chdir(fixtureDir)
       const opt = { realpath: true }
-      t.same(glob.sync(pattern, opt).sort(alphasort), expect)
+      t.same(glob.globSync(pattern, opt).sort(alphasort), expect)
       t.same((await glob(pattern, opt)).sort(alphasort), expect)
     })
   })
diff --git a/test/signal.ts b/test/signal.ts
new file mode 100644
index 00000000..717a45c5
--- /dev/null
+++ b/test/signal.ts
@@ -0,0 +1,89 @@
+import * as fs from 'fs'
+import { resolve } from 'path'
+import t from 'tap'
+import { glob, globStream, globStreamSync, globSync } from '../'
+
+const mocks = (ac: AbortController) => {
+  const fsMock = {
+    ...fs,
+    readdirSync: (path: string, options: any) => {
+      ac.abort(yeet)
+      return fs.readdirSync(path, options)
+    },
+  }
+  return {
+    fs: fsMock,
+    'path-scurry': t.mock('path-scurry', { fs: fsMock }),
+  }
+}
+
+const cwd = resolve(__dirname, 'fixtures/a')
+
+const yeet = new Error('yeet')
+
+t.test('pre abort walk', async t => {
+  const ac = new AbortController()
+  ac.abort(yeet)
+  await t.rejects(glob('./**', { cwd, signal: ac.signal }), yeet)
+})
+
+t.test('mid-abort walk', async t => {
+  const ac = new AbortController()
+  const res = glob('./**', { cwd, signal: ac.signal })
+  ac.abort(yeet)
+  await t.rejects(res, yeet)
+})
+
+t.test('pre abort sync walk', t => {
+  const ac = new AbortController()
+  ac.abort(yeet)
+  t.throws(() => globSync('./**', { cwd, signal: ac.signal }))
+  t.end()
+})
+
+t.test('mid-abort sync walk', t => {
+  const ac = new AbortController()
+  const { globSync } = t.mock('../', mocks(ac))
+  t.throws(() => globSync('./**', { cwd, signal: ac.signal }))
+  t.end()
+})
+
+t.test('pre abort stream', t => {
+  const ac = new AbortController()
+  ac.abort(yeet)
+  const s = globStream('./**', { cwd, signal: ac.signal })
+  s.on('error', er => {
+    t.equal(er, yeet)
+    t.end()
+  })
+})
+
+t.test('mid-abort stream', t => {
+  const ac = new AbortController()
+  const s = globStream('./**', { cwd, signal: ac.signal })
+  s.on('error', er => {
+    t.equal(er, yeet)
+    t.end()
+  })
+  s.once('data', () => ac.abort(yeet))
+})
+
+t.test('pre abort sync stream', t => {
+  const ac = new AbortController()
+  ac.abort(yeet)
+  const s = globStreamSync('./**', { cwd, signal: ac.signal })
+  s.on('error', er => {
+    t.equal(er, yeet)
+    t.end()
+  })
+})
+
+t.test('mid-abort sync stream', t => {
+  const ac = new AbortController()
+  const s = globStreamSync('./**', { cwd, signal: ac.signal })
+  s.on('error', er => {
+    t.equal(er, yeet)
+    t.end()
+  })
+  s.on('data', () => ac.abort(yeet))
+})
diff --git a/test/slash-cwd.ts b/test/slash-cwd.ts
index ffb8c82a..dab9e0d2 100644
--- a/test/slash-cwd.ts
+++ b/test/slash-cwd.ts
@@ -11,6 +11,6 @@ const opt: GlobOptions = { cwd }
 process.chdir(__dirname + '/..')
 
 t.test('slashes only match directories', async t => {
-  t.same(glob.sync(pattern, opt), expect, 'sync test')
+  t.same(glob.globSync(pattern, opt), expect, 'sync test')
   t.same(await glob(pattern, opt), expect, 'async test')
 })
diff --git a/test/stream.ts b/test/stream.ts
index 37ca8072..e808314f 100644
--- a/test/stream.ts
+++ b/test/stream.ts
@@ -1,7 +1,14 @@
 import { resolve, sep } from 'path'
 import t from 'tap'
-import { Glob } from '../'
-const fixture = resolve(__dirname, 'fixtures/a')
+import {
+  Glob,
+  globIterate,
+  globIterateSync,
+  globStream,
+  globStreamSync,
+} from '../'
+import {glob, globSync} from '../dist/cjs'
+const cwd = resolve(__dirname, 'fixtures/a')
 const j = (a: string[]) => a.map(a => a.split('/').join(sep))
 const expect = j([
   '',
@@ -34,7 +41,7 @@ const expect = j([
 
 t.test('stream', t => {
   let sync: boolean = true
-  const s = new Glob('./**', { cwd: fixture })
+  const s = new Glob('./**', { cwd })
   const stream = s.stream()
   const e = new Set(expect)
   stream.on('data', c => {
@@ -61,7 +68,7 @@ t.test('stream', t => {
 
 t.test('streamSync', t => {
   let sync: boolean = true
-  const s = new Glob('./**', { cwd: fixture })
+  const s = new Glob('./**', { cwd })
   const stream = s.streamSync()
   const e = new Set(expect)
   stream.on('data', c => {
@@ -87,7 +94,7 @@ t.test('streamSync', t => {
 })
 
 t.test('iterate', async t => {
-  const s = new Glob('./**', { cwd: fixture })
+  const s = new Glob('./**', { cwd })
   const e = new Set(expect)
   for await (const c of s.iterate()) {
     t.equal(e.has(c), true, JSON.stringify(c))
@@ -105,7 +112,7 @@ t.test('iterate', async t => {
 })
 
 t.test('iterateSync', t => {
-  const s = new Glob('./**', { cwd: fixture })
+  const s = new Glob('./**', { cwd })
   const e = new Set(expect)
   for (const c of s.iterateSync()) {
     t.equal(e.has(c), true, JSON.stringify(c))
@@ -123,8 +130,29 @@ t.test('iterateSync', t => {
   t.end()
 })
 
+t.test('walk', async t => {
+  const s = new Glob('./**', { cwd })
+  const e = new Set(expect)
+  const actual = new Set(await s.walk())
+  t.same(actual, e)
+  const d = new Glob('./**', s)
+  const dactual= new Set(await d.walk())
+  t.same(dactual, e)
+})
+
+t.test('walkSync', t => {
+  const s = new Glob('./**', { cwd })
+  const e = new Set(expect)
+  const actual = new Set(s.walkSync())
+  t.same(actual, e)
+  const d = new Glob('./**', s)
+  const dactual= new Set(d.walkSync())
+  t.same(dactual, e)
+  t.end()
+})
+
 t.test('for await', async t => {
-  const s = new Glob('./**', { cwd: fixture })
+  const s = new Glob('./**', { cwd })
   const e = new Set(expect)
   for await (const c of s) {
     t.equal(e.has(c), true, JSON.stringify(c))
@@ -142,7 +170,7 @@ t.test('for await', async t => {
 })
 
 t.test('for of', t => {
-  const s = new Glob('./**', { cwd: fixture })
+  const s = new Glob('./**', { cwd })
   const e = new Set(expect)
   for (const c of s) {
     t.equal(e.has(c), true, JSON.stringify(c))
@@ -159,3 +187,71 @@ t.test('for of', t => {
   t.equal(f.size, 0, 'saw all entries')
   t.end()
 })
+
+t.test('iterate on main', async t => {
+  const s = globIterate('./**', { cwd })
+  const e = new Set(expect)
+  for await (const c of s) {
+    t.equal(e.has(c), true, JSON.stringify(c))
+    e.delete(c)
+  }
+  t.equal(e.size, 0, 'saw all entries')
+})
+
+t.test('iterateSync on main', t => {
+  const s = globIterateSync('./**', { cwd })
+  const e = new Set(expect)
+  for (const c of s) {
+    t.equal(e.has(c), true, JSON.stringify(c))
+    e.delete(c)
+  }
+  t.equal(e.size, 0, 'saw all entries')
+  t.end()
+})
+
+t.test('stream on main', t => {
+  let sync: boolean = true
+  const stream = globStream('./**', { cwd })
+  const e = new Set(expect)
+  stream.on('data', c => {
+    t.equal(e.has(c), true, JSON.stringify(c))
+    e.delete(c)
+  })
+  stream.on('end', () => {
+    t.equal(e.size, 0, 'saw all entries')
+    t.equal(sync, false, 'did not finish in one tick')
+    t.end()
+  })
+  sync = false
+})
+
+t.test('streamSync on main', t => {
+  let sync: boolean = true
+  const stream = globStreamSync('./**', { cwd })
+  const e = new Set(expect)
+  stream.on('data', c => {
+    t.equal(e.has(c), true, JSON.stringify(c))
+    e.delete(c)
+  })
+  stream.on('end', () => {
+    t.equal(e.size, 0, 'saw all entries')
+    t.equal(sync, true, 'finished synchronously')
+    t.end()
+  })
+  sync = false
+})
+
+t.test('walk on main', async t => {
+  const s = glob('./**', { cwd })
+  const e = new Set(expect)
+  const actual = new Set(await s)
+  t.same(actual, e)
+})
+
+t.test('walkSync', t => {
+  const s = globSync('./**', { cwd })
+  const e = new Set(expect)
+  const actual = new Set(s)
+  t.same(actual, e)
+  t.end()
+})
diff --git a/test/windows-paths-fs.ts b/test/windows-paths-fs.ts
index 52b04437..842343eb 100644
--- a/test/windows-paths-fs.ts
+++ b/test/windows-paths-fs.ts
@@ -31,7 +31,7 @@ t.test('treat backslash as escape', t => {
   for (const [pattern, expect] of cases) {
     t.test(pattern, async t => {
       t.strictSame(
-        glob.sync(pattern, { cwd: dir }).map(s => s.replace(/\\/g, '/')),
+        glob.globSync(pattern, { cwd: dir }).map(s => s.replace(/\\/g, '/')),
         expect,
         'sync'
       )
@@ -60,7 +60,7 @@ t.test('treat backslash as separator', t => {
     t.test(pattern, async t => {
       t.strictSame(
         glob
-          .sync(pattern, { cwd: dir, windowsPathsNoEscape: true })
+          .globSync(pattern, { cwd: dir, windowsPathsNoEscape: true })
           .map(s => s.replace(/\\/g, '/')),
         expect,
         'sync'

From 210310b528bf311cb7ab23fe1b448674e4d4f8aa Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sun, 26 Feb 2023 00:32:25 -0800
Subject: [PATCH 106/163] omit symlinks on windows

---
 src/walker.ts            |  9 ++++++---
 test/match-base.ts       |  4 +++-
 test/platform.ts         |  4 ++--
 test/stream.ts           | 13 ++++++-------
 test/windows-paths-fs.ts |  4 +++-
 5 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/src/walker.ts b/src/walker.ts
index 16f1749a..eae56405 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -134,9 +134,12 @@ export abstract class GlobUtil {
   onResume(fn: () => any) {
     if (this.signal?.aborted) return
     /* c8 ignore start */
-    if (!this.paused) fn()
-    /* c8 ignore stop */
-    else this.#onResume.push(fn)
+    if (!this.paused) {
+      fn()
+    } else {
+      /* c8 ignore stop */
+      this.#onResume.push(fn)
+    }
   }
 
   // do the requisite realpath/stat checking, and return the path
diff --git a/test/match-base.ts b/test/match-base.ts
index 1284c762..ccfd5b16 100644
--- a/test/match-base.ts
+++ b/test/match-base.ts
@@ -47,7 +47,9 @@ t.test('cwd', async t => {
 
 t.test('noglobstar', async t => {
   t.rejects(glob(pattern, { matchBase: true, noglobstar: true }))
-  t.throws(() => glob.globSync(pattern, { matchBase: true, noglobstar: true }))
+  t.throws(() =>
+    glob.globSync(pattern, { matchBase: true, noglobstar: true })
+  )
   t.end()
 })
 
diff --git a/test/platform.ts b/test/platform.ts
index c1a67b77..037fc55d 100644
--- a/test/platform.ts
+++ b/test/platform.ts
@@ -9,8 +9,8 @@ import {
 } from 'path-scurry'
 import { Glob } from '../'
 import { glob } from '../dist/cjs'
-import {GlobWalker} from '../dist/cjs/walker'
-import {Pattern} from '../dist/cjs/pattern'
+import { GlobWalker } from '../dist/cjs/walker'
+import { Pattern } from '../dist/cjs/pattern'
 
 t.test('default platform is process.platform', t => {
   const g = new Glob('.', {})
diff --git a/test/stream.ts b/test/stream.ts
index e808314f..d0e7baa3 100644
--- a/test/stream.ts
+++ b/test/stream.ts
@@ -7,23 +7,19 @@ import {
   globStream,
   globStreamSync,
 } from '../'
-import {glob, globSync} from '../dist/cjs'
+import { glob, globSync } from '../dist/cjs'
 const cwd = resolve(__dirname, 'fixtures/a')
 const j = (a: string[]) => a.map(a => a.split('/').join(sep))
 const expect = j([
   '',
   'z',
   'x',
-  'symlink',
   'cb',
   'c',
   'bc',
   'b',
   'abcfed',
   'abcdef',
-  'symlink/a',
-  'symlink/a/b',
-  'symlink/a/b/c',
   'cb/e',
   'cb/e/f',
   'c/d',
@@ -37,6 +33,9 @@ const expect = j([
   'abcfed/g/h',
   'abcdef/g',
   'abcdef/g/h',
+  ...(process.platform !== 'win32'
+    ? ['symlink', 'symlink/a', 'symlink/a/b', 'symlink/a/b/c']
+    : []),
 ])
 
 t.test('stream', t => {
@@ -136,7 +135,7 @@ t.test('walk', async t => {
   const actual = new Set(await s.walk())
   t.same(actual, e)
   const d = new Glob('./**', s)
-  const dactual= new Set(await d.walk())
+  const dactual = new Set(await d.walk())
   t.same(dactual, e)
 })
 
@@ -146,7 +145,7 @@ t.test('walkSync', t => {
   const actual = new Set(s.walkSync())
   t.same(actual, e)
   const d = new Glob('./**', s)
-  const dactual= new Set(d.walkSync())
+  const dactual = new Set(d.walkSync())
   t.same(dactual, e)
   t.end()
 })
diff --git a/test/windows-paths-fs.ts b/test/windows-paths-fs.ts
index 842343eb..45d495db 100644
--- a/test/windows-paths-fs.ts
+++ b/test/windows-paths-fs.ts
@@ -31,7 +31,9 @@ t.test('treat backslash as escape', t => {
   for (const [pattern, expect] of cases) {
     t.test(pattern, async t => {
       t.strictSame(
-        glob.globSync(pattern, { cwd: dir }).map(s => s.replace(/\\/g, '/')),
+        glob
+          .globSync(pattern, { cwd: dir })
+          .map(s => s.replace(/\\/g, '/')),
         expect,
         'sync'
       )

From 5cbacdd6c4ab286cd65decc487a146f5f37b0719 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sun, 26 Feb 2023 01:14:31 -0800
Subject: [PATCH 107/163] minimatch@7.2.0

---
 package-lock.json | 14 +++++++-------
 package.json      |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index d4232beb..d23956d6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "minimatch": "^7.1.4",
+        "minimatch": "^7.2.0",
         "minipass": "^4.2.4",
         "path-scurry": "^1.4.0"
       },
@@ -2920,9 +2920,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "7.1.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.4.tgz",
-      "integrity": "sha512-dZdn8jDUB4Y3eu7hABT6IgLTMQ9cVf+vhhXjLAkuN40wRkweVxEpvnGYLYZUhNB0P+BbTOZDzo+1rCitOQWc3g==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.2.0.tgz",
+      "integrity": "sha512-rMRHmwySzopAQjmWW6TkAKCEDKNaY/HuV/c2YkWWuWnfkTwApt0V4hnYzzPnZ/5Gcd2+8MPncSyuOGPl3xPvcg==",
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
@@ -8568,9 +8568,9 @@
       }
     },
     "minimatch": {
-      "version": "7.1.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.1.4.tgz",
-      "integrity": "sha512-dZdn8jDUB4Y3eu7hABT6IgLTMQ9cVf+vhhXjLAkuN40wRkweVxEpvnGYLYZUhNB0P+BbTOZDzo+1rCitOQWc3g==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.2.0.tgz",
+      "integrity": "sha512-rMRHmwySzopAQjmWW6TkAKCEDKNaY/HuV/c2YkWWuWnfkTwApt0V4hnYzzPnZ/5Gcd2+8MPncSyuOGPl3xPvcg==",
       "requires": {
         "brace-expansion": "^2.0.1"
       }
diff --git a/package.json b/package.json
index 16cd230d..3f22bd89 100644
--- a/package.json
+++ b/package.json
@@ -59,7 +59,7 @@
   },
   "dependencies": {
     "fs.realpath": "^1.0.0",
-    "minimatch": "^7.1.4",
+    "minimatch": "^7.2.0",
     "minipass": "^4.2.4",
     "path-scurry": "^1.4.0"
   },

From 4829c8887af895d5b24f09345f88a8e6ce7f881c Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sun, 26 Feb 2023 01:16:38 -0800
Subject: [PATCH 108/163] upgrade ci actions

---
 .github/workflows/ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cac0372b..c884730f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -25,10 +25,10 @@ jobs:
 
     steps:
       - name: Checkout Repository
-        uses: actions/checkout@v1.1.0
+        uses: actions/checkout@v3
 
       - name: Use Nodejs ${{ matrix.node-version }}
-        uses: actions/setup-node@v1
+        uses: actions/setup-node@v3
         with:
           node-version: ${{ matrix.node-version }}
 

From 20b2f8888c84575a46b8b1434282483cc89c84d4 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sun, 26 Feb 2023 21:25:13 -0800
Subject: [PATCH 109/163] docs, fix benchmark script

---
 README.md        | 483 +++++++++++++++++++++++++++++++++--------------
 benchmark.sh     |  24 +--
 changelog.md     |   2 +
 src/glob.ts      | 102 +++++-----
 src/index.ts     |  16 +-
 src/pattern.ts   |  16 +-
 src/processor.ts |   6 +-
 7 files changed, 422 insertions(+), 227 deletions(-)

diff --git a/README.md b/README.md
index 6b6a4316..44d0d413 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
 
 Match files using the patterns the shell uses.
 
-This is a glob implementation in JavaScript. It uses the
-[`minimatch`](http://npm.im/minimatch) library to do its
-matching.
+The most correct and second fastest glob implementation in
+JavaScript.  (See **Comparison to Other JavaScript Glob
+Implementations** at the bottom of this readme.)
 
 ![a fun cartoon logo made of glob characters](logo/glob.png)
 
@@ -18,160 +18,286 @@ npm i glob
 
 ```js
 // load using import
-import { glob } from 'glob'
-// or using commonjs
-const { glob } = require('glob')
-
-// or default export is fine too
+import { glob, globSync, globStream, globStreamSync, Glob } from 'glob'
+// or using commonjs, that's fine, too
+const {
+  glob,
+  globSync,
+  globStream,
+  globStreamSync,
+  Glob,
+} = require('glob')
+
+// or default export is fine too, just returns the glob function
 import glob from 'glob'
 // or using commonjs
 const glob = require('glob')
 
-// these all return arrays of filenames
+// the main glob() and globSync() resolve/return array of filenames
 
 // all js files, but don't look in node_modules
 const jsfiles = await glob('**/*.js', { ignore: 'node_modules/**' })
 
+// pass in a signal to cancel the glob walk
+const stopAfter100ms = await glob('**/*.css', {
+  signal: AbortSignal.timeout(100),
+})
+
 // multiple patterns supported as well
 const images = await glob(['css/*.{png,jpeg}', 'public/*.{png,jpeg}'])
 
 // but of course you can do that with the glob pattern also
-const imagesAlt = await glob('{css,public}/*.{png,jpeg}')
+// the sync function is the same, just returns a string[] instead
+// of Promise
+const imagesAlt = globSync('{css,public}/*.{png,jpeg}')
+
+// you can also stream them, this is a Minipass stream
+const filesStream = globStream(['**/*.dat', 'logs/**/*.log'])
+
+// construct a Glob object if you wanna do it that way, which
+// allows for much faster walks if you have to look in the same
+// folder multiple times.
+const g = new Glob('**/foo')
+// glob objects are async iterators, can also do globIterate() or
+// g.iterate(), same deal
+for await (const file of g) {
+  console.log('found a foo file:', file)
+}
+// pass a glob as the glob options to reuse its settings and caches
+const g2 = new Glob('**/bar', g)
+// sync iteration works as well
+for (const file of g2) {
+  console.log('found a bar file:', file)
+}
+
+// you can also pass withFileTypes: true to get Path objects
+// these are like a Dirent, but with some more added powers
+// check out http://npm.im/path-scurry for more info on their API
+const g3 = new Glob('**/baz/**', { withFileTypes: true })
+g3.stream().on('data', path => {
+  console.log(
+    'got a path object',
+    path.fullpath(),
+    path.isDirectory(),
+    path.readdirSync().map(e => e.name)
+  )
+})
 ```
 
-## `glob(pattern: string | string[], options?: GlobOptions) => Promise`
+**Note** Glob patterns should always use `/` as a path separator,
+even on Windows systems, as `\` is used to escape glob
+characters. If you wish to use `\` as a path separator _instead
+of_ using it as an escape character on Windows platforms, you may
+set `windowsPathsNoEscape:true` in the options. In this mode,
+special glob characters cannot be escaped, making it impossible
+to match a literal `*` `?` and so on in filenames.
+
+## `glob(pattern: string | string[], options?: GlobOptions) => Promise`
 
 Perform an asynchronous glob search for the pattern(s) specified.
-See below for options field desciptions.
+Returns
+[Path](https://isaacs.github.io/path-scurry/classes/PathBase)
+objects if the `withFileTypes` option is set to `true`. See below
+for full options field desciptions.
 
-## `globSync(pattern: string, options?: GlobOptions) => string[]`
+## `globSync(pattern: string, options?: GlobOptions) => string[] | Path[]`
 
 Synchronous form of `glob()`.
 
-## Options
+## `globIterate(pattern: string | string[], options?: GlobOptions) => AsyncGenerator`
+
+Return an async iterator for walking glob pattern matches.
+
+## `globIterateSync(pattern: string | string[], options?: GlobOptions) => Generator`
+
+Return a sync iterator for walking glob pattern matches.
+
+## `globStream(pattern: string | string[], options?: GlobOptions) => Minipass`
+
+Return a stream that emits all the strings or `Path` objects and
+then emits `end` when completed.
+
+## `globStreamSync(pattern: string | string[], options?: GlobOptions) => Minipass`
+
+Syncronous form of `globStream()`. Will read all the matches as
+fast as you consume them, even all in a single tick if you
+consume them immediately, but will still respond to backpressure
+if they're not consumed immediately.
+
+## `hasMagic(pattern: string | string[], options?: GlobOptions) => boolean`
+
+Returns `true` if the provided pattern contains any "magic" glob
+characters, given the options provided.
+
+Note that brace expansion is not considered "magic", as that just
+turns one string into an array of strings. So a pattern like
+`'x{a,b}y'` would return `false`, because `'xay'` and `'xby'`
+both do not contain any magic glob characters, and it's treated
+the same as if you had called it on `['xay', 'xby']`.
+
+## Class `Glob`
+
+An object that can perform glob pattern traversals.
+
+### `const g = new Glob(pattern: string | string[], options: GlobOptions)`
 
-Exported as `GlobOptions` TypeScript interface.
+See full options descriptions below.
 
-All options that can be passed to
-[`minimatch`](http://npm.im/minimatch) can also be passed to Glob
-to affect pattern matching behavior.
+Note that a previous `Glob` object can be passed as the
+`GlobOptions` to another `Glob` instantiation to re-use settings
+and caches with a new pattern.
 
-All options are optional, and false by default, unless otherwise
-noted.
+Traversal functions can be called multiple times to run the walk
+again.
+
+### `g.stream()`
+
+Stream results asynchronously,
+
+### `g.streamSync()`
+
+Stream results synchronously.
+
+### `g.iterate()`
+
+Default async iteration function. Returns an AsyncGenerator that
+iterates over the results.
+
+### `g.iterateSync()`
+
+Default sync iteration function. Returns a Generator that
+iterates over the results.
+
+### `g.walk()`
+
+Returns a Promise that resolves to the results array.
+
+### `g.walkSync()`
+
+Returns a results array.
+
+### Properties
+
+All options are stored as properties on the `Glob` object.
+
+- `opts` The options provided to the constructor.
+- `patterns` An array of parsed immutable `Pattern` objects.
+
+## Options
 
-All options are added to the Glob object, as well.
+Exported as `GlobOptions` TypeScript interface. A `GlobOptions`
+object may be provided to any of the exported methods, and must
+be provided to the `Glob` constructor.
+
+All options are optional, boolean, and false by default, unless
+otherwise noted.
+
+All resolved options are added to the Glob object as properties.
 
 If you are running many `glob` operations, you can pass a Glob
 object as the `options` argument to a subsequent operation to
-shortcut some `readdir` calls. At the very least, you may pass in
-a shared `cache` option, so that parallel glob operations will be
-sped up by sharing information about the filesystem.
-
-- `cwd` The current working directory in which to search.
-  Defaults to `process.cwd()`. This option is always coerced to
-  use forward-slashes as a path separator, because it is not
-  tested as a glob pattern, so there is no need to escape
+share the previously loaded cache.
+
+- `cwd` String. The current working directory in which to
+  search. Defaults to `process.cwd()`. This option is always
+  coerced to use forward-slashes as a path separator, because it
+  is not tested as a glob pattern, so there is no need to escape
   anything. See also: "Windows, CWDs, Drive Letters, and UNC
   Paths", below.
+
 - `windowsPathsNoEscape` Use `\\` as a path separator _only_, and
   _never_ as an escape character. If set, all `\\` characters are
-  replaced with `/` in the pattern. Note that this makes it
-  **impossible** to match against paths containing literal glob
-  pattern characters, but allows matching with patterns
-  constructed using `path.join()` and `path.resolve()` on Windows
-  platforms, mimicking the (buggy!) behavior of Glob v7 and
-  before on Windows. Please use with caution, and be mindful of
-  [the caveat below about Windows paths](#windows). (For legacy
-  reasons, this is also set if `allowWindowsEscape` is set to the
-  exact value `false`.)
+  replaced with `/` in the pattern.
+
+  Note that this makes it **impossible** to match against paths
+  containing literal glob pattern characters, but allows matching
+  with patterns constructed using `path.join()` and
+  `path.resolve()` on Windows platforms, mimicking the (buggy!)
+  behavior of Glob v7 and before on Windows. Please use with
+  caution, and be mindful of [the caveat below about Windows
+  paths](#windows). (For legacy reasons, this is also set if
+  `allowWindowsEscape` is set to the exact value `false`.)
+
 - `dot` Include `.dot` files in normal matches and `globstar`
   matches. Note that an explicit dot in a portion of the pattern
   will always match dot files.
+
 - `mark` Add a `/` character to directory matches. Note that this
   requires additional stat calls.
-- `nosort` Don't sort the results.
-- `cache` See `cache` property above. Pass in a previously
-  generated cache object to save some fs calls.
-- `nounique` In some cases, brace-expanded patterns or symlinks
-  resolved with `{realpath: true}` can result in the same path
-  showing up multiple times in the result set. By default, this
-  implementation prevents duplicates in the result set. Set this
-  flag to disable that behavior.
+
 - `nobrace` Do not expand `{a,b}` and `{1..3}` brace sets.
+
 - `noglobstar` Do not match `**` against multiple filenames. (Ie,
   treat it as a normal `*` instead.)
-- `noext` Do not match `+(a|b)` "extglob" patterns.
-- `nocase` Perform a case-insensitive match. Note: on
-  case-insensitive filesystems, non-magic patterns may match
-  case-insensitively by default, since `stat` and `readdir` will
-  not raise errors.
+
+- `noext` Do not match "extglob" patterns such as `+(a|b)`.
+
+- `nocase` Perform a case-insensitive match. This defaults to
+  `true` on macOS and Windows systems, and `false` on all others.
+
+  **Note** `nocase` should only be explicitly set when it is
+  known that the filesystem's case sensitivity differs from the
+  platform default. If set `true` on case-sensitive file
+  systems, or `false` on case-insensitive file systems, then the
+  walk may return more or less results than expected.
+
 - `matchBase` Perform a basename-only match if the pattern does
   not contain any slash characters. That is, `*.js` would be
   treated as equivalent to `**/*.js`, matching all js files in
   all directories.
-- `nodir` Do not match directories, only files. (Note: to match
-  _only_ directories, simply put a `/` at the end of the
-  pattern.)
-- `ignore` A glob pattern or array of glob patterns to exclude
-  from matches. To ignore all children within a directory, as
-  well as the entry itself, append `/**'` to the ignore pattern.
-  Note: `ignore` patterns are _always_ in `dot:true` mode,
-  regardless of any other settings.
-- `follow` Follow symlinked directories when expanding `**`
-  patterns. Note that this can result in a lot of duplicate
-  references in the presence of cyclic links, and make
-  performance quite bad.
-- `realpath` Set to true to call `fs.realpath` on all of the
-  results. In the case of an entry that cannot be resolved, the
-  path-resolved absolute path to the matched entry is returned
-  (though it will usually be a broken symlink).
-- `absolute` Set to true to always receive absolute paths for
-  matched files. Note that this does _not_ make an extra system
-  call to get the realpath, it only does string path resolution.
-- `nonull` When a brace-expanded portion of the pattern does not
-  have find matches, setting `{nonull:true}` will cause glob to
-  return the pattern itself instead of the empty set.
-
-`preserveSlashes` is always set to `true`, and `nocomment` and
-`nonegate` are always set to `false`.
 
-## `hasMagic(pattern: string, options?: GlobOptions) => boolean`
+- `nodir` Do not match directories, only files. (Note: to match
+  _only_ directories, put a `/` at the end of the pattern.)
 
-Returns `true` if there are any special characters in the
-pattern, and `false` otherwise.
+- `ignore` string or string[]. A glob pattern or array of glob
+  patterns to exclude from matches. To ignore all children within
+  a directory, as well as the entry itself, append `/**'` to the
+  ignore pattern.
 
-Note that the options affect the results. If `noext:true` is set
-in the options object, then `+(a|b)` will not be considered a
-magic pattern. If the pattern has a brace expansion, like
-`a/{b/c,x/y}` then that is considered magical, unless
-`{nobrace:true}` is set in the options.
+  **Note** `ignore` patterns are _always_ in `dot:true` mode,
+  regardless of any other settings.
 
-## Class: `Glob`
+- `follow` Follow symlinked directories when expanding `**`
+  patterns. This can result in a lot of duplicate references in
+  the presence of cyclic links, and make performance quite bad.
 
-The implementation called by the `glob()` method.
+  By default, a `**` in a pattern will follow 1 symbolic link if
+  it is not the first item in the pattern, or none if it is the
+  first item in the pattern, following the same behavior as Bash.
 
-```js
-import { Glob } from 'glob'
-const ohMyGlob = new Glob(pattern, options)
+- `realpath` Set to true to call `fs.realpath` on all of the
+  results. In the case of an entry that cannot be resolved, the
+  entry is omitted. This incurs a slight performance penalty, of
+  course, because of the added system calls.
 
-// sync traversal
-const results = ohMyGlob.processSync()
+- `absolute` Set to true to always receive absolute paths for
+  matched files. This does _not_ make an extra system call to get
+  the realpath, it only does string path resolution.
 
-// async traversal
-const results = await ohMyGlob.process()
-```
+  By default, when this option is not set, absolute paths are
+  returned for patterns that are absolute, and otherwise paths
+  are returned that are relative to the `cwd` setting.
 
-### `new Glob(pattern: string, options?: GlobOptions | Glob)`
+  `absolute` may not be used along with `withFileTypes`.
 
-Constructs a new `Glob` object.
+- `platform` Defaults to value of `process.platform` if
+  available, or `'linux'` if not. Setting `platform:'win32'` on
+  non-Windows systems may cause strange behavior.
 
-### `glob.process() => Promise`
+- `withFileTypes` Return [PathScurry](http://npm.im/path-scurry)
+  `Path` objects instead of strings. These are similar to a
+  NodeJS `Dirent` object, but with additional methods and
+  properties.
 
-Performs a directory walk and returns the matching entries.
+  `withFileTypes` may not be used along with `absolute`.
 
-### `glob.processSync() => string[]`
+- `signal` An AbortSignal which will cancel the Glob walk when
+  triggered.
 
-Synchronous form of `glob.process()`
+- `scurry` A [PathScurry](http://npm.im/path-scurry) object used
+  to traverse the file system. If the `nocase` option is set
+  explicitly, then any provided `scurry` object must match this
+  setting.
 
 ## Glob Primer
 
@@ -189,16 +315,25 @@ sections may contain slash characters, so `a{/b/c,bcd}` would
 expand into `a/b/c` and `abcd`.
 
 The following characters have special magic meaning when used in
-a path portion:
-
-- `*` Matches 0 or more characters in a single path portion
-- `?` Matches 1 character
+a path portion. With the exception of `**`, none of these match
+path separators (ie, `/` on all platforms, and `\` on Windows).
+
+- `*` Matches 0 or more characters in a single path portion.
+  When alone in a path portion, it must match at least 1
+  character. If `dot:true` is not specified, then `*` will not
+  match against a `.` character at the start of a path portion.
+- `?` Matches 1 character. If `dot:true` is not specified, then
+  `?` will not match against a `.` character at the start of a
+  path portion.
 - `[...]` Matches a range of characters, similar to a RegExp
   range. If the first character of the range is `!` or `^` then
-  it matches any character not in the range.
+  it matches any character not in the range. If the first
+  character is `]`, then it will be considered the same as `\]`,
+  rather than the end of the character class.
 - `!(pattern|pattern|pattern)` Matches anything that does not
   match any of the patterns provided. May _not_ contain `/`
-  characters.
+  characters. Similar to `*`, if alone in a path portion, then
+  the path portion must have at least one character.
 - `?(pattern|pattern|pattern)` Matches zero or one occurrence of
   the patterns provided. May _not_ contain `/` characters.
 - `+(pattern|pattern|pattern)` Matches one or more occurrences of
@@ -210,10 +345,14 @@ a path portion:
 - `**` If a "globstar" is alone in a path portion, then it
   matches zero or more directories and subdirectories searching
   for matches. It does not crawl symlinked directories, unless
-  `{follow:true}` is passed in the options object.
+  `{follow:true}` is passed in the options object. A pattern
+  like `a/b/**` will only match `a/b` if it is a directory.
+  Follows 1 symbolic link if not the first item in the pattern,
+  or 0 if it is the first item, unless `follow:true` is set, in
+  which case it follows all symbolic links.
 
-Note that `[:class:]`, `[=c=]`, and `[.symbol.]` style class
-patterns are _not_ supported by this implementation.
+`[:class:]`, `[=c=]`, and `[.symbol.]` style class patterns are
+_not_ supported by this implementation at this time.
 
 ### Dots
 
@@ -247,9 +386,6 @@ $ echo a*s*d*f
 a*s*d*f
 ```
 
-To return the pattern when there are no matches, use the
-`{nonull:true}` option.
-
 ## Comparisons to other fnmatch/glob implementations
 
 While strict compliance with the existing standards is a
@@ -268,12 +404,9 @@ of the pattern. This prevents infinite loops and duplicates and
 the like. You can force glob to traverse symlinks with `**` by
 setting `{follow:true}` in the options.
 
-If an escaped pattern has no matches, and the `nonull` flag is
-set, then glob returns the pattern as-provided, rather than
-interpreting the character escapes. For example, `glob.match([],
-"\\*a\\?")` will return `"\\*a\\?"` rather than `"*a?"`. This is
-akin to setting the `nullglob` option in bash, except that it
-does not resolve escaped pattern characters.
+There is no equivalent of the `nonull` option. A pattern that
+does not find any matches simply resolves to nothing. (An empty
+array, immediately ended stream, etc.)
 
 If brace expansion is not disabled, then it is performed before
 any other interpretation of the glob pattern. Thus, a pattern
@@ -285,20 +418,12 @@ valid, matching proceeds.
 The character class patterns `[:class:]` (POSIX standard named
 classes), `[=c=]` (locale-specific character collation weight),
 and `[.symbol.]` (collating symbol) style class patterns are
-_not_ supported by this implementation.
+_not_ supported by this implementation at this time.
 
 ### Repeated Slashes
 
-Patterns that have excess `/` characters between non-magic
-portions will have their excess `/` characters preserved in the
-result. That is, empty path portions in the pattern will match
-the parent directory, be appended to the parent path with a `/`,
-and returned.
-
-Empty path portions immediately following any "magic" glob
-pattern will be omitted.
-
-This is by design to match the behavior of the Bash shell.
+Unlike Bash and zsh, repeated `/` are always coalesced into a
+single path separator.
 
 ### Comments and Negation
 
@@ -336,14 +461,17 @@ option is ignored, and the traversal starts at `/`, plus any
 non-magic path portions specified in the pattern.
 
 On Windows systems, the behavior is similar, but the concept of
-an "absolute path" is much more involved.
+an "absolute path" is somewhat more involved.
 
 #### UNC Paths
 
-A UNC path may be used as the start of a pattern. For example, a
-pattern like: `//?/x:/*` will return all file entries in the root
-of the `x:` drive. A pattern like `//ComputerName/Share/*` will
-return all files in the associated share.
+A UNC path may be used as the start of a pattern on Windows
+platforms. For example, a pattern like: `//?/x:/*` will return
+all file entries in the root of the `x:` drive. A pattern like
+`//ComputerName/Share/*` will return all files in the associated
+share.
+
+UNC path roots are always compared case insensitively.
 
 #### Drive Letters
 
@@ -358,9 +486,10 @@ traversal.
 For example, `glob('/tmp', { cwd: 'c:/any/thing' })` will return
 `['c:/tmp']` as the result.
 
-If an explicit `cwd` option is not provided, then the traversal
-will run on whichever drive the active `process.cwd()` returns.
-(That is, the result of `path.resolve('/')`.)
+If an explicit `cwd` option is not provided, and the pattern
+starts with `/`, then the traversal will run on the root of the
+drive provided as the `cwd` option. (That is, it is the result of
+`path.resolve('/')`.)
 
 ## Race Conditions
 
@@ -412,11 +541,89 @@ npm test
 # to re-generate test fixtures
 npm run test-regen
 
-# to benchmark against bash/zsh
+# run the benchmarks
 npm run bench
 
 # to profile javascript
 npm run prof
 ```
 
+## Comparison to Other JavaScript Glob Implementations
+
+**tl;dr**
+
+- If you want glob matching that is as faithful as possible to
+  Bash pattern expansion semantics, and as fast as possible
+  within that constraint, _use this module_.
+- If you are reasonably sure that the patterns you will encounter
+  are relatively simple, and want the absolutely fastest glob
+  matcher out there, _use [fast-glob](http://npm.im/fast-glob)_.
+- If you are reasonably sure that the patterns you will encounter
+  are relatively simple, and want the convenience of
+  automatically respecting `.gitignore` files, _use
+  [globby](http://npm.im/globby)_.
+
+There are some other glob matcher libraries on npm, but these
+three are (in my opinion, as of 2023) the best.
+
+----
+
+**full explanation**
+
+Every library reflects a set of opinions and priorities in the
+trade-offs it makes. Other than this library, I can personally
+recommend both [globby](http://npm.im/globby) and
+[fast-glob](http://npm.im/fast-glob), though they differ in their
+benefits and drawbacks.
+
+Both have very nice APIs and are reasonably fast.
+
+`fast-glob` is, as far as I am aware, the fastest glob
+implementation in JavaScript today. However, there are many
+cases where the choices that `fast-glob` makes in pursuit of
+speed mean that its results differ from the results returned by
+Bash and other sh-like shells, which may be surprising.
+
+In my testing, `fast-glob` is around 10-20% faster than this
+module when walking over 200k files nested 4 directories
+deep[1](#fn-webscale). However, there are some inconsistencies
+with Bash matching behavior that this module does not suffer
+from:
+
+- `**` only matches files, not directories
+- `..` path portions are not handled unless they appear at the
+  start of the pattern
+- `./!()` will not match any files that _start_ with
+  ``, even if they do not match ``. For
+  example, `!(9).txt` will not match `9999.txt`.
+- Some brace patterns in the middle of a pattern will result in
+  failing to find certain matches.
+- Extglob patterns are allowed to contain `/` characters.
+
+Globby exhibits all of the same pattern semantics as fast-glob,
+(as it is a wrapper around fast-glob) and is slightly slower than
+node-glob (by about 10-20% in the benchmark test set, or in other
+words, anywhere from 20-50% slower than fast-glob). However, it
+adds some API conveniences that may be worth the costs.
+
+- Support for `.gitignore` and other ignore files.
+- Support for negated globs (ie, patterns starting with `!`
+  rather than using a separate `ignore` option).
+
+The priority of this module is "correctness" in the sense of
+performing a glob pattern expansion as faithfully as possible to
+the behavior of Bash and other sh-like shells, with as much speed
+as possible.
+
+Note that prior versions of `node-glob` are _not_ on this list.
+Former versions of this module are far too slow for any cases
+where performance matters at all, and were designed with APIs
+that are extremely dated by current JavaScript standards.
+
+----
+
+[1]: In the cases where this module
+returns results and `fast-glob` doesn't, it's even faster, of
+course.
+
 ![](oh-my-glob.gif)
diff --git a/benchmark.sh b/benchmark.sh
index a2d49e78..111ac4e4 100644
--- a/benchmark.sh
+++ b/benchmark.sh
@@ -32,10 +32,10 @@ tt () {
 
 t () {
   rm -f stderr stdout
-  tt "$@" 2>stderr >stdout || true
+  tt "$@" 2>stderr >stdout || (cat stderr >&2 ; exit 1 )
   echo $(cat stderr | grep real | awk -F $'\t' '{ print $2 }' || true)' '\
     $(cat stdout)
-  rm -f stderr stdout
+  # rm -f stderr stdout
 }
 
 # warm up the fs cache so we don't get a spurious slow first result
@@ -85,10 +85,10 @@ CJS
 MJS
   t node "$wd/bench-working-dir/globby-sync.mjs" "$p"
 
-#  echo -n $'node current glob.sync cjs    \t'
+#  echo -n $'node current globSync cjs    \t'
 #  cat > "$wd/bench-working-dir/sync.cjs" < "$wd/bench-working-dir/sync.mjs" < "$wd/bench-working-dir/stream-sync.mjs" < c++)
     .on('end', () => console.log(c))
 MJS
@@ -159,9 +159,9 @@ MJS
 
   echo -n $'node current glob stream      \t'
   cat > "$wd/bench-working-dir/stream.mjs" < c++)
     .on('end', () => console.log(c))
 MJS
diff --git a/changelog.md b/changelog.md
index c4bdc0a6..0c54c233 100644
--- a/changelog.md
+++ b/changelog.md
@@ -67,6 +67,8 @@ changes.
 - `realpath:true` no longer implies `absolute:true`. The
   relative path to the realpath will be emitted when `absolute`
   is not set.
+- `realpath:true` will cause invalid symbolic links to be
+  omitted, rather than matching the link itself.
 
 ## Performance and Algorithm Changes
 
diff --git a/src/glob.ts b/src/glob.ts
index bf2f3f9b..aac65c5b 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -9,11 +9,10 @@ import {
 } from 'path-scurry'
 import { Ignore } from './ignore.js'
 import { Pattern } from './pattern.js'
-import { GlobStream, GlobWalker, Matches } from './walker.js'
+import { GlobStream, GlobWalker } from './walker.js'
 
-type MatchSet = Minimatch['set']
-type GlobSet = Exclude
-type GlobParts = Exclude
+export type MatchSet = Minimatch['set']
+export type GlobParts = Exclude
 
 // if no process global, just call it linux.
 // so we default to case-sensitive, / separators
@@ -58,7 +57,7 @@ export type GlobOptionsWithFileTypesUnset = GlobOptions & {
   withFileTypes?: undefined
 }
 
-type Result = Opts extends GlobOptionsWithFileTypesTrue
+export type Result = Opts extends GlobOptionsWithFileTypesTrue
   ? Path
   : Opts extends GlobOptionsWithFileTypesFalse
   ? string
@@ -67,7 +66,7 @@ type Result = Opts extends GlobOptionsWithFileTypesTrue
   : string | Path
 export type Results = Result[]
 
-type FileTypes = Opts extends GlobOptionsWithFileTypesTrue
+export type FileTypes = Opts extends GlobOptionsWithFileTypesTrue
   ? true
   : Opts extends GlobOptionsWithFileTypesFalse
   ? false
@@ -76,34 +75,28 @@ type FileTypes = Opts extends GlobOptionsWithFileTypesTrue
   : boolean
 
 export class Glob {
-  withFileTypes: FileTypes
-  pattern: string[]
-  ignore?: Ignore
-  follow: boolean
+  absolute: boolean
+  cwd: string
   dot: boolean
+  follow: boolean
+  ignore?: Ignore
   mark: boolean
-  nodir: boolean
-  cwd: string
-  matchSet: MatchSet
-  globSet: GlobSet
-  globParts: GlobParts
-  realpath: boolean
-  absolute: boolean
   matchBase: boolean
-  windowsPathsNoEscape: boolean
+  nobrace: boolean
+  nocase: boolean
+  nodir: boolean
+  noext: boolean
   noglobstar: boolean
-  matches?: Matches
-  seen?: Set
-  walked?: Map
-  nocase?: boolean
+  pattern: string[]
+  platform: NodeJS.Platform
+  realpath: boolean
   scurry: PathScurry
+  signal?: AbortSignal
+  windowsPathsNoEscape: boolean
+  withFileTypes: FileTypes
+
   opts: Opts
-  globUtilOpts: Opts
-  platform: NodeJS.Platform
   patterns: Pattern[]
-  signal?: AbortSignal
-  nobrace: boolean
-  noext: boolean
 
   constructor(pattern: string | string[], opts: Opts) {
     this.withFileTypes = !!opts.withFileTypes as FileTypes
@@ -169,12 +162,6 @@ export class Glob {
     }
     this.nocase = this.scurry.nocase
 
-    this.globUtilOpts = {
-      ...opts,
-      platform: this.platform,
-      nocase: this.nocase,
-    }
-
     const mmo: MinimatchOptions = {
       // default nocase based on platform
       ...opts,
@@ -192,48 +179,43 @@ export class Glob {
     }
 
     const mms = this.pattern.map(p => new Minimatch(p, mmo))
-    const [matchSet, globSet, globParts] = mms.reduce(
-      (set: [MatchSet, GlobSet, GlobParts], m) => {
+    const [matchSet, globParts] = mms.reduce(
+      (set: [MatchSet, GlobParts], m) => {
         set[0].push(...m.set)
-        set[1].push(...m.globSet)
-        set[2].push(...m.globParts)
+        set[1].push(...m.globParts)
         return set
       },
-      [[], [], []]
+      [[], []]
     )
     this.patterns = matchSet.map((set, i) => {
       return new Pattern(set, globParts[i], 0, this.platform)
     })
-    this.matchSet = matchSet
-    this.globSet = globSet
-    this.globParts = globParts
   }
 
-  async walk(): Promise> {
+  async walk(): Promise>
+  async walk(): Promise<(string | Path)[]> {
     // Walkers always return array of Path objects, so we just have to
     // coerce them into the right shape.  It will have already called
     // realpath() if the option was set to do so, so we know that's cached.
     // start out knowing the cwd, at least
-    const walker = new GlobWalker(this.patterns, this.scurry.cwd, {
-      ...this.opts,
-      platform: this.platform,
-      nocase: this.nocase,
-    })
-    return this.finish(await walker.walk())
-  }
-
-  walkSync(): Results {
-    const walker = new GlobWalker(this.patterns, this.scurry.cwd, {
-      ...this.opts,
-      platform: this.platform,
-      nocase: this.nocase,
-    })
-    return this.finish(walker.walkSync())
+    return [
+      ...(await new GlobWalker(this.patterns, this.scurry.cwd, {
+        ...this.opts,
+        platform: this.platform,
+        nocase: this.nocase,
+      }).walk()),
+    ]
   }
 
-  finish(matches: Matches): Results
-  finish(matches: Set): (string | Path)[] {
-    return [...matches]
+  walkSync(): Results
+  walkSync(): (string | Path)[] {
+    return [
+      ...new GlobWalker(this.patterns, this.scurry.cwd, {
+        ...this.opts,
+        platform: this.platform,
+        nocase: this.nocase,
+      }).walkSync(),
+    ]
   }
 
   stream(): Minipass, Result>
diff --git a/src/index.ts b/src/index.ts
index 670087ed..67c1c374 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,13 +1,13 @@
-import {
-  Glob,
+import type {
   GlobOptions,
   GlobOptionsWithFileTypesFalse,
   GlobOptionsWithFileTypesTrue,
   GlobOptionsWithFileTypesUnset,
   Results,
 } from './glob.js'
+import { Glob } from './glob.js'
 import { hasMagic } from './has-magic.js'
-import {
+import type {
   GWOFileTypesFalse,
   GWOFileTypesTrue,
   GWOFileTypesUnset,
@@ -155,8 +155,16 @@ export function globIterateSync(
 
 /* c8 ignore start */
 export { Glob } from './glob.js'
-export type { GlobOptions } from './glob.js'
+export type {
+  GlobOptions,
+  GlobOptionsWithFileTypesFalse,
+  GlobOptionsWithFileTypesTrue,
+  GlobOptionsWithFileTypesUnset,
+  Result,
+  Results,
+} from './glob.js'
 export { hasMagic } from './has-magic.js'
+export type { MatchStream } from './walker.js'
 /* c8 ignore stop */
 export default Object.assign(glob, {
   glob,
diff --git a/src/pattern.ts b/src/pattern.ts
index 676d61c3..3d086533 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -1,24 +1,20 @@
 // this is just a very light wrapper around 2 arrays with an offset index
 
 import { GLOBSTAR } from 'minimatch'
-type MMRegExp = RegExp & {
-  _glob?: string
-  _src?: string
-}
-export type MMPattern = string | MMRegExp | typeof GLOBSTAR
+export type MMPattern = string | RegExp | typeof GLOBSTAR
 
 // an array of length >= 1
-type PatternList = [p: MMPattern, ...rest: MMPattern[]]
-type UNCPatternList = [
+export type PatternList = [p: MMPattern, ...rest: MMPattern[]]
+export type UNCPatternList = [
   p0: '',
   p1: '',
   p2: string,
   p3: string,
   ...rest: MMPattern[]
 ]
-type DrivePatternList = [p0: string, ...rest: MMPattern[]]
-type AbsolutePatternList = [p0: '', ...rest: MMPattern[]]
-type GlobList = [p: string, ...rest: string[]]
+export type DrivePatternList = [p0: string, ...rest: MMPattern[]]
+export type AbsolutePatternList = [p0: '', ...rest: MMPattern[]]
+export type GlobList = [p: string, ...rest: string[]]
 
 const isPatternList = (pl: MMPattern[]): pl is PatternList =>
   pl.length >= 1
diff --git a/src/processor.ts b/src/processor.ts
index c2e6aab0..092c1f4b 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -5,7 +5,7 @@ import { Path } from 'path-scurry'
 import { MMPattern, Pattern } from './pattern.js'
 import { GlobWalkerOpts } from './walker.js'
 
-class HasWalkedCache {
+export class HasWalkedCache {
   store: Map>
   constructor(store: Map> = new Map()) {
     this.store = store
@@ -24,7 +24,7 @@ class HasWalkedCache {
   }
 }
 
-class MatchRecord {
+export class MatchRecord {
   store: Map = new Map()
   add(target: Path, absolute: boolean, ifDir: boolean) {
     const n = (absolute ? 2 : 0) | (ifDir ? 1 : 0)
@@ -41,7 +41,7 @@ class MatchRecord {
   }
 }
 
-class SubWalks {
+export class SubWalks {
   store: Map = new Map()
   add(target: Path, pattern: Pattern) {
     if (!target.canReaddir()) {

From 9a5a45a1c873b1df3f05cc55c535b6345a6857e0 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sun, 26 Feb 2023 21:31:59 -0800
Subject: [PATCH 110/163] put bench results in readme

---
 README.md | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 296 insertions(+)

diff --git a/README.md b/README.md
index 44d0d413..2a56d43b 100644
--- a/README.md
+++ b/README.md
@@ -627,3 +627,299 @@ returns results and `fast-glob` doesn't, it's even faster, of
 course.
 
 ![](oh-my-glob.gif)
+
+### Benchmark Results
+
+First number is time, smaller is better.
+
+Second number is the count of results returned.
+
+```
+--- pattern: '**' ---
+~~ sync ~~
+node fast-glob sync             0m0.598s  200364
+node globby sync                0m0.765s  200364
+node current globSync mjs       0m0.683s  222656
+node current glob syncStream    0m0.649s  222656
+~~ async ~~
+node fast-glob async            0m0.350s  200364
+node globby async               0m0.509s  200364
+node current glob async mjs     0m0.463s  222656
+node current glob stream        0m0.411s  222656
+
+--- pattern: '**/..' ---
+~~ sync ~~
+node fast-glob sync             0m0.486s  0
+node globby sync                0m0.769s  200364
+node current globSync mjs       0m0.564s  2242
+node current glob syncStream    0m0.583s  2242
+~~ async ~~
+node fast-glob async            0m0.283s  0
+node globby async               0m0.512s  200364
+node current glob async mjs     0m0.299s  2242
+node current glob stream        0m0.312s  2242
+
+--- pattern: './**/0/**/0/**/0/**/0/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.490s  10
+node globby sync                0m0.517s  10
+node current globSync mjs       0m0.540s  10
+node current glob syncStream    0m0.550s  10
+~~ async ~~
+node fast-glob async            0m0.290s  10
+node globby async               0m0.296s  10
+node current glob async mjs     0m0.278s  10
+node current glob stream        0m0.302s  10
+
+--- pattern: './**/[01]/**/[12]/**/[23]/**/[45]/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.500s  160
+node globby sync                0m0.528s  160
+node current globSync mjs       0m0.556s  160
+node current glob syncStream    0m0.573s  160
+~~ async ~~
+node fast-glob async            0m0.283s  160
+node globby async               0m0.301s  160
+node current glob async mjs     0m0.306s  160
+node current glob stream        0m0.322s  160
+
+--- pattern: './**/0/**/0/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.502s  5230
+node globby sync                0m0.527s  5230
+node current globSync mjs       0m0.544s  5230
+node current glob syncStream    0m0.557s  5230
+~~ async ~~
+node fast-glob async            0m0.285s  5230
+node globby async               0m0.305s  5230
+node current glob async mjs     0m0.304s  5230
+node current glob stream        0m0.310s  5230
+
+--- pattern: '**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.580s  200023
+node globby sync                0m0.771s  200023
+node current globSync mjs       0m0.685s  200023
+node current glob syncStream    0m0.649s  200023
+~~ async ~~
+node fast-glob async            0m0.349s  200023
+node globby async               0m0.509s  200023
+node current glob async mjs     0m0.427s  200023
+node current glob stream        0m0.388s  200023
+
+--- pattern: '{**/*.txt,**/?/**/*.txt,**/?/**/?/**/*.txt,**/?/**/?/**/?/**/*.txt,**/?/**/?/**/?/**/?/**/*.txt}' ---
+~~ sync ~~
+node fast-glob sync             0m0.589s  200023
+node globby sync                0m0.771s  200023
+node current globSync mjs       0m0.716s  200023
+node current glob syncStream    0m0.684s  200023
+~~ async ~~
+node fast-glob async            0m0.351s  200023
+node globby async               0m0.518s  200023
+node current glob async mjs     0m0.462s  200023
+node current glob stream        0m0.468s  200023
+
+--- pattern: '**/5555/0000/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.496s  1000
+node globby sync                0m0.519s  1000
+node current globSync mjs       0m0.539s  1000
+node current glob syncStream    0m0.567s  1000
+~~ async ~~
+node fast-glob async            0m0.285s  1000
+node globby async               0m0.299s  1000
+node current glob async mjs     0m0.305s  1000
+node current glob stream        0m0.301s  1000
+
+--- pattern: './**/0/**/../[01]/**/0/../**/0/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.484s  0
+node globby sync                0m0.507s  0
+node current globSync mjs       0m0.577s  4880
+node current glob syncStream    0m0.586s  4880
+~~ async ~~
+node fast-glob async            0m0.280s  0
+node globby async               0m0.298s  0
+node current glob async mjs     0m0.327s  4880
+node current glob stream        0m0.324s  4880
+
+--- pattern: '**/????/????/????/????/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.547s  100000
+node globby sync                0m0.673s  100000
+node current globSync mjs       0m0.626s  100000
+node current glob syncStream    0m0.618s  100000
+~~ async ~~
+node fast-glob async            0m0.315s  100000
+node globby async               0m0.414s  100000
+node current glob async mjs     0m0.366s  100000
+node current glob stream        0m0.345s  100000
+
+--- pattern: './{**/?{/**/?{/**/?{/**/?,,,,},,,,},,,,},,,}/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.588s  100000
+node globby sync                0m0.670s  100000
+node current globSync mjs       0m0.717s  200023
+node current glob syncStream    0m0.687s  200023
+~~ async ~~
+node fast-glob async            0m0.343s  100000
+node globby async               0m0.418s  100000
+node current glob async mjs     0m0.519s  200023
+node current glob stream        0m0.451s  200023
+
+--- pattern: '**/!(0|9).txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.573s  160023
+node globby sync                0m0.731s  160023
+node current globSync mjs       0m0.680s  180023
+node current glob syncStream    0m0.659s  180023
+~~ async ~~
+node fast-glob async            0m0.345s  160023
+node globby async               0m0.476s  160023
+node current glob async mjs     0m0.427s  180023
+node current glob stream        0m0.388s  180023
+
+--- pattern: './{*/**/../{*/**/../{*/**/../{*/**/../{*/**,,,,},,,,},,,,},,,,},,,,}/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.483s  0
+node globby sync                0m0.512s  0
+node current globSync mjs       0m0.811s  200023
+node current glob syncStream    0m0.773s  200023
+~~ async ~~
+node fast-glob async            0m0.280s  0
+node globby async               0m0.299s  0
+node current glob async mjs     0m0.617s  200023
+node current glob stream        0m0.568s  200023
+
+--- pattern: './*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/../*/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.485s  0
+node globby sync                0m0.507s  0
+node current globSync mjs       0m0.759s  200023
+node current glob syncStream    0m0.740s  200023
+~~ async ~~
+node fast-glob async            0m0.281s  0
+node globby async               0m0.297s  0
+node current glob async mjs     0m0.544s  200023
+node current glob stream        0m0.464s  200023
+
+--- pattern: './*/**/../*/**/../*/**/../*/**/../*/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.486s  0
+node globby sync                0m0.513s  0
+node current globSync mjs       0m0.734s  200023
+node current glob syncStream    0m0.696s  200023
+~~ async ~~
+node fast-glob async            0m0.286s  0
+node globby async               0m0.296s  0
+node current glob async mjs     0m0.506s  200023
+node current glob stream        0m0.483s  200023
+
+--- pattern: './0/**/../1/**/../2/**/../3/**/../4/**/../5/**/../6/**/../7/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.060s  0
+node globby sync                0m0.074s  0
+node current globSync mjs       0m0.067s  0
+node current glob syncStream    0m0.066s  0
+~~ async ~~
+node fast-glob async            0m0.060s  0
+node globby async               0m0.075s  0
+node current glob async mjs     0m0.066s  0
+node current glob stream        0m0.067s  0
+
+--- pattern: './**/?/**/?/**/?/**/?/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.568s  100000
+node globby sync                0m0.651s  100000
+node current globSync mjs       0m0.619s  100000
+node current glob syncStream    0m0.617s  100000
+~~ async ~~
+node fast-glob async            0m0.332s  100000
+node globby async               0m0.409s  100000
+node current glob async mjs     0m0.372s  100000
+node current glob stream        0m0.351s  100000
+
+--- pattern: '**/*/**/*/**/*/**/*/**' ---
+~~ sync ~~
+node fast-glob sync             0m0.603s  200113
+node globby sync                0m0.798s  200113
+node current globSync mjs       0m0.730s  222137
+node current glob syncStream    0m0.693s  222137
+~~ async ~~
+node fast-glob async            0m0.356s  200113
+node globby async               0m0.525s  200113
+node current glob async mjs     0m0.508s  222137
+node current glob stream        0m0.455s  222137
+
+--- pattern: './**/*/**/*/**/*/**/*/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.622s  200000
+node globby sync                0m0.792s  200000
+node current globSync mjs       0m0.722s  200000
+node current glob syncStream    0m0.695s  200000
+~~ async ~~
+node fast-glob async            0m0.369s  200000
+node globby async               0m0.527s  200000
+node current glob async mjs     0m0.502s  200000
+node current glob stream        0m0.481s  200000
+
+--- pattern: '**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.588s  200023
+node globby sync                0m0.771s  200023
+node current globSync mjs       0m0.684s  200023
+node current glob syncStream    0m0.658s  200023
+~~ async ~~
+node fast-glob async            0m0.352s  200023
+node globby async               0m0.516s  200023
+node current glob async mjs     0m0.432s  200023
+node current glob stream        0m0.384s  200023
+
+--- pattern: './**/**/**/**/**/**/**/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.589s  200023
+node globby sync                0m0.766s  200023
+node current globSync mjs       0m0.682s  200023
+node current glob syncStream    0m0.652s  200023
+~~ async ~~
+node fast-glob async            0m0.352s  200023
+node globby async               0m0.523s  200023
+node current glob async mjs     0m0.436s  200023
+node current glob stream        0m0.380s  200023
+
+--- pattern: '**/*/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.592s  200023
+node globby sync                0m0.776s  200023
+node current globSync mjs       0m0.691s  200023
+node current glob syncStream    0m0.659s  200023
+~~ async ~~
+node fast-glob async            0m0.357s  200023
+node globby async               0m0.513s  200023
+node current glob async mjs     0m0.471s  200023
+node current glob stream        0m0.424s  200023
+
+--- pattern: '**/*/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.585s  200023
+node globby sync                0m0.766s  200023
+node current globSync mjs       0m0.694s  200023
+node current glob syncStream    0m0.664s  200023
+~~ async ~~
+node fast-glob async            0m0.350s  200023
+node globby async               0m0.514s  200023
+node current glob async mjs     0m0.472s  200023
+node current glob stream        0m0.424s  200023
+
+--- pattern: '**/[0-9]/**/*.txt' ---
+~~ sync ~~
+node fast-glob sync             0m0.544s  100000
+node globby sync                0m0.636s  100000
+node current globSync mjs       0m0.626s  100000
+node current glob syncStream    0m0.621s  100000
+~~ async ~~
+node fast-glob async            0m0.322s  100000
+node globby async               0m0.404s  100000
+node current glob async mjs     0m0.360s  100000
+node current glob stream        0m0.352s  100000
+```

From d03ed0ae5a1d7e5a471667f8c530393226a5dd5e Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sun, 26 Feb 2023 21:32:24 -0800
Subject: [PATCH 111/163] typedoc github action

---
 .github/workflows/typedoc.yml | 50 +++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 .github/workflows/typedoc.yml

diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml
new file mode 100644
index 00000000..e5bc0ef8
--- /dev/null
+++ b/.github/workflows/typedoc.yml
@@ -0,0 +1,50 @@
+# Simple workflow for deploying static content to GitHub Pages
+name: Deploy static content to Pages
+
+on:
+  # Runs on pushes targeting the default branch
+  push:
+    branches: ["main"]
+
+  # Allows you to run this workflow manually from the Actions tab
+  workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+  contents: read
+  pages: write
+  id-token: write
+
+# Allow one concurrent deployment
+concurrency:
+  group: "pages"
+  cancel-in-progress: true
+
+jobs:
+  # Single deploy job since we're just deploying
+  deploy:
+    environment:
+      name: github-pages
+      url: ${{ steps.deployment.outputs.page_url }}
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v3
+      - name: Use Nodejs ${{ matrix.node-version }}
+        uses: actions/setup-node@v3
+        with:
+          node-version: 18.x
+      - name: Install dependencies
+        run: npm install
+      - name: Generate typedocs
+        run: npm run typedoc
+
+      - name: Setup Pages
+        uses: actions/configure-pages@v3
+      - name: Upload artifact
+        uses: actions/upload-pages-artifact@v1
+        with:
+          path: './docs'
+      - name: Deploy to GitHub Pages
+        id: deployment
+        uses: actions/deploy-pages@v1

From fa0cd771fc241806425dd33ddb7417c5c2596772 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sun, 26 Feb 2023 21:59:50 -0800
Subject: [PATCH 112/163] cwd can be a file:// url

---
 README.md         |  3 +++
 changelog.md      |  1 +
 package-lock.json | 14 +++++++-------
 package.json      |  2 +-
 src/glob.ts       |  8 +++++++-
 src/walker.ts     |  2 +-
 6 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index 2a56d43b..a20a2d65 100644
--- a/README.md
+++ b/README.md
@@ -205,6 +205,9 @@ share the previously loaded cache.
   anything. See also: "Windows, CWDs, Drive Letters, and UNC
   Paths", below.
 
+  This option may be eiher a string path or a `file://` URL
+  object or string.
+
 - `windowsPathsNoEscape` Use `\\` as a path separator _only_, and
   _never_ as an escape character. If set, all `\\` characters are
   replaced with `/` in the pattern.
diff --git a/changelog.md b/changelog.md
index 0c54c233..591d7d98 100644
--- a/changelog.md
+++ b/changelog.md
@@ -41,6 +41,7 @@ changes.
   `mark:true`.)
 - Simplified `cwd` behavior so it is far less magical, and relies
   less on platform-specific absolute path representations.
+- `cwd` can be a File URL or a string path.
 - More efficient handling for absolute patterns. (That is,
   patterns that start with `/` on any platform, or start with a
   drive letter or UNC path on Windows.)
diff --git a/package-lock.json b/package-lock.json
index d23956d6..fbc050bf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,7 +12,7 @@
         "fs.realpath": "^1.0.0",
         "minimatch": "^7.2.0",
         "minipass": "^4.2.4",
-        "path-scurry": "^1.4.0"
+        "path-scurry": "^1.5.0"
       },
       "devDependencies": {
         "@types/mkdirp": "^1.0.2",
@@ -3226,9 +3226,9 @@
       }
     },
     "node_modules/path-scurry": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.4.0.tgz",
-      "integrity": "sha512-kSNY3gm5ul3nBwDFkX9i8pkqZ5r0YsutWwpaUmog0utwOGwiRBiJlks955VGSsKde5EmviX02DlEDEWj7miukA==",
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.5.0.tgz",
+      "integrity": "sha512-hJ8rODLI9B2qwsYAd32rrI76gwVUPeu5kq/do6URDj2bJCVH3ilyT978Mv/NLuFMaqzHrn3XtiDLMZHaTTh4vA==",
       "dependencies": {
         "lru-cache": "^7.14.1",
         "minipass": "^4.0.2"
@@ -8801,9 +8801,9 @@
       "dev": true
     },
     "path-scurry": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.4.0.tgz",
-      "integrity": "sha512-kSNY3gm5ul3nBwDFkX9i8pkqZ5r0YsutWwpaUmog0utwOGwiRBiJlks955VGSsKde5EmviX02DlEDEWj7miukA==",
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.5.0.tgz",
+      "integrity": "sha512-hJ8rODLI9B2qwsYAd32rrI76gwVUPeu5kq/do6URDj2bJCVH3ilyT978Mv/NLuFMaqzHrn3XtiDLMZHaTTh4vA==",
       "requires": {
         "lru-cache": "^7.14.1",
         "minipass": "^4.0.2"
diff --git a/package.json b/package.json
index 3f22bd89..6c9553b2 100644
--- a/package.json
+++ b/package.json
@@ -61,7 +61,7 @@
     "fs.realpath": "^1.0.0",
     "minimatch": "^7.2.0",
     "minipass": "^4.2.4",
-    "path-scurry": "^1.4.0"
+    "path-scurry": "^1.5.0"
   },
   "devDependencies": {
     "@types/mkdirp": "^1.0.2",
diff --git a/src/glob.ts b/src/glob.ts
index aac65c5b..cfdd58e2 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -7,6 +7,7 @@ import {
   PathScurryPosix,
   PathScurryWin32,
 } from 'path-scurry'
+import {fileURLToPath} from 'url'
 import { Ignore } from './ignore.js'
 import { Pattern } from './pattern.js'
 import { GlobStream, GlobWalker } from './walker.js'
@@ -26,7 +27,7 @@ const defaultPlatform: NodeJS.Platform =
 export interface GlobOptions {
   absolute?: boolean
   allowWindowsEscape?: boolean
-  cwd?: string
+  cwd?: string | URL
   dot?: boolean
   follow?: boolean
   ignore?: string | string[] | Ignore
@@ -105,6 +106,11 @@ export class Glob {
     this.dot = !!opts.dot
     this.nodir = !!opts.nodir
     this.mark = !!opts.mark
+    if (!opts.cwd) {
+      this.cwd = ''
+    } else if (opts.cwd instanceof URL || opts.cwd.startsWith('file://')) {
+      opts.cwd = fileURLToPath(opts.cwd)
+    }
     this.cwd = opts.cwd || ''
     this.nobrace = !!opts.nobrace
     this.noext = !!opts.noext
diff --git a/src/walker.ts b/src/walker.ts
index eae56405..479cb737 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -13,7 +13,7 @@ import { Processor } from './processor.js'
 export interface GlobWalkerOpts {
   absolute?: boolean
   allowWindowsEscape?: boolean
-  cwd?: string
+  cwd?: string | URL
   dot?: boolean
   follow?: boolean
   ignore?: string | string[] | Ignore

From cdd1627bd63431741310c3b4f3f920ef78dabbf0 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Sun, 26 Feb 2023 22:06:20 -0800
Subject: [PATCH 113/163] update all the things, remove unused mkdirp types

---
 package-lock.json | 7208 +++++++--------------------------------------
 package.json      |    1 -
 2 files changed, 1015 insertions(+), 6194 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index fbc050bf..c1aaee59 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,7 +1,7 @@
 {
   "name": "glob",
   "version": "9.0.0-0",
-  "lockfileVersion": 2,
+  "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
@@ -15,7 +15,6 @@
         "path-scurry": "^1.5.0"
       },
       "devDependencies": {
-        "@types/mkdirp": "^1.0.2",
         "@types/node": "^18.11.18",
         "@types/tap": "^15.0.7",
         "c8": "^7.12.0",
@@ -36,58 +35,59 @@
       }
     },
     "node_modules/@ampproject/remapping": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.1.tgz",
-      "integrity": "sha512-Aolwjd7HSC2PyY0fDj/wA/EimQT4HfEnFYNp5s9CQlrdhyvWTtvZ5YzrUPu6R6/1jKiUlxu8bUhkdSnKHNAHMA==",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+      "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
       "dev": true,
       "dependencies": {
-        "@jridgewell/trace-mapping": "^0.3.0"
+        "@jridgewell/gen-mapping": "^0.1.0",
+        "@jridgewell/trace-mapping": "^0.3.9"
       },
       "engines": {
         "node": ">=6.0.0"
       }
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
-      "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
       "dev": true,
       "dependencies": {
-        "@babel/highlight": "^7.16.7"
+        "@babel/highlight": "^7.18.6"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/compat-data": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz",
-      "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==",
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz",
+      "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/core": {
-      "version": "7.17.2",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz",
-      "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==",
-      "dev": true,
-      "dependencies": {
-        "@ampproject/remapping": "^2.0.0",
-        "@babel/code-frame": "^7.16.7",
-        "@babel/generator": "^7.17.0",
-        "@babel/helper-compilation-targets": "^7.16.7",
-        "@babel/helper-module-transforms": "^7.16.7",
-        "@babel/helpers": "^7.17.2",
-        "@babel/parser": "^7.17.0",
-        "@babel/template": "^7.16.7",
-        "@babel/traverse": "^7.17.0",
-        "@babel/types": "^7.17.0",
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz",
+      "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==",
+      "dev": true,
+      "dependencies": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.18.6",
+        "@babel/generator": "^7.21.0",
+        "@babel/helper-compilation-targets": "^7.20.7",
+        "@babel/helper-module-transforms": "^7.21.0",
+        "@babel/helpers": "^7.21.0",
+        "@babel/parser": "^7.21.0",
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.0",
+        "@babel/types": "^7.21.0",
         "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
-        "json5": "^2.1.2",
+        "json5": "^2.2.2",
         "semver": "^6.3.0"
       },
       "engines": {
@@ -99,28 +99,44 @@
       }
     },
     "node_modules/@babel/generator": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz",
-      "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==",
+      "version": "7.21.1",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz",
+      "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.17.0",
-        "jsesc": "^2.5.1",
-        "source-map": "^0.5.0"
+        "@babel/types": "^7.21.0",
+        "@jridgewell/gen-mapping": "^0.3.2",
+        "@jridgewell/trace-mapping": "^0.3.17",
+        "jsesc": "^2.5.1"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+      "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/set-array": "^1.0.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.9"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
     "node_modules/@babel/helper-compilation-targets": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz",
-      "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==",
+      "version": "7.20.7",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
+      "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
       "dev": true,
       "dependencies": {
-        "@babel/compat-data": "^7.16.4",
-        "@babel/helper-validator-option": "^7.16.7",
-        "browserslist": "^4.17.5",
+        "@babel/compat-data": "^7.20.5",
+        "@babel/helper-validator-option": "^7.18.6",
+        "browserslist": "^4.21.3",
+        "lru-cache": "^5.1.1",
         "semver": "^6.3.0"
       },
       "engines": {
@@ -130,150 +146,152 @@
         "@babel/core": "^7.0.0"
       }
     },
-    "node_modules/@babel/helper-environment-visitor": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz",
-      "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==",
+    "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.16.7"
-      },
-      "engines": {
-        "node": ">=6.9.0"
+        "yallist": "^3.0.2"
       }
     },
-    "node_modules/@babel/helper-function-name": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz",
-      "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==",
+    "node_modules/@babel/helper-environment-visitor": {
+      "version": "7.18.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
+      "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
       "dev": true,
-      "dependencies": {
-        "@babel/helper-get-function-arity": "^7.16.7",
-        "@babel/template": "^7.16.7",
-        "@babel/types": "^7.16.7"
-      },
       "engines": {
         "node": ">=6.9.0"
       }
     },
-    "node_modules/@babel/helper-get-function-arity": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz",
-      "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==",
+    "node_modules/@babel/helper-function-name": {
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz",
+      "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.16.7"
+        "@babel/template": "^7.20.7",
+        "@babel/types": "^7.21.0"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-hoist-variables": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz",
-      "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
+      "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.16.7"
+        "@babel/types": "^7.18.6"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-module-imports": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz",
-      "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
+      "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.16.7"
+        "@babel/types": "^7.18.6"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-module-transforms": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz",
-      "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==",
+      "version": "7.21.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz",
+      "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-environment-visitor": "^7.16.7",
-        "@babel/helper-module-imports": "^7.16.7",
-        "@babel/helper-simple-access": "^7.16.7",
-        "@babel/helper-split-export-declaration": "^7.16.7",
-        "@babel/helper-validator-identifier": "^7.16.7",
-        "@babel/template": "^7.16.7",
-        "@babel/traverse": "^7.16.7",
-        "@babel/types": "^7.16.7"
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-module-imports": "^7.18.6",
+        "@babel/helper-simple-access": "^7.20.2",
+        "@babel/helper-split-export-declaration": "^7.18.6",
+        "@babel/helper-validator-identifier": "^7.19.1",
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.2",
+        "@babel/types": "^7.21.2"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-simple-access": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz",
-      "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==",
+      "version": "7.20.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
+      "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.16.7"
+        "@babel/types": "^7.20.2"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-split-export-declaration": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz",
-      "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
+      "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.16.7"
+        "@babel/types": "^7.18.6"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.19.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
+      "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
-      "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==",
+      "version": "7.19.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-option": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz",
-      "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==",
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz",
+      "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helpers": {
-      "version": "7.17.2",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz",
-      "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==",
+      "version": "7.21.0",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz",
+      "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==",
       "dev": true,
       "dependencies": {
-        "@babel/template": "^7.16.7",
-        "@babel/traverse": "^7.17.0",
-        "@babel/types": "^7.17.0"
+        "@babel/template": "^7.20.7",
+        "@babel/traverse": "^7.21.0",
+        "@babel/types": "^7.21.0"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.16.10",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz",
-      "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.16.7",
+        "@babel/helper-validator-identifier": "^7.18.6",
         "chalk": "^2.0.0",
         "js-tokens": "^4.0.0"
       },
@@ -281,10 +299,81 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/highlight/node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@babel/highlight/node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "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/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/@babel/highlight/node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true
+    },
+    "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/@babel/highlight/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@babel/highlight/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/@babel/parser": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz",
-      "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==",
+      "version": "7.21.2",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz",
+      "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==",
       "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -294,33 +383,33 @@
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
-      "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==",
+      "version": "7.20.7",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
+      "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
       "dev": true,
       "dependencies": {
-        "@babel/code-frame": "^7.16.7",
-        "@babel/parser": "^7.16.7",
-        "@babel/types": "^7.16.7"
+        "@babel/code-frame": "^7.18.6",
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz",
-      "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==",
-      "dev": true,
-      "dependencies": {
-        "@babel/code-frame": "^7.16.7",
-        "@babel/generator": "^7.17.0",
-        "@babel/helper-environment-visitor": "^7.16.7",
-        "@babel/helper-function-name": "^7.16.7",
-        "@babel/helper-hoist-variables": "^7.16.7",
-        "@babel/helper-split-export-declaration": "^7.16.7",
-        "@babel/parser": "^7.17.0",
-        "@babel/types": "^7.17.0",
+      "version": "7.21.2",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz",
+      "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.18.6",
+        "@babel/generator": "^7.21.1",
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-function-name": "^7.21.0",
+        "@babel/helper-hoist-variables": "^7.18.6",
+        "@babel/helper-split-export-declaration": "^7.18.6",
+        "@babel/parser": "^7.21.2",
+        "@babel/types": "^7.21.2",
         "debug": "^4.1.0",
         "globals": "^11.1.0"
       },
@@ -328,13 +417,23 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/traverse/node_modules/globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/@babel/types": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz",
-      "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==",
+      "version": "7.21.2",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz",
+      "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.16.7",
+        "@babel/helper-string-parser": "^7.19.4",
+        "@babel/helper-validator-identifier": "^7.19.1",
         "to-fast-properties": "^2.0.0"
       },
       "engines": {
@@ -359,10 +458,20 @@
         "node": ">=12"
       }
     },
+    "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.9",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+      "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.0.3",
+        "@jridgewell/sourcemap-codec": "^1.4.10"
+      }
+    },
     "node_modules/@eslint/eslintrc": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
-      "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz",
+      "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==",
       "dev": true,
       "peer": true,
       "dependencies": {
@@ -383,13 +492,6 @@
         "url": "https://opencollective.com/eslint"
       }
     },
-    "node_modules/@eslint/eslintrc/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,
-      "peer": true
-    },
     "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -401,35 +503,6 @@
         "concat-map": "0.0.1"
       }
     },
-    "node_modules/@eslint/eslintrc/node_modules/globals": {
-      "version": "13.19.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
-      "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "type-fest": "^0.20.2"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "argparse": "^2.0.1"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
     "node_modules/@eslint/eslintrc/node_modules/minimatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -443,17 +516,14 @@
         "node": "*"
       }
     },
-    "node_modules/@eslint/eslintrc/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==",
+    "node_modules/@eslint/js": {
+      "version": "8.35.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz",
+      "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==",
       "dev": true,
       "peer": true,
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       }
     },
     "node_modules/@humanwhocodes/config-array": {
@@ -532,46 +602,151 @@
         "node": ">=8"
       }
     },
-    "node_modules/@istanbuljs/schema": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
-      "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+    "node_modules/@istanbuljs/load-nyc-config/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,
-      "engines": {
-        "node": ">=8"
+      "dependencies": {
+        "sprintf-js": "~1.0.2"
       }
     },
-    "node_modules/@jridgewell/resolve-uri": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
-      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
       "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
       "engines": {
-        "node": ">=6.0.0"
+        "node": ">=8"
       }
     },
-    "node_modules/@jridgewell/sourcemap-codec": {
-      "version": "1.4.14",
-      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
-      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
-      "dev": true
-    },
-    "node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.9",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
-      "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+    "node_modules/@istanbuljs/load-nyc-config/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": {
-        "@jridgewell/resolve-uri": "^3.0.3",
-        "@jridgewell/sourcemap-codec": "^1.4.10"
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
       }
     },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
       "dev": true,
-      "peer": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@istanbuljs/schema": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+      "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+      "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/set-array": "^1.0.0",
+        "@jridgewell/sourcemap-codec": "^1.4.10"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/set-array": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.4.14",
+      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+      "dev": true
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.17",
+      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+      "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/resolve-uri": "3.1.0",
+        "@jridgewell/sourcemap-codec": "1.4.14"
+      }
+    },
+    "node_modules/@nodelib/fs.scandir": {
+      "version": "2.1.5",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+      "dev": true,
+      "peer": true,
       "dependencies": {
         "@nodelib/fs.stat": "2.0.5",
         "run-parallel": "^1.1.9"
@@ -634,34 +809,25 @@
       "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
       "dev": true
     },
-    "node_modules/@types/mkdirp": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.2.tgz",
-      "integrity": "sha512-o0K1tSO0Dx5X6xlU5F1D6625FawhC3dU3iqr25lluNv/+/QIVH8RLNEiVokgIZo+mz+87w/3Mkg/VvQS+J51fQ==",
-      "dev": true,
-      "dependencies": {
-        "@types/node": "*"
-      }
-    },
     "node_modules/@types/node": {
-      "version": "18.11.18",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
-      "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==",
+      "version": "18.14.2",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz",
+      "integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==",
       "dev": true
     },
     "node_modules/@types/tap": {
-      "version": "15.0.7",
-      "resolved": "https://registry.npmjs.org/@types/tap/-/tap-15.0.7.tgz",
-      "integrity": "sha512-TTMajw4gxQfFgYbhXhy/Tb2OiNcwS+4oP/9yp1/GdU0pFJo3wtnkYhRgmQy39ksh+rnoa0VrPHJ4Tuv2cLNQ5A==",
+      "version": "15.0.8",
+      "resolved": "https://registry.npmjs.org/@types/tap/-/tap-15.0.8.tgz",
+      "integrity": "sha512-ZfeoiZlLIaFi4t6wccwbTEicrHREkP0bOq8dZVi/nWvG5F8O7LlS2cSUZBiOW/D4cgWS/p2uhM3lJoyzFAl80w==",
       "dev": true,
       "dependencies": {
         "@types/node": "*"
       }
     },
     "node_modules/acorn": {
-      "version": "8.8.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
-      "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+      "version": "8.8.2",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+      "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
       "dev": true,
       "bin": {
         "acorn": "bin/acorn"
@@ -728,22 +894,31 @@
         "node": ">=8"
       }
     },
+    "node_modules/ansi-sequence-parser": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz",
+      "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==",
+      "dev": true
+    },
     "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==",
+      "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": "^1.9.0"
+        "color-convert": "^2.0.1"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
     "node_modules/anymatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
       "dev": true,
       "dependencies": {
         "normalize-path": "^3.0.0",
@@ -768,7 +943,7 @@
     "node_modules/archy": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
-      "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+      "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
       "dev": true
     },
     "node_modules/arg": {
@@ -778,35 +953,11 @@
       "dev": true
     },
     "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/asn1": {
-      "version": "0.2.6",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
-      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "node_modules/assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "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,
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": ">=0.8"
-      }
+      "peer": true
     },
     "node_modules/async-hook-domain": {
       "version": "2.0.4",
@@ -817,49 +968,11 @@
         "node": ">=10"
       }
     },
-    "node_modules/asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "node_modules/aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/aws4": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
-      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
     },
-    "node_modules/bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
     "node_modules/binary-extensions": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -899,26 +1012,31 @@
       }
     },
     "node_modules/browserslist": {
-      "version": "4.19.1",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz",
-      "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==",
+      "version": "4.21.5",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
+      "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
       "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        }
+      ],
       "dependencies": {
-        "caniuse-lite": "^1.0.30001286",
-        "electron-to-chromium": "^1.4.17",
-        "escalade": "^3.1.1",
-        "node-releases": "^2.0.1",
-        "picocolors": "^1.0.0"
+        "caniuse-lite": "^1.0.30001449",
+        "electron-to-chromium": "^1.4.284",
+        "node-releases": "^2.0.8",
+        "update-browserslist-db": "^1.0.10"
       },
       "bin": {
         "browserslist": "cli.js"
       },
       "engines": {
         "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/browserslist"
       }
     },
     "node_modules/buffer-from": {
@@ -928,9 +1046,9 @@
       "dev": true
     },
     "node_modules/c8": {
-      "version": "7.12.0",
-      "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz",
-      "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==",
+      "version": "7.13.0",
+      "resolved": "https://registry.npmjs.org/c8/-/c8-7.13.0.tgz",
+      "integrity": "sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==",
       "dev": true,
       "dependencies": {
         "@bcoe/v8-coverage": "^0.2.3",
@@ -953,182 +1071,86 @@
         "node": ">=10.12.0"
       }
     },
-    "node_modules/c8/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==",
+    "node_modules/c8/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": {
-        "locate-path": "^6.0.0",
-        "path-exists": "^4.0.0"
+        "glob": "^7.1.3"
       },
-      "engines": {
-        "node": ">=10"
+      "bin": {
+        "rimraf": "bin.js"
       },
       "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/c8/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==",
+    "node_modules/caching-transform": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
+      "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
       "dev": true,
       "dependencies": {
-        "p-locate": "^5.0.0"
+        "hasha": "^5.0.0",
+        "make-dir": "^3.0.0",
+        "package-hash": "^4.0.0",
+        "write-file-atomic": "^3.0.0"
       },
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=8"
       }
     },
-    "node_modules/c8/node_modules/p-limit": {
+    "node_modules/callsites": {
       "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
-      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
       "dev": true,
-      "dependencies": {
-        "yocto-queue": "^0.1.0"
-      },
+      "peer": true,
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=6"
       }
     },
-    "node_modules/c8/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==",
+    "node_modules/camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
       "dev": true,
-      "dependencies": {
-        "p-limit": "^3.0.2"
-      },
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=6"
       }
     },
-    "node_modules/c8/node_modules/rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001458",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz",
+      "integrity": "sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w==",
       "dev": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/c8/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"
-      }
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        }
+      ]
     },
-    "node_modules/c8/node_modules/yargs": {
-      "version": "16.2.0",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+    "node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
       "dev": true,
+      "peer": 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"
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
       },
       "engines": {
         "node": ">=10"
-      }
-    },
-    "node_modules/c8/node_modules/yargs-parser": {
-      "version": "20.2.9",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
-      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/caching-transform": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
-      "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
-      "dev": true,
-      "dependencies": {
-        "hasha": "^5.0.0",
-        "make-dir": "^3.0.0",
-        "package-hash": "^4.0.0",
-        "write-file-atomic": "^3.0.0"
       },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "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,
-      "peer": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/camelcase": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
-      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/caniuse-lite": {
-      "version": "1.0.30001311",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001311.tgz",
-      "integrity": "sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==",
-      "dev": true,
       "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/browserslist"
-      }
-    },
-    "node_modules/caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "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"
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
     "node_modules/chokidar": {
@@ -1158,6 +1180,18 @@
         "fsevents": "~2.3.2"
       }
     },
+    "node_modules/chokidar/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/clean-stack": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@@ -1179,18 +1213,21 @@
       }
     },
     "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==",
+      "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.3"
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
       }
     },
     "node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "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/color-support": {
@@ -1202,69 +1239,23 @@
         "color-support": "bin.js"
       }
     },
-    "node_modules/combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "delayed-stream": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/commondir": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
-      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
       "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=",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
       "dev": true
     },
     "node_modules/convert-source-map": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
-      "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
-      "dev": true,
-      "dependencies": {
-        "safe-buffer": "~5.1.1"
-      }
-    },
-    "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,
-      "optional": true,
-      "peer": true
-    },
-    "node_modules/coveralls": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz",
-      "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "js-yaml": "^3.13.1",
-        "lcov-parse": "^1.0.0",
-        "log-driver": "^1.2.7",
-        "minimist": "^1.2.5",
-        "request": "^2.88.2"
-      },
-      "bin": {
-        "coveralls": "bin/coveralls.js"
-      },
-      "engines": {
-        "node": ">=6"
-      }
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+      "dev": true
     },
     "node_modules/create-require": {
       "version": "1.1.1",
@@ -1286,24 +1277,10 @@
         "node": ">= 8"
       }
     },
-    "node_modules/dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
     "node_modules/debug": {
-      "version": "4.3.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
-      "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
       "dev": true,
       "dependencies": {
         "ms": "2.1.2"
@@ -1320,7 +1297,7 @@
     "node_modules/decamelize": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -1334,26 +1311,18 @@
       "peer": true
     },
     "node_modules/default-require-extensions": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz",
-      "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==",
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz",
+      "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==",
       "dev": true,
       "dependencies": {
         "strip-bom": "^4.0.0"
       },
       "engines": {
         "node": ">=8"
-      }
-    },
-    "node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": ">=0.4.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/diff": {
@@ -1378,22 +1347,10 @@
         "node": ">=6.0.0"
       }
     },
-    "node_modules/ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.68",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz",
-      "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==",
+      "version": "1.4.311",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.311.tgz",
+      "integrity": "sha512-RoDlZufvrtr2Nx3Yx5MB8jX3aHIxm8nRWPJm3yVvyHmyKaRvn90RjzB6hNnt0AkhS3IInJdyRfQb4mWhPvUjVw==",
       "dev": true
     },
     "node_modules/emoji-regex": {
@@ -1418,22 +1375,27 @@
       }
     },
     "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=",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
       "dev": true,
+      "peer": true,
       "engines": {
-        "node": ">=0.8.0"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/eslint": {
-      "version": "8.31.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz",
-      "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==",
+      "version": "8.35.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.35.0.tgz",
+      "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==",
       "dev": true,
       "peer": true,
       "dependencies": {
-        "@eslint/eslintrc": "^1.4.1",
+        "@eslint/eslintrc": "^2.0.0",
+        "@eslint/js": "8.35.0",
         "@humanwhocodes/config-array": "^0.11.8",
         "@humanwhocodes/module-importer": "^1.0.1",
         "@nodelib/fs.walk": "^1.2.8",
@@ -1447,7 +1409,7 @@
         "eslint-utils": "^3.0.0",
         "eslint-visitor-keys": "^3.3.0",
         "espree": "^9.4.0",
-        "esquery": "^1.4.0",
+        "esquery": "^1.4.2",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
         "file-entry-cache": "^6.0.1",
@@ -1548,29 +1510,6 @@
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       }
     },
-    "node_modules/eslint/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,
-      "peer": true,
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/eslint/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,
-      "peer": true
-    },
     "node_modules/eslint/node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1582,228 +1521,35 @@
         "concat-map": "0.0.1"
       }
     },
-    "node_modules/eslint/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+    "node_modules/eslint/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "dev": true,
       "peer": true,
       "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
+        "brace-expansion": "^1.1.7"
       },
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
+        "node": "*"
       }
     },
-    "node_modules/eslint/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==",
+    "node_modules/espree": {
+      "version": "9.4.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
+      "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
       "dev": true,
       "peer": true,
       "dependencies": {
-        "color-name": "~1.1.4"
+        "acorn": "^8.8.0",
+        "acorn-jsx": "^5.3.2",
+        "eslint-visitor-keys": "^3.3.0"
       },
       "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/eslint/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,
-      "peer": true
-    },
-    "node_modules/eslint/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,
-      "peer": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint/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,
-      "peer": true,
-      "dependencies": {
-        "locate-path": "^6.0.0",
-        "path-exists": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint/node_modules/glob-parent": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "is-glob": "^4.0.3"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      }
-    },
-    "node_modules/eslint/node_modules/globals": {
-      "version": "13.19.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
-      "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "type-fest": "^0.20.2"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint/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,
-      "peer": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/eslint/node_modules/js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "argparse": "^2.0.1"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/eslint/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,
-      "peer": true,
-      "dependencies": {
-        "p-locate": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/eslint/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,
-      "peer": true,
-      "dependencies": {
-        "yocto-queue": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint/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,
-      "peer": true,
-      "dependencies": {
-        "p-limit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint/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,
-      "peer": true,
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/eslint/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,
-      "peer": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/espree": {
-      "version": "9.4.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
-      "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "acorn": "^8.8.0",
-        "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^3.3.0"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/esprima": {
@@ -1820,9 +1566,9 @@
       }
     },
     "node_modules/esquery": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
-      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz",
+      "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==",
       "dev": true,
       "peer": true,
       "dependencies": {
@@ -1868,28 +1614,9 @@
     "node_modules/events-to-array": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz",
-      "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=",
+      "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==",
       "dev": true
     },
-    "node_modules/extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "node_modules/extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "optional": true,
-      "peer": true
-    },
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -1964,22 +1691,25 @@
       }
     },
     "node_modules/find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "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": "^5.0.0",
+        "locate-path": "^6.0.0",
         "path-exists": "^4.0.0"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/findit": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz",
-      "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=",
+      "integrity": "sha512-ENZS237/Hr8bjczn5eKuBohLgaD0JyUd0arxretR1f9RO46vZHA1b2y0VorgGV3WaOT3c+78P8h7v4JGJ1i/rg==",
       "dev": true
     },
     "node_modules/flat-cache": {
@@ -2032,33 +1762,6 @@
         "node": ">=8.0.0"
       }
     },
-    "node_modules/forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/form-data": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
-      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 0.12"
-      }
-    },
     "node_modules/fromentries": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
@@ -2082,13 +1785,13 @@
     "node_modules/fs-exists-cached": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz",
-      "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=",
+      "integrity": "sha512-kSxoARUDn4F2RPXX48UXnaFKwVU7Ivd/6qpzZL29MCDmr9sTvybv4gFCp+qaI4fM9m0z9fgz/yJvi56GAz+BZg==",
       "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="
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
     },
     "node_modules/fsevents": {
       "version": "2.3.2",
@@ -2137,17 +1840,6 @@
         "node": ">=8.0.0"
       }
     },
-    "node_modules/getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      }
-    },
     "node_modules/glob": {
       "version": "7.2.3",
       "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -2169,15 +1861,16 @@
       }
     },
     "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==",
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
       "dev": true,
+      "peer": true,
       "dependencies": {
-        "is-glob": "^4.0.1"
+        "is-glob": "^4.0.3"
       },
       "engines": {
-        "node": ">= 6"
+        "node": ">=10.13.0"
       }
     },
     "node_modules/glob/node_modules/brace-expansion": {
@@ -2203,18 +1896,25 @@
       }
     },
     "node_modules/globals": {
-      "version": "11.12.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
-      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "version": "13.20.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+      "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
       "dev": true,
+      "peer": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/graceful-fs": {
-      "version": "4.2.9",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
-      "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
+      "version": "4.2.10",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
     "node_modules/grapheme-splitter": {
@@ -2224,40 +1924,13 @@
       "dev": true,
       "peer": true
     },
-    "node_modules/har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+    "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,
-      "optional": true,
-      "peer": true,
       "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/har-validator": {
-      "version": "5.1.5",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
-      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
-      "deprecated": "this library is no longer supported",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "ajv": "^6.12.3",
-        "har-schema": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "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": ">=8"
       }
     },
     "node_modules/hasha": {
@@ -2276,29 +1949,21 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/hasha/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/html-escaper": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
       "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
       "dev": true
     },
-    "node_modules/http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^1.2.2",
-        "sshpk": "^1.7.0"
-      },
-      "engines": {
-        "node": ">=0.8",
-        "npm": ">=1.3.7"
-      }
-    },
     "node_modules/ignore": {
       "version": "5.2.4",
       "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@@ -2326,20 +1991,10 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/import-fresh/node_modules/resolve-from": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/imurmurhash": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
       "dev": true,
       "engines": {
         "node": ">=0.8.19"
@@ -2357,7 +2012,7 @@
     "node_modules/inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
       "dev": true,
       "dependencies": {
         "once": "^1.3.0",
@@ -2385,7 +2040,7 @@
     "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=",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -2446,7 +2101,7 @@
     "node_modules/is-typedarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
       "dev": true
     },
     "node_modules/is-windows": {
@@ -2461,17 +2116,9 @@
     "node_modules/isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
     },
-    "node_modules/isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "node_modules/istanbul-lib-coverage": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
@@ -2540,15 +2187,6 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/istanbul-lib-processinfo/node_modules/uuid": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
-      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
-      "dev": true,
-      "bin": {
-        "uuid": "dist/bin/uuid"
-      }
-    },
     "node_modules/istanbul-lib-report": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
@@ -2563,27 +2201,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/istanbul-lib-report/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/istanbul-lib-report/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/istanbul-lib-source-maps": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
@@ -2598,19 +2215,10 @@
         "node": ">=10"
       }
     },
-    "node_modules/istanbul-lib-source-maps/node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/istanbul-reports": {
-      "version": "3.1.4",
-      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz",
-      "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==",
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+      "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
       "dev": true,
       "dependencies": {
         "html-escaper": "^2.0.0",
@@ -2633,9 +2241,9 @@
       }
     },
     "node_modules/js-sdsl": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz",
-      "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz",
+      "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==",
       "dev": true,
       "peer": true,
       "funding": {
@@ -2650,26 +2258,18 @@
       "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==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
       "dev": true,
+      "peer": true,
       "dependencies": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
+        "argparse": "^2.0.1"
       },
       "bin": {
         "js-yaml": "bin/js-yaml.js"
       }
     },
-    "node_modules/jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "node_modules/jsesc": {
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -2682,14 +2282,6 @@
         "node": ">=4"
       }
     },
-    "node_modules/json-schema": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
-      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "node_modules/json-schema-traverse": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -2704,14 +2296,6 @@
       "dev": true,
       "peer": true
     },
-    "node_modules/json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "node_modules/json5": {
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -2730,34 +2314,6 @@
       "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
       "dev": true
     },
-    "node_modules/jsprim": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
-      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.4.0",
-        "verror": "1.10.0"
-      },
-      "engines": {
-        "node": ">=0.6.0"
-      }
-    },
-    "node_modules/lcov-parse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz",
-      "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "bin": {
-        "lcov-parse": "bin/cli.js"
-      }
-    },
     "node_modules/levn": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -2811,22 +2367,31 @@
         "node": ">=8"
       }
     },
+    "node_modules/libtap/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
     "node_modules/locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "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": "^4.1.0"
+        "p-locate": "^5.0.0"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/lodash.flattendeep": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
-      "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
+      "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==",
       "dev": true
     },
     "node_modules/lodash.merge": {
@@ -2836,21 +2401,10 @@
       "dev": true,
       "peer": true
     },
-    "node_modules/log-driver": {
-      "version": "1.2.7",
-      "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz",
-      "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": ">=0.8.6"
-      }
-    },
     "node_modules/lru-cache": {
-      "version": "7.14.1",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz",
-      "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==",
+      "version": "7.17.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.17.0.tgz",
+      "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==",
       "engines": {
         "node": ">=12"
       }
@@ -2894,31 +2448,6 @@
         "node": ">= 12"
       }
     },
-    "node_modules/mime-db": {
-      "version": "1.51.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
-      "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.34",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
-      "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "mime-db": "1.51.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
     "node_modules/minimatch": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.2.0.tgz",
@@ -2933,14 +2462,6 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/minimist": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
-      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "node_modules/minipass": {
       "version": "4.2.4",
       "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.4.tgz",
@@ -2950,12 +2471,12 @@
       }
     },
     "node_modules/mkdirp": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.0.0.tgz",
-      "integrity": "sha512-M9ecBPkCu6jZ+H19zruhjw/JB97qqVhyi1H2Lxxo2XAoIMdpHKQ8MfQiMzXk9SH/oJXIbM3oSAfLB8qSWJdCLA==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.3.tgz",
+      "integrity": "sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw==",
       "dev": true,
       "bin": {
-        "mkdirp": "dist/cjs/bin.js"
+        "mkdirp": "dist/cjs/src/bin.js"
       },
       "engines": {
         "node": ">=10"
@@ -2990,9 +2511,9 @@
       }
     },
     "node_modules/node-releases": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz",
-      "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==",
+      "version": "2.0.10",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
+      "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
       "dev": true
     },
     "node_modules/normalize-path": {
@@ -3045,84 +2566,43 @@
         "node": ">=8.9"
       }
     },
-    "node_modules/nyc/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/oauth-sign": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
-      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+    "node_modules/nyc/node_modules/cliui": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
       "dev": true,
       "dependencies": {
-        "wrappy": "1"
-      }
-    },
-    "node_modules/opener": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
-      "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
-      "dev": true,
-      "bin": {
-        "opener": "bin/opener-bin.js"
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^6.2.0"
       }
     },
-    "node_modules/optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+    "node_modules/nyc/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
       "dev": true,
-      "peer": 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"
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
       },
       "engines": {
-        "node": ">= 0.8.0"
+        "node": ">=8"
       }
     },
-    "node_modules/own-or": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz",
-      "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=",
-      "dev": true
-    },
-    "node_modules/own-or-env": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.2.tgz",
-      "integrity": "sha512-NQ7v0fliWtK7Lkb+WdFqe6ky9XAzYmlkXthQrBbzlYbmFKoAYbDDcwmOm6q8kOuwSRXW8bdL5ORksploUJmWgw==",
+    "node_modules/nyc/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
       "dev": true,
       "dependencies": {
-        "own-or": "^1.0.0"
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "node_modules/p-limit": {
+    "node_modules/nyc/node_modules/p-limit": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
       "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
@@ -3137,7 +2617,7 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/p-locate": {
+    "node_modules/nyc/node_modules/p-locate": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
       "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
@@ -3149,13 +2629,173 @@
         "node": ">=8"
       }
     },
-    "node_modules/p-map": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
-      "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+    "node_modules/nyc/node_modules/resolve-from": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
       "dev": true,
-      "dependencies": {
-        "aggregate-error": "^3.0.0"
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nyc/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/nyc/node_modules/wrap-ansi": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nyc/node_modules/y18n": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
+      "dev": true
+    },
+    "node_modules/nyc/node_modules/yargs": {
+      "version": "15.4.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^6.0.0",
+        "decamelize": "^1.2.0",
+        "find-up": "^4.1.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^4.2.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^18.1.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nyc/node_modules/yargs-parser": {
+      "version": "18.1.3",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+      "dev": true,
+      "dependencies": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "dev": true,
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/opener": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
+      "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
+      "dev": true,
+      "bin": {
+        "opener": "bin/opener-bin.js"
+      }
+    },
+    "node_modules/optionator": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+      "dev": true,
+      "peer": 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/own-or": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz",
+      "integrity": "sha512-NfZr5+Tdf6MB8UI9GLvKRs4cXY8/yB0w3xtt84xFdWy8hkGjn+JFc60VhzS/hFRfbyxFcGYMTjnF4Me+RbbqrA==",
+      "dev": true
+    },
+    "node_modules/own-or-env": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.2.tgz",
+      "integrity": "sha512-NQ7v0fliWtK7Lkb+WdFqe6ky9XAzYmlkXthQrBbzlYbmFKoAYbDDcwmOm6q8kOuwSRXW8bdL5ORksploUJmWgw==",
+      "dev": true,
+      "dependencies": {
+        "own-or": "^1.0.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/p-map": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
+      "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+      "dev": true,
+      "dependencies": {
+        "aggregate-error": "^3.0.0"
       },
       "engines": {
         "node": ">=8"
@@ -3210,7 +2850,7 @@
     "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=",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -3240,14 +2880,6 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "node_modules/picocolors": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
@@ -3278,6 +2910,58 @@
         "node": ">=8"
       }
     },
+    "node_modules/pkg-dir/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/prelude-ls": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -3289,9 +2973,9 @@
       }
     },
     "node_modules/prettier": {
-      "version": "2.8.3",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz",
-      "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==",
+      "version": "2.8.4",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz",
+      "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==",
       "dev": true,
       "bin": {
         "prettier": "bin-prettier.js"
@@ -3315,34 +2999,15 @@
         "node": ">=8"
       }
     },
-    "node_modules/psl": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
-      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "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==",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
       "dev": true,
       "engines": {
         "node": ">=6"
       }
     },
-    "node_modules/qs": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
-      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "engines": {
-        "node": ">=0.6"
-      }
-    },
     "node_modules/queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -3392,7 +3057,7 @@
     "node_modules/release-zalgo": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
-      "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
+      "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==",
       "dev": true,
       "dependencies": {
         "es6-error": "^4.0.1"
@@ -3401,44 +3066,10 @@
         "node": ">=4"
       }
     },
-    "node_modules/request": {
-      "version": "2.88.2",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
-      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
-      "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "aws-sign2": "~0.7.0",
-        "aws4": "^1.8.0",
-        "caseless": "~0.12.0",
-        "combined-stream": "~1.0.6",
-        "extend": "~3.0.2",
-        "forever-agent": "~0.6.1",
-        "form-data": "~2.3.2",
-        "har-validator": "~5.1.3",
-        "http-signature": "~1.2.0",
-        "is-typedarray": "~1.0.0",
-        "isstream": "~0.1.2",
-        "json-stringify-safe": "~5.0.1",
-        "mime-types": "~2.1.19",
-        "oauth-sign": "~0.9.0",
-        "performance-now": "^2.1.0",
-        "qs": "~6.5.2",
-        "safe-buffer": "^5.1.2",
-        "tough-cookie": "~2.5.0",
-        "tunnel-agent": "^0.6.0",
-        "uuid": "^3.3.2"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
     "node_modules/require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -3451,12 +3082,13 @@
       "dev": true
     },
     "node_modules/resolve-from": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
-      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+      "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,
+      "peer": true,
       "engines": {
-        "node": ">=8"
+        "node": ">=4"
       }
     },
     "node_modules/reusify": {
@@ -3471,9 +3103,9 @@
       }
     },
     "node_modules/rimraf": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.1.tgz",
-      "integrity": "sha512-Z4Y81w8atcvaJuJuBB88VpADRH66okZAuEm+Jtaufa+s7rZmIz+Hik2G53kGaNytE7lsfXyWktTmfVz0H9xuDg==",
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.2.tgz",
+      "integrity": "sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==",
       "dev": true,
       "bin": {
         "rimraf": "dist/cjs/src/bin.js"
@@ -3509,20 +3141,6 @@
         "queue-microtask": "^1.2.2"
       }
     },
-    "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/safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "node_modules/semver": {
       "version": "6.3.0",
       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@@ -3535,7 +3153,7 @@
     "node_modules/set-blocking": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
       "dev": true
     },
     "node_modules/shebang-command": {
@@ -3560,11 +3178,12 @@
       }
     },
     "node_modules/shiki": {
-      "version": "0.12.1",
-      "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.12.1.tgz",
-      "integrity": "sha512-aieaV1m349rZINEBkjxh2QbBvFFQOlgqYTNtCal82hHj4dDZ76oMlQIX+C7ryerBTDiga3e5NfH6smjdJ02BbQ==",
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.1.tgz",
+      "integrity": "sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==",
       "dev": true,
       "dependencies": {
+        "ansi-sequence-parser": "^1.1.0",
         "jsonc-parser": "^3.2.0",
         "vscode-oniguruma": "^1.7.0",
         "vscode-textmate": "^8.0.0"
@@ -3577,9 +3196,9 @@
       "dev": true
     },
     "node_modules/source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -3595,15 +3214,6 @@
         "source-map": "^0.6.0"
       }
     },
-    "node_modules/source-map-support/node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/spawn-wrap": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
@@ -3639,40 +3249,13 @@
     "node_modules/sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
       "dev": true
     },
-    "node_modules/sshpk": {
-      "version": "1.17.0",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
-      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "asn1": "~0.2.3",
-        "assert-plus": "^1.0.0",
-        "bcrypt-pbkdf": "^1.0.0",
-        "dashdash": "^1.12.0",
-        "ecc-jsbn": "~0.1.1",
-        "getpass": "^0.1.1",
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.0.2",
-        "tweetnacl": "~0.14.0"
-      },
-      "bin": {
-        "sshpk-conv": "bin/sshpk-conv",
-        "sshpk-sign": "bin/sshpk-sign",
-        "sshpk-verify": "bin/sshpk-verify"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/stack-utils": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz",
-      "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+      "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
       "dev": true,
       "dependencies": {
         "escape-string-regexp": "^2.0.0"
@@ -3739,15 +3322,15 @@
       }
     },
     "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==",
+      "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": "^3.0.0"
+        "has-flag": "^4.0.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/tap": {
@@ -3880,6 +3463,12 @@
         "node": ">=8"
       }
     },
+    "node_modules/tap-parser/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
     "node_modules/tap-yaml": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.2.tgz",
@@ -5826,7 +5415,7 @@
     "node_modules/to-fast-properties": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
-      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -5844,25 +5433,10 @@
         "node": ">=8.0"
       }
     },
-    "node_modules/tough-cookie": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
-      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "psl": "^1.1.28",
-        "punycode": "^2.1.1"
-      },
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
     "node_modules/trivial-deferred": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.0.1.tgz",
-      "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=",
+      "integrity": "sha512-dagAKX7vaesNNAwOc9Np9C2mJ+7YopF4lk+jE2JML9ta4kZ91Y6UruJNH65bLRYoUROD8EY+Pmi44qQWwXR7sw==",
       "dev": true
     },
     "node_modules/ts-node": {
@@ -5908,28 +5482,6 @@
         }
       }
     },
-    "node_modules/tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "safe-buffer": "^5.0.1"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "node_modules/type-check": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -5944,12 +5496,16 @@
       }
     },
     "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==",
+      "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,
+      "peer": true,
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/typedarray-to-buffer": {
@@ -5962,15 +5518,15 @@
       }
     },
     "node_modules/typedoc": {
-      "version": "0.23.24",
-      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.24.tgz",
-      "integrity": "sha512-bfmy8lNQh+WrPYcJbtjQ6JEEsVl/ce1ZIXyXhyW+a1vFrjO39t6J8sL/d6FfAGrJTc7McCXgk9AanYBSNvLdIA==",
+      "version": "0.23.26",
+      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.26.tgz",
+      "integrity": "sha512-5m4KwR5tOLnk0OtMaRn9IdbeRM32uPemN9kur7YK9wFqx8U0CYrvO9aVq6ysdZSV1c824BTm+BuQl2Ze/k1HtA==",
       "dev": true,
       "dependencies": {
         "lunr": "^2.3.9",
-        "marked": "^4.2.5",
-        "minimatch": "^5.1.2",
-        "shiki": "^0.12.1"
+        "marked": "^4.2.12",
+        "minimatch": "^7.1.3",
+        "shiki": "^0.14.1"
       },
       "bin": {
         "typedoc": "bin/typedoc"
@@ -5982,22 +5538,10 @@
         "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x"
       }
     },
-    "node_modules/typedoc/node_modules/minimatch": {
-      "version": "5.1.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.4.tgz",
-      "integrity": "sha512-U0iNYXt9wALljzfnGkhFSy5sAC6/SCR3JrHrlsdJz4kF8MvhTRQNiC59iUi1iqsitV7abrNAJWElVL9pdnoUgw==",
-      "dev": true,
-      "dependencies": {
-        "brace-expansion": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
     "node_modules/typescript": {
-      "version": "4.9.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
-      "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
+      "version": "4.9.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -6008,34 +5552,38 @@
       }
     },
     "node_modules/unicode-length": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz",
-      "integrity": "sha512-Ph/j1VbS3/r77nhoY2WU0GWGjVYOHL3xpKp0y/Eq2e5r0mT/6b649vm7KFO6RdAdrZkYLdxphYVgvODxPB+Ebg==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.1.0.tgz",
+      "integrity": "sha512-4bV582zTV9Q02RXBxSUMiuN/KHo5w4aTojuKTNT96DIKps/SIawFp7cS5Mu25VuY1AioGXrmYyzKZUzh8OqoUw==",
       "dev": true,
       "dependencies": {
-        "punycode": "^2.0.0",
-        "strip-ansi": "^3.0.1"
-      }
-    },
-    "node_modules/unicode-length/node_modules/ansi-regex": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
+        "punycode": "^2.0.0"
       }
     },
-    "node_modules/unicode-length/node_modules/strip-ansi": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+    "node_modules/update-browserslist-db": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
+      "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
       "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        }
+      ],
       "dependencies": {
-        "ansi-regex": "^2.0.0"
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
       },
-      "engines": {
-        "node": ">=0.10.0"
+      "bin": {
+        "browserslist-lint": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
       }
     },
     "node_modules/uri-js": {
@@ -6049,15 +5597,12 @@
       }
     },
     "node_modules/uuid": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
-      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
+      "version": "8.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
       "dev": true,
-      "optional": true,
-      "peer": true,
       "bin": {
-        "uuid": "bin/uuid"
+        "uuid": "dist/bin/uuid"
       }
     },
     "node_modules/v8-compile-cache-lib": {
@@ -6067,9 +5612,9 @@
       "dev": true
     },
     "node_modules/v8-to-istanbul": {
-      "version": "9.0.1",
-      "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
-      "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz",
+      "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==",
       "dev": true,
       "dependencies": {
         "@jridgewell/trace-mapping": "^0.3.12",
@@ -6080,32 +5625,6 @@
         "node": ">=10.12.0"
       }
     },
-    "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": {
-      "version": "0.3.17",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
-      "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
-      "dev": true,
-      "dependencies": {
-        "@jridgewell/resolve-uri": "3.1.0",
-        "@jridgewell/sourcemap-codec": "1.4.14"
-      }
-    },
-    "node_modules/verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-      "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
-      "optional": true,
-      "peer": true,
-      "dependencies": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      }
-    },
     "node_modules/vscode-oniguruma": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
@@ -6136,7 +5655,7 @@
     "node_modules/which-module": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
-      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+      "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
       "dev": true
     },
     "node_modules/word-wrap": {
@@ -6166,43 +5685,10 @@
         "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=",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
       "dev": true
     },
     "node_modules/write-file-atomic": {
@@ -6218,15 +5704,18 @@
       }
     },
     "node_modules/y18n": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
-      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
-      "dev": true
+      "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==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
       "dev": true
     },
     "node_modules/yaml": {
@@ -6239,4719 +5728,52 @@
       }
     },
     "node_modules/yargs": {
-      "version": "15.4.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
-      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+      "version": "16.2.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
       "dev": true,
       "dependencies": {
-        "cliui": "^6.0.0",
-        "decamelize": "^1.2.0",
-        "find-up": "^4.1.0",
-        "get-caller-file": "^2.0.1",
+        "cliui": "^7.0.2",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
-        "require-main-filename": "^2.0.0",
-        "set-blocking": "^2.0.0",
         "string-width": "^4.2.0",
-        "which-module": "^2.0.0",
-        "y18n": "^4.0.0",
-        "yargs-parser": "^18.1.2"
+        "y18n": "^5.0.5",
+        "yargs-parser": "^20.2.2"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=10"
       }
     },
     "node_modules/yargs-parser": {
-      "version": "18.1.3",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
-      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+      "version": "20.2.9",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
       "dev": true,
-      "dependencies": {
-        "camelcase": "^5.0.0",
-        "decamelize": "^1.2.0"
-      },
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
       }
     },
-    "node_modules/yargs/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==",
+    "node_modules/yn": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
       "dev": true,
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
       "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/yargs/node_modules/cliui": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
-      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
-      "dev": true,
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^6.2.0"
+        "node": ">=6"
       }
     },
-    "node_modules/yargs/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==",
+    "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,
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
       "engines": {
-        "node": ">=7.0.0"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
-    },
-    "node_modules/yargs/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/yargs/node_modules/wrap-ansi": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
-      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/yn": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
-      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "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": {
-    "@ampproject/remapping": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.1.tgz",
-      "integrity": "sha512-Aolwjd7HSC2PyY0fDj/wA/EimQT4HfEnFYNp5s9CQlrdhyvWTtvZ5YzrUPu6R6/1jKiUlxu8bUhkdSnKHNAHMA==",
-      "dev": true,
-      "requires": {
-        "@jridgewell/trace-mapping": "^0.3.0"
-      }
-    },
-    "@babel/code-frame": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz",
-      "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==",
-      "dev": true,
-      "requires": {
-        "@babel/highlight": "^7.16.7"
-      }
-    },
-    "@babel/compat-data": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz",
-      "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==",
-      "dev": true
-    },
-    "@babel/core": {
-      "version": "7.17.2",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz",
-      "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==",
-      "dev": true,
-      "requires": {
-        "@ampproject/remapping": "^2.0.0",
-        "@babel/code-frame": "^7.16.7",
-        "@babel/generator": "^7.17.0",
-        "@babel/helper-compilation-targets": "^7.16.7",
-        "@babel/helper-module-transforms": "^7.16.7",
-        "@babel/helpers": "^7.17.2",
-        "@babel/parser": "^7.17.0",
-        "@babel/template": "^7.16.7",
-        "@babel/traverse": "^7.17.0",
-        "@babel/types": "^7.17.0",
-        "convert-source-map": "^1.7.0",
-        "debug": "^4.1.0",
-        "gensync": "^1.0.0-beta.2",
-        "json5": "^2.1.2",
-        "semver": "^6.3.0"
-      }
-    },
-    "@babel/generator": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz",
-      "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.17.0",
-        "jsesc": "^2.5.1",
-        "source-map": "^0.5.0"
-      }
-    },
-    "@babel/helper-compilation-targets": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz",
-      "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==",
-      "dev": true,
-      "requires": {
-        "@babel/compat-data": "^7.16.4",
-        "@babel/helper-validator-option": "^7.16.7",
-        "browserslist": "^4.17.5",
-        "semver": "^6.3.0"
-      }
-    },
-    "@babel/helper-environment-visitor": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz",
-      "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.16.7"
-      }
-    },
-    "@babel/helper-function-name": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz",
-      "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-get-function-arity": "^7.16.7",
-        "@babel/template": "^7.16.7",
-        "@babel/types": "^7.16.7"
-      }
-    },
-    "@babel/helper-get-function-arity": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz",
-      "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.16.7"
-      }
-    },
-    "@babel/helper-hoist-variables": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz",
-      "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.16.7"
-      }
-    },
-    "@babel/helper-module-imports": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz",
-      "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.16.7"
-      }
-    },
-    "@babel/helper-module-transforms": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz",
-      "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-environment-visitor": "^7.16.7",
-        "@babel/helper-module-imports": "^7.16.7",
-        "@babel/helper-simple-access": "^7.16.7",
-        "@babel/helper-split-export-declaration": "^7.16.7",
-        "@babel/helper-validator-identifier": "^7.16.7",
-        "@babel/template": "^7.16.7",
-        "@babel/traverse": "^7.16.7",
-        "@babel/types": "^7.16.7"
-      }
-    },
-    "@babel/helper-simple-access": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz",
-      "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.16.7"
-      }
-    },
-    "@babel/helper-split-export-declaration": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz",
-      "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "^7.16.7"
-      }
-    },
-    "@babel/helper-validator-identifier": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz",
-      "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==",
-      "dev": true
-    },
-    "@babel/helper-validator-option": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz",
-      "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==",
-      "dev": true
-    },
-    "@babel/helpers": {
-      "version": "7.17.2",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz",
-      "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==",
-      "dev": true,
-      "requires": {
-        "@babel/template": "^7.16.7",
-        "@babel/traverse": "^7.17.0",
-        "@babel/types": "^7.17.0"
-      }
-    },
-    "@babel/highlight": {
-      "version": "7.16.10",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz",
-      "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-validator-identifier": "^7.16.7",
-        "chalk": "^2.0.0",
-        "js-tokens": "^4.0.0"
-      }
-    },
-    "@babel/parser": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz",
-      "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==",
-      "dev": true
-    },
-    "@babel/template": {
-      "version": "7.16.7",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz",
-      "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.16.7",
-        "@babel/parser": "^7.16.7",
-        "@babel/types": "^7.16.7"
-      }
-    },
-    "@babel/traverse": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz",
-      "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.16.7",
-        "@babel/generator": "^7.17.0",
-        "@babel/helper-environment-visitor": "^7.16.7",
-        "@babel/helper-function-name": "^7.16.7",
-        "@babel/helper-hoist-variables": "^7.16.7",
-        "@babel/helper-split-export-declaration": "^7.16.7",
-        "@babel/parser": "^7.17.0",
-        "@babel/types": "^7.17.0",
-        "debug": "^4.1.0",
-        "globals": "^11.1.0"
-      }
-    },
-    "@babel/types": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz",
-      "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-validator-identifier": "^7.16.7",
-        "to-fast-properties": "^2.0.0"
-      }
-    },
-    "@bcoe/v8-coverage": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
-      "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
-      "dev": true
-    },
-    "@cspotcode/source-map-support": {
-      "version": "0.8.1",
-      "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
-      "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
-      "dev": true,
-      "requires": {
-        "@jridgewell/trace-mapping": "0.3.9"
-      }
-    },
-    "@eslint/eslintrc": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
-      "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "ajv": "^6.12.4",
-        "debug": "^4.3.2",
-        "espree": "^9.4.0",
-        "globals": "^13.19.0",
-        "ignore": "^5.2.0",
-        "import-fresh": "^3.2.1",
-        "js-yaml": "^4.1.0",
-        "minimatch": "^3.1.2",
-        "strip-json-comments": "^3.1.1"
-      },
-      "dependencies": {
-        "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,
-          "peer": true
-        },
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "globals": {
-          "version": "13.19.0",
-          "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
-          "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "type-fest": "^0.20.2"
-          }
-        },
-        "js-yaml": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-          "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "argparse": "^2.0.1"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        },
-        "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,
-          "peer": true
-        }
-      }
-    },
-    "@humanwhocodes/config-array": {
-      "version": "0.11.8",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
-      "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "@humanwhocodes/object-schema": "^1.2.1",
-        "debug": "^4.1.1",
-        "minimatch": "^3.0.5"
-      },
-      "dependencies": {
-        "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,
-          "peer": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        }
-      }
-    },
-    "@humanwhocodes/module-importer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
-      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
-      "dev": true,
-      "peer": true
-    },
-    "@humanwhocodes/object-schema": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
-      "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
-      "dev": true,
-      "peer": true
-    },
-    "@istanbuljs/load-nyc-config": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
-      "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
-      "dev": true,
-      "requires": {
-        "camelcase": "^5.3.1",
-        "find-up": "^4.1.0",
-        "get-package-type": "^0.1.0",
-        "js-yaml": "^3.13.1",
-        "resolve-from": "^5.0.0"
-      }
-    },
-    "@istanbuljs/schema": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
-      "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
-      "dev": true
-    },
-    "@jridgewell/resolve-uri": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
-      "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
-      "dev": true
-    },
-    "@jridgewell/sourcemap-codec": {
-      "version": "1.4.14",
-      "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
-      "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
-      "dev": true
-    },
-    "@jridgewell/trace-mapping": {
-      "version": "0.3.9",
-      "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
-      "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
-      "dev": true,
-      "requires": {
-        "@jridgewell/resolve-uri": "^3.0.3",
-        "@jridgewell/sourcemap-codec": "^1.4.10"
-      }
-    },
-    "@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "@nodelib/fs.stat": "2.0.5",
-        "run-parallel": "^1.1.9"
-      }
-    },
-    "@nodelib/fs.stat": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "dev": true,
-      "peer": true
-    },
-    "@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      }
-    },
-    "@tsconfig/node10": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
-      "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
-      "dev": true
-    },
-    "@tsconfig/node12": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
-      "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
-      "dev": true
-    },
-    "@tsconfig/node14": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
-      "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
-      "dev": true
-    },
-    "@tsconfig/node16": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
-      "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
-      "dev": true
-    },
-    "@types/istanbul-lib-coverage": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
-      "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
-      "dev": true
-    },
-    "@types/mkdirp": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.2.tgz",
-      "integrity": "sha512-o0K1tSO0Dx5X6xlU5F1D6625FawhC3dU3iqr25lluNv/+/QIVH8RLNEiVokgIZo+mz+87w/3Mkg/VvQS+J51fQ==",
-      "dev": true,
-      "requires": {
-        "@types/node": "*"
-      }
-    },
-    "@types/node": {
-      "version": "18.11.18",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
-      "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==",
-      "dev": true
-    },
-    "@types/tap": {
-      "version": "15.0.7",
-      "resolved": "https://registry.npmjs.org/@types/tap/-/tap-15.0.7.tgz",
-      "integrity": "sha512-TTMajw4gxQfFgYbhXhy/Tb2OiNcwS+4oP/9yp1/GdU0pFJo3wtnkYhRgmQy39ksh+rnoa0VrPHJ4Tuv2cLNQ5A==",
-      "dev": true,
-      "requires": {
-        "@types/node": "*"
-      }
-    },
-    "acorn": {
-      "version": "8.8.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
-      "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
-      "dev": true
-    },
-    "acorn-jsx": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
-      "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-      "dev": true,
-      "peer": true,
-      "requires": {}
-    },
-    "acorn-walk": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
-      "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
-      "dev": true
-    },
-    "aggregate-error": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
-      "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
-      "dev": true,
-      "requires": {
-        "clean-stack": "^2.0.0",
-        "indent-string": "^4.0.0"
-      }
-    },
-    "ajv": {
-      "version": "6.12.6",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
-      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "fast-deep-equal": "^3.1.1",
-        "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.4.1",
-        "uri-js": "^4.2.2"
-      }
-    },
-    "ansi-regex": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true
-    },
-    "ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "dev": true,
-      "requires": {
-        "color-convert": "^1.9.0"
-      }
-    },
-    "anymatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
-      "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
-      "dev": true,
-      "requires": {
-        "normalize-path": "^3.0.0",
-        "picomatch": "^2.0.4"
-      }
-    },
-    "append-transform": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
-      "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
-      "dev": true,
-      "requires": {
-        "default-require-extensions": "^3.0.0"
-      }
-    },
-    "archy": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
-      "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
-      "dev": true
-    },
-    "arg": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
-      "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
-      "dev": true
-    },
-    "argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-      "dev": true,
-      "requires": {
-        "sprintf-js": "~1.0.2"
-      }
-    },
-    "asn1": {
-      "version": "0.2.6",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
-      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "async-hook-domain": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-2.0.4.tgz",
-      "integrity": "sha512-14LjCmlK1PK8eDtTezR6WX8TMaYNIzBIsd2D1sGoGjgx0BuNMMoSdk7i/drlbtamy0AWv9yv2tkB+ASdmeqFIw==",
-      "dev": true
-    },
-    "asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "aws-sign2": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "aws4": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
-      "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
-    },
-    "bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
-    "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
-    },
-    "bind-obj-methods": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-3.0.0.tgz",
-      "integrity": "sha512-nLEaaz3/sEzNSyPWRsN9HNsqwk1AUyECtGj+XwGdIi3xABnEqecvXtIJ0wehQXuuER5uZ/5fTs2usONgYjG+iw==",
-      "dev": true
-    },
-    "brace-expansion": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
-      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
-      "requires": {
-        "balanced-match": "^1.0.0"
-      }
-    },
-    "braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-      "dev": true,
-      "requires": {
-        "fill-range": "^7.0.1"
-      }
-    },
-    "browserslist": {
-      "version": "4.19.1",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz",
-      "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==",
-      "dev": true,
-      "requires": {
-        "caniuse-lite": "^1.0.30001286",
-        "electron-to-chromium": "^1.4.17",
-        "escalade": "^3.1.1",
-        "node-releases": "^2.0.1",
-        "picocolors": "^1.0.0"
-      }
-    },
-    "buffer-from": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
-      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
-      "dev": true
-    },
-    "c8": {
-      "version": "7.12.0",
-      "resolved": "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz",
-      "integrity": "sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A==",
-      "dev": true,
-      "requires": {
-        "@bcoe/v8-coverage": "^0.2.3",
-        "@istanbuljs/schema": "^0.1.3",
-        "find-up": "^5.0.0",
-        "foreground-child": "^2.0.0",
-        "istanbul-lib-coverage": "^3.2.0",
-        "istanbul-lib-report": "^3.0.0",
-        "istanbul-reports": "^3.1.4",
-        "rimraf": "^3.0.2",
-        "test-exclude": "^6.0.0",
-        "v8-to-istanbul": "^9.0.0",
-        "yargs": "^16.2.0",
-        "yargs-parser": "^20.2.9"
-      },
-      "dependencies": {
-        "find-up": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
-          "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
-          "dev": true,
-          "requires": {
-            "locate-path": "^6.0.0",
-            "path-exists": "^4.0.0"
-          }
-        },
-        "locate-path": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
-          "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
-          "dev": true,
-          "requires": {
-            "p-locate": "^5.0.0"
-          }
-        },
-        "p-limit": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
-          "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
-          "dev": true,
-          "requires": {
-            "yocto-queue": "^0.1.0"
-          }
-        },
-        "p-locate": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
-          "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
-          "dev": true,
-          "requires": {
-            "p-limit": "^3.0.2"
-          }
-        },
-        "rimraf": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        },
-        "y18n": {
-          "version": "5.0.8",
-          "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
-          "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-          "dev": true
-        },
-        "yargs": {
-          "version": "16.2.0",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-          "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
-          "dev": true,
-          "requires": {
-            "cliui": "^7.0.2",
-            "escalade": "^3.1.1",
-            "get-caller-file": "^2.0.5",
-            "require-directory": "^2.1.1",
-            "string-width": "^4.2.0",
-            "y18n": "^5.0.5",
-            "yargs-parser": "^20.2.2"
-          }
-        },
-        "yargs-parser": {
-          "version": "20.2.9",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
-          "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
-          "dev": true
-        }
-      }
-    },
-    "caching-transform": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
-      "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
-      "dev": true,
-      "requires": {
-        "hasha": "^5.0.0",
-        "make-dir": "^3.0.0",
-        "package-hash": "^4.0.0",
-        "write-file-atomic": "^3.0.0"
-      }
-    },
-    "callsites": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
-      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-      "dev": true,
-      "peer": true
-    },
-    "camelcase": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
-      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
-      "dev": true
-    },
-    "caniuse-lite": {
-      "version": "1.0.30001311",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001311.tgz",
-      "integrity": "sha512-mleTFtFKfykEeW34EyfhGIFjGCqzhh38Y0LhdQ9aWF+HorZTtdgKV/1hEE0NlFkG2ubvisPV6l400tlbPys98A==",
-      "dev": true
-    },
-    "caseless": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-      "dev": true,
-      "requires": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      }
-    },
-    "chokidar": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
-      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
-      "dev": true,
-      "requires": {
-        "anymatch": "~3.1.2",
-        "braces": "~3.0.2",
-        "fsevents": "~2.3.2",
-        "glob-parent": "~5.1.2",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.6.0"
-      }
-    },
-    "clean-stack": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
-      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
-      "dev": true
-    },
-    "cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
-      "dev": true,
-      "requires": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^7.0.0"
-      }
-    },
-    "color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
-      "dev": true,
-      "requires": {
-        "color-name": "1.1.3"
-      }
-    },
-    "color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-      "dev": true
-    },
-    "color-support": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
-      "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
-      "dev": true
-    },
-    "combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "delayed-stream": "~1.0.0"
-      }
-    },
-    "commondir": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
-      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
-      "dev": true
-    },
-    "concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-      "dev": true
-    },
-    "convert-source-map": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz",
-      "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==",
-      "dev": true,
-      "requires": {
-        "safe-buffer": "~5.1.1"
-      }
-    },
-    "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,
-      "optional": true,
-      "peer": true
-    },
-    "coveralls": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz",
-      "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "js-yaml": "^3.13.1",
-        "lcov-parse": "^1.0.0",
-        "log-driver": "^1.2.7",
-        "minimist": "^1.2.5",
-        "request": "^2.88.2"
-      }
-    },
-    "create-require": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
-      "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
-      "dev": true
-    },
-    "cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
-      "dev": true,
-      "requires": {
-        "path-key": "^3.1.0",
-        "shebang-command": "^2.0.0",
-        "which": "^2.0.1"
-      }
-    },
-    "dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "debug": {
-      "version": "4.3.3",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
-      "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
-      "dev": true,
-      "requires": {
-        "ms": "2.1.2"
-      }
-    },
-    "decamelize": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
-      "dev": true
-    },
-    "deep-is": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
-      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
-      "dev": true,
-      "peer": true
-    },
-    "default-require-extensions": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz",
-      "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==",
-      "dev": true,
-      "requires": {
-        "strip-bom": "^4.0.0"
-      }
-    },
-    "delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "diff": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-      "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
-      "dev": true
-    },
-    "doctrine": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
-      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "esutils": "^2.0.2"
-      }
-    },
-    "ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
-    "electron-to-chromium": {
-      "version": "1.4.68",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz",
-      "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==",
-      "dev": true
-    },
-    "emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true
-    },
-    "es6-error": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
-      "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
-      "dev": true
-    },
-    "escalade": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
-      "dev": true
-    },
-    "escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-      "dev": true
-    },
-    "eslint": {
-      "version": "8.31.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz",
-      "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "@eslint/eslintrc": "^1.4.1",
-        "@humanwhocodes/config-array": "^0.11.8",
-        "@humanwhocodes/module-importer": "^1.0.1",
-        "@nodelib/fs.walk": "^1.2.8",
-        "ajv": "^6.10.0",
-        "chalk": "^4.0.0",
-        "cross-spawn": "^7.0.2",
-        "debug": "^4.3.2",
-        "doctrine": "^3.0.0",
-        "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^7.1.1",
-        "eslint-utils": "^3.0.0",
-        "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.4.0",
-        "esquery": "^1.4.0",
-        "esutils": "^2.0.2",
-        "fast-deep-equal": "^3.1.3",
-        "file-entry-cache": "^6.0.1",
-        "find-up": "^5.0.0",
-        "glob-parent": "^6.0.2",
-        "globals": "^13.19.0",
-        "grapheme-splitter": "^1.0.4",
-        "ignore": "^5.2.0",
-        "import-fresh": "^3.0.0",
-        "imurmurhash": "^0.1.4",
-        "is-glob": "^4.0.0",
-        "is-path-inside": "^3.0.3",
-        "js-sdsl": "^4.1.4",
-        "js-yaml": "^4.1.0",
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "levn": "^0.4.1",
-        "lodash.merge": "^4.6.2",
-        "minimatch": "^3.1.2",
-        "natural-compare": "^1.4.0",
-        "optionator": "^0.9.1",
-        "regexpp": "^3.2.0",
-        "strip-ansi": "^6.0.1",
-        "strip-json-comments": "^3.1.0",
-        "text-table": "^0.2.0"
-      },
-      "dependencies": {
-        "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,
-          "peer": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "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,
-          "peer": true
-        },
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-          "dev": true,
-          "peer": true
-        },
-        "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,
-          "peer": true
-        },
-        "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,
-          "peer": true,
-          "requires": {
-            "locate-path": "^6.0.0",
-            "path-exists": "^4.0.0"
-          }
-        },
-        "glob-parent": {
-          "version": "6.0.2",
-          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-          "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "is-glob": "^4.0.3"
-          }
-        },
-        "globals": {
-          "version": "13.19.0",
-          "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz",
-          "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "type-fest": "^0.20.2"
-          }
-        },
-        "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,
-          "peer": true
-        },
-        "js-yaml": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-          "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "argparse": "^2.0.1"
-          }
-        },
-        "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,
-          "peer": true,
-          "requires": {
-            "p-locate": "^5.0.0"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        },
-        "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,
-          "peer": true,
-          "requires": {
-            "yocto-queue": "^0.1.0"
-          }
-        },
-        "p-locate": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
-          "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "p-limit": "^3.0.2"
-          }
-        },
-        "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,
-          "peer": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
-        "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,
-          "peer": true
-        }
-      }
-    },
-    "eslint-config-prettier": {
-      "version": "8.6.0",
-      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz",
-      "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==",
-      "dev": true,
-      "requires": {}
-    },
-    "eslint-scope": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
-      "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^5.2.0"
-      }
-    },
-    "eslint-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-      "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "eslint-visitor-keys": "^2.0.0"
-      },
-      "dependencies": {
-        "eslint-visitor-keys": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-          "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-          "dev": true,
-          "peer": true
-        }
-      }
-    },
-    "eslint-visitor-keys": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-      "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-      "dev": true,
-      "peer": true
-    },
-    "espree": {
-      "version": "9.4.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
-      "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "acorn": "^8.8.0",
-        "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^3.3.0"
-      }
-    },
-    "esprima": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
-      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
-      "dev": true
-    },
-    "esquery": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
-      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "estraverse": "^5.1.0"
-      }
-    },
-    "esrecurse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
-      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "estraverse": "^5.2.0"
-      }
-    },
-    "estraverse": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "dev": true,
-      "peer": true
-    },
-    "esutils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
-      "dev": true,
-      "peer": true
-    },
-    "events-to-array": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz",
-      "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=",
-      "dev": true
-    },
-    "extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "extsprintf": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "dev": true,
-      "peer": true
-    },
-    "fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true,
-      "peer": true
-    },
-    "fast-levenshtein": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
-      "dev": true,
-      "peer": true
-    },
-    "fastq": {
-      "version": "1.15.0",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
-      "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "reusify": "^1.0.4"
-      }
-    },
-    "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,
-      "peer": true,
-      "requires": {
-        "flat-cache": "^3.0.4"
-      }
-    },
-    "fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-      "dev": true,
-      "requires": {
-        "to-regex-range": "^5.0.1"
-      }
-    },
-    "find-cache-dir": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
-      "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
-      "dev": true,
-      "requires": {
-        "commondir": "^1.0.1",
-        "make-dir": "^3.0.2",
-        "pkg-dir": "^4.1.0"
-      }
-    },
-    "find-up": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
-      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
-      "dev": true,
-      "requires": {
-        "locate-path": "^5.0.0",
-        "path-exists": "^4.0.0"
-      }
-    },
-    "findit": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz",
-      "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=",
-      "dev": true
-    },
-    "flat-cache": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
-      "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "flatted": "^3.1.0",
-        "rimraf": "^3.0.2"
-      },
-      "dependencies": {
-        "rimraf": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-          "dev": true,
-          "peer": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        }
-      }
-    },
-    "flatted": {
-      "version": "3.2.7",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
-      "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
-      "dev": true,
-      "peer": true
-    },
-    "foreground-child": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
-      "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
-      "dev": true,
-      "requires": {
-        "cross-spawn": "^7.0.0",
-        "signal-exit": "^3.0.2"
-      }
-    },
-    "forever-agent": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "form-data": {
-      "version": "2.3.3",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
-      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
-        "mime-types": "^2.1.12"
-      }
-    },
-    "fromentries": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
-      "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==",
-      "dev": true
-    },
-    "fs-exists-cached": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz",
-      "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=",
-      "dev": true
-    },
-    "fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
-    },
-    "fsevents": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
-      "dev": true,
-      "optional": true
-    },
-    "function-loop": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-2.0.1.tgz",
-      "integrity": "sha512-ktIR+O6i/4h+j/ZhZJNdzeI4i9lEPeEK6UPR2EVyTVBqOwcU3Za9xYKLH64ZR9HmcROyRrOkizNyjjtWJzDDkQ==",
-      "dev": true
-    },
-    "gensync": {
-      "version": "1.0.0-beta.2",
-      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
-      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
-      "dev": true
-    },
-    "get-caller-file": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
-      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-      "dev": true
-    },
-    "get-package-type": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
-      "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
-      "dev": true
-    },
-    "getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-      "dev": true,
-      "requires": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "dependencies": {
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        }
-      }
-    },
-    "glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "requires": {
-        "is-glob": "^4.0.1"
-      }
-    },
-    "globals": {
-      "version": "11.12.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
-      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
-      "dev": true
-    },
-    "graceful-fs": {
-      "version": "4.2.9",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
-      "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
-      "dev": true
-    },
-    "grapheme-splitter": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
-      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
-      "dev": true,
-      "peer": true
-    },
-    "har-schema": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "har-validator": {
-      "version": "5.1.5",
-      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
-      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "ajv": "^6.12.3",
-        "har-schema": "^2.0.0"
-      }
-    },
-    "has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
-      "dev": true
-    },
-    "hasha": {
-      "version": "5.2.2",
-      "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
-      "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==",
-      "dev": true,
-      "requires": {
-        "is-stream": "^2.0.0",
-        "type-fest": "^0.8.0"
-      }
-    },
-    "html-escaper": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
-      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
-      "dev": true
-    },
-    "http-signature": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "assert-plus": "^1.0.0",
-        "jsprim": "^1.2.2",
-        "sshpk": "^1.7.0"
-      }
-    },
-    "ignore": {
-      "version": "5.2.4",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
-      "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
-      "dev": true,
-      "peer": true
-    },
-    "import-fresh": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
-      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "parent-module": "^1.0.0",
-        "resolve-from": "^4.0.0"
-      },
-      "dependencies": {
-        "resolve-from": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
-          "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-          "dev": true,
-          "peer": true
-        }
-      }
-    },
-    "imurmurhash": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-      "dev": true
-    },
-    "indent-string": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
-      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
-      "dev": true
-    },
-    "inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-      "dev": true,
-      "requires": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
-    "inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true
-    },
-    "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,
-      "requires": {
-        "binary-extensions": "^2.0.0"
-      }
-    },
-    "is-extglob": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
-      "dev": true
-    },
-    "is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true
-    },
-    "is-glob": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
-      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "dev": true,
-      "requires": {
-        "is-extglob": "^2.1.1"
-      }
-    },
-    "is-number": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
-      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "dev": true
-    },
-    "is-path-inside": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
-      "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
-      "dev": true,
-      "peer": true
-    },
-    "is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
-      "dev": true
-    },
-    "is-typedarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
-      "dev": true
-    },
-    "is-windows": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
-      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
-      "dev": true
-    },
-    "isexe": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-      "dev": true
-    },
-    "isstream": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "istanbul-lib-coverage": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
-      "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
-      "dev": true
-    },
-    "istanbul-lib-hook": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz",
-      "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==",
-      "dev": true,
-      "requires": {
-        "append-transform": "^2.0.0"
-      }
-    },
-    "istanbul-lib-instrument": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
-      "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
-      "dev": true,
-      "requires": {
-        "@babel/core": "^7.7.5",
-        "@istanbuljs/schema": "^0.1.2",
-        "istanbul-lib-coverage": "^3.0.0",
-        "semver": "^6.3.0"
-      }
-    },
-    "istanbul-lib-processinfo": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz",
-      "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==",
-      "dev": true,
-      "requires": {
-        "archy": "^1.0.0",
-        "cross-spawn": "^7.0.3",
-        "istanbul-lib-coverage": "^3.2.0",
-        "p-map": "^3.0.0",
-        "rimraf": "^3.0.0",
-        "uuid": "^8.3.2"
-      },
-      "dependencies": {
-        "rimraf": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        },
-        "uuid": {
-          "version": "8.3.2",
-          "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
-          "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
-          "dev": true
-        }
-      }
-    },
-    "istanbul-lib-report": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
-      "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
-      "dev": true,
-      "requires": {
-        "istanbul-lib-coverage": "^3.0.0",
-        "make-dir": "^3.0.0",
-        "supports-color": "^7.1.0"
-      },
-      "dependencies": {
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
-      }
-    },
-    "istanbul-lib-source-maps": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
-      "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
-      "dev": true,
-      "requires": {
-        "debug": "^4.1.1",
-        "istanbul-lib-coverage": "^3.0.0",
-        "source-map": "^0.6.1"
-      },
-      "dependencies": {
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true
-        }
-      }
-    },
-    "istanbul-reports": {
-      "version": "3.1.4",
-      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz",
-      "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==",
-      "dev": true,
-      "requires": {
-        "html-escaper": "^2.0.0",
-        "istanbul-lib-report": "^3.0.0"
-      }
-    },
-    "jackspeak": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.2.tgz",
-      "integrity": "sha512-GHeGTmnuaHnvS+ZctRB01bfxARuu9wW83ENbuiweu07SFcVlZrJpcshSre/keGT7YGBhLHg/+rXCNSrsEHKU4Q==",
-      "dev": true,
-      "requires": {
-        "cliui": "^7.0.4"
-      }
-    },
-    "js-sdsl": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz",
-      "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==",
-      "dev": true,
-      "peer": true
-    },
-    "js-tokens": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
-      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true
-    },
-    "js-yaml": {
-      "version": "3.14.1",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
-      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
-      "dev": true,
-      "requires": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
-      }
-    },
-    "jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "jsesc": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
-      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
-      "dev": true
-    },
-    "json-schema": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
-      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "json-schema-traverse": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
-      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-      "dev": true,
-      "peer": true
-    },
-    "json-stable-stringify-without-jsonify": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
-      "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
-      "dev": true,
-      "peer": true
-    },
-    "json-stringify-safe": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "json5": {
-      "version": "2.2.3",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
-      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
-      "dev": true
-    },
-    "jsonc-parser": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
-      "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
-      "dev": true
-    },
-    "jsprim": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
-      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "assert-plus": "1.0.0",
-        "extsprintf": "1.3.0",
-        "json-schema": "0.4.0",
-        "verror": "1.10.0"
-      }
-    },
-    "lcov-parse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz",
-      "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "levn": {
-      "version": "0.4.1",
-      "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
-      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "prelude-ls": "^1.2.1",
-        "type-check": "~0.4.0"
-      }
-    },
-    "libtap": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.4.0.tgz",
-      "integrity": "sha512-STLFynswQ2A6W14JkabgGetBNk6INL1REgJ9UeNKw5llXroC2cGLgKTqavv0sl8OLVztLLipVKMcQ7yeUcqpmg==",
-      "dev": true,
-      "requires": {
-        "async-hook-domain": "^2.0.4",
-        "bind-obj-methods": "^3.0.0",
-        "diff": "^4.0.2",
-        "function-loop": "^2.0.1",
-        "minipass": "^3.1.5",
-        "own-or": "^1.0.0",
-        "own-or-env": "^1.0.2",
-        "signal-exit": "^3.0.4",
-        "stack-utils": "^2.0.4",
-        "tap-parser": "^11.0.0",
-        "tap-yaml": "^1.0.0",
-        "tcompare": "^5.0.6",
-        "trivial-deferred": "^1.0.1"
-      },
-      "dependencies": {
-        "minipass": {
-          "version": "3.3.6",
-          "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
-          "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
-          "dev": true,
-          "requires": {
-            "yallist": "^4.0.0"
-          }
-        }
-      }
-    },
-    "locate-path": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
-      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
-      "dev": true,
-      "requires": {
-        "p-locate": "^4.1.0"
-      }
-    },
-    "lodash.flattendeep": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
-      "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
-      "dev": true
-    },
-    "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,
-      "peer": true
-    },
-    "log-driver": {
-      "version": "1.2.7",
-      "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz",
-      "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "lru-cache": {
-      "version": "7.14.1",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.1.tgz",
-      "integrity": "sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA=="
-    },
-    "lunr": {
-      "version": "2.3.9",
-      "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
-      "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
-      "dev": true
-    },
-    "make-dir": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
-      "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
-      "dev": true,
-      "requires": {
-        "semver": "^6.0.0"
-      }
-    },
-    "make-error": {
-      "version": "1.3.6",
-      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
-      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
-      "dev": true
-    },
-    "marked": {
-      "version": "4.2.12",
-      "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz",
-      "integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==",
-      "dev": true
-    },
-    "mime-db": {
-      "version": "1.51.0",
-      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz",
-      "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "mime-types": {
-      "version": "2.1.34",
-      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz",
-      "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "mime-db": "1.51.0"
-      }
-    },
-    "minimatch": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.2.0.tgz",
-      "integrity": "sha512-rMRHmwySzopAQjmWW6TkAKCEDKNaY/HuV/c2YkWWuWnfkTwApt0V4hnYzzPnZ/5Gcd2+8MPncSyuOGPl3xPvcg==",
-      "requires": {
-        "brace-expansion": "^2.0.1"
-      }
-    },
-    "minimist": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
-      "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "minipass": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.4.tgz",
-      "integrity": "sha512-lwycX3cBMTvcejsHITUgYj6Gy6A7Nh4Q6h9NP4sTHY1ccJlC7yKzDmiShEHsJ16Jf1nKGDEaiHxiltsJEvk0nQ=="
-    },
-    "mkdirp": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.0.0.tgz",
-      "integrity": "sha512-M9ecBPkCu6jZ+H19zruhjw/JB97qqVhyi1H2Lxxo2XAoIMdpHKQ8MfQiMzXk9SH/oJXIbM3oSAfLB8qSWJdCLA==",
-      "dev": true
-    },
-    "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
-    },
-    "natural-compare": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
-      "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
-      "dev": true,
-      "peer": true
-    },
-    "node-preload": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
-      "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==",
-      "dev": true,
-      "requires": {
-        "process-on-spawn": "^1.0.0"
-      }
-    },
-    "node-releases": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz",
-      "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==",
-      "dev": true
-    },
-    "normalize-path": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
-      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-      "dev": true
-    },
-    "nyc": {
-      "version": "15.1.0",
-      "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
-      "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==",
-      "dev": true,
-      "requires": {
-        "@istanbuljs/load-nyc-config": "^1.0.0",
-        "@istanbuljs/schema": "^0.1.2",
-        "caching-transform": "^4.0.0",
-        "convert-source-map": "^1.7.0",
-        "decamelize": "^1.2.0",
-        "find-cache-dir": "^3.2.0",
-        "find-up": "^4.1.0",
-        "foreground-child": "^2.0.0",
-        "get-package-type": "^0.1.0",
-        "glob": "^7.1.6",
-        "istanbul-lib-coverage": "^3.0.0",
-        "istanbul-lib-hook": "^3.0.0",
-        "istanbul-lib-instrument": "^4.0.0",
-        "istanbul-lib-processinfo": "^2.0.2",
-        "istanbul-lib-report": "^3.0.0",
-        "istanbul-lib-source-maps": "^4.0.0",
-        "istanbul-reports": "^3.0.2",
-        "make-dir": "^3.0.0",
-        "node-preload": "^0.2.1",
-        "p-map": "^3.0.0",
-        "process-on-spawn": "^1.0.0",
-        "resolve-from": "^5.0.0",
-        "rimraf": "^3.0.0",
-        "signal-exit": "^3.0.2",
-        "spawn-wrap": "^2.0.0",
-        "test-exclude": "^6.0.0",
-        "yargs": "^15.0.2"
-      },
-      "dependencies": {
-        "rimraf": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        }
-      }
-    },
-    "oauth-sign": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
-      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-      "dev": true,
-      "requires": {
-        "wrappy": "1"
-      }
-    },
-    "opener": {
-      "version": "1.5.2",
-      "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
-      "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
-      "dev": true
-    },
-    "optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "deep-is": "^0.1.3",
-        "fast-levenshtein": "^2.0.6",
-        "levn": "^0.4.1",
-        "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0",
-        "word-wrap": "^1.2.3"
-      }
-    },
-    "own-or": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz",
-      "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=",
-      "dev": true
-    },
-    "own-or-env": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.2.tgz",
-      "integrity": "sha512-NQ7v0fliWtK7Lkb+WdFqe6ky9XAzYmlkXthQrBbzlYbmFKoAYbDDcwmOm6q8kOuwSRXW8bdL5ORksploUJmWgw==",
-      "dev": true,
-      "requires": {
-        "own-or": "^1.0.0"
-      }
-    },
-    "p-limit": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
-      "dev": true,
-      "requires": {
-        "p-try": "^2.0.0"
-      }
-    },
-    "p-locate": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
-      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
-      "dev": true,
-      "requires": {
-        "p-limit": "^2.2.0"
-      }
-    },
-    "p-map": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
-      "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
-      "dev": true,
-      "requires": {
-        "aggregate-error": "^3.0.0"
-      }
-    },
-    "p-try": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
-      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
-      "dev": true
-    },
-    "package-hash": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
-      "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "^4.1.15",
-        "hasha": "^5.0.0",
-        "lodash.flattendeep": "^4.4.0",
-        "release-zalgo": "^1.0.0"
-      }
-    },
-    "parent-module": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
-      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "callsites": "^3.0.0"
-      }
-    },
-    "path-exists": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
-      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true
-    },
-    "path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
-      "dev": true
-    },
-    "path-key": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
-      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true
-    },
-    "path-scurry": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.5.0.tgz",
-      "integrity": "sha512-hJ8rODLI9B2qwsYAd32rrI76gwVUPeu5kq/do6URDj2bJCVH3ilyT978Mv/NLuFMaqzHrn3XtiDLMZHaTTh4vA==",
-      "requires": {
-        "lru-cache": "^7.14.1",
-        "minipass": "^4.0.2"
-      }
-    },
-    "performance-now": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "picocolors": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
-      "dev": true
-    },
-    "picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true
-    },
-    "pkg-dir": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
-      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
-      "dev": true,
-      "requires": {
-        "find-up": "^4.0.0"
-      }
-    },
-    "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,
-      "peer": true
-    },
-    "prettier": {
-      "version": "2.8.3",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz",
-      "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==",
-      "dev": true
-    },
-    "process-on-spawn": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
-      "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==",
-      "dev": true,
-      "requires": {
-        "fromentries": "^1.2.0"
-      }
-    },
-    "psl": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
-      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "punycode": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
-      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
-      "dev": true
-    },
-    "qs": {
-      "version": "6.5.3",
-      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
-      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "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,
-      "peer": true
-    },
-    "readdirp": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-      "dev": true,
-      "requires": {
-        "picomatch": "^2.2.1"
-      }
-    },
-    "regexpp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
-      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
-      "dev": true,
-      "peer": true
-    },
-    "release-zalgo": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
-      "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
-      "dev": true,
-      "requires": {
-        "es6-error": "^4.0.1"
-      }
-    },
-    "request": {
-      "version": "2.88.2",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
-      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "aws-sign2": "~0.7.0",
-        "aws4": "^1.8.0",
-        "caseless": "~0.12.0",
-        "combined-stream": "~1.0.6",
-        "extend": "~3.0.2",
-        "forever-agent": "~0.6.1",
-        "form-data": "~2.3.2",
-        "har-validator": "~5.1.3",
-        "http-signature": "~1.2.0",
-        "is-typedarray": "~1.0.0",
-        "isstream": "~0.1.2",
-        "json-stringify-safe": "~5.0.1",
-        "mime-types": "~2.1.19",
-        "oauth-sign": "~0.9.0",
-        "performance-now": "^2.1.0",
-        "qs": "~6.5.2",
-        "safe-buffer": "^5.1.2",
-        "tough-cookie": "~2.5.0",
-        "tunnel-agent": "^0.6.0",
-        "uuid": "^3.3.2"
-      }
-    },
-    "require-directory": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
-      "dev": true
-    },
-    "require-main-filename": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
-      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
-      "dev": true
-    },
-    "resolve-from": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
-      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
-      "dev": true
-    },
-    "reusify": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
-      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-      "dev": true,
-      "peer": true
-    },
-    "rimraf": {
-      "version": "4.1.1",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.1.tgz",
-      "integrity": "sha512-Z4Y81w8atcvaJuJuBB88VpADRH66okZAuEm+Jtaufa+s7rZmIz+Hik2G53kGaNytE7lsfXyWktTmfVz0H9xuDg==",
-      "dev": true
-    },
-    "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,
-      "peer": true,
-      "requires": {
-        "queue-microtask": "^1.2.2"
-      }
-    },
-    "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
-    },
-    "safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "semver": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-      "dev": true
-    },
-    "set-blocking": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
-      "dev": true
-    },
-    "shebang-command": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
-      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
-      "dev": true,
-      "requires": {
-        "shebang-regex": "^3.0.0"
-      }
-    },
-    "shebang-regex": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
-      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true
-    },
-    "shiki": {
-      "version": "0.12.1",
-      "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.12.1.tgz",
-      "integrity": "sha512-aieaV1m349rZINEBkjxh2QbBvFFQOlgqYTNtCal82hHj4dDZ76oMlQIX+C7ryerBTDiga3e5NfH6smjdJ02BbQ==",
-      "dev": true,
-      "requires": {
-        "jsonc-parser": "^3.2.0",
-        "vscode-oniguruma": "^1.7.0",
-        "vscode-textmate": "^8.0.0"
-      }
-    },
-    "signal-exit": {
-      "version": "3.0.7",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
-      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
-      "dev": true
-    },
-    "source-map": {
-      "version": "0.5.7",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-      "dev": true
-    },
-    "source-map-support": {
-      "version": "0.5.21",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
-      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
-      "dev": true,
-      "requires": {
-        "buffer-from": "^1.0.0",
-        "source-map": "^0.6.0"
-      },
-      "dependencies": {
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true
-        }
-      }
-    },
-    "spawn-wrap": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
-      "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
-      "dev": true,
-      "requires": {
-        "foreground-child": "^2.0.0",
-        "is-windows": "^1.0.2",
-        "make-dir": "^3.0.0",
-        "rimraf": "^3.0.0",
-        "signal-exit": "^3.0.2",
-        "which": "^2.0.1"
-      },
-      "dependencies": {
-        "rimraf": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        }
-      }
-    },
-    "sprintf-js": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
-      "dev": true
-    },
-    "sshpk": {
-      "version": "1.17.0",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
-      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "asn1": "~0.2.3",
-        "assert-plus": "^1.0.0",
-        "bcrypt-pbkdf": "^1.0.0",
-        "dashdash": "^1.12.0",
-        "ecc-jsbn": "~0.1.1",
-        "getpass": "^0.1.1",
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.0.2",
-        "tweetnacl": "~0.14.0"
-      }
-    },
-    "stack-utils": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz",
-      "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==",
-      "dev": true,
-      "requires": {
-        "escape-string-regexp": "^2.0.0"
-      },
-      "dependencies": {
-        "escape-string-regexp": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
-          "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
-          "dev": true
-        }
-      }
-    },
-    "string-width": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-      "dev": true,
-      "requires": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
-      }
-    },
-    "strip-ansi": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
-      "requires": {
-        "ansi-regex": "^5.0.1"
-      }
-    },
-    "strip-bom": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
-      "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
-      "dev": true
-    },
-    "strip-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,
-      "peer": true
-    },
-    "supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
-      "requires": {
-        "has-flag": "^3.0.0"
-      }
-    },
-    "tap": {
-      "version": "16.3.4",
-      "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.4.tgz",
-      "integrity": "sha512-SAexdt2ZF4XBgye6TPucFI2y7VE0qeFXlXucJIV1XDPCs+iJodk0MYacr1zR6Ycltzz7PYg8zrblDXKbAZM2LQ==",
-      "dev": true,
-      "requires": {
-        "@isaacs/import-jsx": "^4.0.1",
-        "@types/react": "^17.0.52",
-        "chokidar": "^3.3.0",
-        "findit": "^2.0.0",
-        "foreground-child": "^2.0.0",
-        "fs-exists-cached": "^1.0.0",
-        "glob": "^7.2.3",
-        "ink": "^3.2.0",
-        "isexe": "^2.0.0",
-        "istanbul-lib-processinfo": "^2.0.3",
-        "jackspeak": "^1.4.2",
-        "libtap": "^1.4.0",
-        "minipass": "^3.3.4",
-        "mkdirp": "^1.0.4",
-        "nyc": "^15.1.0",
-        "opener": "^1.5.1",
-        "react": "^17.0.2",
-        "rimraf": "^3.0.0",
-        "signal-exit": "^3.0.6",
-        "source-map-support": "^0.5.16",
-        "tap-mocha-reporter": "^5.0.3",
-        "tap-parser": "^11.0.2",
-        "tap-yaml": "^1.0.2",
-        "tcompare": "^5.0.7",
-        "treport": "^3.0.4",
-        "which": "^2.0.2"
-      },
-      "dependencies": {
-        "@ampproject/remapping": {
-          "version": "2.1.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@jridgewell/trace-mapping": "^0.3.0"
-          }
-        },
-        "@babel/code-frame": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/highlight": "^7.16.7"
-          }
-        },
-        "@babel/compat-data": {
-          "version": "7.17.7",
-          "bundled": true,
-          "dev": true
-        },
-        "@babel/core": {
-          "version": "7.17.8",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@ampproject/remapping": "^2.1.0",
-            "@babel/code-frame": "^7.16.7",
-            "@babel/generator": "^7.17.7",
-            "@babel/helper-compilation-targets": "^7.17.7",
-            "@babel/helper-module-transforms": "^7.17.7",
-            "@babel/helpers": "^7.17.8",
-            "@babel/parser": "^7.17.8",
-            "@babel/template": "^7.16.7",
-            "@babel/traverse": "^7.17.3",
-            "@babel/types": "^7.17.0",
-            "convert-source-map": "^1.7.0",
-            "debug": "^4.1.0",
-            "gensync": "^1.0.0-beta.2",
-            "json5": "^2.1.2",
-            "semver": "^6.3.0"
-          }
-        },
-        "@babel/generator": {
-          "version": "7.17.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.17.0",
-            "jsesc": "^2.5.1",
-            "source-map": "^0.5.0"
-          }
-        },
-        "@babel/helper-annotate-as-pure": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.16.7"
-          }
-        },
-        "@babel/helper-compilation-targets": {
-          "version": "7.17.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/compat-data": "^7.17.7",
-            "@babel/helper-validator-option": "^7.16.7",
-            "browserslist": "^4.17.5",
-            "semver": "^6.3.0"
-          }
-        },
-        "@babel/helper-environment-visitor": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.16.7"
-          }
-        },
-        "@babel/helper-function-name": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/helper-get-function-arity": "^7.16.7",
-            "@babel/template": "^7.16.7",
-            "@babel/types": "^7.16.7"
-          }
-        },
-        "@babel/helper-get-function-arity": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.16.7"
-          }
-        },
-        "@babel/helper-hoist-variables": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.16.7"
-          }
-        },
-        "@babel/helper-module-imports": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.16.7"
-          }
-        },
-        "@babel/helper-module-transforms": {
-          "version": "7.17.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/helper-environment-visitor": "^7.16.7",
-            "@babel/helper-module-imports": "^7.16.7",
-            "@babel/helper-simple-access": "^7.17.7",
-            "@babel/helper-split-export-declaration": "^7.16.7",
-            "@babel/helper-validator-identifier": "^7.16.7",
-            "@babel/template": "^7.16.7",
-            "@babel/traverse": "^7.17.3",
-            "@babel/types": "^7.17.0"
-          }
-        },
-        "@babel/helper-plugin-utils": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true
-        },
-        "@babel/helper-simple-access": {
-          "version": "7.17.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.17.0"
-          }
-        },
-        "@babel/helper-split-export-declaration": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/types": "^7.16.7"
-          }
-        },
-        "@babel/helper-validator-identifier": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true
-        },
-        "@babel/helper-validator-option": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true
-        },
-        "@babel/helpers": {
-          "version": "7.17.8",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/template": "^7.16.7",
-            "@babel/traverse": "^7.17.3",
-            "@babel/types": "^7.17.0"
-          }
-        },
-        "@babel/highlight": {
-          "version": "7.16.10",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.16.7",
-            "chalk": "^2.0.0",
-            "js-tokens": "^4.0.0"
-          }
-        },
-        "@babel/parser": {
-          "version": "7.17.8",
-          "bundled": true,
-          "dev": true
-        },
-        "@babel/plugin-proposal-object-rest-spread": {
-          "version": "7.17.3",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/compat-data": "^7.17.0",
-            "@babel/helper-compilation-targets": "^7.16.7",
-            "@babel/helper-plugin-utils": "^7.16.7",
-            "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
-            "@babel/plugin-transform-parameters": "^7.16.7"
-          }
-        },
-        "@babel/plugin-syntax-jsx": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/helper-plugin-utils": "^7.16.7"
-          }
-        },
-        "@babel/plugin-syntax-object-rest-spread": {
-          "version": "7.8.3",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/helper-plugin-utils": "^7.8.0"
-          }
-        },
-        "@babel/plugin-transform-destructuring": {
-          "version": "7.17.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/helper-plugin-utils": "^7.16.7"
-          }
-        },
-        "@babel/plugin-transform-parameters": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/helper-plugin-utils": "^7.16.7"
-          }
-        },
-        "@babel/plugin-transform-react-jsx": {
-          "version": "7.17.3",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/helper-annotate-as-pure": "^7.16.7",
-            "@babel/helper-module-imports": "^7.16.7",
-            "@babel/helper-plugin-utils": "^7.16.7",
-            "@babel/plugin-syntax-jsx": "^7.16.7",
-            "@babel/types": "^7.17.0"
-          }
-        },
-        "@babel/template": {
-          "version": "7.16.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.16.7",
-            "@babel/parser": "^7.16.7",
-            "@babel/types": "^7.16.7"
-          }
-        },
-        "@babel/traverse": {
-          "version": "7.17.3",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/code-frame": "^7.16.7",
-            "@babel/generator": "^7.17.3",
-            "@babel/helper-environment-visitor": "^7.16.7",
-            "@babel/helper-function-name": "^7.16.7",
-            "@babel/helper-hoist-variables": "^7.16.7",
-            "@babel/helper-split-export-declaration": "^7.16.7",
-            "@babel/parser": "^7.17.3",
-            "@babel/types": "^7.17.0",
-            "debug": "^4.1.0",
-            "globals": "^11.1.0"
-          }
-        },
-        "@babel/types": {
-          "version": "7.17.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/helper-validator-identifier": "^7.16.7",
-            "to-fast-properties": "^2.0.0"
-          }
-        },
-        "@isaacs/import-jsx": {
-          "version": "4.0.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@babel/core": "^7.5.5",
-            "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
-            "@babel/plugin-transform-destructuring": "^7.5.0",
-            "@babel/plugin-transform-react-jsx": "^7.3.0",
-            "caller-path": "^3.0.1",
-            "find-cache-dir": "^3.2.0",
-            "make-dir": "^3.0.2",
-            "resolve-from": "^3.0.0",
-            "rimraf": "^3.0.0"
-          }
-        },
-        "@jridgewell/resolve-uri": {
-          "version": "3.0.5",
-          "bundled": true,
-          "dev": true
-        },
-        "@jridgewell/sourcemap-codec": {
-          "version": "1.4.11",
-          "bundled": true,
-          "dev": true
-        },
-        "@jridgewell/trace-mapping": {
-          "version": "0.3.4",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@jridgewell/resolve-uri": "^3.0.3",
-            "@jridgewell/sourcemap-codec": "^1.4.10"
-          }
-        },
-        "@types/prop-types": {
-          "version": "15.7.4",
-          "bundled": true,
-          "dev": true
-        },
-        "@types/react": {
-          "version": "17.0.52",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@types/prop-types": "*",
-            "@types/scheduler": "*",
-            "csstype": "^3.0.2"
-          }
-        },
-        "@types/scheduler": {
-          "version": "0.16.2",
-          "bundled": true,
-          "dev": true
-        },
-        "@types/yoga-layout": {
-          "version": "1.9.2",
-          "bundled": true,
-          "dev": true
-        },
-        "ansi-escapes": {
-          "version": "4.3.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "type-fest": "^0.21.3"
-          },
-          "dependencies": {
-            "type-fest": {
-              "version": "0.21.3",
-              "bundled": true,
-              "dev": true
-            }
-          }
-        },
-        "ansi-regex": {
-          "version": "5.0.1",
-          "bundled": true,
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "3.2.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "ansicolors": {
-          "version": "0.3.2",
-          "bundled": true,
-          "dev": true
-        },
-        "astral-regex": {
-          "version": "2.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "auto-bind": {
-          "version": "4.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "balanced-match": {
-          "version": "1.0.2",
-          "bundled": true,
-          "dev": true
-        },
-        "brace-expansion": {
-          "version": "1.1.11",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "browserslist": {
-          "version": "4.20.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "caniuse-lite": "^1.0.30001317",
-            "electron-to-chromium": "^1.4.84",
-            "escalade": "^3.1.1",
-            "node-releases": "^2.0.2",
-            "picocolors": "^1.0.0"
-          }
-        },
-        "caller-callsite": {
-          "version": "4.1.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "callsites": "^3.1.0"
-          }
-        },
-        "caller-path": {
-          "version": "3.0.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "caller-callsite": "^4.1.0"
-          }
-        },
-        "callsites": {
-          "version": "3.1.0",
-          "bundled": true,
-          "dev": true
-        },
-        "caniuse-lite": {
-          "version": "1.0.30001319",
-          "bundled": true,
-          "dev": true
-        },
-        "cardinal": {
-          "version": "2.1.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "ansicolors": "~0.3.2",
-            "redeyed": "~2.1.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "ci-info": {
-          "version": "2.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "cli-boxes": {
-          "version": "2.2.1",
-          "bundled": true,
-          "dev": true
-        },
-        "cli-cursor": {
-          "version": "3.1.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "restore-cursor": "^3.1.0"
-          }
-        },
-        "cli-truncate": {
-          "version": "2.1.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "slice-ansi": "^3.0.0",
-            "string-width": "^4.2.0"
-          }
-        },
-        "code-excerpt": {
-          "version": "3.0.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "convert-to-spaces": "^1.0.1"
-          }
-        },
-        "color-convert": {
-          "version": "1.9.3",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "bundled": true,
-          "dev": true
-        },
-        "commondir": {
-          "version": "1.0.1",
-          "bundled": true,
-          "dev": true
-        },
-        "concat-map": {
-          "version": "0.0.1",
-          "bundled": true,
-          "dev": true
-        },
-        "convert-source-map": {
-          "version": "1.8.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "safe-buffer": "~5.1.1"
-          }
-        },
-        "convert-to-spaces": {
-          "version": "1.0.2",
-          "bundled": true,
-          "dev": true
-        },
-        "csstype": {
-          "version": "3.0.11",
-          "bundled": true,
-          "dev": true
-        },
-        "debug": {
-          "version": "4.3.4",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "ms": "2.1.2"
-          }
-        },
-        "electron-to-chromium": {
-          "version": "1.4.89",
-          "bundled": true,
-          "dev": true
-        },
-        "emoji-regex": {
-          "version": "8.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "escalade": {
-          "version": "3.1.1",
-          "bundled": true,
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "bundled": true,
-          "dev": true
-        },
-        "esprima": {
-          "version": "4.0.1",
-          "bundled": true,
-          "dev": true
-        },
-        "events-to-array": {
-          "version": "1.1.2",
-          "bundled": true,
-          "dev": true
-        },
-        "find-cache-dir": {
-          "version": "3.3.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "commondir": "^1.0.1",
-            "make-dir": "^3.0.2",
-            "pkg-dir": "^4.1.0"
-          }
-        },
-        "find-up": {
-          "version": "4.1.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "locate-path": "^5.0.0",
-            "path-exists": "^4.0.0"
-          }
-        },
-        "fs.realpath": {
-          "version": "1.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "gensync": {
-          "version": "1.0.0-beta.2",
-          "bundled": true,
-          "dev": true
-        },
-        "glob": {
-          "version": "7.2.3",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.1.1",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
-          }
-        },
-        "globals": {
-          "version": "11.12.0",
-          "bundled": true,
-          "dev": true
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "indent-string": {
-          "version": "4.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "inflight": {
-          "version": "1.0.6",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "once": "^1.3.0",
-            "wrappy": "1"
-          }
-        },
-        "inherits": {
-          "version": "2.0.4",
-          "bundled": true,
-          "dev": true
-        },
-        "ink": {
-          "version": "3.2.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "ansi-escapes": "^4.2.1",
-            "auto-bind": "4.0.0",
-            "chalk": "^4.1.0",
-            "cli-boxes": "^2.2.0",
-            "cli-cursor": "^3.1.0",
-            "cli-truncate": "^2.1.0",
-            "code-excerpt": "^3.0.0",
-            "indent-string": "^4.0.0",
-            "is-ci": "^2.0.0",
-            "lodash": "^4.17.20",
-            "patch-console": "^1.0.0",
-            "react-devtools-core": "^4.19.1",
-            "react-reconciler": "^0.26.2",
-            "scheduler": "^0.20.2",
-            "signal-exit": "^3.0.2",
-            "slice-ansi": "^3.0.0",
-            "stack-utils": "^2.0.2",
-            "string-width": "^4.2.2",
-            "type-fest": "^0.12.0",
-            "widest-line": "^3.1.0",
-            "wrap-ansi": "^6.2.0",
-            "ws": "^7.5.5",
-            "yoga-layout-prebuilt": "^1.9.6"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "4.3.0",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "color-convert": "^2.0.1"
-              }
-            },
-            "chalk": {
-              "version": "4.1.2",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "ansi-styles": "^4.1.0",
-                "supports-color": "^7.1.0"
-              }
-            },
-            "color-convert": {
-              "version": "2.0.1",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "color-name": "~1.1.4"
-              }
-            },
-            "color-name": {
-              "version": "1.1.4",
-              "bundled": true,
-              "dev": true
-            },
-            "has-flag": {
-              "version": "4.0.0",
-              "bundled": true,
-              "dev": true
-            },
-            "supports-color": {
-              "version": "7.2.0",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "has-flag": "^4.0.0"
-              }
-            }
-          }
-        },
-        "is-ci": {
-          "version": "2.0.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "ci-info": "^2.0.0"
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "3.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "js-tokens": {
-          "version": "4.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "jsesc": {
-          "version": "2.5.2",
-          "bundled": true,
-          "dev": true
-        },
-        "json5": {
-          "version": "2.2.3",
-          "bundled": true,
-          "dev": true
-        },
-        "locate-path": {
-          "version": "5.0.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "p-locate": "^4.1.0"
-          }
-        },
-        "lodash": {
-          "version": "4.17.21",
-          "bundled": true,
-          "dev": true
-        },
-        "loose-envify": {
-          "version": "1.4.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "js-tokens": "^3.0.0 || ^4.0.0"
-          }
-        },
-        "make-dir": {
-          "version": "3.1.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "semver": "^6.0.0"
-          }
-        },
-        "mimic-fn": {
-          "version": "2.1.0",
-          "bundled": true,
-          "dev": true
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        },
-        "minipass": {
-          "version": "3.3.4",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "yallist": "^4.0.0"
-          }
-        },
-        "mkdirp": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
-          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
-          "dev": true
-        },
-        "ms": {
-          "version": "2.1.2",
-          "bundled": true,
-          "dev": true
-        },
-        "node-releases": {
-          "version": "2.0.2",
-          "bundled": true,
-          "dev": true
-        },
-        "object-assign": {
-          "version": "4.1.1",
-          "bundled": true,
-          "dev": true
-        },
-        "once": {
-          "version": "1.4.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "wrappy": "1"
-          }
-        },
-        "onetime": {
-          "version": "5.1.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "mimic-fn": "^2.1.0"
-          }
-        },
-        "p-limit": {
-          "version": "2.3.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "p-try": "^2.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "4.1.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "p-limit": "^2.2.0"
-          }
-        },
-        "p-try": {
-          "version": "2.2.0",
-          "bundled": true,
-          "dev": true
-        },
-        "patch-console": {
-          "version": "1.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "path-exists": {
-          "version": "4.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "path-is-absolute": {
-          "version": "1.0.1",
-          "bundled": true,
-          "dev": true
-        },
-        "picocolors": {
-          "version": "1.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "pkg-dir": {
-          "version": "4.2.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "find-up": "^4.0.0"
-          }
-        },
-        "punycode": {
-          "version": "2.1.1",
-          "bundled": true,
-          "dev": true
-        },
-        "react": {
-          "version": "17.0.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "loose-envify": "^1.1.0",
-            "object-assign": "^4.1.1"
-          }
-        },
-        "react-devtools-core": {
-          "version": "4.24.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "shell-quote": "^1.6.1",
-            "ws": "^7"
-          }
-        },
-        "react-reconciler": {
-          "version": "0.26.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "loose-envify": "^1.1.0",
-            "object-assign": "^4.1.1",
-            "scheduler": "^0.20.2"
-          }
-        },
-        "redeyed": {
-          "version": "2.1.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "esprima": "~4.0.0"
-          }
-        },
-        "resolve-from": {
-          "version": "3.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "restore-cursor": {
-          "version": "3.1.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "onetime": "^5.1.0",
-            "signal-exit": "^3.0.2"
-          }
-        },
-        "rimraf": {
-          "version": "3.0.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "glob": "^7.1.3"
-          }
-        },
-        "safe-buffer": {
-          "version": "5.1.2",
-          "bundled": true,
-          "dev": true
-        },
-        "scheduler": {
-          "version": "0.20.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "loose-envify": "^1.1.0",
-            "object-assign": "^4.1.1"
-          }
-        },
-        "semver": {
-          "version": "6.3.0",
-          "bundled": true,
-          "dev": true
-        },
-        "shell-quote": {
-          "version": "1.7.3",
-          "bundled": true,
-          "dev": true
-        },
-        "signal-exit": {
-          "version": "3.0.7",
-          "bundled": true,
-          "dev": true
-        },
-        "slice-ansi": {
-          "version": "3.0.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.0.0",
-            "astral-regex": "^2.0.0",
-            "is-fullwidth-code-point": "^3.0.0"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "4.3.0",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "color-convert": "^2.0.1"
-              }
-            },
-            "color-convert": {
-              "version": "2.0.1",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "color-name": "~1.1.4"
-              }
-            },
-            "color-name": {
-              "version": "1.1.4",
-              "bundled": true,
-              "dev": true
-            }
-          }
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "bundled": true,
-          "dev": true
-        },
-        "stack-utils": {
-          "version": "2.0.5",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "escape-string-regexp": "^2.0.0"
-          },
-          "dependencies": {
-            "escape-string-regexp": {
-              "version": "2.0.0",
-              "bundled": true,
-              "dev": true
-            }
-          }
-        },
-        "string-width": {
-          "version": "4.2.3",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "emoji-regex": "^8.0.0",
-            "is-fullwidth-code-point": "^3.0.0",
-            "strip-ansi": "^6.0.1"
-          }
-        },
-        "strip-ansi": {
-          "version": "6.0.1",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^5.0.1"
-          }
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        },
-        "tap-parser": {
-          "version": "11.0.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "events-to-array": "^1.0.1",
-            "minipass": "^3.1.6",
-            "tap-yaml": "^1.0.0"
-          }
-        },
-        "tap-yaml": {
-          "version": "1.0.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "yaml": "^1.10.2"
-          }
-        },
-        "to-fast-properties": {
-          "version": "2.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "treport": {
-          "version": "3.0.4",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@isaacs/import-jsx": "^4.0.1",
-            "cardinal": "^2.1.1",
-            "chalk": "^3.0.0",
-            "ink": "^3.2.0",
-            "ms": "^2.1.2",
-            "tap-parser": "^11.0.0",
-            "tap-yaml": "^1.0.0",
-            "unicode-length": "^2.0.2"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "4.3.0",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "color-convert": "^2.0.1"
-              }
-            },
-            "chalk": {
-              "version": "3.0.0",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "ansi-styles": "^4.1.0",
-                "supports-color": "^7.1.0"
-              }
-            },
-            "color-convert": {
-              "version": "2.0.1",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "color-name": "~1.1.4"
-              }
-            },
-            "color-name": {
-              "version": "1.1.4",
-              "bundled": true,
-              "dev": true
-            },
-            "has-flag": {
-              "version": "4.0.0",
-              "bundled": true,
-              "dev": true
-            },
-            "supports-color": {
-              "version": "7.2.0",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "has-flag": "^4.0.0"
-              }
-            }
-          }
-        },
-        "type-fest": {
-          "version": "0.12.0",
-          "bundled": true,
-          "dev": true
-        },
-        "unicode-length": {
-          "version": "2.0.2",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "punycode": "^2.0.0",
-            "strip-ansi": "^3.0.1"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "2.1.1",
-              "bundled": true,
-              "dev": true
-            },
-            "strip-ansi": {
-              "version": "3.0.1",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "ansi-regex": "^2.0.0"
-              }
-            }
-          }
-        },
-        "widest-line": {
-          "version": "3.1.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "string-width": "^4.0.0"
-          }
-        },
-        "wrap-ansi": {
-          "version": "6.2.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.0.0",
-            "string-width": "^4.1.0",
-            "strip-ansi": "^6.0.0"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "4.3.0",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "color-convert": "^2.0.1"
-              }
-            },
-            "color-convert": {
-              "version": "2.0.1",
-              "bundled": true,
-              "dev": true,
-              "requires": {
-                "color-name": "~1.1.4"
-              }
-            },
-            "color-name": {
-              "version": "1.1.4",
-              "bundled": true,
-              "dev": true
-            }
-          }
-        },
-        "wrappy": {
-          "version": "1.0.2",
-          "bundled": true,
-          "dev": true
-        },
-        "ws": {
-          "version": "7.5.7",
-          "bundled": true,
-          "dev": true,
-          "requires": {}
-        },
-        "yallist": {
-          "version": "4.0.0",
-          "bundled": true,
-          "dev": true
-        },
-        "yaml": {
-          "version": "1.10.2",
-          "bundled": true,
-          "dev": true
-        },
-        "yoga-layout-prebuilt": {
-          "version": "1.10.0",
-          "bundled": true,
-          "dev": true,
-          "requires": {
-            "@types/yoga-layout": "1.9.2"
-          }
-        }
-      }
-    },
-    "tap-mocha-reporter": {
-      "version": "5.0.3",
-      "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.3.tgz",
-      "integrity": "sha512-6zlGkaV4J+XMRFkN0X+yuw6xHbE9jyCZ3WUKfw4KxMyRGOpYSRuuQTRJyWX88WWuLdVTuFbxzwXhXuS2XE6o0g==",
-      "dev": true,
-      "requires": {
-        "color-support": "^1.1.0",
-        "debug": "^4.1.1",
-        "diff": "^4.0.1",
-        "escape-string-regexp": "^2.0.0",
-        "glob": "^7.0.5",
-        "tap-parser": "^11.0.0",
-        "tap-yaml": "^1.0.0",
-        "unicode-length": "^2.0.2"
-      },
-      "dependencies": {
-        "escape-string-regexp": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
-          "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
-          "dev": true
-        }
-      }
-    },
-    "tap-parser": {
-      "version": "11.0.2",
-      "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-11.0.2.tgz",
-      "integrity": "sha512-6qGlC956rcORw+fg7Fv1iCRAY8/bU9UabUAhs3mXRH6eRmVZcNPLheSXCYaVaYeSwx5xa/1HXZb1537YSvwDZg==",
-      "dev": true,
-      "requires": {
-        "events-to-array": "^1.0.1",
-        "minipass": "^3.1.6",
-        "tap-yaml": "^1.0.0"
-      },
-      "dependencies": {
-        "minipass": {
-          "version": "3.3.6",
-          "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
-          "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
-          "dev": true,
-          "requires": {
-            "yallist": "^4.0.0"
-          }
-        }
-      }
-    },
-    "tap-yaml": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.2.tgz",
-      "integrity": "sha512-GegASpuqBnRNdT1U+yuUPZ8rEU64pL35WPBpCISWwff4dErS2/438barz7WFJl4Nzh3Y05tfPidZnH+GaV1wMg==",
-      "dev": true,
-      "requires": {
-        "yaml": "^1.10.2"
-      }
-    },
-    "tcompare": {
-      "version": "5.0.7",
-      "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-5.0.7.tgz",
-      "integrity": "sha512-d9iddt6YYGgyxJw5bjsN7UJUO1kGOtjSlNy/4PoGYAjQS5pAT/hzIoLf1bZCw+uUxRmZJh7Yy1aA7xKVRT9B4w==",
-      "dev": true,
-      "requires": {
-        "diff": "^4.0.2"
-      }
-    },
-    "test-exclude": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
-      "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
-      "dev": true,
-      "requires": {
-        "@istanbuljs/schema": "^0.1.2",
-        "glob": "^7.1.4",
-        "minimatch": "^3.0.4"
-      },
-      "dependencies": {
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        }
-      }
-    },
-    "text-table": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
-      "dev": true,
-      "peer": true
-    },
-    "to-fast-properties": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
-      "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
-      "dev": true
-    },
-    "to-regex-range": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
-      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dev": true,
-      "requires": {
-        "is-number": "^7.0.0"
-      }
-    },
-    "tough-cookie": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
-      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "psl": "^1.1.28",
-        "punycode": "^2.1.1"
-      }
-    },
-    "trivial-deferred": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.0.1.tgz",
-      "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=",
-      "dev": true
-    },
-    "ts-node": {
-      "version": "10.9.1",
-      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
-      "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
-      "dev": true,
-      "requires": {
-        "@cspotcode/source-map-support": "^0.8.0",
-        "@tsconfig/node10": "^1.0.7",
-        "@tsconfig/node12": "^1.0.7",
-        "@tsconfig/node14": "^1.0.0",
-        "@tsconfig/node16": "^1.0.2",
-        "acorn": "^8.4.1",
-        "acorn-walk": "^8.1.1",
-        "arg": "^4.1.0",
-        "create-require": "^1.1.0",
-        "diff": "^4.0.1",
-        "make-error": "^1.1.1",
-        "v8-compile-cache-lib": "^3.0.1",
-        "yn": "3.1.1"
-      }
-    },
-    "tunnel-agent": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "type-check": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
-      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "prelude-ls": "^1.2.1"
-      }
-    },
-    "type-fest": {
-      "version": "0.8.1",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
-      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
-      "dev": true
-    },
-    "typedarray-to-buffer": {
-      "version": "3.1.5",
-      "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
-      "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
-      "dev": true,
-      "requires": {
-        "is-typedarray": "^1.0.0"
-      }
-    },
-    "typedoc": {
-      "version": "0.23.24",
-      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.24.tgz",
-      "integrity": "sha512-bfmy8lNQh+WrPYcJbtjQ6JEEsVl/ce1ZIXyXhyW+a1vFrjO39t6J8sL/d6FfAGrJTc7McCXgk9AanYBSNvLdIA==",
-      "dev": true,
-      "requires": {
-        "lunr": "^2.3.9",
-        "marked": "^4.2.5",
-        "minimatch": "^5.1.2",
-        "shiki": "^0.12.1"
-      },
-      "dependencies": {
-        "minimatch": {
-          "version": "5.1.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.4.tgz",
-          "integrity": "sha512-U0iNYXt9wALljzfnGkhFSy5sAC6/SCR3JrHrlsdJz4kF8MvhTRQNiC59iUi1iqsitV7abrNAJWElVL9pdnoUgw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^2.0.1"
-          }
-        }
-      }
-    },
-    "typescript": {
-      "version": "4.9.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
-      "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
-      "dev": true
-    },
-    "unicode-length": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz",
-      "integrity": "sha512-Ph/j1VbS3/r77nhoY2WU0GWGjVYOHL3xpKp0y/Eq2e5r0mT/6b649vm7KFO6RdAdrZkYLdxphYVgvODxPB+Ebg==",
-      "dev": true,
-      "requires": {
-        "punycode": "^2.0.0",
-        "strip-ansi": "^3.0.1"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-          "dev": true
-        },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^2.0.0"
-          }
-        }
-      }
-    },
-    "uri-js": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
-      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
-      "dev": true,
-      "peer": true,
-      "requires": {
-        "punycode": "^2.1.0"
-      }
-    },
-    "uuid": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
-      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
-    "v8-compile-cache-lib": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
-      "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
-      "dev": true
-    },
-    "v8-to-istanbul": {
-      "version": "9.0.1",
-      "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
-      "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
-      "dev": true,
-      "requires": {
-        "@jridgewell/trace-mapping": "^0.3.12",
-        "@types/istanbul-lib-coverage": "^2.0.1",
-        "convert-source-map": "^1.6.0"
-      },
-      "dependencies": {
-        "@jridgewell/trace-mapping": {
-          "version": "0.3.17",
-          "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
-          "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
-          "dev": true,
-          "requires": {
-            "@jridgewell/resolve-uri": "3.1.0",
-            "@jridgewell/sourcemap-codec": "1.4.14"
-          }
-        }
-      }
-    },
-    "verror": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-      "dev": true,
-      "optional": true,
-      "peer": true,
-      "requires": {
-        "assert-plus": "^1.0.0",
-        "core-util-is": "1.0.2",
-        "extsprintf": "^1.2.0"
-      }
-    },
-    "vscode-oniguruma": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
-      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
-      "dev": true
-    },
-    "vscode-textmate": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
-      "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
-      "dev": true
-    },
-    "which": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
-      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
-      "dev": true,
-      "requires": {
-        "isexe": "^2.0.0"
-      }
-    },
-    "which-module": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
-      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
-      "dev": true
-    },
-    "word-wrap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
-      "dev": true,
-      "peer": true
-    },
-    "wrap-ansi": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-      "dev": true,
-      "requires": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-          "dev": true
-        }
-      }
-    },
-    "wrappy": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-      "dev": true
-    },
-    "write-file-atomic": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
-      "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
-      "dev": true,
-      "requires": {
-        "imurmurhash": "^0.1.4",
-        "is-typedarray": "^1.0.0",
-        "signal-exit": "^3.0.2",
-        "typedarray-to-buffer": "^3.1.5"
-      }
-    },
-    "y18n": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
-      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
-      "dev": true
-    },
-    "yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-      "dev": true
-    },
-    "yaml": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
-      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
-      "dev": true
-    },
-    "yargs": {
-      "version": "15.4.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
-      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
-      "dev": true,
-      "requires": {
-        "cliui": "^6.0.0",
-        "decamelize": "^1.2.0",
-        "find-up": "^4.1.0",
-        "get-caller-file": "^2.0.1",
-        "require-directory": "^2.1.1",
-        "require-main-filename": "^2.0.0",
-        "set-blocking": "^2.0.0",
-        "string-width": "^4.2.0",
-        "which-module": "^2.0.0",
-        "y18n": "^4.0.0",
-        "yargs-parser": "^18.1.2"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "cliui": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
-          "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
-          "dev": true,
-          "requires": {
-            "string-width": "^4.2.0",
-            "strip-ansi": "^6.0.0",
-            "wrap-ansi": "^6.2.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-          "dev": true
-        },
-        "wrap-ansi": {
-          "version": "6.2.0",
-          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
-          "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.0.0",
-            "string-width": "^4.1.0",
-            "strip-ansi": "^6.0.0"
-          }
-        }
-      }
-    },
-    "yargs-parser": {
-      "version": "18.1.3",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
-      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
-      "dev": true,
-      "requires": {
-        "camelcase": "^5.0.0",
-        "decamelize": "^1.2.0"
-      }
-    },
-    "yn": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
-      "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
-      "dev": true
-    },
-    "yocto-queue": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
-      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
-      "dev": true
     }
   }
 }
diff --git a/package.json b/package.json
index 6c9553b2..05d3806c 100644
--- a/package.json
+++ b/package.json
@@ -64,7 +64,6 @@
     "path-scurry": "^1.5.0"
   },
   "devDependencies": {
-    "@types/mkdirp": "^1.0.2",
     "@types/node": "^18.11.18",
     "@types/tap": "^15.0.7",
     "c8": "^7.12.0",

From b22fc7daaaf8a1d231f68c91e22f94376f65bd0b Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 27 Feb 2023 11:58:41 -0800
Subject: [PATCH 114/163] minimatch@7.3.0

This adds support for posix character classes
---
 package-lock.json | 8 ++++----
 package.json      | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index c1aaee59..6d254ac7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "minimatch": "^7.2.0",
+        "minimatch": "^7.3.0",
         "minipass": "^4.2.4",
         "path-scurry": "^1.5.0"
       },
@@ -2449,9 +2449,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.2.0.tgz",
-      "integrity": "sha512-rMRHmwySzopAQjmWW6TkAKCEDKNaY/HuV/c2YkWWuWnfkTwApt0V4hnYzzPnZ/5Gcd2+8MPncSyuOGPl3xPvcg==",
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.3.0.tgz",
+      "integrity": "sha512-WaMDuhKa7a6zKiwplR1AOz+zGvJba24k5VU1Cy6NhEguavT2YRlHxuINUgTas4wiS6fwBpYq4TcA1XIECSntyw==",
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
diff --git a/package.json b/package.json
index 05d3806c..c7746710 100644
--- a/package.json
+++ b/package.json
@@ -59,7 +59,7 @@
   },
   "dependencies": {
     "fs.realpath": "^1.0.0",
-    "minimatch": "^7.2.0",
+    "minimatch": "^7.3.0",
     "minipass": "^4.2.4",
     "path-scurry": "^1.5.0"
   },

From ad3904d7f143e814896c0114731acf462d075cc3 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 27 Feb 2023 11:59:42 -0800
Subject: [PATCH 115/163] update readme with posix class support

---
 README.md | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index a20a2d65..33bf8342 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 Match files using the patterns the shell uses.
 
 The most correct and second fastest glob implementation in
-JavaScript.  (See **Comparison to Other JavaScript Glob
+JavaScript. (See **Comparison to Other JavaScript Glob
 Implementations** at the bottom of this readme.)
 
 ![a fun cartoon logo made of glob characters](logo/glob.png)
@@ -418,10 +418,10 @@ expanded **first** into the set of `+(a|b)` and `+(a|c)`, and
 those patterns are checked for validity. Since those two are
 valid, matching proceeds.
 
-The character class patterns `[:class:]` (POSIX standard named
-classes), `[=c=]` (locale-specific character collation weight),
-and `[.symbol.]` (collating symbol) style class patterns are
-_not_ supported by this implementation at this time.
+The character class patterns `[:class:]` (posix standard named
+classes) style class patterns are supported and unicode-aware,
+but `[=c=]` (locale-specific character collation weight), and
+`[.symbol.]` (collating symbol), are not.
 
 ### Repeated Slashes
 
@@ -569,7 +569,7 @@ npm run prof
 There are some other glob matcher libraries on npm, but these
 three are (in my opinion, as of 2023) the best.
 
-----
+---
 
 **full explanation**
 
@@ -623,7 +623,7 @@ Former versions of this module are far too slow for any cases
 where performance matters at all, and were designed with APIs
 that are extremely dated by current JavaScript standards.
 
-----
+---
 
 [1]: In the cases where this module
 returns results and `fast-glob` doesn't, it's even faster, of

From 474172d5e87a5eda64c0dffb10ead57c2826c805 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 27 Feb 2023 12:02:19 -0800
Subject: [PATCH 116/163] update readme with cwd URL support

---
 README.md | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index 33bf8342..fb49bccb 100644
--- a/README.md
+++ b/README.md
@@ -198,12 +198,12 @@ If you are running many `glob` operations, you can pass a Glob
 object as the `options` argument to a subsequent operation to
 share the previously loaded cache.
 
-- `cwd` String. The current working directory in which to
-  search. Defaults to `process.cwd()`. This option is always
-  coerced to use forward-slashes as a path separator, because it
-  is not tested as a glob pattern, so there is no need to escape
-  anything. See also: "Windows, CWDs, Drive Letters, and UNC
-  Paths", below.
+- `cwd` String path or `file://` string or URL object. The
+  current working directory in which to search. Defaults to
+  `process.cwd()`. This option is always coerced to use
+  forward-slashes as a path separator, because it is not tested
+  as a glob pattern, so there is no need to escape anything. See
+  also: "Windows, CWDs, Drive Letters, and UNC Paths", below.
 
   This option may be eiher a string path or a `file://` URL
   object or string.

From 42a3ac7ec172bb1b502a048e1bb3f14cf299f117 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 27 Feb 2023 12:05:43 -0800
Subject: [PATCH 117/163] link to bash manual for Pattern Matching

---
 README.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index fb49bccb..0d38616b 100644
--- a/README.md
+++ b/README.md
@@ -515,7 +515,8 @@ majority of operations, this is never a problem.
 ### See Also:
 
 - `man sh`
-- `man bash` (Search for "Pattern Matching")
+- `man bash` [Pattern
+  Matching](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html)
 - `man 3 fnmatch`
 - `man 5 gitignore`
 - [minimatch documentation](https://github.com/isaacs/minimatch)

From a547a9c3e9c3a9e734204435871d6339d2d62e55 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 27 Feb 2023 12:46:49 -0800
Subject: [PATCH 118/163] more docs

---
 README.md        |  10 ++-
 src/glob.ts      | 179 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/has-magic.ts |   4 ++
 src/ignore.ts    |   3 +
 src/index.ts     |  24 +++++++
 src/pattern.ts   |  63 ++++++++++++++---
 src/processor.ts |  18 +++++
 src/walker.ts    |   6 ++
 8 files changed, 291 insertions(+), 16 deletions(-)

diff --git a/README.md b/README.md
index 0d38616b..edf8c456 100644
--- a/README.md
+++ b/README.md
@@ -200,10 +200,8 @@ share the previously loaded cache.
 
 - `cwd` String path or `file://` string or URL object. The
   current working directory in which to search. Defaults to
-  `process.cwd()`. This option is always coerced to use
-  forward-slashes as a path separator, because it is not tested
-  as a glob pattern, so there is no need to escape anything. See
-  also: "Windows, CWDs, Drive Letters, and UNC Paths", below.
+  `process.cwd()`.  See also: "Windows, CWDs, Drive Letters, and
+  UNC Paths", below.
 
   This option may be eiher a string path or a `file://` URL
   object or string.
@@ -354,8 +352,8 @@ path separators (ie, `/` on all platforms, and `\` on Windows).
   or 0 if it is the first item, unless `follow:true` is set, in
   which case it follows all symbolic links.
 
-`[:class:]`, `[=c=]`, and `[.symbol.]` style class patterns are
-_not_ supported by this implementation at this time.
+`[:class:]` patterns are supported by this implementation, but
+`[=c=]` and `[.symbol.]` style class patterns are not.
 
 ### Dots
 
diff --git a/src/glob.ts b/src/glob.ts
index cfdd58e2..af40fe7a 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -7,7 +7,7 @@ import {
   PathScurryPosix,
   PathScurryWin32,
 } from 'path-scurry'
-import {fileURLToPath} from 'url'
+import { fileURLToPath } from 'url'
 import { Ignore } from './ignore.js'
 import { Pattern } from './pattern.js'
 import { GlobStream, GlobWalker } from './walker.js'
@@ -24,30 +24,163 @@ const defaultPlatform: NodeJS.Platform =
     ? process.platform
     : 'linux'
 
+/**
+ * A `GlobOptions` object may be provided to any of the exported methods, and
+ * must be provided to the `Glob` constructor.
+ *
+ * All options are optional, boolean, and false by default, unless otherwise
+ * noted.
+ *
+ * All resolved options are added to the Glob object as properties.
+ *
+ * If you are running many `glob` operations, you can pass a Glob object as the
+ * `options` argument to a subsequent operation to share the previously loaded
+ * cache.
+ */
 export interface GlobOptions {
+  /**
+   * Set to true to always receive absolute paths for
+   * matched files. This does _not_ make an extra system call to get
+   * the realpath, it only does string path resolution.
+   *
+   * By default, when this option is not set, absolute paths are
+   * returned for patterns that are absolute, and otherwise paths
+   * are returned that are relative to the `cwd` setting.
+   *
+   * Conflicts with {@link withFileTypes}
+   */
   absolute?: boolean
+  /**
+   * Set to false to enable {@link windowsPathsNoEscape}
+   *
+   * @deprecated
+   */
   allowWindowsEscape?: boolean
+  /**
+   * The current working directory in which to search. Defaults to
+   * `process.cwd()`.
+   *
+   * May be eiher a string path or a `file://` URL object or string.
+   */
   cwd?: string | URL
+  /**
+   * Include `.dot` files in normal matches and `globstar`
+   * matches. Note that an explicit dot in a portion of the pattern
+   * will always match dot files.
+   */
   dot?: boolean
+  /**
+   * Follow symlinked directories when expanding `**`
+   * patterns. This can result in a lot of duplicate references in
+   * the presence of cyclic links, and make performance quite bad.
+   *
+   * By default, a `**` in a pattern will follow 1 symbolic link if
+   * it is not the first item in the pattern, or none if it is the
+   * first item in the pattern, following the same behavior as Bash.
+   */
   follow?: boolean
+  /**
+   * A glob pattern or array of glob patterns to exclude from matches. To
+   * ignore all children within a directory, as well as the entry itself,
+   * append `/**'` to the ignore pattern.
+   */
   ignore?: string | string[] | Ignore
+  /**
+   * Add a `/` character to directory matches. Note that this requires
+   * additional stat calls in some cases.
+   */
   mark?: boolean
+  /**
+   * Perform a basename-only match if the pattern does not contain any slash
+   * characters. That is, `*.js` would be treated as equivalent to
+   * `**\/*.js`, matching all js files in all directories.
+   */
   matchBase?: boolean
+  /**
+   * Do not expand `{a,b}` and `{1..3}` brace sets.
+   */
   nobrace?: boolean
+  /**
+   * Perform a case-insensitive match. This defaults to `true` on macOS and
+   * Windows systems, and `false` on all others.
+   *
+   * **Note** `nocase` should only be explicitly set when it is
+   * known that the filesystem's case sensitivity differs from the
+   * platform default. If set `true` on case-sensitive file
+   * systems, or `false` on case-insensitive file systems, then the
+   * walk may return more or less results than expected.
+   */
   nocase?: boolean
+  /**
+   * Do not match directories, only files. (Note: to match
+   * _only_ directories, put a `/` at the end of the pattern.)
+   */
   nodir?: boolean
+  /**
+   * Do not match "extglob" patterns such as `+(a|b)`.
+   */
   noext?: boolean
+  /**
+   * Do not match `**` against multiple filenames. (Ie, treat it as a normal
+   * `*` instead.)
+   *
+   * Conflicts with {@link matchBase}
+   */
   noglobstar?: boolean
+  /**
+   * Defaults to value of `process.platform` if available, or `'linux'` if
+   * not. Setting `platform:'win32'` on non-Windows systems may cause strange
+   * behavior.
+   */
   platform?: NodeJS.Platform
+  /**
+   * Set to true to call `fs.realpath` on all of the
+   * results. In the case of an entry that cannot be resolved, the
+   * entry is omitted. This incurs a slight performance penalty, of
+   * course, because of the added system calls.
+   */
   realpath?: boolean
+  /**
+   * A [PathScurry](http://npm.im/path-scurry) object used
+   * to traverse the file system. If the `nocase` option is set
+   * explicitly, then any provided `scurry` object must match this
+   * setting.
+   */
   scurry?: PathScurry
+  /**
+   * An AbortSignal which will cancel the Glob walk when
+   * triggered.
+   */
   signal?: AbortSignal
+  /**
+   * Use `\\` as a path separator _only_, and
+   *  _never_ as an escape character. If set, all `\\` characters are
+   *  replaced with `/` in the pattern.
+   *
+   *  Note that this makes it **impossible** to match against paths
+   *  containing literal glob pattern characters, but allows matching
+   *  with patterns constructed using `path.join()` and
+   *  `path.resolve()` on Windows platforms, mimicking the (buggy!)
+   *  behavior of Glob v7 and before on Windows. Please use with
+   *  caution, and be mindful of [the caveat below about Windows
+   *  paths](#windows). (For legacy reasons, this is also set if
+   *  `allowWindowsEscape` is set to the exact value `false`.)
+   */
   windowsPathsNoEscape?: boolean
+  /**
+   * Return [PathScurry](http://npm.im/path-scurry)
+   * `Path` objects instead of strings. These are similar to a
+   * NodeJS `Dirent` object, but with additional methods and
+   * properties.
+   *
+   * Conflicts with {@link absolute}
+   */
   withFileTypes?: boolean
 }
 
 export type GlobOptionsWithFileTypesTrue = GlobOptions & {
   withFileTypes: true
+  absolute?: false
 }
 
 export type GlobOptionsWithFileTypesFalse = GlobOptions & {
@@ -75,7 +208,10 @@ export type FileTypes = Opts extends GlobOptionsWithFileTypesTrue
   ? false
   : boolean
 
-export class Glob {
+/**
+ * An object that can perform glob pattern traversals.
+ */
+export class Glob implements GlobOptions {
   absolute: boolean
   cwd: string
   dot: boolean
@@ -96,9 +232,28 @@ export class Glob {
   windowsPathsNoEscape: boolean
   withFileTypes: FileTypes
 
+  /**
+   * The options provided to the constructor.
+   */
   opts: Opts
+
+  /**
+   * An array of parsed immutable {@link Pattern} objects.
+   */
   patterns: Pattern[]
 
+  /**
+   * All options are stored as properties on the `Glob` object.
+   *
+   * See {@link GlobOptions} for full options descriptions.
+   *
+   * Note that a previous `Glob` object can be passed as the
+   * `GlobOptions` to another `Glob` instantiation to re-use settings
+   * and caches with a new pattern.
+   *
+   * Traversal functions can be called multiple times to run the walk
+   * again.
+   */
   constructor(pattern: string | string[], opts: Opts) {
     this.withFileTypes = !!opts.withFileTypes as FileTypes
     this.signal = opts.signal
@@ -198,6 +353,9 @@ export class Glob {
     })
   }
 
+  /**
+   * Returns a Promise that resolves to the results array.
+   */
   async walk(): Promise>
   async walk(): Promise<(string | Path)[]> {
     // Walkers always return array of Path objects, so we just have to
@@ -213,6 +371,9 @@ export class Glob {
     ]
   }
 
+  /**
+   * synchronous {@link Glob.walk}
+   */
   walkSync(): Results
   walkSync(): (string | Path)[] {
     return [
@@ -224,6 +385,9 @@ export class Glob {
     ]
   }
 
+  /**
+   * Stream results asynchronously.
+   */
   stream(): Minipass, Result>
   stream(): Minipass {
     return new GlobStream(this.patterns, this.scurry.cwd, {
@@ -233,6 +397,9 @@ export class Glob {
     }).stream()
   }
 
+  /**
+   * Stream results synchronously.
+   */
   streamSync(): Minipass, Result>
   streamSync(): Minipass {
     return new GlobStream(this.patterns, this.scurry.cwd, {
@@ -242,6 +409,10 @@ export class Glob {
     }).streamSync()
   }
 
+  /**
+   * Default sync iteration function. Returns a Generator that
+   * iterates over the results.
+   */
   iterateSync(): Generator, void, void> {
     return this.streamSync()[Symbol.iterator]()
   }
@@ -249,6 +420,10 @@ export class Glob {
     return this.iterateSync()
   }
 
+  /**
+   * Default async iteration function. Returns an AsyncGenerator that
+   * iterates over the results.
+   */
   iterate(): AsyncGenerator, void, void> {
     return this.stream()[Symbol.asyncIterator]()
   }
diff --git a/src/has-magic.ts b/src/has-magic.ts
index e2db2b43..ea85c700 100644
--- a/src/has-magic.ts
+++ b/src/has-magic.ts
@@ -1,5 +1,9 @@
 import { Glob, GlobOptions } from './glob.js'
 
+/**
+ * Return true if the patterns provided contain any magic
+ * glob characters.
+ */
 export const hasMagic = (
   pattern: string | string[],
   options: GlobOptions = {}
diff --git a/src/ignore.ts b/src/ignore.ts
index d2fbb0d8..60d4deec 100644
--- a/src/ignore.ts
+++ b/src/ignore.ts
@@ -15,6 +15,9 @@ const defaultPlatform: NodeJS.Platform =
     ? process.platform
     : 'linux'
 
+/**
+ * Class used to process ignored patterns
+ */
 export class Ignore {
   relative: Minimatch[]
   relativeChildren: Minimatch[]
diff --git a/src/index.ts b/src/index.ts
index 67c1c374..f2d6d10d 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -15,6 +15,11 @@ import type {
   Result,
 } from './walker.js'
 
+/**
+ * Syncronous form of {@link globStream}. Will read all the matches as fast as
+ * you consume them, even all in a single tick if you consume them immediately,
+ * but will still respond to backpressure if they're not consumed immediately.
+ */
 export function globStreamSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesTrue
@@ -38,6 +43,10 @@ export function globStreamSync(
   return new Glob(pattern, options).streamSync()
 }
 
+/**
+ * Return a stream that emits all the strings or `Path` objects and
+ * then emits `end` when completed.
+ */
 export function globStream(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesFalse
@@ -61,6 +70,9 @@ export function globStream(
   return new Glob(pattern, options).stream()
 }
 
+/**
+ * Synchronous form of {@link glob}
+ */
 export function globSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesFalse
@@ -84,6 +96,12 @@ export function globSync(
   return new Glob(pattern, options).walkSync()
 }
 
+/**
+ * Perform an asynchronous glob search for the pattern(s) specified. Returns
+ * [Path](https://isaacs.github.io/path-scurry/classes/PathBase) objects if the
+ * {@link withFileTypes} option is set to `true`. See {@link GlobOptions} for
+ * full option descriptions.
+ */
 export async function glob(
   pattern: string | string[],
   options?: GlobOptionsWithFileTypesUnset | undefined
@@ -107,6 +125,9 @@ export async function glob(
   return new Glob(pattern, options).walk()
 }
 
+/**
+ * Return an async iterator for walking glob pattern matches.
+ */
 export function globIterate(
   pattern: string | string[],
   options?: GlobOptionsWithFileTypesUnset | undefined
@@ -130,6 +151,9 @@ export function globIterate(
   return new Glob(pattern, options).iterate()
 }
 
+/**
+ * Return a sync iterator for walking glob pattern matches.
+ */
 export function globIterateSync(
   pattern: string | string[],
   options?: GlobOptionsWithFileTypesUnset | undefined
diff --git a/src/pattern.ts b/src/pattern.ts
index 3d086533..e9fadf73 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -20,6 +20,10 @@ const isPatternList = (pl: MMPattern[]): pl is PatternList =>
   pl.length >= 1
 const isGlobList = (gl: string[]): gl is GlobList => gl.length >= 1
 
+/**
+ * An immutable-ish view on an array of glob parts and their parsed
+ * results
+ */
 export class Pattern {
   readonly #patternList: PatternList
   readonly #globList: GlobList
@@ -98,20 +102,35 @@ export class Pattern {
     }
   }
 
+  /**
+   * The first entry in the parsed list of patterns
+   */
   pattern(): MMPattern {
     return this.#patternList[this.#index]
   }
 
+  /**
+   * true of if pattern() returns a string
+   */
   isString(): boolean {
     return typeof this.#patternList[this.#index] === 'string'
   }
+  /**
+   * true of if pattern() returns GLOBSTAR
+   */
   isGlobstar(): boolean {
     return this.#patternList[this.#index] === GLOBSTAR
   }
+  /**
+   * true if pattern() returns a regexp
+   */
   isRegExp(): boolean {
     return this.#patternList[this.#index] instanceof RegExp
   }
 
+  /**
+   * The /-joined set of glob parts that make up this pattern
+   */
   globString(): string {
     return (this.#globString =
       this.#globString ||
@@ -122,10 +141,16 @@ export class Pattern {
         : this.#globList.slice(this.#index).join('/')))
   }
 
+  /**
+   * true if there are more pattern parts after this one
+   */
   hasMore(): boolean {
     return this.length > this.#index + 1
   }
 
+  /**
+   * The rest of the pattern after this part, or null if this is the end
+   */
   rest(): Pattern | null {
     if (this.#rest !== undefined) return this.#rest
     if (!this.hasMore()) return (this.#rest = null)
@@ -141,9 +166,11 @@ export class Pattern {
     return this.#rest
   }
 
-  // pattern like: //host/share/...
-  // split = [ '', '', 'host', 'share', ... ]
-  isUNC(pl = this.#patternList): pl is UNCPatternList {
+  /**
+   * true if the pattern represents a //unc/path/ on windows
+   */
+  isUNC(): boolean {
+    const pl = this.#patternList
     return this.#isUNC !== undefined
       ? this.#isUNC
       : (this.#isUNC =
@@ -162,7 +189,11 @@ export class Pattern {
   // XXX: would be nice to handle patterns like `c:*` to test the cwd
   // in c: for *, but I don't know of a way to even figure out what that
   // cwd is without actually chdir'ing into it?
-  isDrive(pl = this.#patternList): pl is DrivePatternList {
+  /**
+   * True if the pattern starts with a drive letter on Windows
+   */
+  isDrive(): boolean {
+    const pl = this.#patternList
     return this.#isDrive !== undefined
       ? this.#isDrive
       : (this.#isDrive =
@@ -176,16 +207,22 @@ export class Pattern {
   // pattern = '/' or '/...' or '/x/...'
   // split = ['', ''] or ['', ...] or ['', 'x', ...]
   // Drive and UNC both considered absolute on windows
-  isAbsolute(pl = this.#patternList): pl is AbsolutePatternList {
+  /**
+   * True if the pattern is rooted on an absolute path
+   */
+  isAbsolute(): boolean {
+    const pl = this.#patternList
     return this.#isAbsolute !== undefined
       ? this.#isAbsolute
       : (this.#isAbsolute =
           (pl[0] === '' && pl.length > 1) ||
-          this.isDrive(pl) ||
-          this.isUNC(pl))
+          this.isDrive() ||
+          this.isUNC())
   }
 
-  // consume the root of the pattern, and return it
+  /**
+   * consume the root of the pattern, and return it
+   */
   root(): string {
     const p = this.#patternList[0]
     return typeof p === 'string' && this.isAbsolute() && this.#index === 0
@@ -193,6 +230,9 @@ export class Pattern {
       : ''
   }
 
+  /**
+   * True if the pattern has any non-string components
+   */
   hasMagic(): boolean {
     for (let i = 0; i < this.length; i++) {
       if (typeof this.#patternList[i] !== 'string') {
@@ -202,6 +242,10 @@ export class Pattern {
     return false
   }
 
+  /**
+   * Check to see if the current globstar pattern is allowed to follow
+   * a symbolic link.
+   */
   checkFollowGlobstar(): boolean {
     return !(
       this.#index === 0 ||
@@ -210,6 +254,9 @@ export class Pattern {
     )
   }
 
+  /**
+   * Mark that the current globstar pattern is following a symbolic link
+   */
   markFollowGlobstar(): boolean {
     if (this.#index === 0 || !this.isGlobstar() || !this.#followGlobstar)
       return false
diff --git a/src/processor.ts b/src/processor.ts
index 092c1f4b..974b8ba5 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -5,6 +5,9 @@ import { Path } from 'path-scurry'
 import { MMPattern, Pattern } from './pattern.js'
 import { GlobWalkerOpts } from './walker.js'
 
+/**
+ * A cache of which patterns have been processed for a given Path
+ */
 export class HasWalkedCache {
   store: Map>
   constructor(store: Map> = new Map()) {
@@ -24,6 +27,11 @@ export class HasWalkedCache {
   }
 }
 
+/**
+ * A record of which paths have been matched in a given walk step,
+ * and whether they only are considered a match if they are a directory,
+ * and whether their absolute or relative path should be returned.
+ */
 export class MatchRecord {
   store: Map = new Map()
   add(target: Path, absolute: boolean, ifDir: boolean) {
@@ -41,6 +49,10 @@ export class MatchRecord {
   }
 }
 
+/**
+ * A collection of patterns that must be processed in a subsequent step
+ * for a given path.
+ */
 export class SubWalks {
   store: Map = new Map()
   add(target: Path, pattern: Pattern) {
@@ -71,6 +83,12 @@ export class SubWalks {
   }
 }
 
+/**
+ * The class that processes patterns for a given path.
+ *
+ * Handles child entry filtering, and determining whether a path's
+ * directory contents must be read.
+ */
 export class Processor {
   hasWalkedCache: HasWalkedCache
   matches = new MatchRecord()
diff --git a/src/walker.ts b/src/walker.ts
index 479cb737..d813f9f2 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -1,3 +1,9 @@
+/**
+ * Single-use utility classes to provide functionality to the {@link Glob}
+ * methods.
+ *
+ * @module
+ */
 import Minipass from 'minipass'
 import { Path } from 'path-scurry'
 import { Ignore } from './ignore.js'

From 58159ca6767e7f8925e9301b9c0ac11211bde50b Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 27 Feb 2023 12:47:00 -0800
Subject: [PATCH 119/163] test: cwd can be a url

---
 test/url-cwd.ts | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 test/url-cwd.ts

diff --git a/test/url-cwd.ts b/test/url-cwd.ts
new file mode 100644
index 00000000..1733dabe
--- /dev/null
+++ b/test/url-cwd.ts
@@ -0,0 +1,15 @@
+import t from 'tap'
+import {pathToFileURL} from 'url'
+import {Glob} from '../'
+
+t.test('can use file url as cwd option', t => {
+  const fileURL = pathToFileURL(process.cwd())
+  const fileURLString = String(fileURL)
+  const ps = new Glob('.', { cwd: process.cwd()})
+  const pu = new Glob('.', { cwd: fileURL })
+  const pus = new Glob('.', { cwd: fileURLString })
+  t.equal(ps.cwd, process.cwd())
+  t.equal(pu.cwd, process.cwd())
+  t.equal(pus.cwd, process.cwd())
+  t.end()
+})

From a68703e61894ef260323dcc9f95b21f17197d951 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 27 Feb 2023 12:51:14 -0800
Subject: [PATCH 120/163] 9.0.0

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 6d254ac7..2c4a7b9f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.0.0-0",
+  "version": "9.0.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.0.0-0",
+      "version": "9.0.0",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index c7746710..03e6031d 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.0.0-0",
+  "version": "9.0.0",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"

From 03b9bcaa3b42b28f02139c27e15d1610ff9da4f0 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 27 Feb 2023 12:54:48 -0800
Subject: [PATCH 121/163] allow v14 higher than 14.17

https://fosstodon.org/@lukekarrys@hachyderm.io/109932512560141503

Of course, AbortSignal will have to be polyfilled if you want to use that.
---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 03e6031d..721557d3 100644
--- a/package.json
+++ b/package.json
@@ -91,6 +91,6 @@
     "url": "https://github.com/sponsors/isaacs"
   },
   "engines": {
-    "node": ">=16"
+    "node": ">=16 || 14 >=14.17"
   }
 }

From bedc98cfbb12f68e588c5f774d8bab5380fb6552 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 27 Feb 2023 12:55:25 -0800
Subject: [PATCH 122/163] 9.0.1

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 2c4a7b9f..43cbe966 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.0.0",
+  "version": "9.0.1",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.0.0",
+      "version": "9.0.1",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index 721557d3..8a689b56 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.0.0",
+  "version": "9.0.1",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"

From 9a97c528028ae1e6828ea145f015b5da9761e648 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 28 Feb 2023 13:26:12 -0800
Subject: [PATCH 123/163] add top-level types field to package.json

Fix: #494
---
 package.json            | 1 +
 test/bash-comparison.ts | 2 +-
 test/broken-symlink.ts  | 2 +-
 test/follow.ts          | 2 +-
 4 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/package.json b/package.json
index 8a689b56..bdf903b7 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
   },
   "main": "./dist/cjs/index-cjs.js",
   "module": "./dist/mjs/index.js",
+  "types": "./dist/mjs/index.d.ts",
   "exports": {
     ".": {
       "import": {
diff --git a/test/bash-comparison.ts b/test/bash-comparison.ts
index 8406dbbc..6dc97407 100644
--- a/test/bash-comparison.ts
+++ b/test/bash-comparison.ts
@@ -2,7 +2,7 @@
 // show that it does the same thing by default as the shell.
 import { resolve } from 'path'
 import t from 'tap'
-import { glob } from '../'
+import glob from '../'
 import { bashResults } from './bash-results'
 const globs = Object.keys(bashResults)
 
diff --git a/test/broken-symlink.ts b/test/broken-symlink.ts
index b854829a..fc30f391 100644
--- a/test/broken-symlink.ts
+++ b/test/broken-symlink.ts
@@ -1,6 +1,6 @@
 import { relative } from 'path'
 import t from 'tap'
-import { glob } from '../'
+import glob from '../'
 import { GlobOptionsWithFileTypesUnset } from '../src/glob.js'
 
 if (process.platform === 'win32') {
diff --git a/test/follow.ts b/test/follow.ts
index 101b3667..c917191c 100644
--- a/test/follow.ts
+++ b/test/follow.ts
@@ -1,5 +1,5 @@
 import t from 'tap'
-import { glob } from '../'
+import glob from '../'
 
 if (process.platform === 'win32') {
   t.plan(0, 'skip on windows')

From 281e91edb5176c3594c60f6e28655ce29e421044 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 28 Feb 2023 13:31:25 -0800
Subject: [PATCH 124/163] 9.0.2

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 43cbe966..78f95bd7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.0.1",
+  "version": "9.0.2",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.0.1",
+      "version": "9.0.2",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index bdf903b7..34de39b0 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.0.1",
+  "version": "9.0.2",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"

From 36f13cf2c9a6728a1ef09713d2b61248bceeabc6 Mon Sep 17 00:00:00 2001
From: Jake Boone 
Date: Tue, 28 Feb 2023 17:17:09 -0700
Subject: [PATCH 125/163] make subheadings h3's under "9.0" h2 heading in
 changelog.md

---
 changelog.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/changelog.md b/changelog.md
index 591d7d98..1a33f64d 100644
--- a/changelog.md
+++ b/changelog.md
@@ -3,7 +3,7 @@
 This is a full rewrite, with significant API and algorithm
 changes.
 
-## High-Level Feature and API Surface Changes
+### High-Level Feature and API Surface Changes
 
 - Only support node 16 and higher.
 - Promise API instead of callbacks.
@@ -32,7 +32,7 @@ changes.
   constructor. `{}` may be provided to accept all default
   options.
 
-## Options Changes
+### Options Changes
 
 - Removed `root` option and mounting behavior.
 - Removed `stat` option. It's slow and pointless. (Could bring
@@ -71,7 +71,7 @@ changes.
 - `realpath:true` will cause invalid symbolic links to be
   omitted, rather than matching the link itself.
 
-## Performance and Algorithm Changes
+### Performance and Algorithm Changes
 
 - Massive performance improvements.
 - Removed nearly all stat calls, in favor of using

From 5d9b6a539a372301861a5f0a173f1740e16d46bb Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 28 Feb 2023 19:56:19 -0800
Subject: [PATCH 126/163] Changelog: add note about method names changing

---
 changelog.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/changelog.md b/changelog.md
index 1a33f64d..f477a191 100644
--- a/changelog.md
+++ b/changelog.md
@@ -7,6 +7,8 @@ changes.
 
 - Only support node 16 and higher.
 - Promise API instead of callbacks.
+- Exported function names have changed, as have the methods on
+  the Glob class. See API documentation for details.
 - Accept pattern as string or array of strings.
 - Hybrid module distribution.
 - Full TypeScript support.

From 02a1da4234c199833c22e9d7b6ff8ffee99215c3 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 28 Feb 2023 12:33:11 -0800
Subject: [PATCH 127/163] Add `root` option, respect `absolute:false`

Fix: #492

PR-URL: https://github.com/isaacs/node-glob/pull/498
Credit: @isaacs
Close: #498
Reviewed-by: @isaacs
---
 README.md                           | 30 +++++++++-
 changelog.md                        |  9 +++
 src/glob.ts                         | 69 ++++++++++++++++++----
 src/processor.ts                    |  8 ++-
 src/walker.ts                       |  7 ++-
 tap-snapshots/test/root.ts.test.cjs | 90 +++++++++++++++++++++++++++++
 test/root.ts                        | 46 +++++++++++++++
 7 files changed, 241 insertions(+), 18 deletions(-)
 create mode 100644 tap-snapshots/test/root.ts.test.cjs
 create mode 100644 test/root.ts

diff --git a/README.md b/README.md
index edf8c456..391a1930 100644
--- a/README.md
+++ b/README.md
@@ -200,12 +200,33 @@ share the previously loaded cache.
 
 - `cwd` String path or `file://` string or URL object. The
   current working directory in which to search. Defaults to
-  `process.cwd()`.  See also: "Windows, CWDs, Drive Letters, and
+  `process.cwd()`. See also: "Windows, CWDs, Drive Letters, and
   UNC Paths", below.
 
   This option may be eiher a string path or a `file://` URL
   object or string.
 
+- `root` A string path resolved against the `cwd` option, which
+  is used as the starting point for absolute patterns that start
+  with `/`, (but not drive letters or UNC paths on Windows).
+
+  Note that this _doesn't_ necessarily limit the walk to the
+  `root` directory, and doesn't affect the cwd starting point for
+  non-absolute patterns. A pattern containing `..` will still be
+  able to traverse out of the root directory, if it is not an
+  actual root directory on the filesystem, and any non-absolute
+  patterns will be matched in the `cwd`. For example, the
+  pattern `/../*` with `{root:'/some/path'}` will return all
+  files in `/some`, not all files in `/some/path`. The pattern
+  `*` with `{root:'/some/path'}` will return all the entries in
+  the cwd, not the entries in `/some/path`.
+
+  To start absolute and non-absolute patterns in the same
+  path, you can use `{root:''}`. However, be aware that on
+  Windows systems, a pattern like `x:/*` or `//host/share/*` will
+  _always_ start in the `x:/` or `//host/share` directory,
+  regardless of the `root` setting.
+
 - `windowsPathsNoEscape` Use `\\` as a path separator _only_, and
   _never_ as an escape character. If set, all `\\` characters are
   replaced with `/` in the pattern.
@@ -272,13 +293,16 @@ share the previously loaded cache.
   course, because of the added system calls.
 
 - `absolute` Set to true to always receive absolute paths for
-  matched files. This does _not_ make an extra system call to get
-  the realpath, it only does string path resolution.
+  matched files. Set to `false` to always receive relative paths
+  for matched files.
 
   By default, when this option is not set, absolute paths are
   returned for patterns that are absolute, and otherwise paths
   are returned that are relative to the `cwd` setting.
 
+  This does _not_ make an extra system call to get the realpath,
+  it only does string path resolution.
+
   `absolute` may not be used along with `withFileTypes`.
 
 - `platform` Defaults to value of `process.platform` if
diff --git a/changelog.md b/changelog.md
index f477a191..af7b5647 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,12 @@
+## 9.1
+
+- Bring back the `root` option, albeit with slightly different
+  semantics than in v8 and before.
+- Support `{ absolute:false }` option to explicitly always return
+  relative paths. An unset `absolute` setting will still return
+  absolute or relative paths based on whether the pattern is
+  absolute.
+
 ## 9.0
 
 This is a full rewrite, with significant API and algorithm
diff --git a/src/glob.ts b/src/glob.ts
index af40fe7a..9d3b7dbd 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -39,23 +39,27 @@ const defaultPlatform: NodeJS.Platform =
  */
 export interface GlobOptions {
   /**
-   * Set to true to always receive absolute paths for
-   * matched files. This does _not_ make an extra system call to get
-   * the realpath, it only does string path resolution.
+   * Set to `true` to always receive absolute paths for
+   * matched files. Set to `false` to always return relative paths.
+   *
+   * When this option is not set, absolute paths are returned for patterns
+   * that are absolute, and otherwise paths are returned that are relative
+   * to the `cwd` setting.
    *
-   * By default, when this option is not set, absolute paths are
-   * returned for patterns that are absolute, and otherwise paths
-   * are returned that are relative to the `cwd` setting.
+   * This does _not_ make an extra system call to get
+   * the realpath, it only does string path resolution.
    *
    * Conflicts with {@link withFileTypes}
    */
   absolute?: boolean
+
   /**
    * Set to false to enable {@link windowsPathsNoEscape}
    *
    * @deprecated
    */
   allowWindowsEscape?: boolean
+
   /**
    * The current working directory in which to search. Defaults to
    * `process.cwd()`.
@@ -63,12 +67,14 @@ export interface GlobOptions {
    * May be eiher a string path or a `file://` URL object or string.
    */
   cwd?: string | URL
+
   /**
    * Include `.dot` files in normal matches and `globstar`
    * matches. Note that an explicit dot in a portion of the pattern
    * will always match dot files.
    */
   dot?: boolean
+
   /**
    * Follow symlinked directories when expanding `**`
    * patterns. This can result in a lot of duplicate references in
@@ -79,27 +85,32 @@ export interface GlobOptions {
    * first item in the pattern, following the same behavior as Bash.
    */
   follow?: boolean
+
   /**
    * A glob pattern or array of glob patterns to exclude from matches. To
    * ignore all children within a directory, as well as the entry itself,
    * append `/**'` to the ignore pattern.
    */
   ignore?: string | string[] | Ignore
+
   /**
    * Add a `/` character to directory matches. Note that this requires
    * additional stat calls in some cases.
    */
   mark?: boolean
+
   /**
    * Perform a basename-only match if the pattern does not contain any slash
    * characters. That is, `*.js` would be treated as equivalent to
    * `**\/*.js`, matching all js files in all directories.
    */
   matchBase?: boolean
+
   /**
    * Do not expand `{a,b}` and `{1..3}` brace sets.
    */
   nobrace?: boolean
+
   /**
    * Perform a case-insensitive match. This defaults to `true` on macOS and
    * Windows systems, and `false` on all others.
@@ -111,15 +122,18 @@ export interface GlobOptions {
    * walk may return more or less results than expected.
    */
   nocase?: boolean
+
   /**
    * Do not match directories, only files. (Note: to match
    * _only_ directories, put a `/` at the end of the pattern.)
    */
   nodir?: boolean
+
   /**
    * Do not match "extglob" patterns such as `+(a|b)`.
    */
   noext?: boolean
+
   /**
    * Do not match `**` against multiple filenames. (Ie, treat it as a normal
    * `*` instead.)
@@ -127,12 +141,14 @@ export interface GlobOptions {
    * Conflicts with {@link matchBase}
    */
   noglobstar?: boolean
+
   /**
    * Defaults to value of `process.platform` if available, or `'linux'` if
    * not. Setting `platform:'win32'` on non-Windows systems may cause strange
    * behavior.
    */
   platform?: NodeJS.Platform
+
   /**
    * Set to true to call `fs.realpath` on all of the
    * results. In the case of an entry that cannot be resolved, the
@@ -140,6 +156,32 @@ export interface GlobOptions {
    * course, because of the added system calls.
    */
   realpath?: boolean
+
+  /**
+   *
+   * A string path resolved against the `cwd` option, which
+   * is used as the starting point for absolute patterns that start
+   * with `/`, (but not drive letters or UNC paths on Windows).
+   *
+   * Note that this _doesn't_ necessarily limit the walk to the
+   * `root` directory, and doesn't affect the cwd starting point for
+   * non-absolute patterns. A pattern containing `..` will still be
+   * able to traverse out of the root directory, if it is not an
+   * actual root directory on the filesystem, and any non-absolute
+   * patterns will be matched in the `cwd`. For example, the
+   * pattern `/../*` with `{root:'/some/path'}` will return all
+   * files in `/some`, not all files in `/some/path`. The pattern
+   * `*` with `{root:'/some/path'}` will return all the entries in
+   * the cwd, not the entries in `/some/path`.
+   *
+   * To start absolute and non-absolute patterns in the same
+   * path, you can use `{root:''}`. However, be aware that on
+   * Windows systems, a pattern like `x:/*` or `//host/share/*` will
+   * _always_ start in the `x:/` or `//host/share` directory,
+   * regardless of the `root` setting.
+   */
+  root?: string
+
   /**
    * A [PathScurry](http://npm.im/path-scurry) object used
    * to traverse the file system. If the `nocase` option is set
@@ -147,11 +189,13 @@ export interface GlobOptions {
    * setting.
    */
   scurry?: PathScurry
+
   /**
    * An AbortSignal which will cancel the Glob walk when
    * triggered.
    */
   signal?: AbortSignal
+
   /**
    * Use `\\` as a path separator _only_, and
    *  _never_ as an escape character. If set, all `\\` characters are
@@ -167,6 +211,7 @@ export interface GlobOptions {
    *  `allowWindowsEscape` is set to the exact value `false`.)
    */
   windowsPathsNoEscape?: boolean
+
   /**
    * Return [PathScurry](http://npm.im/path-scurry)
    * `Path` objects instead of strings. These are similar to a
@@ -180,7 +225,7 @@ export interface GlobOptions {
 
 export type GlobOptionsWithFileTypesTrue = GlobOptions & {
   withFileTypes: true
-  absolute?: false
+  absolute?: undefined
 }
 
 export type GlobOptionsWithFileTypesFalse = GlobOptions & {
@@ -212,8 +257,9 @@ export type FileTypes = Opts extends GlobOptionsWithFileTypesTrue
  * An object that can perform glob pattern traversals.
  */
 export class Glob implements GlobOptions {
-  absolute: boolean
+  absolute?: boolean
   cwd: string
+  root?: string
   dot: boolean
   follow: boolean
   ignore?: Ignore
@@ -267,16 +313,17 @@ export class Glob implements GlobOptions {
       opts.cwd = fileURLToPath(opts.cwd)
     }
     this.cwd = opts.cwd || ''
+    this.root = opts.root
     this.nobrace = !!opts.nobrace
     this.noext = !!opts.noext
     this.realpath = !!opts.realpath
-    this.absolute = !!opts.absolute
+    this.absolute = opts.absolute
 
     this.noglobstar = !!opts.noglobstar
     this.matchBase = !!opts.matchBase
 
-    if (this.withFileTypes && this.absolute) {
-      throw new Error('cannot set absolute:true and withFileTypes:true')
+    if (this.withFileTypes && this.absolute !== undefined) {
+      throw new Error('cannot set absolute and withFileTypes:true')
     }
 
     if (typeof pattern === 'string') {
diff --git a/src/processor.ts b/src/processor.ts
index 974b8ba5..87e8802f 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -118,11 +118,15 @@ export class Processor {
       this.hasWalkedCache.storeWalked(t, pattern)
 
       const root = pattern.root()
-      const absolute = pattern.isAbsolute()
+      const absolute = pattern.isAbsolute() && this.opts.absolute !== false
 
       // start absolute patterns at root
       if (root) {
-        t = t.resolve(root)
+        t = t.resolve(
+          root === '/' && this.opts.root !== undefined
+            ? this.opts.root
+            : root
+        )
         const rest = pattern.rest()
         if (!rest) {
           this.matches.add(t, true, false)
diff --git a/src/walker.ts b/src/walker.ts
index d813f9f2..bc49b98a 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -32,6 +32,7 @@ export interface GlobWalkerOpts {
   noglobstar?: boolean
   platform?: NodeJS.Platform
   realpath?: boolean
+  root?: string
   signal?: AbortSignal
   windowsPathsNoEscape?: boolean
   withFileTypes?: boolean
@@ -188,16 +189,18 @@ export abstract class GlobUtil {
 
   matchFinish(e: Path, absolute: boolean) {
     if (this.#ignored(e)) return
+    const abs =
+      this.opts.absolute === undefined ? absolute : this.opts.absolute
     this.seen.add(e)
     const mark = this.opts.mark && e.isDirectory() ? this.#sep : ''
     // ok, we have what we need!
     if (this.opts.withFileTypes) {
       this.matchEmit(e)
-    } else if (this.opts.absolute || absolute) {
+    } else if (abs) {
       this.matchEmit(e.fullpath() + mark)
     } else {
       const rel = e.relative()
-      this.matchEmit(!rel && mark ? './' : rel + mark)
+      this.matchEmit(!rel && mark ? '.' + mark : rel + mark)
     }
   }
 
diff --git a/tap-snapshots/test/root.ts.test.cjs b/tap-snapshots/test/root.ts.test.cjs
new file mode 100644
index 00000000..bd6187a7
--- /dev/null
+++ b/tap-snapshots/test/root.ts.test.cjs
@@ -0,0 +1,90 @@
+/* IMPORTANT
+ * This snapshot file is auto-generated, but designed for humans.
+ * It should be checked into source control and tracked carefully.
+ * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
+ * Make sure to inspect the output below.  Do not ignore changes!
+ */
+'use strict'
+exports[`test/root.ts TAP set root option absolute=false > async 1`] = `
+Array [
+  "x/x/a",
+  "x/x/x/a",
+  "x/x/x/y",
+  "x/x/x/y/r",
+  "x/x/y",
+  "x/x/y/r",
+  "x/y",
+  "x/y/r",
+  "y/r",
+]
+`
+
+exports[`test/root.ts TAP set root option absolute=false > sync 1`] = `
+Array [
+  "x/x/a",
+  "x/x/x/a",
+  "x/x/x/y",
+  "x/x/x/y/r",
+  "x/x/y",
+  "x/x/y/r",
+  "x/y",
+  "x/y/r",
+  "y/r",
+]
+`
+
+exports[`test/root.ts TAP set root option absolute=true > async 1`] = `
+Array [
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/a",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/x/a",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/x/y",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/x/y/r",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/y",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/y/r",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/y",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/y/r",
+  "{CWD}/test/tap-testdir-root-set-root-option/y/r",
+]
+`
+
+exports[`test/root.ts TAP set root option absolute=true > sync 1`] = `
+Array [
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/a",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/x/a",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/x/y",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/x/y/r",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/y",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/y/r",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/y",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/y/r",
+  "{CWD}/test/tap-testdir-root-set-root-option/y/r",
+]
+`
+
+exports[`test/root.ts TAP set root option absolute=undefined > async 1`] = `
+Array [
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/a",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/x/a",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/x/y",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/y",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/y",
+  "x/x/x/y/r",
+  "x/x/y/r",
+  "x/y/r",
+  "y/r",
+]
+`
+
+exports[`test/root.ts TAP set root option absolute=undefined > sync 1`] = `
+Array [
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/a",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/x/a",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/x/y",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/x/y",
+  "{CWD}/test/tap-testdir-root-set-root-option/x/y",
+  "x/x/x/y/r",
+  "x/x/y/r",
+  "x/y/r",
+  "y/r",
+]
+`
diff --git a/test/root.ts b/test/root.ts
new file mode 100644
index 00000000..b979c5df
--- /dev/null
+++ b/test/root.ts
@@ -0,0 +1,46 @@
+import { resolve, sep } from 'path'
+import t from 'tap'
+import { Glob } from '../'
+
+const alphasort = (a: string, b: string) => a.localeCompare(b, 'en')
+const j = (a: string[]) =>
+  a
+    .map(s => s.split(process.cwd()).join('{CWD}').split(sep).join('/'))
+    .sort(alphasort)
+
+t.test('set root option', t => {
+  const cwd = t.testdir({
+    x: {
+      a: '',
+      x: {
+        a: '',
+        x: {
+          a: '',
+          y: {
+            r: '',
+          },
+        },
+        y: {
+          r: '',
+        },
+      },
+      y: {
+        r: '',
+      },
+    },
+    y: {
+      r: '',
+    },
+  })
+
+  const pattern = ['**/r', '/**/a', '/**/../y']
+  const root = resolve(cwd, 'x/x')
+  t.plan(3)
+  for (const absolute of [true, false, undefined]) {
+    t.test(`absolute=${absolute}`, async t => {
+      const g = new Glob(pattern, { root, absolute, cwd })
+      t.matchSnapshot(j(await g.walk()), 'async')
+      t.matchSnapshot(j(g.walkSync()), 'sync')
+    })
+  }
+})

From 08e7348d2f8e04e88dfa24180be14cd9285fa511 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 28 Feb 2023 12:52:21 -0800
Subject: [PATCH 128/163] Add `magicalBraces` option

This tells hasMagic to treat brace expansion as magical.

Fix: #496

PR-URL: https://github.com/isaacs/node-glob/pull/499
Credit: @isaacs
Close: #499
Reviewed-by: @isaacs
---
 README.md         | 19 ++++++++++++++-----
 changelog.md      |  2 ++
 src/glob.ts       | 12 +++++++++++-
 src/has-magic.ts  | 18 ++++++++++++++----
 test/has-magic.ts |  8 ++++++++
 5 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index 391a1930..bb3ed96f 100644
--- a/README.md
+++ b/README.md
@@ -129,11 +129,14 @@ if they're not consumed immediately.
 Returns `true` if the provided pattern contains any "magic" glob
 characters, given the options provided.
 
-Note that brace expansion is not considered "magic", as that just
-turns one string into an array of strings. So a pattern like
-`'x{a,b}y'` would return `false`, because `'xay'` and `'xby'`
-both do not contain any magic glob characters, and it's treated
-the same as if you had called it on `['xay', 'xby']`.
+Brace expansion is not considered "magic" unless the
+`magicalBraces` option is set, as brace expansion just turns one
+string into an array of strings. So a pattern like `'x{a,b}y'`
+would return `false`, because `'xay'` and `'xby'` both do not
+contain any magic glob characters, and it's treated the same as
+if you had called it on `['xay', 'xby']`. When
+`magicalBraces:true` is in the options, brace expansion _is_
+treated as a pattern having magic.
 
 ## Class `Glob`
 
@@ -244,6 +247,12 @@ share the previously loaded cache.
   matches. Note that an explicit dot in a portion of the pattern
   will always match dot files.
 
+- `magicalBraces` Treat brace expansion like `{a,b}` as a "magic"
+  pattern. Has no effect if {@link nobrace} is set.
+
+  Only has effect on the {@link hasMagic} function, no effect on
+  glob pattern matching itself.
+
 - `mark` Add a `/` character to directory matches. Note that this
   requires additional stat calls.
 
diff --git a/changelog.md b/changelog.md
index af7b5647..9dc6775a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -6,6 +6,8 @@
   relative paths. An unset `absolute` setting will still return
   absolute or relative paths based on whether the pattern is
   absolute.
+- Add `magicalBraces` option to treat brace expansion as "magic"
+  in the `hasMagic` function.
 
 ## 9.0
 
diff --git a/src/glob.ts b/src/glob.ts
index 9d3b7dbd..b21f805c 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -93,6 +93,14 @@ export interface GlobOptions {
    */
   ignore?: string | string[] | Ignore
 
+  /**
+   * Treat brace expansion like `{a,b}` as a "magic" pattern. Has no
+   * effect if {@link nobrace} is set.
+   *
+   * Only has effect on the {@link hasMagic} function.
+   */
+  magicalBraces?: boolean
+
   /**
    * Add a `/` character to directory matches. Note that this requires
    * additional stat calls in some cases.
@@ -263,7 +271,8 @@ export class Glob implements GlobOptions {
   dot: boolean
   follow: boolean
   ignore?: Ignore
-  mark: boolean
+  magicalBraces: boolean
+  mark?: boolean
   matchBase: boolean
   nobrace: boolean
   nocase: boolean
@@ -314,6 +323,7 @@ export class Glob implements GlobOptions {
     }
     this.cwd = opts.cwd || ''
     this.root = opts.root
+    this.magicalBraces = !!opts.magicalBraces
     this.nobrace = !!opts.nobrace
     this.noext = !!opts.noext
     this.realpath = !!opts.realpath
diff --git a/src/has-magic.ts b/src/has-magic.ts
index ea85c700..07fc5af5 100644
--- a/src/has-magic.ts
+++ b/src/has-magic.ts
@@ -2,7 +2,15 @@ import { Glob, GlobOptions } from './glob.js'
 
 /**
  * Return true if the patterns provided contain any magic
- * glob characters.
+ * glob characters, given the options provided.
+ *
+ * Brace expansion is not considered "magic" unless the `magicalBraces` option
+ * is set, as brace expansion just turns one string into an array of strings.
+ * So a pattern like `'x{a,b}y'` would return `false`, because `'xay'` and
+ * `'xby'` both do not contain any magic glob characters, and it's treated the
+ * same as if you had called it on `['xay', 'xby']`. When
+ * `magicalBraces:true` is in the options, brace expansion _is_ treated as a
+ * pattern having magic.
  */
 export const hasMagic = (
   pattern: string | string[],
@@ -11,8 +19,10 @@ export const hasMagic = (
   if (!Array.isArray(pattern)) {
     pattern = [pattern]
   }
+  const length = pattern.length
   const g = new Glob(pattern, options)
-  return g.patterns.length === 0
-    ? false
-    : g.patterns.some(p => p.hasMagic())
+  if (g.magicalBraces && g.patterns.length !== length) {
+    return true
+  }
+  return g.patterns.some(p => p.hasMagic())
 }
diff --git a/test/has-magic.ts b/test/has-magic.ts
index 4495550a..47d104f4 100644
--- a/test/has-magic.ts
+++ b/test/has-magic.ts
@@ -23,8 +23,16 @@ t.test('detect magic in glob patterns', async t => {
     'no magic in a/b/+(x|y) noext'
   )
   t.notOk(glob.hasMagic('{a,b}'), 'no magic in {a,b}')
+  t.ok(
+    glob.hasMagic('{a,b}', { magicalBraces: true }),
+    'magical braces are magic in {a,b}'
+  )
   t.notOk(
     glob.hasMagic('{a,b}', { nobrace: true }),
     'no magic in {a,b} nobrace:true'
   )
+  t.notOk(
+    glob.hasMagic('{a,b}', { nobrace: true, magicalBraces: true }),
+    'magical braces not magic in {a,b} nobrace:true'
+  )
 })

From 08333109894f0609d109e00051924f9525e2394d Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 28 Feb 2023 13:23:35 -0800
Subject: [PATCH 129/163] Add `dotRelative` option

Fix: #495

PR-URL: https://github.com/isaacs/node-glob/pull/500
Credit: @isaacs
Close: #500
Reviewed-by: @isaacs
---
 README.md            | 10 ++++++
 changelog.md         |  1 +
 src/glob.ts          | 13 ++++++++
 src/walker.ts        |  5 ++-
 test/dot-relative.ts | 75 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 103 insertions(+), 1 deletion(-)
 create mode 100644 test/dot-relative.ts

diff --git a/README.md b/README.md
index bb3ed96f..7988b749 100644
--- a/README.md
+++ b/README.md
@@ -253,6 +253,16 @@ share the previously loaded cache.
   Only has effect on the {@link hasMagic} function, no effect on
   glob pattern matching itself.
 
+- `dotRelative` Prepend all relative path strings with `./` (or
+  `.\` on Windows).
+
+  Without this option, returned relative paths are "bare", so
+  instead of returning `'./foo/bar'`, they are returned as
+  `'foo/bar'`.
+
+  Relative patterns starting with `'../'` are not prepended with
+  `./`, even if this option is set.
+
 - `mark` Add a `/` character to directory matches. Note that this
   requires additional stat calls.
 
diff --git a/changelog.md b/changelog.md
index 9dc6775a..a53c45a8 100644
--- a/changelog.md
+++ b/changelog.md
@@ -8,6 +8,7 @@
   absolute.
 - Add `magicalBraces` option to treat brace expansion as "magic"
   in the `hasMagic` function.
+- Add `dotRelative` option
 
 ## 9.0
 
diff --git a/src/glob.ts b/src/glob.ts
index b21f805c..68b1435c 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -75,6 +75,17 @@ export interface GlobOptions {
    */
   dot?: boolean
 
+  /**
+   * Prepend all relative path strings with `./` (or `.\` on Windows).
+   *
+   * Without this option, returned relative paths are "bare", so instead of
+   * returning `'./foo/bar'`, they are returned as `'foo/bar'`.
+   *
+   * Relative patterns starting with `'../'` are not prepended with `./`, even
+   * if this option is set.
+   */
+  dotRelative?: boolean
+
   /**
    * Follow symlinked directories when expanding `**`
    * patterns. This can result in a lot of duplicate references in
@@ -269,6 +280,7 @@ export class Glob implements GlobOptions {
   cwd: string
   root?: string
   dot: boolean
+  dotRelative: boolean
   follow: boolean
   ignore?: Ignore
   magicalBraces: boolean
@@ -314,6 +326,7 @@ export class Glob implements GlobOptions {
     this.signal = opts.signal
     this.follow = !!opts.follow
     this.dot = !!opts.dot
+    this.dotRelative = !!opts.dotRelative
     this.nodir = !!opts.nodir
     this.mark = !!opts.mark
     if (!opts.cwd) {
diff --git a/src/walker.ts b/src/walker.ts
index bc49b98a..ade37d95 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -21,6 +21,7 @@ export interface GlobWalkerOpts {
   allowWindowsEscape?: boolean
   cwd?: string | URL
   dot?: boolean
+  dotRelative?: boolean
   follow?: boolean
   ignore?: string | string[] | Ignore
   mark?: boolean
@@ -200,7 +201,9 @@ export abstract class GlobUtil {
       this.matchEmit(e.fullpath() + mark)
     } else {
       const rel = e.relative()
-      this.matchEmit(!rel && mark ? '.' + mark : rel + mark)
+      const pre = this.opts.dotRelative && !rel.startsWith('..' + this.#sep)
+        ? '.' + this.#sep : ''
+      this.matchEmit(!rel && mark ? '.' + mark : pre + rel + mark)
     }
   }
 
diff --git a/test/dot-relative.ts b/test/dot-relative.ts
new file mode 100644
index 00000000..62c0c168
--- /dev/null
+++ b/test/dot-relative.ts
@@ -0,0 +1,75 @@
+import t from 'tap'
+import { Glob } from '../'
+import { bashResults } from './bash-results'
+import {resolve, sep} from 'path'
+
+const pattern = 'a/b/**'
+process.chdir(__dirname + '/fixtures')
+
+const marks = [true, false]
+for (const mark of marks) {
+  t.test('mark=' + mark, t => {
+    t.plan(3)
+
+    t.test('Emits relative matches prefixed with ./', async t => {
+      const g = new Glob(pattern, { dotRelative: true })
+      const results = await g.walk()
+
+      t.equal(
+        results.length,
+        bashResults[pattern].length,
+        'must match all files'
+      )
+      for (const m of results) {
+        t.ok(m.startsWith('.' + sep))
+      }
+    })
+
+    t.test('returns ./ prefixed matches synchronously', async t => {
+      const g = new Glob(pattern, { dotRelative: true })
+      const results = g.walkSync()
+
+      t.equal(
+        results.length,
+        bashResults[pattern].length,
+        'must match all files'
+      )
+      for (const m of results) {
+        t.ok(m.startsWith('.' + sep))
+      }
+    })
+
+    t.test('does not prefix with ./ unless dotRelative is true', async t => {
+      const g = new Glob(pattern, {})
+      const results = await g.walk()
+
+      t.equal(
+        results.length,
+        bashResults[pattern].length,
+        'must match all files'
+      )
+      for (const m of results) {
+        t.ok(mark && m === '.' + sep || !m.startsWith('.' + sep))
+      }
+    })
+  })
+}
+
+t.test('does not add ./ for patterns starting in ../', async t => {
+  t.plan(2)
+  const pattern = '../a/b/**'
+  const cwd = resolve(__dirname, 'fixtures/a')
+  t.test('async', async t => {
+    const g = new Glob(pattern, { dotRelative: true, cwd })
+    for await (const m of g) {
+      t.ok(!m.startsWith('.' + sep + '..' + sep))
+    }
+  })
+  t.test('sync', t => {
+    const g = new Glob(pattern, { dotRelative: true, cwd })
+    for (const m of g) {
+      t.ok(!m.startsWith('.' + sep + '..' + sep))
+    }
+    t.end()
+  })
+})

From acace9ad20e2faa8934f1cdf53a79bc67e6c65df Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 28 Feb 2023 23:00:39 -0800
Subject: [PATCH 130/163] minimatch@7.4.0

---
 package-lock.json | 10 +++++-----
 package.json      |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 78f95bd7..acb391c0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "minimatch": "^7.3.0",
+        "minimatch": "^7.4.0",
         "minipass": "^4.2.4",
         "path-scurry": "^1.5.0"
       },
@@ -28,7 +28,7 @@
         "typescript": "^4.9.4"
       },
       "engines": {
-        "node": ">=16"
+        "node": ">=16 || 14 >=14.17"
       },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
@@ -2449,9 +2449,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "7.3.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.3.0.tgz",
-      "integrity": "sha512-WaMDuhKa7a6zKiwplR1AOz+zGvJba24k5VU1Cy6NhEguavT2YRlHxuINUgTas4wiS6fwBpYq4TcA1XIECSntyw==",
+      "version": "7.4.0",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.0.tgz",
+      "integrity": "sha512-Co6cQqQPyou/311vxtcfit/RKf+MbRN6qa5K3Zfh2Fo9+Pvfg8C1LeaAXcoRfwhxfZIe8sBc/kLXdkR88xJGBg==",
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
diff --git a/package.json b/package.json
index 34de39b0..3d3fb2ea 100644
--- a/package.json
+++ b/package.json
@@ -60,7 +60,7 @@
   },
   "dependencies": {
     "fs.realpath": "^1.0.0",
-    "minimatch": "^7.3.0",
+    "minimatch": "^7.4.0",
     "minipass": "^4.2.4",
     "path-scurry": "^1.5.0"
   },

From 8404778e33a6ff1d38bb0813517e501d7e1eb5db Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 28 Feb 2023 23:14:59 -0800
Subject: [PATCH 131/163] Use escape, unescape, hasMagic from Minimatch

Fix: https://github.com/isaacs/node-glob/issues/367
---
 README.md        | 28 ++++++++++++++++++++++++++++
 src/has-magic.ts | 20 +++++++++-----------
 src/index.ts     |  5 +++++
 src/pattern.ts   | 12 ------------
 test/escape.ts   | 18 ++++++++++++++++++
 5 files changed, 60 insertions(+), 23 deletions(-)
 create mode 100644 test/escape.ts

diff --git a/README.md b/README.md
index 7988b749..f3b587e6 100644
--- a/README.md
+++ b/README.md
@@ -138,6 +138,34 @@ if you had called it on `['xay', 'xby']`. When
 `magicalBraces:true` is in the options, brace expansion _is_
 treated as a pattern having magic.
 
+## `escape(pattern: string, options?: GlobOptions) => string`
+
+Escape all magic characters in a glob pattern, so that it will
+only ever match literal strings
+
+If the `windowsPathsNoEscape` option is used, then characters are
+escaped by wrapping in `[]`, because a magic character wrapped in
+a character class can only be satisfied by that exact character.
+
+Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot
+be escaped or unescaped.
+
+## `unescape(pattern: string, options?: GlobOptions) => string`
+
+Un-escape a glob string that may contain some escaped characters.
+
+If the `windowsPathsNoEscape` option is used, then square-brace
+escapes are removed, but not backslash escapes.  For example, it
+will turn the string `'[*]'` into `*`, but it will not turn
+`'\\*'` into `'*'`, because `\` is a path separator in
+`windowsPathsNoEscape` mode.
+
+When `windowsPathsNoEscape` is not set, then both brace escapes
+and backslash escapes are removed.
+
+Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot
+be escaped or unescaped.
+
 ## Class `Glob`
 
 An object that can perform glob pattern traversals.
diff --git a/src/has-magic.ts b/src/has-magic.ts
index 07fc5af5..748d7c52 100644
--- a/src/has-magic.ts
+++ b/src/has-magic.ts
@@ -1,16 +1,16 @@
-import { Glob, GlobOptions } from './glob.js'
+import { Minimatch } from 'minimatch'
+import { GlobOptions } from './glob.js'
 
 /**
- * Return true if the patterns provided contain any magic
- * glob characters, given the options provided.
+ * Return true if the patterns provided contain any magic glob characters,
+ * given the options provided.
  *
  * Brace expansion is not considered "magic" unless the `magicalBraces` option
  * is set, as brace expansion just turns one string into an array of strings.
  * So a pattern like `'x{a,b}y'` would return `false`, because `'xay'` and
  * `'xby'` both do not contain any magic glob characters, and it's treated the
- * same as if you had called it on `['xay', 'xby']`. When
- * `magicalBraces:true` is in the options, brace expansion _is_ treated as a
- * pattern having magic.
+ * same as if you had called it on `['xay', 'xby']`. When `magicalBraces:true`
+ * is in the options, brace expansion _is_ treated as a pattern having magic.
  */
 export const hasMagic = (
   pattern: string | string[],
@@ -19,10 +19,8 @@ export const hasMagic = (
   if (!Array.isArray(pattern)) {
     pattern = [pattern]
   }
-  const length = pattern.length
-  const g = new Glob(pattern, options)
-  if (g.magicalBraces && g.patterns.length !== length) {
-    return true
+  for (const p of pattern) {
+    if (new Minimatch(p, options).hasMagic()) return true
   }
-  return g.patterns.some(p => p.hasMagic())
+  return false
 }
diff --git a/src/index.ts b/src/index.ts
index f2d6d10d..0cd7be2a 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,4 @@
+import { escape, unescape } from 'minimatch'
 import type {
   GlobOptions,
   GlobOptionsWithFileTypesFalse,
@@ -178,6 +179,7 @@ export function globIterateSync(
 }
 
 /* c8 ignore start */
+export { escape, unescape } from 'minimatch'
 export { Glob } from './glob.js'
 export type {
   GlobOptions,
@@ -189,6 +191,7 @@ export type {
 } from './glob.js'
 export { hasMagic } from './has-magic.js'
 export type { MatchStream } from './walker.js'
+
 /* c8 ignore stop */
 export default Object.assign(glob, {
   glob,
@@ -199,4 +202,6 @@ export default Object.assign(glob, {
   globIterateSync,
   Glob,
   hasMagic,
+  escape,
+  unescape,
 })
diff --git a/src/pattern.ts b/src/pattern.ts
index e9fadf73..32da1fac 100644
--- a/src/pattern.ts
+++ b/src/pattern.ts
@@ -230,18 +230,6 @@ export class Pattern {
       : ''
   }
 
-  /**
-   * True if the pattern has any non-string components
-   */
-  hasMagic(): boolean {
-    for (let i = 0; i < this.length; i++) {
-      if (typeof this.#patternList[i] !== 'string') {
-        return true
-      }
-    }
-    return false
-  }
-
   /**
    * Check to see if the current globstar pattern is allowed to follow
    * a symbolic link.
diff --git a/test/escape.ts b/test/escape.ts
new file mode 100644
index 00000000..b9a56342
--- /dev/null
+++ b/test/escape.ts
@@ -0,0 +1,18 @@
+import t from 'tap'
+import { unescape, escape, hasMagic } from '../'
+import { bashResults } from './bash-results'
+
+for (const pattern of Object.keys(bashResults)) {
+  t.notOk(hasMagic(escape(pattern)), `escape(${pattern})`)
+  const pp = escape(pattern)
+  const pw = escape(pattern, {
+    windowsPathsNoEscape: true
+  })
+  t.notOk(hasMagic(pp, { platform: 'linux' }), 'no magic after posix escape')
+  t.notOk(hasMagic(pw, { platform: 'win32', windowsPathsNoEscape: true }),
+    'no magic after windows escape')
+  const up = unescape(pp)
+  const uw = unescape(pw, { windowsPathsNoEscape: true })
+  t.equal(up, pattern, 'unescaped posix pattern returned')
+  t.equal(uw, pattern, 'unescaped windows pattern returned')
+}

From 166d0b4d6a7efd31524735c62498a0ffa09689f4 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 28 Feb 2023 23:33:03 -0800
Subject: [PATCH 132/163] changelog entry for escape, unescape

---
 changelog.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/changelog.md b/changelog.md
index a53c45a8..ec785414 100644
--- a/changelog.md
+++ b/changelog.md
@@ -9,6 +9,7 @@
 - Add `magicalBraces` option to treat brace expansion as "magic"
   in the `hasMagic` function.
 - Add `dotRelative` option
+- Add `escape()` and `unescape()` methods
 
 ## 9.0
 

From 531e1cce7910fc8d362d5d5f4132d9b65029c64d Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 28 Feb 2023 23:38:28 -0800
Subject: [PATCH 133/163] 9.1.0

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index acb391c0..1b0b1bd9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.0.2",
+  "version": "9.1.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.0.2",
+      "version": "9.1.0",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index 3d3fb2ea..f37a4ba5 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.0.2",
+  "version": "9.1.0",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"

From f82cb34a4238d6e7c99907c1e5fa5dbc69ac402c Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Wed, 1 Mar 2023 00:00:29 -0800
Subject: [PATCH 134/163] minimatch@7.4.1

---
 package-lock.json | 8 ++++----
 package.json      | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 1b0b1bd9..e30d11ad 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "minimatch": "^7.4.0",
+        "minimatch": "^7.4.1",
         "minipass": "^4.2.4",
         "path-scurry": "^1.5.0"
       },
@@ -2449,9 +2449,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.0.tgz",
-      "integrity": "sha512-Co6cQqQPyou/311vxtcfit/RKf+MbRN6qa5K3Zfh2Fo9+Pvfg8C1LeaAXcoRfwhxfZIe8sBc/kLXdkR88xJGBg==",
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.1.tgz",
+      "integrity": "sha512-Oz1iPEP+MGl7KS3SciLsLLcuZ7VsBfb7Qrz/jYt/s/sYAv272P26HSLz2f77Y6hzTKXiBi6g765fqpEDNc5fJw==",
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
diff --git a/package.json b/package.json
index f37a4ba5..3ebcfcb4 100644
--- a/package.json
+++ b/package.json
@@ -60,7 +60,7 @@
   },
   "dependencies": {
     "fs.realpath": "^1.0.0",
-    "minimatch": "^7.4.0",
+    "minimatch": "^7.4.1",
     "minipass": "^4.2.4",
     "path-scurry": "^1.5.0"
   },

From d89e63a7313ce4113a5ec7a411152278a7abaef5 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Wed, 1 Mar 2023 10:47:12 -0800
Subject: [PATCH 135/163] correct require() export

I'd meant to update the types to point to index.d.ts, and inadvertently
changed the *export* to index.js instead, whoops.

Re: #503
---
 package.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/package.json b/package.json
index 3ebcfcb4..3e8ae22d 100644
--- a/package.json
+++ b/package.json
@@ -17,8 +17,8 @@
         "default": "./dist/mjs/index.js"
       },
       "require": {
-        "types": "./dist/cjs/index-cjs.d.ts",
-        "default": "./dist/cjs/index.js"
+        "types": "./dist/cjs/index.d.ts",
+        "default": "./dist/cjs/index-cjs.js"
       }
     }
   },

From 15d797d74913609b134ee54acaf348426650271b Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Wed, 1 Mar 2023 10:48:50 -0800
Subject: [PATCH 136/163] 9.1.1

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index e30d11ad..e509b039 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.1.0",
+  "version": "9.1.1",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.1.0",
+      "version": "9.1.1",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index 3e8ae22d..e9324263 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.1.0",
+  "version": "9.1.1",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"

From 24f44747d6980115d8cabfd51904246079856b15 Mon Sep 17 00:00:00 2001
From: Colin Rotherham 
Date: Wed, 1 Mar 2023 16:20:48 +0000
Subject: [PATCH 137/163] export declaration maps for TypeScript source

---
 tsconfig-base.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tsconfig-base.json b/tsconfig-base.json
index 45872adc..89d37168 100644
--- a/tsconfig-base.json
+++ b/tsconfig-base.json
@@ -4,6 +4,7 @@
   "compilerOptions": {
     "allowSyntheticDefaultImports": true,
     "declaration": true,
+    "declarationMap": true,
     "esModuleInterop": true,
     "forceConsistentCasingInFileNames": true,
     "moduleResolution": "node",

From 02790d6b1e3b0fd14fc4271056ecde115d869a06 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Wed, 1 Mar 2023 11:06:59 -0800
Subject: [PATCH 138/163] 9.1.2

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index e509b039..df016329 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.1.1",
+  "version": "9.1.2",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.1.1",
+      "version": "9.1.2",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index e9324263..58263af2 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.1.1",
+  "version": "9.1.2",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"

From 31b7e788a3b96570b50c015c51f42faa607b219d Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Wed, 1 Mar 2023 13:56:53 -0800
Subject: [PATCH 139/163] path-scurry@1.6.1

---
 package-lock.json | 8 ++++----
 package.json      | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index df016329..a664bb2f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,7 +12,7 @@
         "fs.realpath": "^1.0.0",
         "minimatch": "^7.4.1",
         "minipass": "^4.2.4",
-        "path-scurry": "^1.5.0"
+        "path-scurry": "^1.6.1"
       },
       "devDependencies": {
         "@types/node": "^18.11.18",
@@ -2866,9 +2866,9 @@
       }
     },
     "node_modules/path-scurry": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.5.0.tgz",
-      "integrity": "sha512-hJ8rODLI9B2qwsYAd32rrI76gwVUPeu5kq/do6URDj2bJCVH3ilyT978Mv/NLuFMaqzHrn3XtiDLMZHaTTh4vA==",
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.1.tgz",
+      "integrity": "sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA==",
       "dependencies": {
         "lru-cache": "^7.14.1",
         "minipass": "^4.0.2"
diff --git a/package.json b/package.json
index 58263af2..000e6ba1 100644
--- a/package.json
+++ b/package.json
@@ -62,7 +62,7 @@
     "fs.realpath": "^1.0.0",
     "minimatch": "^7.4.1",
     "minipass": "^4.2.4",
-    "path-scurry": "^1.5.0"
+    "path-scurry": "^1.6.1"
   },
   "devDependencies": {
     "@types/node": "^18.11.18",

From 3128b345b4096814e1a9883b2b11ba2249e42da3 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Wed, 1 Mar 2023 14:17:39 -0800
Subject: [PATCH 140/163] add support for custom fs override option

Fix: #280
---
 README.md         |  4 ++++
 changelog.md      |  6 ++++++
 src/glob.ts       | 12 +++++++++++-
 test/custom-fs.ts | 30 ++++++++++++++++++++++++++++++
 4 files changed, 51 insertions(+), 1 deletion(-)
 create mode 100644 test/custom-fs.ts

diff --git a/README.md b/README.md
index f3b587e6..542c45bc 100644
--- a/README.md
+++ b/README.md
@@ -366,6 +366,10 @@ share the previously loaded cache.
 - `signal` An AbortSignal which will cancel the Glob walk when
   triggered.
 
+- `fs` An override object to pass in custom filesystem methods.
+  See [PathScurry docs](http://npm.im/path-scurry) for what can
+  be overridden.
+
 - `scurry` A [PathScurry](http://npm.im/path-scurry) object used
   to traverse the file system. If the `nocase` option is set
   explicitly, then any provided `scurry` object must match this
diff --git a/changelog.md b/changelog.md
index ec785414..bcd657e5 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,9 @@
+# cganhe glo
+
+## 9.2
+
+- Support using a custom fs object, which is passed to PathScurry
+
 ## 9.1
 
 - Bring back the `root` option, albeit with slightly different
diff --git a/src/glob.ts b/src/glob.ts
index 68b1435c..584b156d 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -1,6 +1,7 @@
 import { Minimatch, MinimatchOptions } from 'minimatch'
 import Minipass from 'minipass'
 import {
+  FSOption,
   Path,
   PathScurry,
   PathScurryDarwin,
@@ -240,6 +241,12 @@ export interface GlobOptions {
    * Conflicts with {@link absolute}
    */
   withFileTypes?: boolean
+
+  /**
+   * An fs implementation to override some or all of the defaults.  See
+   * http://npm.im/path-scurry for details about what can be overridden.
+   */
+  fs?: FSOption
 }
 
 export type GlobOptionsWithFileTypesTrue = GlobOptions & {
@@ -389,7 +396,10 @@ export class Glob implements GlobOptions {
           : opts.platform
           ? PathScurryPosix
           : PathScurry
-      this.scurry = new Scurry(this.cwd, { nocase: opts.nocase })
+      this.scurry = new Scurry(this.cwd, {
+        nocase: opts.nocase,
+        fs: opts.fs,
+      })
     }
     this.nocase = this.scurry.nocase
 
diff --git a/test/custom-fs.ts b/test/custom-fs.ts
new file mode 100644
index 00000000..c8470832
--- /dev/null
+++ b/test/custom-fs.ts
@@ -0,0 +1,30 @@
+import t from 'tap'
+import { globSync } from '../'
+
+// just a rudimentary test, since PathScurry tests it more anyway
+import { readdirSync } from 'fs'
+let readdirCalled = 0
+const myReaddirSync = (path: string, options: { withFileTypes: true }) => {
+  readdirCalled++
+  return readdirSync(path, options)
+}
+
+const cwd = t.testdir({
+  a: '',
+  b: '',
+  c: {},
+})
+
+t.same(
+  new Set(['a', 'b', 'c', '']),
+  new Set(
+    globSync('**', {
+      fs: {
+        readdirSync: myReaddirSync,
+      },
+      cwd,
+    })
+  )
+)
+
+t.equal(readdirCalled, 2)

From 2d503ccb4bcfd0d26b175d2018e82068b1cbb5e6 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 2 Mar 2023 12:18:00 -0800
Subject: [PATCH 141/163] script to make a big tree for testing large walks

---
 .gitignore               |  1 +
 .prettierignore          |  2 ++
 package-lock.json        | 16 ++++++------
 package.json             |  4 +--
 scripts/make-big-tree.js | 56 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 69 insertions(+), 10 deletions(-)
 create mode 100644 scripts/make-big-tree.js

diff --git a/.gitignore b/.gitignore
index 5ce40583..1d5bc735 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@
 /coverage
 /test/fixtures
 /bench-working-dir
+/scripts/fixture
diff --git a/.prettierignore b/.prettierignore
index 9fdb805a..fb94be32 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -7,3 +7,5 @@
 /.nyc_output
 /coverage
 /benchmark
+/scripts/fixture
+/test/fixture
diff --git a/package-lock.json b/package-lock.json
index a664bb2f..e9eb2156 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,9 +19,9 @@
         "@types/tap": "^15.0.7",
         "c8": "^7.12.0",
         "eslint-config-prettier": "^8.6.0",
-        "mkdirp": "^2.0.0",
+        "mkdirp": "^2.1.4",
         "prettier": "^2.8.3",
-        "rimraf": "^4.1.1",
+        "rimraf": "^4.1.3",
         "tap": "^16.3.4",
         "ts-node": "^10.9.1",
         "typedoc": "^0.23.24",
@@ -2471,9 +2471,9 @@
       }
     },
     "node_modules/mkdirp": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.3.tgz",
-      "integrity": "sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw==",
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.4.tgz",
+      "integrity": "sha512-Cy9cV4pRSl1o10i1dURTuRt4T04l0DkS1WZrT+Jir886OqOVkSv4FbOA7pgjhS8kEUrmm4kCRvv5var2iOCxpA==",
       "dev": true,
       "bin": {
         "mkdirp": "dist/cjs/src/bin.js"
@@ -3103,9 +3103,9 @@
       }
     },
     "node_modules/rimraf": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.2.tgz",
-      "integrity": "sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==",
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.3.tgz",
+      "integrity": "sha512-iyzalDLo3l5FZxxaIGUY7xI4Bf90Xt7pCipc1Mr7RsdU7H3538z+M0tlsUDrz0aHeGS9uNqiKHUJyTewwRP91Q==",
       "dev": true,
       "bin": {
         "rimraf": "dist/cjs/src/bin.js"
diff --git a/package.json b/package.json
index 000e6ba1..dcbaf001 100644
--- a/package.json
+++ b/package.json
@@ -69,9 +69,9 @@
     "@types/tap": "^15.0.7",
     "c8": "^7.12.0",
     "eslint-config-prettier": "^8.6.0",
-    "mkdirp": "^2.0.0",
+    "mkdirp": "^2.1.4",
     "prettier": "^2.8.3",
-    "rimraf": "^4.1.1",
+    "rimraf": "^4.1.3",
     "tap": "^16.3.4",
     "ts-node": "^10.9.1",
     "typedoc": "^0.23.24",
diff --git a/scripts/make-big-tree.js b/scripts/make-big-tree.js
new file mode 100644
index 00000000..a2543771
--- /dev/null
+++ b/scripts/make-big-tree.js
@@ -0,0 +1,56 @@
+#!/usr/bin/env node
+const mkdirp = require('mkdirp')
+const { readFileSync } = require('fs')
+const { writeFile } = require('fs/promises')
+const rimraf = require('rimraf')
+const filesPerDir = 10
+const dirsPerDir = 5
+const max = (module === require.main && +process.argv[2]) || 1_000_000
+const { now } = performance
+let lastReported = now()
+
+const report = s => {
+  if (!process.stderr.isTTY) return
+  process.stderr.write('\r' + s.padEnd(40))
+}
+
+let made = 0
+const makeStep = async dir => {
+  if (now() - lastReported > 250) report('growing: ' + made)
+  const promises = []
+  for (let i = 0; i < filesPerDir && made < max; i++) {
+    made++
+    promises.push(writeFile(`${dir}/${i}.txt`, ''))
+  }
+  await Promise.all(promises)
+
+  const childDirs = []
+  for (let i = 0; i < dirsPerDir && made < max; i++) {
+    made++
+    await mkdirp(`${dir}/${i}`)
+    childDirs.push(makeStep(`${dir}/${i}`))
+  }
+  await Promise.all(childDirs)
+}
+
+const make = async root => {
+  try {
+    const already = +readFileSync(`${root}/bigtree.txt`)
+    if (already === max) {
+      console.log('already done!')
+      return
+    }
+  } catch (_) {}
+  report('chop down previous bigtree...')
+  await rimraf(root + '/bigtree')
+  report('creating bigtree...')
+  report('\n')
+  await mkdirp(root + '/bigtree')
+  await makeStep(root + '/bigtree')
+  await writeFile(`${root}/bigtree.txt`, `${max}`)
+}
+
+make(__dirname + '/fixture').then(() => {
+  if (process.stderr.isTTY) process.stderr.write('\r'.padEnd(40) + '\r')
+  console.log('done')
+})

From ef3f0fbe1a4aa0ec9dc6c901860b675617747f30 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 2 Mar 2023 12:18:33 -0800
Subject: [PATCH 142/163] code formatting

---
 README.md            |  2 +-
 src/walker.ts        |  6 ++++--
 test/dot-relative.ts | 27 +++++++++++++++------------
 test/escape.ts       | 13 +++++++++----
 test/url-cwd.ts      |  6 +++---
 5 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/README.md b/README.md
index 542c45bc..96d3459c 100644
--- a/README.md
+++ b/README.md
@@ -155,7 +155,7 @@ be escaped or unescaped.
 Un-escape a glob string that may contain some escaped characters.
 
 If the `windowsPathsNoEscape` option is used, then square-brace
-escapes are removed, but not backslash escapes.  For example, it
+escapes are removed, but not backslash escapes. For example, it
 will turn the string `'[*]'` into `*`, but it will not turn
 `'\\*'` into `'*'`, because `\` is a path separator in
 `windowsPathsNoEscape` mode.
diff --git a/src/walker.ts b/src/walker.ts
index ade37d95..ba0c022c 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -201,8 +201,10 @@ export abstract class GlobUtil {
       this.matchEmit(e.fullpath() + mark)
     } else {
       const rel = e.relative()
-      const pre = this.opts.dotRelative && !rel.startsWith('..' + this.#sep)
-        ? '.' + this.#sep : ''
+      const pre =
+        this.opts.dotRelative && !rel.startsWith('..' + this.#sep)
+          ? '.' + this.#sep
+          : ''
       this.matchEmit(!rel && mark ? '.' + mark : pre + rel + mark)
     }
   }
diff --git a/test/dot-relative.ts b/test/dot-relative.ts
index 62c0c168..5a27027a 100644
--- a/test/dot-relative.ts
+++ b/test/dot-relative.ts
@@ -1,7 +1,7 @@
 import t from 'tap'
 import { Glob } from '../'
 import { bashResults } from './bash-results'
-import {resolve, sep} from 'path'
+import { resolve, sep } from 'path'
 
 const pattern = 'a/b/**'
 process.chdir(__dirname + '/fixtures')
@@ -39,19 +39,22 @@ for (const mark of marks) {
       }
     })
 
-    t.test('does not prefix with ./ unless dotRelative is true', async t => {
-      const g = new Glob(pattern, {})
-      const results = await g.walk()
+    t.test(
+      'does not prefix with ./ unless dotRelative is true',
+      async t => {
+        const g = new Glob(pattern, {})
+        const results = await g.walk()
 
-      t.equal(
-        results.length,
-        bashResults[pattern].length,
-        'must match all files'
-      )
-      for (const m of results) {
-        t.ok(mark && m === '.' + sep || !m.startsWith('.' + sep))
+        t.equal(
+          results.length,
+          bashResults[pattern].length,
+          'must match all files'
+        )
+        for (const m of results) {
+          t.ok((mark && m === '.' + sep) || !m.startsWith('.' + sep))
+        }
       }
-    })
+    )
   })
 }
 
diff --git a/test/escape.ts b/test/escape.ts
index b9a56342..5e1ac085 100644
--- a/test/escape.ts
+++ b/test/escape.ts
@@ -6,11 +6,16 @@ for (const pattern of Object.keys(bashResults)) {
   t.notOk(hasMagic(escape(pattern)), `escape(${pattern})`)
   const pp = escape(pattern)
   const pw = escape(pattern, {
-    windowsPathsNoEscape: true
+    windowsPathsNoEscape: true,
   })
-  t.notOk(hasMagic(pp, { platform: 'linux' }), 'no magic after posix escape')
-  t.notOk(hasMagic(pw, { platform: 'win32', windowsPathsNoEscape: true }),
-    'no magic after windows escape')
+  t.notOk(
+    hasMagic(pp, { platform: 'linux' }),
+    'no magic after posix escape'
+  )
+  t.notOk(
+    hasMagic(pw, { platform: 'win32', windowsPathsNoEscape: true }),
+    'no magic after windows escape'
+  )
   const up = unescape(pp)
   const uw = unescape(pw, { windowsPathsNoEscape: true })
   t.equal(up, pattern, 'unescaped posix pattern returned')
diff --git a/test/url-cwd.ts b/test/url-cwd.ts
index 1733dabe..e3c584b2 100644
--- a/test/url-cwd.ts
+++ b/test/url-cwd.ts
@@ -1,11 +1,11 @@
 import t from 'tap'
-import {pathToFileURL} from 'url'
-import {Glob} from '../'
+import { pathToFileURL } from 'url'
+import { Glob } from '../'
 
 t.test('can use file url as cwd option', t => {
   const fileURL = pathToFileURL(process.cwd())
   const fileURLString = String(fileURL)
-  const ps = new Glob('.', { cwd: process.cwd()})
+  const ps = new Glob('.', { cwd: process.cwd() })
   const pu = new Glob('.', { cwd: fileURL })
   const pus = new Glob('.', { cwd: fileURLString })
   t.equal(ps.cwd, process.cwd())

From 9d3609e314b5e6b3e9adf3a045c4eee934c03d94 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 2 Mar 2023 13:30:10 -0800
Subject: [PATCH 143/163] add maxDepth option

Fix: #296
---
 README.md                                |   3 +
 src/glob.ts                              |  27 ++++++
 src/index.ts                             |  60 ++++++-------
 src/walker.ts                            |  16 ++++
 tap-snapshots/test/max-depth.ts.test.cjs |  38 ++++++++
 test/max-depth.ts                        | 109 +++++++++++++++++++++++
 6 files changed, 219 insertions(+), 34 deletions(-)
 create mode 100644 tap-snapshots/test/max-depth.ts.test.cjs
 create mode 100644 test/max-depth.ts

diff --git a/README.md b/README.md
index 96d3459c..e67e727c 100644
--- a/README.md
+++ b/README.md
@@ -310,6 +310,9 @@ share the previously loaded cache.
   systems, or `false` on case-insensitive file systems, then the
   walk may return more or less results than expected.
 
+- `maxDepth` Specify a number to limit the depth of the directory
+  traversal to this many levels below the `cwd`.
+
 - `matchBase` Perform a basename-only match if the pattern does
   not contain any slash characters. That is, `*.js` would be
   treated as equivalent to `**/*.js`, matching all js files in
diff --git a/src/glob.ts b/src/glob.ts
index 584b156d..7b4e9b89 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -126,6 +126,14 @@ export interface GlobOptions {
    */
   matchBase?: boolean
 
+  /**
+   * Limit the directory traversal to a given depth below the cwd.
+   * Note that this does NOT prevent traversal to sibling folders,
+   * root patterns, and so on. It only limits the maximum folder depth
+   * that the walk will descend, relative to the cwd.
+   */
+  maxDepth?: number
+
   /**
    * Do not expand `{a,b}` and `{1..3}` brace sets.
    */
@@ -293,6 +301,7 @@ export class Glob implements GlobOptions {
   magicalBraces: boolean
   mark?: boolean
   matchBase: boolean
+  maxDepth: number
   nobrace: boolean
   nocase: boolean
   nodir: boolean
@@ -351,6 +360,8 @@ export class Glob implements GlobOptions {
 
     this.noglobstar = !!opts.noglobstar
     this.matchBase = !!opts.matchBase
+    this.maxDepth =
+      typeof opts.maxDepth === 'number' ? opts.maxDepth : Infinity
 
     if (this.withFileTypes && this.absolute !== undefined) {
       throw new Error('cannot set absolute and withFileTypes:true')
@@ -445,6 +456,10 @@ export class Glob implements GlobOptions {
     return [
       ...(await new GlobWalker(this.patterns, this.scurry.cwd, {
         ...this.opts,
+        maxDepth:
+          this.maxDepth !== Infinity
+            ? this.maxDepth + this.scurry.cwd.depth()
+            : Infinity,
         platform: this.platform,
         nocase: this.nocase,
       }).walk()),
@@ -459,6 +474,10 @@ export class Glob implements GlobOptions {
     return [
       ...new GlobWalker(this.patterns, this.scurry.cwd, {
         ...this.opts,
+        maxDepth:
+          this.maxDepth !== Infinity
+            ? this.maxDepth + this.scurry.cwd.depth()
+            : Infinity,
         platform: this.platform,
         nocase: this.nocase,
       }).walkSync(),
@@ -472,6 +491,10 @@ export class Glob implements GlobOptions {
   stream(): Minipass {
     return new GlobStream(this.patterns, this.scurry.cwd, {
       ...this.opts,
+      maxDepth:
+        this.maxDepth !== Infinity
+          ? this.maxDepth + this.scurry.cwd.depth()
+          : Infinity,
       platform: this.platform,
       nocase: this.nocase,
     }).stream()
@@ -484,6 +507,10 @@ export class Glob implements GlobOptions {
   streamSync(): Minipass {
     return new GlobStream(this.patterns, this.scurry.cwd, {
       ...this.opts,
+      maxDepth:
+        this.maxDepth !== Infinity
+          ? this.maxDepth + this.scurry.cwd.depth()
+          : Infinity,
       platform: this.platform,
       nocase: this.nocase,
     }).streamSync()
diff --git a/src/index.ts b/src/index.ts
index 0cd7be2a..4167d0bb 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,20 +1,14 @@
 import { escape, unescape } from 'minimatch'
+import Minipass from 'minipass'
+import { Path } from 'path-scurry'
 import type {
   GlobOptions,
   GlobOptionsWithFileTypesFalse,
   GlobOptionsWithFileTypesTrue,
   GlobOptionsWithFileTypesUnset,
-  Results,
 } from './glob.js'
 import { Glob } from './glob.js'
 import { hasMagic } from './has-magic.js'
-import type {
-  GWOFileTypesFalse,
-  GWOFileTypesTrue,
-  GWOFileTypesUnset,
-  MatchStream,
-  Result,
-} from './walker.js'
 
 /**
  * Syncronous form of {@link globStream}. Will read all the matches as fast as
@@ -24,19 +18,19 @@ import type {
 export function globStreamSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesTrue
-): MatchStream
+): Minipass
 export function globStreamSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesFalse
-): MatchStream
+): Minipass
 export function globStreamSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesUnset
-): MatchStream
+): Minipass
 export function globStreamSync(
   pattern: string | string[],
   options: GlobOptions
-): MatchStream
+): Minipass | Minipass
 export function globStreamSync(
   pattern: string | string[],
   options: GlobOptions = {}
@@ -51,19 +45,19 @@ export function globStreamSync(
 export function globStream(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesFalse
-): MatchStream
+): Minipass
 export function globStream(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesTrue
-): MatchStream
+): Minipass
 export function globStream(
   pattern: string | string[],
   options?: GlobOptionsWithFileTypesUnset | undefined
-): MatchStream
+): Minipass
 export function globStream(
   pattern: string | string[],
   options: GlobOptions
-): MatchStream
+): Minipass | Minipass
 export function globStream(
   pattern: string | string[],
   options: GlobOptions = {}
@@ -77,19 +71,19 @@ export function globStream(
 export function globSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesFalse
-): Results
+): string[]
 export function globSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesTrue
-): Results
+): Path[]
 export function globSync(
   pattern: string | string[],
   options?: GlobOptionsWithFileTypesUnset | undefined
-): Results
+): string[]
 export function globSync(
   pattern: string | string[],
   options: GlobOptions
-): Results
+): Path[] | string[]
 export function globSync(
   pattern: string | string[],
   options: GlobOptions = {}
@@ -106,19 +100,19 @@ export function globSync(
 export async function glob(
   pattern: string | string[],
   options?: GlobOptionsWithFileTypesUnset | undefined
-): Promise>
+): Promise
 export async function glob(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesTrue
-): Promise>
+): Promise
 export async function glob(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesFalse
-): Promise>
+): Promise
 export async function glob(
   pattern: string | string[],
   options: GlobOptions
-): Promise>
+): Promise
 export async function glob(
   pattern: string | string[],
   options: GlobOptions = {}
@@ -132,19 +126,19 @@ export async function glob(
 export function globIterate(
   pattern: string | string[],
   options?: GlobOptionsWithFileTypesUnset | undefined
-): AsyncGenerator, void, void>
+): AsyncGenerator
 export function globIterate(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesTrue
-): AsyncGenerator, void, void>
+): AsyncGenerator
 export function globIterate(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesFalse
-): AsyncGenerator, void, void>
+): AsyncGenerator
 export function globIterate(
   pattern: string | string[],
   options: GlobOptions
-): AsyncGenerator, void, void>
+): AsyncGenerator | AsyncGenerator
 export function globIterate(
   pattern: string | string[],
   options: GlobOptions = {}
@@ -158,19 +152,19 @@ export function globIterate(
 export function globIterateSync(
   pattern: string | string[],
   options?: GlobOptionsWithFileTypesUnset | undefined
-): Generator, void, void>
+): Generator
 export function globIterateSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesTrue
-): Generator, void, void>
+): Generator
 export function globIterateSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesFalse
-): Generator, void, void>
+): Generator
 export function globIterateSync(
   pattern: string | string[],
   options: GlobOptions
-): Generator, void, void>
+): Generator | Generator
 export function globIterateSync(
   pattern: string | string[],
   options: GlobOptions = {}
@@ -186,8 +180,6 @@ export type {
   GlobOptionsWithFileTypesFalse,
   GlobOptionsWithFileTypesTrue,
   GlobOptionsWithFileTypesUnset,
-  Result,
-  Results,
 } from './glob.js'
 export { hasMagic } from './has-magic.js'
 export type { MatchStream } from './walker.js'
diff --git a/src/walker.ts b/src/walker.ts
index ba0c022c..05810776 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -26,6 +26,9 @@ export interface GlobWalkerOpts {
   ignore?: string | string[] | Ignore
   mark?: boolean
   matchBase?: boolean
+  // Note: maxDepth here means "maximum actual Path.depth()",
+  // not "maximum depth beyond cwd"
+  maxDepth?: number
   nobrace?: boolean
   nocase?: boolean
   nodir?: boolean
@@ -100,6 +103,7 @@ export abstract class GlobUtil {
   #ignore?: Ignore
   #sep: '\\' | '/'
   signal?: AbortSignal
+  maxDepth: number
 
   constructor(patterns: Pattern[], path: Path, opts: O)
   constructor(patterns: Pattern[], path: Path, opts: O) {
@@ -110,6 +114,11 @@ export abstract class GlobUtil {
     if (opts.ignore) {
       this.#ignore = makeIgnore(opts.ignore, opts)
     }
+    // ignore, always set with maxDepth, but it's optional on the
+    // GlobOptions type
+    /* c8 ignore start */
+    this.maxDepth = opts.maxDepth || Infinity
+    /* c8 ignore stop */
     if (opts.signal) {
       this.signal = opts.signal
       this.signal.addEventListener('abort', () => {
@@ -166,6 +175,7 @@ export abstract class GlobUtil {
 
   matchCheckTest(e: Path | undefined, ifDir: boolean): Path | undefined {
     return e &&
+      (this.maxDepth === Infinity || e.depth() <= this.maxDepth) &&
       !this.#ignored(e) &&
       (!ifDir || e.canReaddir()) &&
       (!this.opts.nodir || !e.isDirectory())
@@ -255,6 +265,9 @@ export abstract class GlobUtil {
     }
 
     for (const t of processor.subwalkTargets()) {
+      if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) {
+        continue
+      }
       tasks++
       const childrenCached = t.readdirCached()
       if (t.calledReaddir())
@@ -333,6 +346,9 @@ export abstract class GlobUtil {
     }
 
     for (const t of processor.subwalkTargets()) {
+      if (this.maxDepth !== Infinity && t.depth() >= this.maxDepth) {
+        continue
+      }
       tasks++
       const children = t.readdirSync()
       this.walkCB3Sync(t, children, processor, next)
diff --git a/tap-snapshots/test/max-depth.ts.test.cjs b/tap-snapshots/test/max-depth.ts.test.cjs
new file mode 100644
index 00000000..55860f2b
--- /dev/null
+++ b/tap-snapshots/test/max-depth.ts.test.cjs
@@ -0,0 +1,38 @@
+/* IMPORTANT
+ * This snapshot file is auto-generated, but designed for humans.
+ * It should be checked into source control and tracked carefully.
+ * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
+ * Make sure to inspect the output below.  Do not ignore changes!
+ */
+'use strict'
+exports[`test/max-depth.ts TAP set maxDepth > async results 1`] = `
+Array [
+  "",
+  "a",
+  "a/abcdef",
+  "a/abcfed",
+  "a/b",
+  "a/bc",
+  "a/c",
+  "a/cb",
+  "a/symlink",
+  "a/x",
+  "a/z",
+]
+`
+
+exports[`test/max-depth.ts TAP set maxDepth > sync results 1`] = `
+Array [
+  "",
+  "a",
+  "a/abcdef",
+  "a/abcfed",
+  "a/b",
+  "a/bc",
+  "a/c",
+  "a/cb",
+  "a/symlink",
+  "a/x",
+  "a/z",
+]
+`
diff --git a/test/max-depth.ts b/test/max-depth.ts
new file mode 100644
index 00000000..3f2c68a8
--- /dev/null
+++ b/test/max-depth.ts
@@ -0,0 +1,109 @@
+import { resolve } from 'path'
+import { PathScurry } from 'path-scurry'
+import t from 'tap'
+import { Glob, glob, globStream, globStreamSync, globSync } from '../'
+const j = (a: string[]) =>
+  a
+    .map(s => s.replace(/\\/g, '/'))
+    .sort((a, b) => a.localeCompare(b, 'en'))
+t.test('set maxDepth', async t => {
+  const maxDepth = 2
+  const cwd = resolve(__dirname, 'fixtures')
+  const startDepth = new PathScurry(cwd).cwd.depth()
+  const pattern = '{*/*/*/**,*/*/**,**}'
+  const asyncRes = await glob(pattern, {
+    cwd,
+    maxDepth,
+    follow: true,
+    withFileTypes: true,
+  })
+  const syncRes = globSync(pattern, {
+    cwd,
+    maxDepth,
+    follow: true,
+    withFileTypes: true,
+  })
+  const noMaxDepth = globSync(pattern, {
+    cwd,
+    follow: true,
+    withFileTypes: true,
+  })
+  const expect = j(
+    noMaxDepth
+      .filter(p => p.depth() <= startDepth + maxDepth)
+      .map(p => p.relative())
+  )
+
+  const ssync = j(syncRes.map(p => p.relative()))
+  const sasync = j(asyncRes.map(p => p.relative()))
+  t.matchSnapshot(sasync, 'async results')
+  t.matchSnapshot(ssync, 'sync results')
+  t.same(ssync, expect, 'got all results sync')
+  t.same(sasync, expect, 'got all results async')
+  for (const p of syncRes) {
+    t.ok(p.depth() <= startDepth + maxDepth, 'does not exceed maxDepth', {
+      max: startDepth + maxDepth,
+      actual: p.depth(),
+      file: p.relative(),
+      results: 'sync',
+    })
+  }
+  for (const p of asyncRes) {
+    t.ok(p.depth() <= startDepth + maxDepth, 'does not exceed maxDepth', {
+      max: startDepth + maxDepth,
+      actual: p.depth(),
+      file: p.relative(),
+      results: 'async',
+    })
+  }
+
+  t.same(
+    j(
+      await globStream(pattern, { cwd, maxDepth, follow: true }).collect()
+    ),
+    expect,
+    'maxDepth with stream'
+  )
+  t.same(
+    j(
+      await globStreamSync(pattern, {
+        cwd,
+        maxDepth,
+        follow: true,
+      }).collect()
+    ),
+    expect,
+    'maxDepth with streamSync'
+  )
+
+  t.same(
+    await glob(pattern, { cwd, maxDepth: -1, follow: true }),
+    [],
+    'async maxDepth -1'
+  )
+  t.same(
+    globSync(pattern, { cwd, maxDepth: -1, follow: true }),
+    [],
+    'sync maxDepth -1'
+  )
+
+  t.same(
+    await glob(pattern, { cwd, maxDepth: 0, follow: true }),
+    [''],
+    'async maxDepth 0'
+  )
+  t.same(
+    globSync(pattern, { cwd, maxDepth: 0, follow: true }),
+    [''],
+    'async maxDepth 0'
+  )
+
+  const g = new Glob(pattern, { cwd, follow: true, maxDepth })
+  t.same(j([...g]), expect, 'maxDepth with iteration')
+  const ai = new Glob(pattern, g)
+  const aires: string[] = []
+  for await (const res of ai) {
+    aires.push(res)
+  }
+  t.same(j(aires), expect, 'maxDepth with async iteration')
+})

From 95ffddf8f39d1bddc2bd3fabd69ffd53ddacb55e Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 2 Mar 2023 13:49:55 -0800
Subject: [PATCH 144/163] add stat:true option

Fix: #353
---
 README.md     | 21 +++++++++++++++++++++
 src/glob.ts   | 11 +++++++++++
 src/walker.ts |  5 +++--
 test/stat.ts  | 23 +++++++++++++++++++++++
 4 files changed, 58 insertions(+), 2 deletions(-)
 create mode 100644 test/stat.ts

diff --git a/README.md b/README.md
index e67e727c..2521c985 100644
--- a/README.md
+++ b/README.md
@@ -82,6 +82,21 @@ g3.stream().on('data', path => {
     path.readdirSync().map(e => e.name)
   )
 })
+
+// if you use stat:true and withFileTypes, you can sort results
+// by things like modified time, filter by permission mode, etc.
+// All Stats fields will be avialable in that case. Slightly
+// slower, though.
+// For example:
+const results = await glob('**', { stat: true, withFileTypes: true })
+
+const timeSortedFiles = results
+  .sort((a, b) => a.mtimeMS - b.mtimeMS)
+  .map(path => path.fullpath())
+
+const groupReadableFiles = results
+  .filter(path => path.mode & 0o040)
+  .map(path => path.fullpath())
 ```
 
 **Note** Glob patterns should always use `/` as a path separator,
@@ -321,6 +336,12 @@ share the previously loaded cache.
 - `nodir` Do not match directories, only files. (Note: to match
   _only_ directories, put a `/` at the end of the pattern.)
 
+- `stat` Call `lstat()` on all entries, whether required or not
+  to determine whether it's a valid match. When used with
+  `withFileTypes`, this means that matches will include data such
+  as modified time, permissions, and so on. Note that this will
+  incur a performance cost due to the added system calls.
+
 - `ignore` string or string[]. A glob pattern or array of glob
   patterns to exclude from matches. To ignore all children within
   a directory, as well as the entry itself, append `/**'` to the
diff --git a/src/glob.ts b/src/glob.ts
index 7b4e9b89..471e6058 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -218,6 +218,15 @@ export interface GlobOptions {
    */
   scurry?: PathScurry
 
+  /**
+   * Call `lstat()` on all entries, whether required or not to determine
+   * whether it's a valid match. When used with {@link withFileTypes}, this
+   * means that matches will include data such as modified time, permissions,
+   * and so on.  Note that this will incur a performance cost due to the added
+   * system calls.
+   */
+  stat?: boolean
+
   /**
    * An AbortSignal which will cancel the Glob walk when
    * triggered.
@@ -311,6 +320,7 @@ export class Glob implements GlobOptions {
   platform: NodeJS.Platform
   realpath: boolean
   scurry: PathScurry
+  stat: boolean
   signal?: AbortSignal
   windowsPathsNoEscape: boolean
   withFileTypes: FileTypes
@@ -362,6 +372,7 @@ export class Glob implements GlobOptions {
     this.matchBase = !!opts.matchBase
     this.maxDepth =
       typeof opts.maxDepth === 'number' ? opts.maxDepth : Infinity
+    this.stat = !!opts.stat
 
     if (this.withFileTypes && this.absolute !== undefined) {
       throw new Error('cannot set absolute and withFileTypes:true')
diff --git a/src/walker.ts b/src/walker.ts
index 05810776..234e2b9b 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -37,6 +37,7 @@ export interface GlobWalkerOpts {
   platform?: NodeJS.Platform
   realpath?: boolean
   root?: string
+  stat?: boolean
   signal?: AbortSignal
   windowsPathsNoEscape?: boolean
   withFileTypes?: boolean
@@ -169,7 +170,7 @@ export abstract class GlobUtil {
       if (!rpc) return undefined
       e = rpc
     }
-    const needStat = e.isUnknown()
+    const needStat = e.isUnknown() || this.opts.stat
     return this.matchCheckTest(needStat ? await e.lstat() : e, ifDir)
   }
 
@@ -191,7 +192,7 @@ export abstract class GlobUtil {
       if (!rpc) return undefined
       e = rpc
     }
-    const needStat = e.isUnknown()
+    const needStat = e.isUnknown() || this.opts.stat
     return this.matchCheckTest(needStat ? e.lstatSync() : e, ifDir)
   }
 
diff --git a/test/stat.ts b/test/stat.ts
new file mode 100644
index 00000000..9717fb38
--- /dev/null
+++ b/test/stat.ts
@@ -0,0 +1,23 @@
+import { resolve } from 'path'
+import t from 'tap'
+import { glob, globSync } from '../'
+
+t.test('stat: true', async t => {
+  const cwd = resolve(__dirname, 'fixtures')
+  const pattern = '*'
+  const asyncRes = await glob(pattern, {
+    cwd,
+    withFileTypes: true,
+    stat: true,
+  })
+  const syncRes = globSync(pattern, {
+    cwd,
+    withFileTypes: true,
+    stat: true,
+  })
+  t.type(asyncRes[0].mode, 'number')
+  t.type(syncRes[0].mode, 'number')
+
+  const noStat = await glob(pattern, { cwd, withFileTypes: true })
+  t.equal(noStat[0].mode, undefined)
+})

From a2fb6885771132194b4b2ead9a0c6afe09f00a6f Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 2 Mar 2023 14:20:27 -0800
Subject: [PATCH 145/163] remove maxDepth test snapshots

They're unnecessary, since we're already comparing to the unlimited
results, and the presence/absence of 'symlink' makes the test fail
on Windows CI.
---
 tap-snapshots/test/max-depth.ts.test.cjs | 38 ------------------------
 test/max-depth.ts                        |  2 --
 2 files changed, 40 deletions(-)
 delete mode 100644 tap-snapshots/test/max-depth.ts.test.cjs

diff --git a/tap-snapshots/test/max-depth.ts.test.cjs b/tap-snapshots/test/max-depth.ts.test.cjs
deleted file mode 100644
index 55860f2b..00000000
--- a/tap-snapshots/test/max-depth.ts.test.cjs
+++ /dev/null
@@ -1,38 +0,0 @@
-/* IMPORTANT
- * This snapshot file is auto-generated, but designed for humans.
- * It should be checked into source control and tracked carefully.
- * Re-generate by setting TAP_SNAPSHOT=1 and running tests.
- * Make sure to inspect the output below.  Do not ignore changes!
- */
-'use strict'
-exports[`test/max-depth.ts TAP set maxDepth > async results 1`] = `
-Array [
-  "",
-  "a",
-  "a/abcdef",
-  "a/abcfed",
-  "a/b",
-  "a/bc",
-  "a/c",
-  "a/cb",
-  "a/symlink",
-  "a/x",
-  "a/z",
-]
-`
-
-exports[`test/max-depth.ts TAP set maxDepth > sync results 1`] = `
-Array [
-  "",
-  "a",
-  "a/abcdef",
-  "a/abcfed",
-  "a/b",
-  "a/bc",
-  "a/c",
-  "a/cb",
-  "a/symlink",
-  "a/x",
-  "a/z",
-]
-`
diff --git a/test/max-depth.ts b/test/max-depth.ts
index 3f2c68a8..a641ee07 100644
--- a/test/max-depth.ts
+++ b/test/max-depth.ts
@@ -36,8 +36,6 @@ t.test('set maxDepth', async t => {
 
   const ssync = j(syncRes.map(p => p.relative()))
   const sasync = j(asyncRes.map(p => p.relative()))
-  t.matchSnapshot(sasync, 'async results')
-  t.matchSnapshot(ssync, 'sync results')
   t.same(ssync, expect, 'got all results sync')
   t.same(sasync, expect, 'got all results async')
   for (const p of syncRes) {

From cdfde4be93110ae915d1ad233f895cd1901d4c50 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 2 Mar 2023 14:54:06 -0800
Subject: [PATCH 146/163] add custom Ignore support

Fix: #261
Fix: #363
Fix: #335
---
 README.md             | 53 +++++++++++++++++++++++++++++++++++++++----
 src/glob.ts           | 25 +++++++++++++++-----
 src/ignore.ts         |  9 +++++++-
 src/index.ts          |  3 ++-
 src/walker.ts         | 22 ++++++++----------
 test/custom-ignore.ts | 46 +++++++++++++++++++++++++++++++++++++
 6 files changed, 134 insertions(+), 24 deletions(-)
 create mode 100644 test/custom-ignore.ts

diff --git a/README.md b/README.md
index 2521c985..ef821aca 100644
--- a/README.md
+++ b/README.md
@@ -97,6 +97,43 @@ const timeSortedFiles = results
 const groupReadableFiles = results
   .filter(path => path.mode & 0o040)
   .map(path => path.fullpath())
+
+// custom ignores can be done like this, for example by saying
+// you'll ignore all markdown files, and all folders named 'docs'
+const customIgnoreResults = await glob('**', {
+  ignore: {
+    ignored: (p) => /\.md$/.test(p.name),
+    childrenIgnored: (p) => p.isNamed('docs'),
+  },
+})
+
+// another fun use case, only return files with the same name as
+// their parent folder, plus either `.ts` or `.js`
+const folderNamedModules = await glob('**/*.{ts,js}', {
+  ignore: {
+    ignored: (p) => {
+      const pp = p.parent
+      return !(p.isNamed(pp.name + '.ts') || p.isNamed(pp.name + '.js'))
+    }
+  }
+})
+
+// find all files edited in the last hour
+const newFiles = await glob('**', {
+  // need stat so we have mtime
+  stat: true,
+  // only want the files, not the dirs
+  nodir: true,
+  ignore: {
+    ignored: (p) => {
+      return (new Date() - p.mtime) <= (60 * 60 * 1000)
+    },
+    // could add similar childrenIgnored here as well, but
+    // directory mtime is inconsistent across platforms, so
+    // probably better not to, unless you know the system
+    // tracks this reliably.
+  }
+})
 ```
 
 **Note** Glob patterns should always use `/` as a path separator,
@@ -342,14 +379,22 @@ share the previously loaded cache.
   as modified time, permissions, and so on. Note that this will
   incur a performance cost due to the added system calls.
 
-- `ignore` string or string[]. A glob pattern or array of glob
-  patterns to exclude from matches. To ignore all children within
-  a directory, as well as the entry itself, append `/**'` to the
-  ignore pattern.
+- `ignore` string or string[], or an object with `ignore` and
+  `ignoreChildren` methods.
+
+  If a string or string[] is provided, then this is treated as a
+  glob pattern or array of glob patterns to exclude from matches.
+  To ignore all children within a directory, as well as the entry
+  itself, append `'/**'` to the ignore pattern.
 
   **Note** `ignore` patterns are _always_ in `dot:true` mode,
   regardless of any other settings.
 
+  If an object is provided that has `ignored(path)` and/or
+  `childrenIgnored(path)` methods, then these methods will be
+  called to determine whether any Path is a match or if its
+  children should be traversed, respectively.
+
 - `follow` Follow symlinked directories when expanding `**`
   patterns. This can result in a lot of duplicate references in
   the presence of cyclic links, and make performance quite bad.
diff --git a/src/glob.ts b/src/glob.ts
index 471e6058..a78d92b9 100644
--- a/src/glob.ts
+++ b/src/glob.ts
@@ -9,7 +9,7 @@ import {
   PathScurryWin32,
 } from 'path-scurry'
 import { fileURLToPath } from 'url'
-import { Ignore } from './ignore.js'
+import { IgnoreLike } from './ignore.js'
 import { Pattern } from './pattern.js'
 import { GlobStream, GlobWalker } from './walker.js'
 
@@ -99,11 +99,23 @@ export interface GlobOptions {
   follow?: boolean
 
   /**
-   * A glob pattern or array of glob patterns to exclude from matches. To
-   * ignore all children within a directory, as well as the entry itself,
-   * append `/**'` to the ignore pattern.
+   * string or string[], or an object with `ignore` and `ignoreChildren`
+   * methods.
+   *
+   * If a string or string[] is provided, then this is treated as a glob
+   * pattern or array of glob patterns to exclude from matches. To ignore all
+   * children within a directory, as well as the entry itself, append `'/**'`
+   * to the ignore pattern.
+   *
+   * **Note** `ignore` patterns are _always_ in `dot:true` mode, regardless of
+   * any other settings.
+   *
+   * If an object is provided that has `ignored(path)` and/or
+   * `childrenIgnored(path)` methods, then these methods will be called to
+   * determine whether any Path is a match or if its children should be
+   * traversed, respectively.
    */
-  ignore?: string | string[] | Ignore
+  ignore?: string | string[] | IgnoreLike
 
   /**
    * Treat brace expansion like `{a,b}` as a "magic" pattern. Has no
@@ -306,7 +318,7 @@ export class Glob implements GlobOptions {
   dot: boolean
   dotRelative: boolean
   follow: boolean
-  ignore?: Ignore
+  ignore?: string | string[] | IgnoreLike
   magicalBraces: boolean
   mark?: boolean
   matchBase: boolean
@@ -373,6 +385,7 @@ export class Glob implements GlobOptions {
     this.maxDepth =
       typeof opts.maxDepth === 'number' ? opts.maxDepth : Infinity
     this.stat = !!opts.stat
+    this.ignore = opts.ignore
 
     if (this.withFileTypes && this.absolute !== undefined) {
       throw new Error('cannot set absolute and withFileTypes:true')
diff --git a/src/ignore.ts b/src/ignore.ts
index 60d4deec..7ba09cfb 100644
--- a/src/ignore.ts
+++ b/src/ignore.ts
@@ -8,6 +8,11 @@ import { Path } from 'path-scurry'
 import { Pattern } from './pattern.js'
 import { GlobWalkerOpts } from './walker.js'
 
+export interface IgnoreLike {
+  ignored?: (p: Path) => boolean
+  childrenIgnored?: (p: Path) => boolean
+}
+
 const defaultPlatform: NodeJS.Platform =
   typeof process === 'object' &&
   process &&
@@ -18,7 +23,7 @@ const defaultPlatform: NodeJS.Platform =
 /**
  * Class used to process ignored patterns
  */
-export class Ignore {
+export class Ignore implements IgnoreLike {
   relative: Minimatch[]
   relativeChildren: Minimatch[]
   absolute: Minimatch[]
@@ -46,6 +51,8 @@ export class Ignore {
       noglobstar,
       optimizationLevel: 2,
       platform,
+      nocomment: true,
+      nonegate: true,
     }
 
     // this is a little weird, but it gives us a clean set of optimized
diff --git a/src/index.ts b/src/index.ts
index 4167d0bb..2ba37e2a 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -182,9 +182,10 @@ export type {
   GlobOptionsWithFileTypesUnset,
 } from './glob.js'
 export { hasMagic } from './has-magic.js'
+export type { IgnoreLike } from './ignore.js'
 export type { MatchStream } from './walker.js'
-
 /* c8 ignore stop */
+
 export default Object.assign(glob, {
   glob,
   globSync,
diff --git a/src/walker.ts b/src/walker.ts
index 234e2b9b..e32d1880 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -6,7 +6,7 @@
  */
 import Minipass from 'minipass'
 import { Path } from 'path-scurry'
-import { Ignore } from './ignore.js'
+import { Ignore, IgnoreLike } from './ignore.js'
 
 // XXX can we somehow make it so that it NEVER processes a given path more than
 // once, enough that the match set tracking is no longer needed?  that'd speed
@@ -23,7 +23,7 @@ export interface GlobWalkerOpts {
   dot?: boolean
   dotRelative?: boolean
   follow?: boolean
-  ignore?: string | string[] | Ignore
+  ignore?: string | string[] | IgnoreLike
   mark?: boolean
   matchBase?: boolean
   // Note: maxDepth here means "maximum actual Path.depth()",
@@ -79,16 +79,14 @@ export type MatchStream =
     : Minipass
 
 const makeIgnore = (
-  ignore: string | string[] | Ignore,
+  ignore: string | string[] | IgnoreLike,
   opts: GlobWalkerOpts
-): Ignore =>
+): IgnoreLike =>
   typeof ignore === 'string'
     ? new Ignore([ignore], opts)
     : Array.isArray(ignore)
     ? new Ignore(ignore, opts)
-    : /* c8 ignore start */
-      ignore
-/* c8 ignore stop */
+    : ignore
 
 /**
  * basic walking utilities that all the glob walker types use
@@ -101,7 +99,7 @@ export abstract class GlobUtil {
   paused: boolean = false
   aborted: boolean = false
   #onResume: (() => any)[] = []
-  #ignore?: Ignore
+  #ignore?: IgnoreLike
   #sep: '\\' | '/'
   signal?: AbortSignal
   maxDepth: number
@@ -129,10 +127,10 @@ export abstract class GlobUtil {
   }
 
   #ignored(path: Path): boolean {
-    return this.seen.has(path) || !!this.#ignore?.ignored(path)
+    return this.seen.has(path) || !!this.#ignore?.ignored?.(path)
   }
   #childrenIgnored(path: Path): boolean {
-    return !!this.#ignore?.childrenIgnored(path)
+    return !!this.#ignore?.childrenIgnored?.(path)
   }
 
   // backpressure mechanism
@@ -177,9 +175,9 @@ export abstract class GlobUtil {
   matchCheckTest(e: Path | undefined, ifDir: boolean): Path | undefined {
     return e &&
       (this.maxDepth === Infinity || e.depth() <= this.maxDepth) &&
-      !this.#ignored(e) &&
       (!ifDir || e.canReaddir()) &&
-      (!this.opts.nodir || !e.isDirectory())
+      (!this.opts.nodir || !e.isDirectory()) &&
+      !this.#ignored(e)
       ? e
       : undefined
   }
diff --git a/test/custom-ignore.ts b/test/custom-ignore.ts
new file mode 100644
index 00000000..cdc8db16
--- /dev/null
+++ b/test/custom-ignore.ts
@@ -0,0 +1,46 @@
+import { basename, resolve } from 'path'
+import { Path } from 'path-scurry'
+import t from 'tap'
+import { glob, globSync, IgnoreLike } from '../'
+const cwd = resolve(__dirname, 'fixtures')
+
+const j = (a: string[]) =>
+  a
+    .map(s => s.replace(/\\/g, '/'))
+    .sort((a, b) => a.localeCompare(b, 'en'))
+
+t.test('ignore files with long names', async t => {
+  const ignore: IgnoreLike = {
+    ignored: (p: Path) => p.name.length > 1,
+  }
+  const syncRes = globSync('**', { cwd, ignore })
+  const asyncRes = await glob('**', { cwd, ignore })
+  const expect = j(
+    globSync('**', { cwd }).filter(p => basename(p).length === 1)
+  )
+  t.same(j(syncRes), expect)
+  t.same(j(asyncRes), expect)
+  for (const r of syncRes) {
+    if (basename(r).length > 1) t.fail(r)
+  }
+})
+
+t.test('ignore symlink and abcdef directories', async t => {
+  const ignore: IgnoreLike = {
+    childrenIgnored: (p: Path) => {
+      return p.isNamed('symlink') || p.isNamed('abcdef')
+    },
+  }
+  const syncRes = globSync('**', { cwd, ignore, nodir: true })
+  const asyncRes = await glob('**', { cwd, ignore, nodir: true })
+  const expect = j(
+    globSync('**', { nodir: true, cwd }).filter(p => {
+      return !/\bsymlink\b|\babcdef\b/.test(p)
+    })
+  )
+  t.same(j(syncRes), expect)
+  t.same(j(asyncRes), expect)
+  for (const r of syncRes) {
+    if (r === 'symlink' || r === 'basename') t.fail(r)
+  }
+})

From 8acfa52bab61c94f2be25147a618034e0cfac3ab Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 2 Mar 2023 15:03:57 -0800
Subject: [PATCH 147/163] changelog 9.2

---
 changelog.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/changelog.md b/changelog.md
index bcd657e5..b7f18001 100644
--- a/changelog.md
+++ b/changelog.md
@@ -3,6 +3,9 @@
 ## 9.2
 
 - Support using a custom fs object, which is passed to PathScurry
+- add maxDepth option
+- add stat option
+- add custom Ignore support
 
 ## 9.1
 

From 6dcdd41b0f306ef9cdb5b8580a9e269a23252991 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 2 Mar 2023 15:04:13 -0800
Subject: [PATCH 148/163] 9.2.0

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index e9eb2156..6001c6a6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.1.2",
+  "version": "9.2.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.1.2",
+      "version": "9.2.0",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index dcbaf001..655aca74 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.1.2",
+  "version": "9.2.0",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"

From e85032bef5e234ec911fdb5844f6bc605766e19e Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 2 Mar 2023 16:39:36 -0800
Subject: [PATCH 149/163] bug in readme example code

---
 README.md | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index ef821aca..c62c164a 100644
--- a/README.md
+++ b/README.md
@@ -118,7 +118,8 @@ const folderNamedModules = await glob('**/*.{ts,js}', {
   }
 })
 
-// find all files edited in the last hour
+// find all files edited in the last hour, to do this, we ignore
+// all of them that are more than an hour old
 const newFiles = await glob('**', {
   // need stat so we have mtime
   stat: true,
@@ -126,7 +127,7 @@ const newFiles = await glob('**', {
   nodir: true,
   ignore: {
     ignored: (p) => {
-      return (new Date() - p.mtime) <= (60 * 60 * 1000)
+      return (new Date() - p.mtime) > (60 * 60 * 1000)
     },
     // could add similar childrenIgnored here as well, but
     // directory mtime is inconsistent across platforms, so

From c8b33163b9940fa2d35284dd1c6e2ea32d2ebe39 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 2 Mar 2023 16:39:53 -0800
Subject: [PATCH 150/163] 9.2.1

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 6001c6a6..25285f0b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.2.0",
+  "version": "9.2.1",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.2.0",
+      "version": "9.2.1",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index 655aca74..97afe078 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.2.0",
+  "version": "9.2.1",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"

From fa8ed5e7986ee3b29e1b437f895fbf3255f0d549 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Thu, 9 Mar 2023 20:25:57 -0800
Subject: [PATCH 151/163] Improve changelog heading

---
 changelog.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/changelog.md b/changelog.md
index b7f18001..fe432642 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,4 +1,4 @@
-# cganhe glo
+# changeglob
 
 ## 9.2
 

From 589df9690b00df67a0fb5d643046e20b561e04d4 Mon Sep 17 00:00:00 2001
From: Brooks Johnson <2008881+bkjohnson@users.noreply.github.com>
Date: Sun, 12 Mar 2023 10:34:10 -0700
Subject: [PATCH 152/163] Update globSync documentation to match signature

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index c62c164a..85112928 100644
--- a/README.md
+++ b/README.md
@@ -153,7 +153,7 @@ Returns
 objects if the `withFileTypes` option is set to `true`. See below
 for full options field desciptions.
 
-## `globSync(pattern: string, options?: GlobOptions) => string[] | Path[]`
+## `globSync(pattern: string | string[], options?: GlobOptions) => string[] | Path[]`
 
 Synchronous form of `glob()`.
 

From 9e56c7a74e97157000dcc9c1641549c5093a730f Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 14 Mar 2023 06:00:37 -0700
Subject: [PATCH 153/163] bring back the other aliases

Eases the code transition from older versions, why not.
---
 README.md    | 11 ++++++++++
 changelog.md |  5 +++++
 src/index.ts | 61 +++++++++++++++++++++++++++++++++-------------------
 3 files changed, 55 insertions(+), 22 deletions(-)

diff --git a/README.md b/README.md
index 85112928..353c5951 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,7 @@ const {
 } = require('glob')
 
 // or default export is fine too, just returns the glob function
+// with all the aliases attached.
 import glob from 'glob'
 // or using commonjs
 const glob = require('glob')
@@ -157,19 +158,27 @@ for full options field desciptions.
 
 Synchronous form of `glob()`.
 
+Alias: `glob.sync()`
+
 ## `globIterate(pattern: string | string[], options?: GlobOptions) => AsyncGenerator`
 
 Return an async iterator for walking glob pattern matches.
 
+Alias: `glob.iterate()`
+
 ## `globIterateSync(pattern: string | string[], options?: GlobOptions) => Generator`
 
 Return a sync iterator for walking glob pattern matches.
 
+Alias: `glob.iterate.sync()`, `glob.sync.iterate()`
+
 ## `globStream(pattern: string | string[], options?: GlobOptions) => Minipass`
 
 Return a stream that emits all the strings or `Path` objects and
 then emits `end` when completed.
 
+Alias: `glob.stream()`
+
 ## `globStreamSync(pattern: string | string[], options?: GlobOptions) => Minipass`
 
 Syncronous form of `globStream()`. Will read all the matches as
@@ -177,6 +186,8 @@ fast as you consume them, even all in a single tick if you
 consume them immediately, but will still respond to backpressure
 if they're not consumed immediately.
 
+Alias: `glob.stream.sync()`, `glob.sync.stream()`
+
 ## `hasMagic(pattern: string | string[], options?: GlobOptions) => boolean`
 
 Returns `true` if the provided pattern contains any "magic" glob
diff --git a/changelog.md b/changelog.md
index fe432642..55c0129a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,10 @@
 # changeglob
 
+## 9.3
+
+- Add aliases for methods. `glob.sync`, `glob.stream`,
+  `glob.stream.sync`, etc.
+
 ## 9.2
 
 - Support using a custom fs object, which is passed to PathScurry
diff --git a/src/index.ts b/src/index.ts
index 2ba37e2a..27e04f90 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -121,57 +121,69 @@ export async function glob(
 }
 
 /**
- * Return an async iterator for walking glob pattern matches.
+ * Return a sync iterator for walking glob pattern matches.
  */
-export function globIterate(
+export function globIterateSync(
   pattern: string | string[],
   options?: GlobOptionsWithFileTypesUnset | undefined
-): AsyncGenerator
-export function globIterate(
+): Generator
+export function globIterateSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesTrue
-): AsyncGenerator
-export function globIterate(
+): Generator
+export function globIterateSync(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesFalse
-): AsyncGenerator
-export function globIterate(
+): Generator
+export function globIterateSync(
   pattern: string | string[],
   options: GlobOptions
-): AsyncGenerator | AsyncGenerator
-export function globIterate(
+): Generator | Generator
+export function globIterateSync(
   pattern: string | string[],
   options: GlobOptions = {}
 ) {
-  return new Glob(pattern, options).iterate()
+  return new Glob(pattern, options).iterateSync()
 }
 
 /**
- * Return a sync iterator for walking glob pattern matches.
+ * Return an async iterator for walking glob pattern matches.
  */
-export function globIterateSync(
+export function globIterate(
   pattern: string | string[],
   options?: GlobOptionsWithFileTypesUnset | undefined
-): Generator
-export function globIterateSync(
+): AsyncGenerator
+export function globIterate(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesTrue
-): Generator
-export function globIterateSync(
+): AsyncGenerator
+export function globIterate(
   pattern: string | string[],
   options: GlobOptionsWithFileTypesFalse
-): Generator
-export function globIterateSync(
+): AsyncGenerator
+export function globIterate(
   pattern: string | string[],
   options: GlobOptions
-): Generator | Generator
-export function globIterateSync(
+): AsyncGenerator | AsyncGenerator
+export function globIterate(
   pattern: string | string[],
   options: GlobOptions = {}
 ) {
-  return new Glob(pattern, options).iterateSync()
+  return new Glob(pattern, options).iterate()
 }
 
+// aliases: glob.sync.stream() glob.stream.sync() glob.sync() etc
+export const streamSync = globStreamSync
+export const stream = Object.assign(globStream, { sync: globStreamSync })
+export const iterateSync = globIterateSync
+export const iterate = Object.assign(globIterate, {
+  sync: globIterateSync,
+})
+export const sync = Object.assign(globSync, {
+  stream: globStreamSync,
+  iterate: globIterateSync,
+})
+
 /* c8 ignore start */
 export { escape, unescape } from 'minimatch'
 export { Glob } from './glob.js'
@@ -189,10 +201,15 @@ export type { MatchStream } from './walker.js'
 export default Object.assign(glob, {
   glob,
   globSync,
+  sync,
   globStream,
+  stream,
   globStreamSync,
+  streamSync,
   globIterate,
+  iterate,
   globIterateSync,
+  iterateSync,
   Glob,
   hasMagic,
   escape,

From db4504c01be525adda213ece56c0e12db1042e1f Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 14 Mar 2023 06:02:54 -0700
Subject: [PATCH 154/163] 9.3.0

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 25285f0b..40d163f3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.2.1",
+  "version": "9.3.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.2.1",
+      "version": "9.3.0",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index 97afe078..12752269 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.2.1",
+  "version": "9.3.0",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"

From c6a862a7e982bdf9ace8324d8118eb25d1700d4a Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 14 Mar 2023 16:25:32 -0700
Subject: [PATCH 155/163] little readme tweaks

---
 README.md | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 353c5951..bc7fabc4 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ The most correct and second fastest glob implementation in
 JavaScript. (See **Comparison to Other JavaScript Glob
 Implementations** at the bottom of this readme.)
 
-![a fun cartoon logo made of glob characters](logo/glob.png)
+![a fun cartoon logo made of glob characters](https://github.com/isaacs/node-glob/raw/main/logo/glob.png)
 
 ## Usage
 
@@ -16,6 +16,9 @@ Install with npm
 npm i glob
 ```
 
+**Note** the npm package name is _not_ `node-glob` that's a
+different thing that was abandoned years ago.  Just `glob`.
+
 ```js
 // load using import
 import { glob, globSync, globStream, globStreamSync, Glob } from 'glob'
@@ -784,7 +787,7 @@ that are extremely dated by current JavaScript standards.
 returns results and `fast-glob` doesn't, it's even faster, of
 course.
 
-![](oh-my-glob.gif)
+![lumpy space princess saying 'oh my GLOB'](https://github.com/isaacs/node-glob/raw/main/oh-my-glob.gif)
 
 ### Benchmark Results
 

From 273deedb110b86f30be517e5f7e252b4b9ea4b10 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Mar 2023 17:02:07 -0700
Subject: [PATCH 156/163] Move cwd ENOENT test to where it matters

Fix: #515
---
 package-lock.json | 19 +++++++++++++++++
 package.json      |  1 +
 src/processor.ts  |  2 ++
 src/walker.ts     | 52 ++++++++++++++++++++---------------------------
 test/memfs.ts     | 16 +++++++++++++++
 5 files changed, 60 insertions(+), 30 deletions(-)
 create mode 100644 test/memfs.ts

diff --git a/package-lock.json b/package-lock.json
index 40d163f3..cebf6556 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,6 +19,7 @@
         "@types/tap": "^15.0.7",
         "c8": "^7.12.0",
         "eslint-config-prettier": "^8.6.0",
+        "memfs": "^3.4.13",
         "mkdirp": "^2.1.4",
         "prettier": "^2.8.3",
         "rimraf": "^4.1.3",
@@ -1788,6 +1789,12 @@
       "integrity": "sha512-kSxoARUDn4F2RPXX48UXnaFKwVU7Ivd/6qpzZL29MCDmr9sTvybv4gFCp+qaI4fM9m0z9fgz/yJvi56GAz+BZg==",
       "dev": true
     },
+    "node_modules/fs-monkey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
+      "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==",
+      "dev": true
+    },
     "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -2448,6 +2455,18 @@
         "node": ">= 12"
       }
     },
+    "node_modules/memfs": {
+      "version": "3.4.13",
+      "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz",
+      "integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==",
+      "dev": true,
+      "dependencies": {
+        "fs-monkey": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
     "node_modules/minimatch": {
       "version": "7.4.1",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.1.tgz",
diff --git a/package.json b/package.json
index 12752269..40667c26 100644
--- a/package.json
+++ b/package.json
@@ -69,6 +69,7 @@
     "@types/tap": "^15.0.7",
     "c8": "^7.12.0",
     "eslint-config-prettier": "^8.6.0",
+    "memfs": "^3.4.13",
     "mkdirp": "^2.1.4",
     "prettier": "^2.8.3",
     "rimraf": "^4.1.3",
diff --git a/src/processor.ts b/src/processor.ts
index 87e8802f..b0949ceb 100644
--- a/src/processor.ts
+++ b/src/processor.ts
@@ -136,6 +136,8 @@ export class Processor {
         }
       }
 
+      if (t.isENOENT()) continue
+
       let p: MMPattern
       let rest: Pattern | null
       let changed = false
diff --git a/src/walker.ts b/src/walker.ts
index e32d1880..6248da6c 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -405,30 +405,30 @@ export class GlobWalker<
 
   async walk(): Promise> {
     if (this.signal?.aborted) throw this.signal.reason
-    const t = this.path.isUnknown() ? await this.path.lstat() : this.path
-    if (t) {
-      await new Promise((res, rej) => {
-        this.walkCB(t, this.patterns, () => {
-          if (this.signal?.aborted) {
-            rej(this.signal.reason)
-          } else {
-            res(this.matches)
-          }
-        })
-      })
+    if (this.path.isUnknown()) {
+      await this.path.lstat()
     }
+    await new Promise((res, rej) => {
+      this.walkCB(this.path, this.patterns, () => {
+        if (this.signal?.aborted) {
+          rej(this.signal.reason)
+        } else {
+          res(this.matches)
+        }
+      })
+    })
     return this.matches
   }
 
   walkSync(): Matches {
     if (this.signal?.aborted) throw this.signal.reason
-    const t = this.path.isUnknown() ? this.path.lstatSync() : this.path
-    // nothing for the callback to do, because this never pauses
-    if (t) {
-      this.walkCBSync(t, this.patterns, () => {
-        if (this.signal?.aborted) throw this.signal.reason
-      })
+    if (this.path.isUnknown()) {
+      this.path.lstatSync()
     }
+    // nothing for the callback to do, because this never pauses
+    this.walkCBSync(this.path, this.patterns, () => {
+      if (this.signal?.aborted) throw this.signal.reason
+    })
     return this.matches
   }
 }
@@ -463,12 +463,8 @@ export class GlobStream<
   stream(): MatchStream {
     const target = this.path
     if (target.isUnknown()) {
-      target.lstat().then(e => {
-        if (e) {
-          this.walkCB(target, this.patterns, () => this.results.end())
-        } else {
-          this.results.end()
-        }
+      target.lstat().then(() => {
+        this.walkCB(target, this.patterns, () => this.results.end())
       })
     } else {
       this.walkCB(target, this.patterns, () => this.results.end())
@@ -477,14 +473,10 @@ export class GlobStream<
   }
 
   streamSync(): MatchStream {
-    const target = this.path.isUnknown()
-      ? this.path.lstatSync()
-      : this.path
-    if (target) {
-      this.walkCBSync(target, this.patterns, () => this.results.end())
-    } else {
-      this.results.end()
+    if (this.path.isUnknown()) {
+      this.path.lstatSync()
     }
+    this.walkCBSync(this.path, this.patterns, () => this.results.end())
     return this.results
   }
 }
diff --git a/test/memfs.ts b/test/memfs.ts
new file mode 100644
index 00000000..aab5d6d5
--- /dev/null
+++ b/test/memfs.ts
@@ -0,0 +1,16 @@
+import { fs as memfs, vol } from 'memfs'
+import t from 'tap'
+import { glob } from '../'
+t.beforeEach(() => vol.fromJSON({ '/x': 'abc' }))
+
+const fs = memfs as unknown as typeof import('fs')
+
+t.test('should match single file with pattern', async t => {
+  const expandedFiles = await glob(['.', '/**/*'], { nodir: true, fs })
+  t.strictSame(expandedFiles, ['/x'])
+})
+
+t.test('should match single file without pattern', async t => {
+  const expandedFiles = await glob(['.', '/x'], { nodir: true, fs })
+  t.strictSame(expandedFiles, ['/x'])
+})

From facdded226e924bdf778f02e71796e6dea06402b Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Mar 2023 17:02:42 -0700
Subject: [PATCH 157/163] 9.3.1

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index cebf6556..f45cc0aa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.3.0",
+  "version": "9.3.1",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.3.0",
+      "version": "9.3.1",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index 40667c26..b0bb7f37 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.3.0",
+  "version": "9.3.1",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"

From 609d247a40f6f898df1b3ea668fb209064640c5d Mon Sep 17 00:00:00 2001
From: Nick Schonning 
Date: Fri, 3 Mar 2023 02:30:37 -0500
Subject: [PATCH 158/163] chore: use setup-node caching with npm ci

PR-URL: https://github.com/isaacs/node-glob/pull/505
Credit: @nschonni
Close: #505
Reviewed-by: @isaacs
---
 .github/workflows/ci.yml              | 3 ++-
 .github/workflows/isaacs-makework.yml | 3 ++-
 .github/workflows/typedoc.yml         | 3 ++-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c884730f..a2cd6998 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -31,9 +31,10 @@ jobs:
         uses: actions/setup-node@v3
         with:
           node-version: ${{ matrix.node-version }}
+          cache: npm
 
       - name: Install dependencies
-        run: npm install
+        run: npm ci
 
       - name: Run Tests
         run: npm test -- -c -t0 --statements=80 --branches=80 --functions=80 --lines=80
diff --git a/.github/workflows/isaacs-makework.yml b/.github/workflows/isaacs-makework.yml
index 8eb5e855..7f0a44a3 100644
--- a/.github/workflows/isaacs-makework.yml
+++ b/.github/workflows/isaacs-makework.yml
@@ -14,9 +14,10 @@ jobs:
         with:
           fetch-depth: 0
       - name: Use Node.js
-        uses: actions/setup-node@v2.1.4
+        uses: actions/setup-node@v3
         with:
           node-version: 16.x
+          cache: npm
       - name: put repo in package.json
         run: node .github/workflows/package-json-repo.js
       - name: check in package.json if modified
diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml
index e5bc0ef8..f4fe23d6 100644
--- a/.github/workflows/typedoc.yml
+++ b/.github/workflows/typedoc.yml
@@ -34,8 +34,9 @@ jobs:
         uses: actions/setup-node@v3
         with:
           node-version: 18.x
+          cache: npm
       - name: Install dependencies
-        run: npm install
+        run: npm ci
       - name: Generate typedocs
         run: npm run typedoc
 

From 65b9b4745bac495a5f72bcd66f7ccee24cd2f4c2 Mon Sep 17 00:00:00 2001
From: Nick Schonning 
Date: Fri, 3 Mar 2023 02:38:12 -0500
Subject: [PATCH 159/163] chore: remove eslint-config-prettier devDep

PR-URL: https://github.com/isaacs/node-glob/pull/506
Credit: @nschonni
Close: #506
Reviewed-by: @isaacs
---
 package-lock.json | 1542 +++++++++++++--------------------------------
 package.json      |    1 -
 2 files changed, 455 insertions(+), 1088 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index f45cc0aa..6fafe8a7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,7 +18,6 @@
         "@types/node": "^18.11.18",
         "@types/tap": "^15.0.7",
         "c8": "^7.12.0",
-        "eslint-config-prettier": "^8.6.0",
         "memfs": "^3.4.13",
         "mkdirp": "^2.1.4",
         "prettier": "^2.8.3",
@@ -70,21 +69,21 @@
       }
     },
     "node_modules/@babel/core": {
-      "version": "7.21.0",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.0.tgz",
-      "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.3.tgz",
+      "integrity": "sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==",
       "dev": true,
       "dependencies": {
         "@ampproject/remapping": "^2.2.0",
         "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.21.0",
+        "@babel/generator": "^7.21.3",
         "@babel/helper-compilation-targets": "^7.20.7",
-        "@babel/helper-module-transforms": "^7.21.0",
+        "@babel/helper-module-transforms": "^7.21.2",
         "@babel/helpers": "^7.21.0",
-        "@babel/parser": "^7.21.0",
+        "@babel/parser": "^7.21.3",
         "@babel/template": "^7.20.7",
-        "@babel/traverse": "^7.21.0",
-        "@babel/types": "^7.21.0",
+        "@babel/traverse": "^7.21.3",
+        "@babel/types": "^7.21.3",
         "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
@@ -100,12 +99,12 @@
       }
     },
     "node_modules/@babel/generator": {
-      "version": "7.21.1",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz",
-      "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.3.tgz",
+      "integrity": "sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.21.0",
+        "@babel/types": "^7.21.3",
         "@jridgewell/gen-mapping": "^0.3.2",
         "@jridgewell/trace-mapping": "^0.3.17",
         "jsesc": "^2.5.1"
@@ -300,81 +299,10 @@
         "node": ">=6.9.0"
       }
     },
-    "node_modules/@babel/highlight/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/@babel/highlight/node_modules/chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-      "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/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/@babel/highlight/node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
-      "dev": true
-    },
-    "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/@babel/highlight/node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/@babel/highlight/node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/@babel/parser": {
-      "version": "7.21.2",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz",
-      "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz",
+      "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==",
       "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -398,19 +326,19 @@
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.21.2",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz",
-      "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.3.tgz",
+      "integrity": "sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.21.1",
+        "@babel/generator": "^7.21.3",
         "@babel/helper-environment-visitor": "^7.18.9",
         "@babel/helper-function-name": "^7.21.0",
         "@babel/helper-hoist-variables": "^7.18.6",
         "@babel/helper-split-export-declaration": "^7.18.6",
-        "@babel/parser": "^7.21.2",
-        "@babel/types": "^7.21.2",
+        "@babel/parser": "^7.21.3",
+        "@babel/types": "^7.21.3",
         "debug": "^4.1.0",
         "globals": "^11.1.0"
       },
@@ -418,19 +346,10 @@
         "node": ">=6.9.0"
       }
     },
-    "node_modules/@babel/traverse/node_modules/globals": {
-      "version": "11.12.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
-      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/@babel/types": {
-      "version": "7.21.2",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz",
-      "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==",
+      "version": "7.21.3",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz",
+      "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==",
       "dev": true,
       "dependencies": {
         "@babel/helper-string-parser": "^7.19.4",
@@ -469,124 +388,6 @@
         "@jridgewell/sourcemap-codec": "^1.4.10"
       }
     },
-    "node_modules/@eslint/eslintrc": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz",
-      "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "ajv": "^6.12.4",
-        "debug": "^4.3.2",
-        "espree": "^9.4.0",
-        "globals": "^13.19.0",
-        "ignore": "^5.2.0",
-        "import-fresh": "^3.2.1",
-        "js-yaml": "^4.1.0",
-        "minimatch": "^3.1.2",
-        "strip-json-comments": "^3.1.1"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/@eslint/eslintrc/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,
-      "peer": true,
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/@eslint/eslintrc/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/@eslint/js": {
-      "version": "8.35.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz",
-      "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      }
-    },
-    "node_modules/@humanwhocodes/config-array": {
-      "version": "0.11.8",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
-      "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "@humanwhocodes/object-schema": "^1.2.1",
-        "debug": "^4.1.1",
-        "minimatch": "^3.0.5"
-      },
-      "engines": {
-        "node": ">=10.10.0"
-      }
-    },
-    "node_modules/@humanwhocodes/config-array/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,
-      "peer": true,
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/@humanwhocodes/module-importer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
-      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=12.22"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/nzakas"
-      }
-    },
-    "node_modules/@humanwhocodes/object-schema": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
-      "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
-      "dev": true,
-      "peer": true
-    },
     "node_modules/@istanbuljs/load-nyc-config": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -603,15 +404,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/@istanbuljs/load-nyc-config/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/@istanbuljs/load-nyc-config/node_modules/find-up": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
@@ -625,19 +417,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/@istanbuljs/load-nyc-config/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/@istanbuljs/load-nyc-config/node_modules/locate-path": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -677,15 +456,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
-      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/@istanbuljs/schema": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
@@ -742,44 +512,6 @@
         "@jridgewell/sourcemap-codec": "1.4.14"
       }
     },
-    "node_modules/@nodelib/fs.scandir": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
-      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "@nodelib/fs.stat": "2.0.5",
-        "run-parallel": "^1.1.9"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.stat": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
-      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/@nodelib/fs.walk": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
-      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "@nodelib/fs.scandir": "2.1.5",
-        "fastq": "^1.6.0"
-      },
-      "engines": {
-        "node": ">= 8"
-      }
-    },
     "node_modules/@tsconfig/node10": {
       "version": "1.0.9",
       "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
@@ -811,9 +543,9 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "18.14.2",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz",
-      "integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==",
+      "version": "18.15.5",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.5.tgz",
+      "integrity": "sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==",
       "dev": true
     },
     "node_modules/@types/tap": {
@@ -837,16 +569,6 @@
         "node": ">=0.4.0"
       }
     },
-    "node_modules/acorn-jsx": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
-      "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-      "dev": true,
-      "peer": true,
-      "peerDependencies": {
-        "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
-      }
-    },
     "node_modules/acorn-walk": {
       "version": "8.2.0",
       "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
@@ -869,23 +591,6 @@
         "node": ">=8"
       }
     },
-    "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,
-      "peer": 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-regex": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -902,18 +607,15 @@
       "dev": true
     },
     "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==",
+      "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": "^2.0.1"
+        "color-convert": "^1.9.0"
       },
       "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+        "node": ">=4"
       }
     },
     "node_modules/anymatch": {
@@ -954,11 +656,13 @@
       "dev": true
     },
     "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==",
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
       "dev": true,
-      "peer": true
+      "dependencies": {
+        "sprintf-js": "~1.0.2"
+      }
     },
     "node_modules/async-hook-domain": {
       "version": "2.0.4",
@@ -1072,6 +776,48 @@
         "node": ">=10.12.0"
       }
     },
+    "node_modules/c8/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/c8/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/c8/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/c8/node_modules/rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -1102,16 +848,6 @@
         "node": ">=8"
       }
     },
-    "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,
-      "peer": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/camelcase": {
       "version": "5.3.1",
       "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
@@ -1122,9 +858,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001458",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001458.tgz",
-      "integrity": "sha512-lQ1VlUUq5q9ro9X+5gOEyH7i3vm+AYVT1WDCVB69XOZ17KZRhnZ9J0Sqz7wTHQaLBJccNCHq8/Ww5LlOIZbB0w==",
+      "version": "1.0.30001468",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001468.tgz",
+      "integrity": "sha512-zgAo8D5kbOyUcRAgSmgyuvBkjrGk5CGYG5TYgFdpQv+ywcyEpo1LOWoG8YmoflGnh+V+UsNuKYedsoYs0hzV5A==",
       "dev": true,
       "funding": [
         {
@@ -1138,20 +874,38 @@
       ]
     },
     "node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "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,
-      "peer": true,
       "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">=4"
+      }
+    },
+    "node_modules/chalk/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/chalk/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"
       },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
+      "engines": {
+        "node": ">=4"
       }
     },
     "node_modules/chokidar": {
@@ -1181,18 +935,6 @@
         "fsevents": "~2.3.2"
       }
     },
-    "node_modules/chokidar/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/clean-stack": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@@ -1214,21 +956,18 @@
       }
     },
     "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==",
+      "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.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
+        "color-name": "1.1.3"
       }
     },
     "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==",
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
       "dev": true
     },
     "node_modules/color-support": {
@@ -1304,13 +1043,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/deep-is": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
-      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
-      "dev": true,
-      "peer": true
-    },
     "node_modules/default-require-extensions": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz",
@@ -1335,23 +1067,10 @@
         "node": ">=0.3.1"
       }
     },
-    "node_modules/doctrine": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
-      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "esutils": "^2.0.2"
-      },
-      "engines": {
-        "node": ">=6.0.0"
-      }
-    },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.311",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.311.tgz",
-      "integrity": "sha512-RoDlZufvrtr2Nx3Yx5MB8jX3aHIxm8nRWPJm3yVvyHmyKaRvn90RjzB6hNnt0AkhS3IInJdyRfQb4mWhPvUjVw==",
+      "version": "1.4.334",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.334.tgz",
+      "integrity": "sha512-laZ1odk+TRen6q0GeyQx/JEkpD3iSZT7ewopCpKqg9bTjP1l8XRfU3Bg20CFjNPZkp5+NDBl3iqd4o/kPO+Vew==",
       "dev": true
     },
     "node_modules/emoji-regex": {
@@ -1376,292 +1095,33 @@
       }
     },
     "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,
-      "peer": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/eslint": {
-      "version": "8.35.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.35.0.tgz",
-      "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "@eslint/eslintrc": "^2.0.0",
-        "@eslint/js": "8.35.0",
-        "@humanwhocodes/config-array": "^0.11.8",
-        "@humanwhocodes/module-importer": "^1.0.1",
-        "@nodelib/fs.walk": "^1.2.8",
-        "ajv": "^6.10.0",
-        "chalk": "^4.0.0",
-        "cross-spawn": "^7.0.2",
-        "debug": "^4.3.2",
-        "doctrine": "^3.0.0",
-        "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^7.1.1",
-        "eslint-utils": "^3.0.0",
-        "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.4.0",
-        "esquery": "^1.4.2",
-        "esutils": "^2.0.2",
-        "fast-deep-equal": "^3.1.3",
-        "file-entry-cache": "^6.0.1",
-        "find-up": "^5.0.0",
-        "glob-parent": "^6.0.2",
-        "globals": "^13.19.0",
-        "grapheme-splitter": "^1.0.4",
-        "ignore": "^5.2.0",
-        "import-fresh": "^3.0.0",
-        "imurmurhash": "^0.1.4",
-        "is-glob": "^4.0.0",
-        "is-path-inside": "^3.0.3",
-        "js-sdsl": "^4.1.4",
-        "js-yaml": "^4.1.0",
-        "json-stable-stringify-without-jsonify": "^1.0.1",
-        "levn": "^0.4.1",
-        "lodash.merge": "^4.6.2",
-        "minimatch": "^3.1.2",
-        "natural-compare": "^1.4.0",
-        "optionator": "^0.9.1",
-        "regexpp": "^3.2.0",
-        "strip-ansi": "^6.0.1",
-        "strip-json-comments": "^3.1.0",
-        "text-table": "^0.2.0"
-      },
-      "bin": {
-        "eslint": "bin/eslint.js"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
-      }
-    },
-    "node_modules/eslint-config-prettier": {
-      "version": "8.6.0",
-      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.6.0.tgz",
-      "integrity": "sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==",
-      "dev": true,
-      "bin": {
-        "eslint-config-prettier": "bin/cli.js"
-      },
-      "peerDependencies": {
-        "eslint": ">=7.0.0"
-      }
-    },
-    "node_modules/eslint-scope": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
-      "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "esrecurse": "^4.3.0",
-        "estraverse": "^5.2.0"
-      },
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      }
-    },
-    "node_modules/eslint-utils": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-      "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "eslint-visitor-keys": "^2.0.0"
-      },
-      "engines": {
-        "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      },
-      "peerDependencies": {
-        "eslint": ">=5"
-      }
-    },
-    "node_modules/eslint-utils/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,
-      "peer": true,
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/eslint-visitor-keys": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
-      "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      }
-    },
-    "node_modules/eslint/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,
-      "peer": true,
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/eslint/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/espree": {
-      "version": "9.4.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
-      "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
       "dev": true,
-      "peer": true,
-      "dependencies": {
-        "acorn": "^8.8.0",
-        "acorn-jsx": "^5.3.2",
-        "eslint-visitor-keys": "^3.3.0"
-      },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/eslint"
+        "node": ">=0.8.0"
       }
     },
     "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.2",
-      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz",
-      "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "estraverse": "^5.1.0"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "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,
-      "peer": true,
-      "dependencies": {
-        "estraverse": "^5.2.0"
-      },
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/estraverse": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "dev": true,
-      "peer": 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,
-      "peer": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/events-to-array": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz",
-      "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==",
-      "dev": true
-    },
-    "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,
-      "peer": true
-    },
-    "node_modules/fast-json-stable-stringify": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
-      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-      "dev": true,
-      "peer": true
-    },
-    "node_modules/fast-levenshtein": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
-      "dev": true,
-      "peer": true
-    },
-    "node_modules/fastq": {
-      "version": "1.15.0",
-      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
-      "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
-      "dev": true,
-      "peer": 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==",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
       "dev": true,
-      "peer": true,
-      "dependencies": {
-        "flat-cache": "^3.0.4"
+      "bin": {
+        "esparse": "bin/esparse.js",
+        "esvalidate": "bin/esvalidate.js"
       },
       "engines": {
-        "node": "^10.12.0 || >=12.0.0"
+        "node": ">=4"
       }
     },
+    "node_modules/events-to-array": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz",
+      "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==",
+      "dev": true
+    },
     "node_modules/fill-range": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -1713,43 +1173,6 @@
       "integrity": "sha512-ENZS237/Hr8bjczn5eKuBohLgaD0JyUd0arxretR1f9RO46vZHA1b2y0VorgGV3WaOT3c+78P8h7v4JGJ1i/rg==",
       "dev": true
     },
-    "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,
-      "peer": true,
-      "dependencies": {
-        "flatted": "^3.1.0",
-        "rimraf": "^3.0.2"
-      },
-      "engines": {
-        "node": "^10.12.0 || >=12.0.0"
-      }
-    },
-    "node_modules/flat-cache/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,
-      "peer": true,
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/flatted": {
-      "version": "3.2.7",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
-      "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
-      "dev": true,
-      "peer": true
-    },
     "node_modules/foreground-child": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
@@ -1848,89 +1271,50 @@
       }
     },
     "node_modules/glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "version": "9.3.1",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.1.tgz",
+      "integrity": "sha512-qERvJb7IGsnkx6YYmaaGvDpf77c951hICMdWaFXyH3PlVob8sbPJJyJX0kWkiCWyXUzoy9UOTNjGg0RbD8bYIw==",
       "dev": true,
       "dependencies": {
         "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
+        "minimatch": "^7.4.1",
+        "minipass": "^4.2.4",
+        "path-scurry": "^1.6.1"
       },
       "engines": {
-        "node": "*"
+        "node": ">=16 || 14 >=14.17"
       },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
       }
     },
     "node_modules/glob-parent": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
-      "dev": true,
-      "peer": true,
-      "dependencies": {
-        "is-glob": "^4.0.3"
-      },
-      "engines": {
-        "node": ">=10.13.0"
-      }
-    },
-    "node_modules/glob/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/glob/node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "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": {
-        "brace-expansion": "^1.1.7"
+        "is-glob": "^4.0.1"
       },
       "engines": {
-        "node": "*"
+        "node": ">= 6"
       }
     },
     "node_modules/globals": {
-      "version": "13.20.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
-      "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
       "dev": true,
-      "peer": true,
-      "dependencies": {
-        "type-fest": "^0.20.2"
-      },
       "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=4"
       }
     },
     "node_modules/graceful-fs": {
-      "version": "4.2.10",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
-      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
       "dev": true
     },
-    "node_modules/grapheme-splitter": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
-      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
-      "dev": true,
-      "peer": true
-    },
     "node_modules/has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -1956,48 +1340,12 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/hasha/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/html-escaper": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
       "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
       "dev": true
     },
-    "node_modules/ignore": {
-      "version": "5.2.4",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
-      "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
-      "dev": true,
-      "peer": 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,
-      "peer": 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",
@@ -2083,16 +1431,6 @@
         "node": ">=0.12.0"
       }
     },
-    "node_modules/is-path-inside": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
-      "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/is-stream": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -2179,6 +1517,48 @@
         "node": ">=8"
       }
     },
+    "node_modules/istanbul-lib-processinfo/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/istanbul-lib-processinfo/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/istanbul-lib-processinfo/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/istanbul-lib-processinfo/node_modules/rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -2247,17 +1627,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/js-sdsl": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz",
-      "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==",
-      "dev": true,
-      "peer": true,
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/js-sdsl"
-      }
-    },
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -2265,13 +1634,13 @@
       "dev": true
     },
     "node_modules/js-yaml": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
-      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+      "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,
-      "peer": true,
       "dependencies": {
-        "argparse": "^2.0.1"
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
       },
       "bin": {
         "js-yaml": "bin/js-yaml.js"
@@ -2289,20 +1658,6 @@
         "node": ">=4"
       }
     },
-    "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,
-      "peer": 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": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
-      "dev": true,
-      "peer": true
-    },
     "node_modules/json5": {
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
@@ -2321,20 +1676,6 @@
       "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
       "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,
-      "peer": true,
-      "dependencies": {
-        "prelude-ls": "^1.2.1",
-        "type-check": "~0.4.0"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
     "node_modules/libtap": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/libtap/-/libtap-1.4.0.tgz",
@@ -2401,17 +1742,10 @@
       "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==",
       "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,
-      "peer": true
-    },
     "node_modules/lru-cache": {
-      "version": "7.17.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.17.0.tgz",
-      "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==",
+      "version": "7.18.3",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+      "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
       "engines": {
         "node": ">=12"
       }
@@ -2468,9 +1802,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "7.4.1",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.1.tgz",
-      "integrity": "sha512-Oz1iPEP+MGl7KS3SciLsLLcuZ7VsBfb7Qrz/jYt/s/sYAv272P26HSLz2f77Y6hzTKXiBi6g765fqpEDNc5fJw==",
+      "version": "7.4.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz",
+      "integrity": "sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==",
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
@@ -2482,17 +1816,17 @@
       }
     },
     "node_modules/minipass": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.4.tgz",
-      "integrity": "sha512-lwycX3cBMTvcejsHITUgYj6Gy6A7Nh4Q6h9NP4sTHY1ccJlC7yKzDmiShEHsJ16Jf1nKGDEaiHxiltsJEvk0nQ==",
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz",
+      "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==",
       "engines": {
         "node": ">=8"
       }
     },
     "node_modules/mkdirp": {
-      "version": "2.1.4",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.4.tgz",
-      "integrity": "sha512-Cy9cV4pRSl1o10i1dURTuRt4T04l0DkS1WZrT+Jir886OqOVkSv4FbOA7pgjhS8kEUrmm4kCRvv5var2iOCxpA==",
+      "version": "2.1.5",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.5.tgz",
+      "integrity": "sha512-jbjfql+shJtAPrFoKxHOXip4xS+kul9W3OzfzzrqueWK2QMGon2bFH2opl6W9EagBThjEz+iysyi/swOoVfB/w==",
       "dev": true,
       "bin": {
         "mkdirp": "dist/cjs/src/bin.js"
@@ -2510,13 +1844,6 @@
       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
       "dev": true
     },
-    "node_modules/natural-compare": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
-      "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
-      "dev": true,
-      "peer": true
-    },
     "node_modules/node-preload": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
@@ -2585,6 +1912,31 @@
         "node": ">=8.9"
       }
     },
+    "node_modules/nyc/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/nyc/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/nyc/node_modules/cliui": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
@@ -2596,6 +1948,24 @@
         "wrap-ansi": "^6.2.0"
       }
     },
+    "node_modules/nyc/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/nyc/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/nyc/node_modules/find-up": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
@@ -2609,6 +1979,26 @@
         "node": ">=8"
       }
     },
+    "node_modules/nyc/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/nyc/node_modules/locate-path": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -2618,7 +2008,19 @@
         "p-locate": "^4.1.0"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=8"
+      }
+    },
+    "node_modules/nyc/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
       }
     },
     "node_modules/nyc/node_modules/p-limit": {
@@ -2648,15 +2050,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/nyc/node_modules/resolve-from": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
-      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/nyc/node_modules/rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -2745,24 +2138,6 @@
         "opener": "bin/opener-bin.js"
       }
     },
-    "node_modules/optionator": {
-      "version": "0.9.1",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
-      "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
-      "dev": true,
-      "peer": 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/own-or": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz",
@@ -2844,19 +2219,6 @@
         "node": ">=8"
       }
     },
-    "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,
-      "peer": 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",
@@ -2981,20 +2343,10 @@
         "node": ">=8"
       }
     },
-    "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,
-      "peer": true,
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
     "node_modules/prettier": {
-      "version": "2.8.4",
-      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz",
-      "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==",
+      "version": "2.8.5",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.5.tgz",
+      "integrity": "sha512-3gzuxrHbKUePRBB4ZeU08VNkUcqEHaUaouNt0m7LGP4Hti/NuB07C7PPTM/LkWqXoJYJn2McEo5+kxPNrtQkLQ==",
       "dev": true,
       "bin": {
         "prettier": "bin-prettier.js"
@@ -3027,27 +2379,6 @@
         "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"
-        }
-      ],
-      "peer": true
-    },
     "node_modules/readdirp": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -3060,19 +2391,6 @@
         "node": ">=8.10.0"
       }
     },
-    "node_modules/regexpp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
-      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
-      "dev": true,
-      "peer": true,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/mysticatea"
-      }
-    },
     "node_modules/release-zalgo": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
@@ -3101,31 +2419,22 @@
       "dev": true
     },
     "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,
-      "peer": 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==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
       "dev": true,
-      "peer": true,
       "engines": {
-        "iojs": ">=1.0.0",
-        "node": ">=0.10.0"
+        "node": ">=8"
       }
     },
     "node_modules/rimraf": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.3.tgz",
-      "integrity": "sha512-iyzalDLo3l5FZxxaIGUY7xI4Bf90Xt7pCipc1Mr7RsdU7H3538z+M0tlsUDrz0aHeGS9uNqiKHUJyTewwRP91Q==",
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.0.tgz",
+      "integrity": "sha512-X36S+qpCUR0HjXlkDe4NAOhS//aHH0Z+h8Ckf2auGJk3PTnx5rLmrHkwNdbVQuCSUhOyFrlRvFEllZOYE+yZGQ==",
       "dev": true,
+      "dependencies": {
+        "glob": "^9.2.0"
+      },
       "bin": {
         "rimraf": "dist/cjs/src/bin.js"
       },
@@ -3136,30 +2445,6 @@
         "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"
-        }
-      ],
-      "peer": true,
-      "dependencies": {
-        "queue-microtask": "^1.2.2"
-      }
-    },
     "node_modules/semver": {
       "version": "6.3.0",
       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@@ -3250,6 +2535,48 @@
         "node": ">=8"
       }
     },
+    "node_modules/spawn-wrap/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/spawn-wrap/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/spawn-wrap/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/spawn-wrap/node_modules/rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -3327,19 +2654,6 @@
         "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,
-      "peer": true,
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "node_modules/supports-color": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -3444,6 +2758,16 @@
         "node": ">= 8"
       }
     },
+    "node_modules/tap-mocha-reporter/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/tap-mocha-reporter/node_modules/escape-string-regexp": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
@@ -3453,6 +2777,38 @@
         "node": ">=8"
       }
     },
+    "node_modules/tap-mocha-reporter/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/tap-mocha-reporter/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/tap-parser": {
       "version": "11.0.2",
       "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-11.0.2.tgz",
@@ -5412,6 +4768,26 @@
         "concat-map": "0.0.1"
       }
     },
+    "node_modules/test-exclude/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/test-exclude/node_modules/minimatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -5424,13 +4800,6 @@
         "node": "*"
       }
     },
-    "node_modules/text-table": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
-      "dev": true,
-      "peer": true
-    },
     "node_modules/to-fast-properties": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@@ -5453,10 +4822,13 @@
       }
     },
     "node_modules/trivial-deferred": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.0.1.tgz",
-      "integrity": "sha512-dagAKX7vaesNNAwOc9Np9C2mJ+7YopF4lk+jE2JML9ta4kZ91Y6UruJNH65bLRYoUROD8EY+Pmi44qQWwXR7sw==",
-      "dev": true
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.1.1.tgz",
+      "integrity": "sha512-CRmSsCN0PAzyZ5hSFPByf1OPAOxVy4yLctYfrdz3zYMSxGpZI/2UjhYn22VE1iQTlasP4aLHc5/bhFb6WKJwpA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
     },
     "node_modules/ts-node": {
       "version": "10.9.1",
@@ -5501,30 +4873,13 @@
         }
       }
     },
-    "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,
-      "peer": true,
-      "dependencies": {
-        "prelude-ls": "^1.2.1"
-      },
-      "engines": {
-        "node": ">= 0.8.0"
-      }
-    },
     "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==",
+      "version": "0.8.1",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
       "dev": true,
-      "peer": true,
       "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
+        "node": ">=8"
       }
     },
     "node_modules/typedarray-to-buffer": {
@@ -5537,9 +4892,9 @@
       }
     },
     "node_modules/typedoc": {
-      "version": "0.23.26",
-      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.26.tgz",
-      "integrity": "sha512-5m4KwR5tOLnk0OtMaRn9IdbeRM32uPemN9kur7YK9wFqx8U0CYrvO9aVq6ysdZSV1c824BTm+BuQl2Ze/k1HtA==",
+      "version": "0.23.28",
+      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.23.28.tgz",
+      "integrity": "sha512-9x1+hZWTHEQcGoP7qFmlo4unUoVJLB0H/8vfO/7wqTnZxg4kPuji9y3uRzEu0ZKez63OJAUmiGhUrtukC6Uj3w==",
       "dev": true,
       "dependencies": {
         "lunr": "^2.3.9",
@@ -5554,7 +4909,7 @@
         "node": ">= 14.14"
       },
       "peerDependencies": {
-        "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x"
+        "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x"
       }
     },
     "node_modules/typescript": {
@@ -5605,16 +4960,6 @@
         "browserslist": ">= 4.21.0"
       }
     },
-    "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,
-      "peer": true,
-      "dependencies": {
-        "punycode": "^2.1.0"
-      }
-    },
     "node_modules/uuid": {
       "version": "8.3.2",
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
@@ -5677,16 +5022,6 @@
       "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==",
       "dev": true
     },
-    "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,
-      "peer": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/wrap-ansi": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
@@ -5704,6 +5039,39 @@
         "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",
diff --git a/package.json b/package.json
index b0bb7f37..ad989510 100644
--- a/package.json
+++ b/package.json
@@ -68,7 +68,6 @@
     "@types/node": "^18.11.18",
     "@types/tap": "^15.0.7",
     "c8": "^7.12.0",
-    "eslint-config-prettier": "^8.6.0",
     "memfs": "^3.4.13",
     "mkdirp": "^2.1.4",
     "prettier": "^2.8.3",

From 672c944fe7ff155e6fe682921ffdbf3219c78e9d Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Mon, 20 Mar 2023 17:09:50 -0700
Subject: [PATCH 160/163] skip memfs test on windows

---
 test/memfs.ts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/test/memfs.ts b/test/memfs.ts
index aab5d6d5..8df14828 100644
--- a/test/memfs.ts
+++ b/test/memfs.ts
@@ -1,3 +1,7 @@
+if (process.platform === 'win32') {
+  t.plan(0, 'this test does not work on windows')
+  process.exit(0)
+}
 import { fs as memfs, vol } from 'memfs'
 import t from 'tap'
 import { glob } from '../'

From 2054644b0682bc029616afd537718ea2aa765aac Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Tue, 21 Mar 2023 17:56:02 -0700
Subject: [PATCH 161/163] even more comprehensive tests for #515

---
 test/memfs.ts | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/test/memfs.ts b/test/memfs.ts
index 8df14828..dbac7ae3 100644
--- a/test/memfs.ts
+++ b/test/memfs.ts
@@ -2,6 +2,7 @@ if (process.platform === 'win32') {
   t.plan(0, 'this test does not work on windows')
   process.exit(0)
 }
+
 import { fs as memfs, vol } from 'memfs'
 import t from 'tap'
 import { glob } from '../'
@@ -9,12 +10,28 @@ t.beforeEach(() => vol.fromJSON({ '/x': 'abc' }))
 
 const fs = memfs as unknown as typeof import('fs')
 
-t.test('should match single file with pattern', async t => {
-  const expandedFiles = await glob(['.', '/**/*'], { nodir: true, fs })
-  t.strictSame(expandedFiles, ['/x'])
-})
+const mock = {
+  fs: memfs,
+  'fs/promises': memfs.promises,
+}
 
-t.test('should match single file without pattern', async t => {
-  const expandedFiles = await glob(['.', '/x'], { nodir: true, fs })
-  t.strictSame(expandedFiles, ['/x'])
-})
+const patterns = ['/**/*', '/*', '/x']
+const cwds = ['/', undefined]
+for (const pattern of patterns) {
+  t.test(pattern, async t => {
+    for (const cwd of cwds) {
+      t.test(`cwd=${cwd}`, async t => {
+        t.test('mocking the fs', async t => {
+          const { glob } = t.mock('../', {
+            ...mock,
+            'path-scurry': t.mock('path-scurry', mock),
+          })
+          t.strictSame(await glob(pattern, { nodir: true, cwd }), ['/x'])
+        })
+        t.test('passing in fs argument', async t => {
+          t.strictSame(await glob(pattern, { nodir: true, cwd, fs }), ['/x'])
+        })
+      })
+    }
+  })
+}

From bbba601d9c69f8e5e0cfd7422dbf3e1e71b726e6 Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Wed, 22 Mar 2023 11:48:49 -0700
Subject: [PATCH 162/163] add inlineSources

---
 tsconfig-base.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tsconfig-base.json b/tsconfig-base.json
index 89d37168..5af9f89c 100644
--- a/tsconfig-base.json
+++ b/tsconfig-base.json
@@ -5,6 +5,7 @@
     "allowSyntheticDefaultImports": true,
     "declaration": true,
     "declarationMap": true,
+    "inlineSources": true,
     "esModuleInterop": true,
     "forceConsistentCasingInFileNames": true,
     "moduleResolution": "node",

From 3426f33533ed4c4a262a093009ce55e69491fd6b Mon Sep 17 00:00:00 2001
From: isaacs 
Date: Wed, 22 Mar 2023 11:49:08 -0700
Subject: [PATCH 163/163] 9.3.2

---
 package-lock.json | 4 ++--
 package.json      | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 6fafe8a7..e16f0d82 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "glob",
-  "version": "9.3.1",
+  "version": "9.3.2",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "glob",
-      "version": "9.3.1",
+      "version": "9.3.2",
       "license": "ISC",
       "dependencies": {
         "fs.realpath": "^1.0.0",
diff --git a/package.json b/package.json
index ad989510..e675cebd 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "author": "Isaac Z. Schlueter  (http://blog.izs.me/)",
   "name": "glob",
   "description": "the most correct and second fastest glob implementation in JavaScript",
-  "version": "9.3.1",
+  "version": "9.3.2",
   "repository": {
     "type": "git",
     "url": "git://github.com/isaacs/node-glob.git"