diff --git a/.eslintrc.json b/.eslintrc.json index b948a5e..c5d141b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,6 +1,6 @@ { "env": { - "es2017": true, + "es2020": true, "mocha": true, "node": true }, @@ -14,7 +14,7 @@ }, "parser": "@typescript-eslint/parser", "parserOptions": { - "ecmaVersion": 2018, + "ecmaVersion": 2020, "sourceType": "module" }, "plugins": [ @@ -124,9 +124,27 @@ }, "overrides": [ { - "files": ["*.js", "*.cjs"], + "files": ["*.js", "*.cjs", "*.html"], + "parser": "espree", + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, "rules": { - "@typescript-eslint/explicit-function-return-type": "off" + "@typescript-eslint/explicit-function-return-type": "off", + "indent": [ + "error", + 2, + { + "ArrayExpression": "first", + "FunctionDeclaration": { "parameters": "off" }, + "FunctionExpression": { "parameters": "off" }, + "ignoreComments": true, + "ObjectExpression": "first", + "SwitchCase": 1 + } + ], + "no-var": "off" } } ] diff --git a/.gitignore b/.gitignore index 23122c9..3a3b5ea 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,6 @@ testem.log # System Files .DS_Store Thumbs.db +/server/node_modules/ +/server/logs/ +/server/build/ diff --git a/angular.json b/angular.json index 8735511..8cb3a74 100644 --- a/angular.json +++ b/angular.json @@ -23,6 +23,11 @@ "glob": "**/*", "input": "node_modules/@tubular/astronomy/dist/resources", "output": "/assets/resources" + }, + { + "glob": "browser-check.min.js*", + "input": "./node_modules/@tubular/browser-check/dist/", + "output": "./assets/" } ], "styles": [ @@ -115,6 +120,11 @@ "glob": "**/*", "input": "node_modules/@tubular/astronomy/dist/resources", "output": "/assets/resources" + }, + { + "glob": "browser-check.min.js*", + "input": "./node_modules/@tubular/browser-check/dist/", + "output": "./assets/" } ] } diff --git a/package-lock.json b/package-lock.json index 7030056..c94a39d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,12 @@ { "name": "svc-ng", - "version": "1.14.8", + "version": "1.15.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "svc-ng", - "version": "1.14.8", - "hasInstallScript": true, + "version": "1.15.0", "license": "MIT AND GPL-3.0-or-later", "dependencies": { "@angular/animations": "^13.2.7", @@ -22,17 +21,18 @@ "@angular/router": "^13.2.7", "@fortawesome/fontawesome-free": "^6.1.1", "@tubular/array-buffer-reader": "^3.0.2", - "@tubular/astronomy": "^3.1.1", + "@tubular/astronomy": "^3.3.0", "@tubular/math": "^3.1.0", "@tubular/ng-widgets": "^2.1.2", "@tubular/time": "^3.8.2", - "@tubular/util": "^4.9.2", + "@tubular/util": "^4.10.0", "core-js": "^2.6.12", "detect-resize": "^0.1.5", "lodash-es": "^4.17.21", "primeicons": "^5.0.0", "primeng": "^13.2.1", "rxjs": "^6.6.7", + "three": "^0.140.2", "zone.js": "~0.11.5" }, "devDependencies": { @@ -40,14 +40,16 @@ "@angular/cli": "^13.2.6", "@angular/compiler-cli": "^13.2.7", "@angular/language-service": "^13.2.7", + "@tubular/browser-check": "^1.2.0", "@types/googlemaps": "^3.43.3", "@types/jasmine": "^4.0.3", "@types/jasminewd2": "^2.0.10", "@types/lodash-es": "^4.17.6", - "@typescript-eslint/eslint-plugin": "^5.21.0", - "@typescript-eslint/parser": "^5.21.0", + "@types/three": "^0.140.0", + "@typescript-eslint/eslint-plugin": "^5.23.0", + "@typescript-eslint/parser": "^5.23.0", "codelyzer": "^6.0.2", - "eslint": "^8.14.0", + "eslint": "^8.15.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-node": "^11.1.0", @@ -58,7 +60,6 @@ "karma-coverage-istanbul-reporter": "~3.0.3", "karma-jasmine": "~5.0.0", "karma-jasmine-html-reporter": "^1.7.0", - "patch-package": "^6.4.7", "protractor": "~7.0.0", "ts-node": "^10.7.0", "typescript": "^4.5.5" @@ -2301,19 +2302,19 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.2.tgz", - "integrity": "sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", + "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", + "espree": "^9.3.2", "globals": "^13.9.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { @@ -2343,9 +2344,9 @@ "dev": true }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -2688,19 +2689,25 @@ } }, "node_modules/@tubular/astronomy": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@tubular/astronomy/-/astronomy-3.1.1.tgz", - "integrity": "sha512-VXtJ8bESqdedNtVqy67rjzXDv57qR+60ITwH4IA1G+E2AVVnmMJ2Zpu8ounkWjNTnSaNf8VouUlc0iwIRUTUVg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@tubular/astronomy/-/astronomy-3.3.0.tgz", + "integrity": "sha512-CSioY7aT9NF/00cmpo34kLeP6aQVD5oEqdnw4ViRAYUtxUCi3ZaXJ9yGKCKNHveHsB6iBgj/XC4TuvbQNfudCg==", "dependencies": { "@tubular/array-buffer-reader": "^3.0.2", "@tubular/math": "^3.1.0", "@tubular/time": "^3.8.2", - "@tubular/util": "^4.9.2" + "@tubular/util": "^4.10.0" }, "engines": { "node": ">=10.24.1" } }, + "node_modules/@tubular/browser-check": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@tubular/browser-check/-/browser-check-1.2.0.tgz", + "integrity": "sha512-rLtDajb56gYJvrZheENgM8u9bejncJ0ITXUJTWedNiosL/q36j0f/NgEM2da5mUmIqXIfrLCIW2Kbkg+Nmf9gQ==", + "dev": true + }, "node_modules/@tubular/math": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@tubular/math/-/math-3.1.0.tgz", @@ -2743,9 +2750,9 @@ } }, "node_modules/@tubular/util": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/@tubular/util/-/util-4.9.2.tgz", - "integrity": "sha512-apErmUDgaRrhJ55Mj0MMhjom7YrjLp/tZI2/eESobjj/cqPv3Lge0h/uPZ+DyHOFVrUAhvnqkbVyaH84QdoZsA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@tubular/util/-/util-4.10.0.tgz", + "integrity": "sha512-L4zhmSjTcxndPtrJgl4WkcJlC7TPJgZ3Hl/TLnysEZlEE1bxbp9yJOKQGkf1D7VghwhU66BuYKtd5DgXEAOtug==", "engines": { "node": ">=10.24.1" } @@ -2998,6 +3005,12 @@ "@types/node": "*" } }, + "node_modules/@types/three": { + "version": "0.140.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.140.0.tgz", + "integrity": "sha512-YPJLSIY6uKUOp1k6BZYDq5GtEIdhfeK04UCbc9IPAVbdn/RNjkfrbnyd7smrsNkJhc0IFASLpd3AAYgwqgXKVQ==", + "dev": true + }, "node_modules/@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -3008,14 +3021,14 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.21.0.tgz", - "integrity": "sha512-fTU85q8v5ZLpoZEyn/u1S2qrFOhi33Edo2CZ0+q1gDaWWm0JuPh3bgOyU8lM0edIEYgKLDkPFiZX2MOupgjlyg==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.23.0.tgz", + "integrity": "sha512-hEcSmG4XodSLiAp1uxv/OQSGsDY6QN3TcRU32gANp+19wGE1QQZLRS8/GV58VRUoXhnkuJ3ZxNQ3T6Z6zM59DA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.21.0", - "@typescript-eslint/type-utils": "5.21.0", - "@typescript-eslint/utils": "5.21.0", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/type-utils": "5.23.0", + "@typescript-eslint/utils": "5.23.0", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", @@ -3041,14 +3054,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.21.0.tgz", - "integrity": "sha512-8RUwTO77hstXUr3pZoWZbRQUxXcSXafZ8/5gpnQCfXvgmP9gpNlRGlWzvfbEQ14TLjmtU8eGnONkff8U2ui2Eg==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.23.0.tgz", + "integrity": "sha512-V06cYUkqcGqpFjb8ttVgzNF53tgbB/KoQT/iB++DOIExKmzI9vBJKjZKt/6FuV9c+zrDsvJKbJ2DOCYwX91cbw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.21.0", - "@typescript-eslint/types": "5.21.0", - "@typescript-eslint/typescript-estree": "5.21.0", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", "debug": "^4.3.2" }, "engines": { @@ -3068,13 +3081,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.21.0.tgz", - "integrity": "sha512-XTX0g0IhvzcH/e3393SvjRCfYQxgxtYzL3UREteUneo72EFlt7UNoiYnikUtmGVobTbhUDByhJ4xRBNe+34kOQ==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.23.0.tgz", + "integrity": "sha512-EhjaFELQHCRb5wTwlGsNMvzK9b8Oco4aYNleeDlNuL6qXWDF47ch4EhVNPh8Rdhf9tmqbN4sWDk/8g+Z/J8JVw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.21.0", - "@typescript-eslint/visitor-keys": "5.21.0" + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3085,12 +3098,12 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.21.0.tgz", - "integrity": "sha512-MxmLZj0tkGlkcZCSE17ORaHl8Th3JQwBzyXL/uvC6sNmu128LsgjTX0NIzy+wdH2J7Pd02GN8FaoudJntFvSOw==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.23.0.tgz", + "integrity": "sha512-iuI05JsJl/SUnOTXA9f4oI+/4qS/Zcgk+s2ir+lRmXI+80D8GaGwoUqs4p+X+4AxDolPpEpVUdlEH4ADxFy4gw==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.21.0", + "@typescript-eslint/utils": "5.23.0", "debug": "^4.3.2", "tsutils": "^3.21.0" }, @@ -3111,9 +3124,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.21.0.tgz", - "integrity": "sha512-XnOOo5Wc2cBlq8Lh5WNvAgHzpjnEzxn4CJBwGkcau7b/tZ556qrWXQz4DJyChYg8JZAD06kczrdgFPpEQZfDsA==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.23.0.tgz", + "integrity": "sha512-NfBsV/h4dir/8mJwdZz7JFibaKC3E/QdeMEDJhiAE3/eMkoniZ7MjbEMCGXw6MZnZDMN3G9S0mH/6WUIj91dmw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3124,13 +3137,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.21.0.tgz", - "integrity": "sha512-Y8Y2T2FNvm08qlcoSMoNchh9y2Uj3QmjtwNMdRQkcFG7Muz//wfJBGBxh8R7HAGQFpgYpdHqUpEoPQk+q9Kjfg==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.23.0.tgz", + "integrity": "sha512-xE9e0lrHhI647SlGMl+m+3E3CKPF1wzvvOEWnuE3CCjjT7UiRnDGJxmAcVKJIlFgK6DY9RB98eLr1OPigPEOGg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.21.0", - "@typescript-eslint/visitor-keys": "5.21.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0", "debug": "^4.3.2", "globby": "^11.0.4", "is-glob": "^4.0.3", @@ -3151,15 +3164,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.21.0.tgz", - "integrity": "sha512-q/emogbND9wry7zxy7VYri+7ydawo2HDZhRZ5k6yggIvXa7PvBbAAZ4PFH/oZLem72ezC4Pr63rJvDK/sTlL8Q==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.23.0.tgz", + "integrity": "sha512-dbgaKN21drqpkbbedGMNPCtRPZo1IOUr5EI9Jrrh99r5UW5Q0dz46RKXeSBoPV+56R6dFKpbrdhgUNSJsDDRZA==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.21.0", - "@typescript-eslint/types": "5.21.0", - "@typescript-eslint/typescript-estree": "5.21.0", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -3175,12 +3188,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.21.0.tgz", - "integrity": "sha512-SX8jNN+iHqAF0riZQMkm7e8+POXa/fXw5cxL+gjpyP+FI+JVNhii53EmQgDAfDcBpFekYSlO0fGytMQwRiMQCA==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.23.0.tgz", + "integrity": "sha512-Vd4mFNchU62sJB8pX19ZSPog05B0Y0CE2UxAZPT5k4iqhRYjPnqyY3woMxCd0++t9OTqkgjST+1ydLBi7e2Fvg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.21.0", + "@typescript-eslint/types": "5.23.0", "eslint-visitor-keys": "^3.0.0" }, "engines": { @@ -3381,9 +3394,9 @@ } }, "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -4493,12 +4506,6 @@ "node": ">=6.0" } }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, "node_modules/circular-dependency-plugin": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz", @@ -6340,12 +6347,12 @@ } }, "node_modules/eslint": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.14.0.tgz", - "integrity": "sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", + "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.2", + "@eslint/eslintrc": "^1.2.3", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -6356,7 +6363,7 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -6372,7 +6379,7 @@ "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", @@ -7029,13 +7036,13 @@ } }, "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -7521,15 +7528,6 @@ "node": ">=8" } }, - "node_modules/find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "dev": true, - "dependencies": { - "micromatch": "^4.0.2" - } - }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -8626,18 +8624,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "dependencies": { - "ci-info": "^2.0.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, "node_modules/is-core-module": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", @@ -9319,15 +9305,6 @@ "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", "dev": true }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -9567,15 +9544,6 @@ "node": ">=0.10.0" } }, - "node_modules/klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11" - } - }, "node_modules/klona": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", @@ -10382,12 +10350,6 @@ "node-gyp-build": "^4.2.2" } }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "node_modules/node-addon-api": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", @@ -11276,151 +11238,6 @@ "node": ">= 0.8" } }, - "node_modules/patch-package": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", - "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", - "dev": true, - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33" - }, - "bin": { - "patch-package": "index.js" - }, - "engines": { - "npm": ">5" - } - }, - "node_modules/patch-package/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/patch-package/node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/patch-package/node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/patch-package/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/patch-package/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/patch-package/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/patch-package/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/patch-package/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/patch-package/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/patch-package/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -14163,6 +13980,11 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "node_modules/three": { + "version": "0.140.2", + "resolved": "https://registry.npmjs.org/three/-/three-0.140.2.tgz", + "integrity": "sha512-DdT/AHm/TbZXEhQKQpGt5/iSgBrmXpjU26FNtj1KhllVPTKj1eG4X/ShyD5W2fngE+I1s1wa4ttC4C3oCJt7Ag==" + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -14581,15 +14403,6 @@ "imurmurhash": "^0.1.4" } }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -16944,19 +16757,19 @@ "dev": true }, "@eslint/eslintrc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.2.tgz", - "integrity": "sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", + "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", + "espree": "^9.3.2", "globals": "^13.9.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "dependencies": { @@ -16979,9 +16792,9 @@ "dev": true }, "globals": { - "version": "13.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz", - "integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -17248,16 +17061,22 @@ "integrity": "sha512-1cQnojuLyFY7K8L2Jc3OGfgipyYktqAKL01a/1p01v6R/KnHuSfnwWmRfswQg5zUNqav6yuouUhVOimT06EDPg==" }, "@tubular/astronomy": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@tubular/astronomy/-/astronomy-3.1.1.tgz", - "integrity": "sha512-VXtJ8bESqdedNtVqy67rjzXDv57qR+60ITwH4IA1G+E2AVVnmMJ2Zpu8ounkWjNTnSaNf8VouUlc0iwIRUTUVg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@tubular/astronomy/-/astronomy-3.3.0.tgz", + "integrity": "sha512-CSioY7aT9NF/00cmpo34kLeP6aQVD5oEqdnw4ViRAYUtxUCi3ZaXJ9yGKCKNHveHsB6iBgj/XC4TuvbQNfudCg==", "requires": { "@tubular/array-buffer-reader": "^3.0.2", "@tubular/math": "^3.1.0", "@tubular/time": "^3.8.2", - "@tubular/util": "^4.9.2" + "@tubular/util": "^4.10.0" } }, + "@tubular/browser-check": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@tubular/browser-check/-/browser-check-1.2.0.tgz", + "integrity": "sha512-rLtDajb56gYJvrZheENgM8u9bejncJ0ITXUJTWedNiosL/q36j0f/NgEM2da5mUmIqXIfrLCIW2Kbkg+Nmf9gQ==", + "dev": true + }, "@tubular/math": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@tubular/math/-/math-3.1.0.tgz", @@ -17283,9 +17102,9 @@ } }, "@tubular/util": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/@tubular/util/-/util-4.9.2.tgz", - "integrity": "sha512-apErmUDgaRrhJ55Mj0MMhjom7YrjLp/tZI2/eESobjj/cqPv3Lge0h/uPZ+DyHOFVrUAhvnqkbVyaH84QdoZsA==" + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@tubular/util/-/util-4.10.0.tgz", + "integrity": "sha512-L4zhmSjTcxndPtrJgl4WkcJlC7TPJgZ3Hl/TLnysEZlEE1bxbp9yJOKQGkf1D7VghwhU66BuYKtd5DgXEAOtug==" }, "@types/body-parser": { "version": "1.19.2", @@ -17534,6 +17353,12 @@ "@types/node": "*" } }, + "@types/three": { + "version": "0.140.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.140.0.tgz", + "integrity": "sha512-YPJLSIY6uKUOp1k6BZYDq5GtEIdhfeK04UCbc9IPAVbdn/RNjkfrbnyd7smrsNkJhc0IFASLpd3AAYgwqgXKVQ==", + "dev": true + }, "@types/ws": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", @@ -17544,14 +17369,14 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.21.0.tgz", - "integrity": "sha512-fTU85q8v5ZLpoZEyn/u1S2qrFOhi33Edo2CZ0+q1gDaWWm0JuPh3bgOyU8lM0edIEYgKLDkPFiZX2MOupgjlyg==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.23.0.tgz", + "integrity": "sha512-hEcSmG4XodSLiAp1uxv/OQSGsDY6QN3TcRU32gANp+19wGE1QQZLRS8/GV58VRUoXhnkuJ3ZxNQ3T6Z6zM59DA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.21.0", - "@typescript-eslint/type-utils": "5.21.0", - "@typescript-eslint/utils": "5.21.0", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/type-utils": "5.23.0", + "@typescript-eslint/utils": "5.23.0", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", @@ -17561,52 +17386,52 @@ } }, "@typescript-eslint/parser": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.21.0.tgz", - "integrity": "sha512-8RUwTO77hstXUr3pZoWZbRQUxXcSXafZ8/5gpnQCfXvgmP9gpNlRGlWzvfbEQ14TLjmtU8eGnONkff8U2ui2Eg==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.23.0.tgz", + "integrity": "sha512-V06cYUkqcGqpFjb8ttVgzNF53tgbB/KoQT/iB++DOIExKmzI9vBJKjZKt/6FuV9c+zrDsvJKbJ2DOCYwX91cbw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.21.0", - "@typescript-eslint/types": "5.21.0", - "@typescript-eslint/typescript-estree": "5.21.0", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", "debug": "^4.3.2" } }, "@typescript-eslint/scope-manager": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.21.0.tgz", - "integrity": "sha512-XTX0g0IhvzcH/e3393SvjRCfYQxgxtYzL3UREteUneo72EFlt7UNoiYnikUtmGVobTbhUDByhJ4xRBNe+34kOQ==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.23.0.tgz", + "integrity": "sha512-EhjaFELQHCRb5wTwlGsNMvzK9b8Oco4aYNleeDlNuL6qXWDF47ch4EhVNPh8Rdhf9tmqbN4sWDk/8g+Z/J8JVw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.21.0", - "@typescript-eslint/visitor-keys": "5.21.0" + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0" } }, "@typescript-eslint/type-utils": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.21.0.tgz", - "integrity": "sha512-MxmLZj0tkGlkcZCSE17ORaHl8Th3JQwBzyXL/uvC6sNmu128LsgjTX0NIzy+wdH2J7Pd02GN8FaoudJntFvSOw==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.23.0.tgz", + "integrity": "sha512-iuI05JsJl/SUnOTXA9f4oI+/4qS/Zcgk+s2ir+lRmXI+80D8GaGwoUqs4p+X+4AxDolPpEpVUdlEH4ADxFy4gw==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.21.0", + "@typescript-eslint/utils": "5.23.0", "debug": "^4.3.2", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.21.0.tgz", - "integrity": "sha512-XnOOo5Wc2cBlq8Lh5WNvAgHzpjnEzxn4CJBwGkcau7b/tZ556qrWXQz4DJyChYg8JZAD06kczrdgFPpEQZfDsA==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.23.0.tgz", + "integrity": "sha512-NfBsV/h4dir/8mJwdZz7JFibaKC3E/QdeMEDJhiAE3/eMkoniZ7MjbEMCGXw6MZnZDMN3G9S0mH/6WUIj91dmw==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.21.0.tgz", - "integrity": "sha512-Y8Y2T2FNvm08qlcoSMoNchh9y2Uj3QmjtwNMdRQkcFG7Muz//wfJBGBxh8R7HAGQFpgYpdHqUpEoPQk+q9Kjfg==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.23.0.tgz", + "integrity": "sha512-xE9e0lrHhI647SlGMl+m+3E3CKPF1wzvvOEWnuE3CCjjT7UiRnDGJxmAcVKJIlFgK6DY9RB98eLr1OPigPEOGg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.21.0", - "@typescript-eslint/visitor-keys": "5.21.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0", "debug": "^4.3.2", "globby": "^11.0.4", "is-glob": "^4.0.3", @@ -17615,26 +17440,26 @@ } }, "@typescript-eslint/utils": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.21.0.tgz", - "integrity": "sha512-q/emogbND9wry7zxy7VYri+7ydawo2HDZhRZ5k6yggIvXa7PvBbAAZ4PFH/oZLem72ezC4Pr63rJvDK/sTlL8Q==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.23.0.tgz", + "integrity": "sha512-dbgaKN21drqpkbbedGMNPCtRPZo1IOUr5EI9Jrrh99r5UW5Q0dz46RKXeSBoPV+56R6dFKpbrdhgUNSJsDDRZA==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.21.0", - "@typescript-eslint/types": "5.21.0", - "@typescript-eslint/typescript-estree": "5.21.0", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.21.0.tgz", - "integrity": "sha512-SX8jNN+iHqAF0riZQMkm7e8+POXa/fXw5cxL+gjpyP+FI+JVNhii53EmQgDAfDcBpFekYSlO0fGytMQwRiMQCA==", + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.23.0.tgz", + "integrity": "sha512-Vd4mFNchU62sJB8pX19ZSPog05B0Y0CE2UxAZPT5k4iqhRYjPnqyY3woMxCd0++t9OTqkgjST+1ydLBi7e2Fvg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.21.0", + "@typescript-eslint/types": "5.23.0", "eslint-visitor-keys": "^3.0.0" } }, @@ -17825,9 +17650,9 @@ } }, "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", "dev": true }, "acorn-import-assertions": { @@ -18658,12 +18483,6 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, "circular-dependency-plugin": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz", @@ -19991,12 +19810,12 @@ "dev": true }, "eslint": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.14.0.tgz", - "integrity": "sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", + "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.2", + "@eslint/eslintrc": "^1.2.3", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -20007,7 +19826,7 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -20023,7 +19842,7 @@ "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", @@ -20492,13 +20311,13 @@ "dev": true }, "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" } }, @@ -20880,15 +20699,6 @@ "path-exists": "^4.0.0" } }, - "find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "dev": true, - "requires": { - "micromatch": "^4.0.2" - } - }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -21714,15 +21524,6 @@ "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, "is-core-module": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", @@ -22222,15 +22023,6 @@ "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", "dev": true }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -22430,15 +22222,6 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, - "klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11" - } - }, "klona": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", @@ -23040,12 +22823,6 @@ "node-gyp-build": "^4.2.2" } }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "node-addon-api": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", @@ -23734,114 +23511,6 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, - "patch-package": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", - "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", - "dev": true, - "requires": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^7.0.1", - "is-ci": "^2.0.0", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.0", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^5.6.0", - "slash": "^2.0.0", - "tmp": "^0.0.33" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "dev": true, - "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -25854,6 +25523,11 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "three": { + "version": "0.140.2", + "resolved": "https://registry.npmjs.org/three/-/three-0.140.2.tgz", + "integrity": "sha512-DdT/AHm/TbZXEhQKQpGt5/iSgBrmXpjU26FNtj1KhllVPTKj1eG4X/ShyD5W2fngE+I1s1wa4ttC4C3oCJt7Ag==" + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -26157,12 +25831,6 @@ "imurmurhash": "^0.1.4" } }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index a11a27b..bfc2716 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svc-ng", - "version": "1.14.8", + "version": "1.15.0", "license": "MIT AND GPL-3.0-or-later", "author": "Kerry Shetline ", "scripts": { @@ -10,8 +10,7 @@ "build-debug": "ng build --sourceMap=true", "test": "ng test", "lint": "eslint 'src/**/*.ts'", - "e2e": "ng e2e", - "postinstall": "patch-package" + "e2e": "ng e2e" }, "private": true, "dependencies": { @@ -27,17 +26,18 @@ "@angular/router": "^13.2.7", "@fortawesome/fontawesome-free": "^6.1.1", "@tubular/array-buffer-reader": "^3.0.2", - "@tubular/astronomy": "^3.1.1", + "@tubular/astronomy": "^3.3.0", "@tubular/math": "^3.1.0", "@tubular/ng-widgets": "^2.1.2", "@tubular/time": "^3.8.2", - "@tubular/util": "^4.9.2", + "@tubular/util": "^4.10.0", "core-js": "^2.6.12", "detect-resize": "^0.1.5", "lodash-es": "^4.17.21", "primeicons": "^5.0.0", "primeng": "^13.2.1", "rxjs": "^6.6.7", + "three": "^0.140.2", "zone.js": "~0.11.5" }, "devDependencies": { @@ -45,14 +45,16 @@ "@angular/cli": "^13.2.6", "@angular/compiler-cli": "^13.2.7", "@angular/language-service": "^13.2.7", + "@tubular/browser-check": "^1.2.0", "@types/googlemaps": "^3.43.3", "@types/jasmine": "^4.0.3", "@types/jasminewd2": "^2.0.10", "@types/lodash-es": "^4.17.6", - "@typescript-eslint/eslint-plugin": "^5.21.0", - "@typescript-eslint/parser": "^5.21.0", + "@types/three": "^0.140.0", + "@typescript-eslint/eslint-plugin": "^5.23.0", + "@typescript-eslint/parser": "^5.23.0", "codelyzer": "^6.0.2", - "eslint": "^8.14.0", + "eslint": "^8.15.0", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-node": "^11.1.0", @@ -63,7 +65,6 @@ "karma-coverage-istanbul-reporter": "~3.0.3", "karma-jasmine": "~5.0.0", "karma-jasmine-html-reporter": "^1.7.0", - "patch-package": "^6.4.7", "protractor": "~7.0.0", "ts-node": "^10.7.0", "typescript": "^4.5.5" diff --git a/patches/@tubular+astronomy+3.1.0.patch b/patches/@tubular+astronomy+3.1.0.patch deleted file mode 100644 index 2c2d8e0..0000000 --- a/patches/@tubular+astronomy+3.1.0.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/node_modules/@tubular/astronomy/dist/fesm2015/index.js b/node_modules/@tubular/astronomy/dist/fesm2015/index.js -index af3a8cc..d19e3b0 100644 ---- a/node_modules/@tubular/astronomy/dist/fesm2015/index.js -+++ b/node_modules/@tubular/astronomy/dist/fesm2015/index.js -@@ -374,7 +374,7 @@ le.behindDisc=le.withinDisc&&!le.inferior,i[e]=le);return i}static solveOuterMoo - ;i=t?zA.solarSystem.getGreenwichApparentSiderealTime(e):DA.getGreenwichMeanSiderealTime(e),this.cachedHourAngle=new l(i,r.DEGREES).add_nonneg(this._longitude),this.cacheTimeHourAngle=e,this.cacheApparentHourAngle=t}return this.cachedHourAngle}getApparentSolarTime(e){const t=this.getLocalHourAngle(e,!0),i=A(e),s=zA.solarSystem.getEquatorialPosition(0,i,this).rightAscension;return t.subtract(s).add_nonneg(l.STRAIGHT)}equatorialTopocentricAdjustment(e,t,i){ - const A=s(t),C=this.getLocalHourAngle(A,0!=(4&i)).radians,B=e.radius,n=u(8.79412/3600/180*D)/B;let a=e.rightAscension.radians;const o=e.declination.radians,r=C-a;let l=h(-this.ρ_cos_gcl*n*u(r),c(o)-this.ρ_cos_gcl*n*c(r)),g=h((u(o)-this.ρ_sin_gcl*n)*c(l),c(o)-this.ρ_cos_gcl*n*c(r));if(0!=(128&i))if(a+=l,m(g)>d-485e-8){l=0;const e=d-m(g),t=1551e-9*this._latitude.cos,i=c(a)*e-u(C)*t,A=u(a)*e+c(C)*t,s=p(i*i+A*A);a=h(A,i),g=(d-s)*O(g)}else l=1551e-9*this._latitude.cos*c(r)/c(g), - g+=1551e-9*this._latitude.cos*u(g)*u(r);return new f(a+l,g,B)}equatorialToHorizontal(e,t,i=0){const A=this.getLocalHourAngle(t,0!=(4&i)).radians,s=e.rightAscension.radians,C=e.declination.radians,B=A-s,n=h(u(B),c(B)*this._latitude.sin-y(C)*this._latitude.cos);let a=g(E(this._latitude.sin*u(C)+this._latitude.cos*c(C)*c(B)));const r=a;if(0!=(16&i)&&(a=G(tA(Ae(a)))),e instanceof f){let t=e.radius;if(0!=(8&i)){const e=6356.755+(6378.14-6356.755)*this._latitude.cos+this.elevation/1e3;t-=u(r)*e/jt} --return new f(n,a,t)}return new o(n,a)}horizontalToEquatorial(e,t,i=0){const A=this.getLocalHourAngle(t,0!=(4&i)).radians;let s=e.altitude.radians;const C=e.azimuth.radians;0!=(16&i)&&(s=G(AA(Ae(s))));const B=A-h(u(C),c(C)*this._latitude.sin+y(s)*this._latitude.cos),n=g(E(this._latitude.sin*u(s)-this._latitude.cos*c(s)*c(C)));return new o(M(B,_),n)}}let XA,VA;try{XA=void 0!==typeof Buffer&&Buffer,VA=!!XA&&new Function("req",'return req("fs").readFile')("undefined"!=typeof require&&require)}catch(e){} -+return new f(n,a,t)}return new o(n,a)}horizontalToEquatorial(e,t,i=0){const A=this.getLocalHourAngle(t,0!=(4&i)).radians;let s=e.altitude.radians;const C=e.azimuth.radians;0!=(16&i)&&(s=G(AA(Ae(s))));const B=A-h(u(C),c(C)*this._latitude.sin+y(s)*this._latitude.cos),n=g(E(this._latitude.sin*u(s)-this._latitude.cos*c(s)*c(C)));return new o(M(B,_),n)}}let XA,VA;try{XA=void 0!==typeof Buffer&&Buffer,VA=!!XA&&new Function("req",'return req("fs").readFile')("undefined"!=typeof reqwire&&reqwire)}catch(e){} - var $A,KA;!function(e){e[e.FK5=0]="FK5",e[e.BSC=1]="BSC",e[e.HIP=2]="HIP"}($A||($A={})),function(e){e[e.INC_FK5=255]="INC_FK5",e[e.NEW_STATE=254]="NEW_STATE",e[e.DBL_PREC=253]="DBL_PREC",e[e.SNG_PREC=252]="SNG_PREC"}(KA||(KA={})) - ;const JA="And~Andromeda~Gam,Bet,Del,Alp,Pi,Mu,Xi,51\nAnt~Antlia~Iot,Alp,The,Eps\nAps~Apus~Bet,Gam,Del-1,Alp\nAql~Aquila~12,Lam,Del,The,Bet,Alp,Gam,Zet,Del;Zet,Eps\nAqr~Aquarius~88,Del,Tau-2,Lam,Phi,Eta,Zet,Gam,Alp,Bet,Mu,Eps;Iot,The,Alp\nAra~Ara~Del,Gam,Bet,Alp,Eps-1,Zet,Eta;Gam,Zet;The,Alp\nAri~Aries~41,Alp,Bet,Gam\nAur~Auriga~Alp,Eps,Eta,Iot,Bet (Tau),The,Bet,Alp\nBoo~Boötes~Zet,Alp,Eps,Del,Bet,Gam,Rho,Alp,Eta\nCae~Caelum~Alp,Bet\nCam~Camelopardalis~7,Bet,Alp,Gam;Alp,36,43\nCap~Capricornus~Alp-1,Bet,Psi,Ome,24,Zet,Eps,Del,Gam,Iot,The,Bet\nCar~Carina~Ups,Bet,Ome,The,FK5:397,FK5:1264,Iot,Eps,Chi,Alp\nCas~Cassiopeia~Eps,Del,Gam,Alp,Bet\nCen~Centaurus~Kap,Eta,Nu,BSC:5089,Iot;The,Nu,Mu,Zet,Eps,Alp;Bet,Eps,Gam,Sig,Del,Rho,Pi,FK5:443,Lam\nCep~Cepheus~Del,Eps,Zet,Iot,Gam,Bet,Alp,Zet;Alp,Eta,The\nCet~Cetus~Gam,Alp,Lam,Mu,Xi-2,Nu,Gam,Del,Omi,Zet,Tau,Bet,Iot,Eta,The,Zet\nCha~Chamaeleon~Bet,Gam,Alp,The,Del-2\nCir~Circinus~Gam,Alp,Bet\nCMa~Canis Major~Eta,Del,Omi-2,Alp,Bet;Eps,Sig,Alp\nCMi~Canis Minor~Alp,Bet\nCnc~Cancer~Alp,Del,Iot;Del,Bet\nCol~Columba~Del,Kap,Gam,Bet,Eta;Bet,Alp,Eps\nCom~Coma Berenices~Alp,Bet,Gam\nCrA~Corona Australis~Zet,Del,Bet,Alp,Gam,Eps\nCrB~Corona Borealis~Iot,Eps,Del,Gam,Alp,Bet,The\nCrt~Crater~Eta,Zet,Gam,Del,Eps,The;Gam,Bet,Alp,Del\nCru~Crux~Alp,Gam;Bet,Del\nCrv~Corvus~Alp,Eps,Gam,Del,Bet,Eps\nCVn~Canes Venatici~Alp,Bet\nCyg~Cygnus~Alp,Gam,Bet;Zet,Eps,Gam,Del,Iot-2,Kap\nDel~Delphinus~Eps,Bet,Alp,Gam,Del,Bet\nDor~Dorado~Del,Bet,Zet,Alp,Gam;BSC:2102,Bet\nDra~Draco~Xi,Nu,Bet,Gam,Xi,Del,Eps,Tau,Chi,Psi,Zet,Eta,@The,Iot,Alp,Kap,Lam\nEqu~Equuleus~Alp,Bet,Del,Gam,Alp\nEri~Eridanus~Lam,Bet,Ome,Mu,Nu,Omi-1,Gam,Pi,Del,Eps,Zet,Eta,@Tau-1,Tau-3,Tau-4,Tau-5,Tau-6,Tau-8,Tau-9,Ups-1,Ups-2,43,Ups-4,The,Iot,Kap,Phi,Chi,Alp\nFor~Fornax~Alp,Bet,Nu\nGem~Gemini~Xi,Gam,Nu,Mu,Eps,Tau,Rho,Alp,Sig,Bet,Kap,Del,Zet,Gam;Lam,Del;Eta,Mu\nGru~Grus~Alp,Bet,Iot,The;Zet,Eps,Bet,Del-2,Mu-1,Lam,Gam\nHer~Hercules~Alp,Bet,Gam;Bet,Zet,Eta,Sig,Tau,Phi,Chi;Zet,Eps,Pi,Eta;Pi,Rho,The,Iot;Eps,Del,Lam,Mu,Xi,Omi\nHor~Horologium~Alp,BSC:868,Zet,Mu,Bet\nHya~Hydra~Pi,Gam,Bet,Xi,Nu,@Mu,Lam,Ups-1,Alp,Iot,The,Zet,Eta,Sig,Del,Eps,Zet\nHyi~Hydrus~Alp,Bet,Gam,Alp\nInd~Indus~Alp,The,Del;The,Bet\nLac~Lacerta~1,FK5:1583,6,2,5,4,Alp,Bet\nLeo~Leo~Eps,Mu,Zet,Gam,Eta,Alp,The,Bet,Del,Gam\nLep~Lepus~Del,Gam,Bet,Alp,Zet,Eta;Eps,Bet;Alp,Mu\nLib~Libra~48,The,Gam,Bet,Sig,Ups,Tau;Sig,Alp-2,Bet\nLMi~Leo Minor~46,Bet,21\nLup~Lupus~The,Eta,Gam,Del,Phi-1,Chi\nLyn~Lynx~Alp,38,FK5:339,31,21,15,2\nLyr~Lyra~Eps-2,Alp,Zet,Bet,Gam,Del-2,Zet\nMen~Mensa~Alp,Gam,Eta,Bet\nMic~Microscopium~The-1,Eps,Gam,Alp\nMon~Monoceros~Zet,Alp,Del,18,8 Eps,13;Del,Bet,Gam\nMus~Musca~Bet,Alp,Gam;Del,Alp,Eps,Lam\nNor~Norma~Eps,Gam-2,Eta\nOct~Octans~Bet,Del,Nu,Bet\nOph~Ophiuchus~45,The,44,Xi,Eta,Bet,Alp,Kap,Del,Eps,Ups,Zet,Eta;70,67,Gam,Bet;Gam,Nu\nOri~Orion~Alp,Zet,Kap,Bet,Del,Gam,Lam,Alp,Mu,Xi,Nu,Chi-1;Xi,Chi-2;Pi-1,Pi-2,Pi-3,Gam;Pi-3,Pi-4,Pi-5,Pi-6\nPav~Pavo~Alp,Bet,Eps,Zet,Eta,Pi,Xi,Lam,Del,Bet,Gam\nPeg~Pegasus~Bet,Alp (And),Gam,Alp,Bet,Eta,Iot,Kap;Bet,Mu,Lam,9,1;Alp,Xi,Zet,The,Eps\nPer~Perseus~Omi,Zet,Xi,Eps,Del,Alp,Gam,Eta,Phi;Alp,Kap,Bet,Rho,16\nPhe~Phoenix~Del,Gam,Bet,Alp,Eps,Eta,Zet,Bet\nPic~Pictor~Alp,Gam,Bet\nPsA~Piscis Austrinus~Alp,Del,Gam,Bet,Mu,Iot,The,Lam,Eps,Alp\nPsc~Pisces~Tau,Ups,Phi,Eta,Omi,Alp,Nu,Mu,Eps,@Del,Ome,Iot,Lam,Kap,Gam,The,Iot\nPup~Puppis~Zet,Sig,Tau,Nu,Pi,Xi,Rho,Zet\nPyx~Pyxis~Bet,Alp,Gam\nRet~Reticulum~Alp,Bet,Del,Eps,Alp\nScl~Sculptor~Alp,Iot,Del,Gam,Bet\nSco~Scorpius~Lam,Kap,Iot-1,The,Eta,Zet-2,Mu-1,Eps,Tau,Alp,Sig,Del,Bet,Nu;Del,Pi,Rho\nSct~Scutum~Bet,Alp,Gam;Alp,Zet\nSer~Serpens Caput~Mu,Eps,Alp,Del,Bet,Kap,Gam,Bet\nSer~Serpens Cauda~The,Eta,Omi,Xi,Nu\nSex~Sextans~Bet,Alp,Gam\nSge~Sagitta~Eta,Gam,Zet,Alp;Zet,Bet\nSgr~Sagittarius~Alp,Iot,The-1,62,52,Tau,Zet,Eps,Eta;Bet-2,Iot;Tau,Sig,Omi,Pi,Rho-1;Zet,Phi,Sig;Mu,Lam,Phi,Del,Gam-2,3;Lam,Del,Eps;Eps,Gam-2\nTau~Taurus~Bet,Tau,Eps,Del,Gam,Lam,Xi,Omi;Zet,Alp,The,Gam\nTel~Telescopium~Zet,Alp,Eps\nTrA~Triangulum Australe~Alp,Bet,Gam,Alp\nTri~Triangulum~Alp,Bet,Gam,Alp\nTuc~Tucana~Del,Alp,Gam,Bet-1,Zet,Eps,Gam\nUMa~Ursa Major~Eta,Zet,Eps,Del,Alp,Bet,Gam,Del;Kap,Iot,The,Ups,Omi,23,Alp;Ups,Bet;Gam,Chi,Nu,Xi;Chi,Psi,Mu,Lam\nUMi~Ursa Minor~Alp,Del,Eps,Zet,Bet,Gam,Eta,Zet\nVel~Vela~Gam,Del,Kap,Phi,Mu,BSC:4167,FK5:1273,FK5:382,Psi,Lam,BSC:3477,FK5:324,Gam\nVir~Virgo~Mu,Iot,Kap,Alp,The,Gam,Del,Zet,Alp;109,Tau,Zet;Eps,Del;Gam,Eta,Bet\nVol~Volans~Alp,Bet,Eps,Zet,Gam,Del,Eps\nVul~Vulpecula~13,Alp,1",YA=-1,WA=-2 - ;function QA(e){return e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)}class es{constructor(e,t){if(this.bscLookup={},this.cachedPositions=[],this.constellations=[],this.ecliptic=new Fi,this.fk5Lookup={},this.hipLookup={},this.messierLookup={},this.ngcIcLookup={},this.nameLookup={},this.properlyInitialized=!1,this.starNames={},this.sunCacheTime=-1e10,this.sunLongitudeCache=-1,this.stars=[],XA){if(e instanceof XA)return this.readStarData(QA(e)),void(t&&t(this.properlyInitialized)) diff --git a/server/.eslintrc.json b/server/.eslintrc.json new file mode 100644 index 0000000..3a6e52a --- /dev/null +++ b/server/.eslintrc.json @@ -0,0 +1,140 @@ +{ + "root": true, + "env": { + "es2020": true, + "mocha": true, + "node": true + }, + "extends": [ + "standard", + "plugin:@typescript-eslint/eslint-recommended" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2020, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint", + "chai-friendly" + ], + "ignorePatterns": ["dist/**/*", "build.js"], + "rules": { + "brace-style": [ + "error", + "stroustrup", + { + "allowSingleLine": true + } + ], + "camelcase": "off", + "comma-dangle": [ + "error", + { + "arrays": "only-multiline", + "objects": "only-multiline", + "imports": "only-multiline", + "exports": "only-multiline", + "functions": "never" + } + ], + "curly": "off", + "@typescript-eslint/explicit-function-return-type": "error", + "indent": "off", + "@typescript-eslint/indent": [ + "error", + 2, + { + "ArrayExpression": "first", + "CallExpression": { "arguments": "off" }, + "FunctionDeclaration": { "parameters": "off" }, + "FunctionExpression": { "parameters": "off" }, + "ignoreComments": true, + "ignoredNodes": [ + "ClassProperty[value]", + "NewExpression[arguments] :expression *", + "TSUnionType" + ], + "ObjectExpression": "first", + "SwitchCase": 1 + } + ], + "guard-for-in": "error", + "key-spacing": "off", + "multiline-ternary": "off", + "node/no-callback-literal": "off", + "no-control-regex": "off", + "no-empty": "off", + "no-labels": "off", + "no-mixed-operators": "off", + "no-multi-spaces": ["error", { + "ignoreEOLComments": true, + "exceptions": { + "Property": true, + "VariableDeclarator": true + } + }], + "no-new": "off", + "no-return-assign": "off", + "no-unexpected-multiline": "off", + "no-unused-expressions": "off", + "no-useless-constructor": "off", + "@typescript-eslint/no-useless-constructor": "error", + "chai-friendly/no-unused-expressions": 2, + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "args": "after-used", + "argsIgnorePattern": "^_", + "ignoreRestSiblings": false, + "vars": "all" + } + ], + "node/no-unsupported-features/es-syntax": "off", + "object-curly-newline": "off", + "object-property-newline": "off", + "one-var": "off", + "operator-linebreak": "off", + "semi": [ + "error", + "always" + ], + "space-before-function-paren": [ + "error", + { + "anonymous": "always", + "named": "never", + "asyncArrow": "always" + } + ], + "quotes": "off", + "@typescript-eslint/quotes": [ + "error", + "single", + { + "allowTemplateLiterals": true, + "avoidEscape": true + } + ], + "yoda": [ + "error", + "never", + { + "exceptRange": true + } + ] + }, + "overrides": [ + { + "files": ["*.js", "*.cjs"], + "rules": { + "@typescript-eslint/explicit-function-return-type": "off" + } + } + ] +} diff --git a/server/app/app.ts b/server/app/app.ts new file mode 100644 index 0000000..00537d3 --- /dev/null +++ b/server/app/app.ts @@ -0,0 +1,72 @@ +import express, { Application, Request, Response } from 'express'; +import serveIndex from 'serve-index'; +import morgan from 'morgan'; +import { join as pathJoin } from 'path'; + +import { router as atlasRouter, initAtlas } from './atlas'; +import { router as stateRouter } from './states'; +import { router as ipToLocationRouter } from './ip-to-location'; +import { router as logRouter } from './log-access'; +import { router as zoneRouter } from './zone-for-location'; +import { router as mapsRouter } from './maps-api'; +import { initTimezoneLargeAlt } from '@tubular/time'; +import { svcApiConsole, svcApiLogStream, svcApiSkipFilter } from './svc-api-logger'; +import { formatDateTime } from '@tubular/util'; +import { getPublicIp } from './public-ip'; + +initTimezoneLargeAlt(); + +const app: Application = express(); +const port = process.env.PORT || 80; + +app.use(morgan((tokens, req, res) => { + // If we're running node as an extension under Apache/nginx, the above IP address will + // probably always be localhost. `x-real-ip` should provide the original remote address. + const remoteAddr = tokens.req(req, res, 'x-real-ip') || tokens['remote-addr'](req, res); + + return [ + formatDateTime(), + '- REQ:', + remoteAddr, + '"' + tokens.method(req, res), + tokens.url(req, res), + 'HTTP/' + tokens['http-version'](req, res) + '"', + tokens.status(req, res), + tokens['response-time'](req, res), 'ms -', + tokens.res(req, res, 'content-length') + ].join(' '); +}, { + skip: svcApiSkipFilter, + stream: svcApiLogStream +})); + +app.use('/atlas/', atlasRouter); +app.use('/atlasdb/atlas/', atlasRouter); // Legacy Tomcat path +app.use('/states/', stateRouter); +app.use('/atlasdb/states/', stateRouter); // Legacy Tomcat path +app.use('/ip/', ipToLocationRouter); +app.use('/log/', logRouter); +app.use('/zoneloc/', zoneRouter); +app.use('/timeservices/zoneloc/', zoneRouter); // Legacy Tomcat path +app.use('/maps/', mapsRouter); +app.use(express.static('../public')); +// Make the flags folder browsable. +app.use('/assets/resources/flags/', serveIndex(pathJoin(__dirname, '../../public/assets/resources/flags/'))); +app.get('/', (req: Request, res: Response) => { + res.send('Static home file not found'); +}); + +(async (): Promise => { + try { + await initAtlas(); + + app.listen(port, () => { + svcApiConsole.log(`Sky View Café listening on port ${port}.`); + getPublicIp(); + }); + } + catch (err) { + svcApiConsole.error('Sky View Café failed to start'); + process.exit(1); + } +})(); diff --git a/server/app/atlas-location.ts b/server/app/atlas-location.ts new file mode 100644 index 0000000..cd89638 --- /dev/null +++ b/server/app/atlas-location.ts @@ -0,0 +1,184 @@ +import { Timezone } from '@tubular/time'; +import { eqci } from './common'; +import { adjustUSCountyName } from './gazetteer'; + +function addParenthetical(s: string): string { + return ` (${s})`; +} + +function compare(a: string, b: string): number { + if (!a && !b) + return 0; + else if (!a) + return -1; + else if (!b) + return 1; + else + return a.localeCompare(b, 'en'); +} + +export class AtlasLocation { + city: string; + variant: string; + county: string; + showCounty: boolean; + state: string; + showState: boolean; + country: string; + longCountry: string; + flagCode: string; + latitude: number; + longitude: number; + elevation: number; + zone: string; + zip: string; + rank: number; + placeType: string; + source: string; + matchedByAlternateName = false; + matchedBySound = false; + geonamesID?: number; + useAsUpdate?: boolean; + + getZoneOffset(): number { + const zoneName = /(.*?)(\?)?$/.exec(this.zone)[1]; + const zone = Timezone.getTimezone(zoneName); + + return Math.round(zone.utcOffset / 60); + } + + getZoneDst(): number { + const zoneName = /(.*?)(\?)?$/.exec(this.zone)[1]; + const zone = Timezone.getTimezone(zoneName); + + return Math.round(zone.dstOffset / 60); + } + + get displayName(): string { + let city = this.city; + let county = this.county; + let cityQualifier = ''; + let displayState; + let stateQualifier = ''; + let showState = this.showState; + + if (this.country === 'USA' || this.country === 'CAN' && this.placeType !== 'A.ADM0') { + if (this.placeType !== 'A.ADM1') + displayState = this.state; + else + displayState = this.country; + + if (this.country === 'USA') { + if (this.placeType === 'A.ADM2') + city = adjustUSCountyName(city, this.state); + else + county = adjustUSCountyName(county, this.state); + } + } + else { + displayState = this.country; + + if (this.country === 'GBR' && this.state) { + stateQualifier = addParenthetical(this.state); + showState = false; + } + else if (this.longCountry && this.placeType !== 'A.ADM0') + stateQualifier = addParenthetical(this.longCountry); + } + + if (county && this.showCounty) + cityQualifier = addParenthetical(county); + + if (this.state && showState) + stateQualifier += addParenthetical(this.state); + + if (this.placeType === 'T.CAPE') + stateQualifier += ' (cape)'; + else if (this.placeType === 'H.LK') + stateQualifier += ' (lake)'; + else if (this.placeType === 'L.PRK') + stateQualifier += ' (park)'; + else if (this.placeType === 'T.PK') + stateQualifier += ' (peak)'; + else if (this.placeType === 'L.MILB') + stateQualifier += ' (military base)'; + else if (this.placeType === 'A.ADM2') { + if (/ (Borough|Census Area|County|Division|Parish)/i.test(city)) { + stateQualifier += ' (county)'; + } + } + else if (this.placeType === 'T.ISL') + stateQualifier += ' (island)'; + else if (this.placeType === 'S.ASTR' || this.placeType === 'T.POLE') + stateQualifier += ' (geographic point)'; + else if (this.placeType === 'T.MT') + stateQualifier += ' (mountain)'; + else if (this.placeType === 'A.ADM0') + stateQualifier += ' (nation)'; + else if (this.placeType === 'S.OBS') + stateQualifier += ' (observatory)'; + else if (this.placeType === 'A.ADM1' && this.country === 'CAN') + stateQualifier += ' (province)'; + else if (this.placeType === 'A.ADM1' && this.country === 'USA') + stateQualifier += ' (state)'; + + return city + cityQualifier + (displayState ? ', ' + displayState : '') + stateQualifier; + } + + set displayName(s: string) { /* Allow but ignore so this can be set via JSON without causing an error. */ } + + isCloseMatch(other: AtlasLocation): boolean { + return eqci(this.city, other.city) && + eqci(this.variant, other.variant) && + eqci(this.county, other.county) && + eqci(this.state, other.state) && + eqci(this.country, other.country) && + Math.abs(this.latitude - other.latitude) < 0.0001 && + Math.abs(this.longitude - other.longitude) < 0.0001 && + this.elevation === other.elevation && + this.zone === other.zone && + this.zip === other.zip && + this.placeType === other.placeType; + } + + toString(): string { + return `${this.displayName} - lat: ${this.latitude}, long: ${this.longitude};` + + (this.zip ? ` zip: ${this.zip};` : '') + + ` zone: ${this.zone}; placeType: ${this.placeType}; source: ${this.source}; rank: ${this.rank}` + + (this.flagCode ? ` flagCode: ${this.flagCode};` : '') + + (this.matchedByAlternateName ? ' matchedByAlternateName;' : '') + + (this.matchedBySound ? ' matchedBySound;' : ''); + } + + toJSON(): any { + const copy: any = {}; + + Object.assign(copy, this); + copy.displayName = this.displayName; + copy.zoneOffset = this.getZoneOffset(); + copy.zoneDst = this.getZoneDst(); + delete copy.geonameID; + delete copy.useAsUpdate; + + return copy; + } + + compareTo(other: AtlasLocation): number { + let comparison = (other.rank || 0) - (this.rank || 0); + + if (comparison) + return comparison; + + comparison = compare(this.city, other.city); + + if (comparison) + return comparison; + + comparison = compare(this.country, other.country); + + if (comparison) + return comparison; + + return compare(this.state, other.state); + } +} diff --git a/server/app/atlas.ts b/server/app/atlas.ts new file mode 100644 index 0000000..ffd9bf1 --- /dev/null +++ b/server/app/atlas.ts @@ -0,0 +1,585 @@ +import { Request, Response, Router } from 'express'; + +import { asyncHandler, notFoundForEverythingElse, formatVariablePrecision } from './common'; +import { doDataBaseSearch, hasSearchBeenDoneRecently, logMessage, pool } from './atlas_database'; +import { + celestialNames, initGazetteer, LocationMap, ParsedSearchString, parseSearchString, + roughDistanceBetweenLocationsInKm +} from './gazetteer'; +import { SearchResult } from './search-result'; +import { AtlasLocation } from './atlas-location'; +import { MapClass } from './map-class'; +import { GettyMetrics, gettySearch } from './getty-search'; +import { initTimezones } from './timezones'; +import { GeonamesMetrics, geonamesSearch } from './geonames-search'; +import { svcApiConsole } from './svc-api-logger'; +import { toInt, toBoolean, makePlainASCII_UC, processMillis } from '@tubular/util'; + +export const router = Router(); + +type RemoteMode = 'skip' | 'normal' | 'extend' | 'forced' | 'only' | 'geonames' | 'getty'; + +class LocationArrayMap extends MapClass { } + +interface RemoteSearchResults { + geoNamesMatches: LocationMap; + geoNamesMetrics: GeonamesMetrics; + geoNamesError: string; + gettyMatches: LocationMap; + gettyMetrics: GettyMetrics; + gettyError: string; + noErrors: boolean; + matches: number; +} + +const DEFAULT_MATCH_LIMIT = 75; +const MAX_MATCH_LIMIT = 500; +const REFRESH_TIME_FOR_INIT_DATA = 86400; // seconds +// const DB_UPDATE = true; + +let lastInit = 0; + +export async function initAtlas(re_init = false): Promise { + try { + await initTimezones(); + await initGazetteer(); + lastInit = processMillis(); + } + catch (err) { + svcApiConsole.error(`Atlas ${re_init ? 're-' : ''}init error: ${err}`); + + if (!re_init) + throw (err); + } +} + +router.get('/', asyncHandler(async (req: Request, res: Response) => { + const startTime = processMillis(); + + const q = req.query.q ? req.query.q.toString().trim() : 'Nashua, NH'; + const version = toInt(req.query.version, 9); + const lang = (req.query.lang?.toString().trim().toLowerCase() || req.header('Accept-Language') || '').substring(0, 2); + const callback = req.query.callback; + const plainText = toBoolean(req.query.pt, false, true); + const remoteMode = (/skip|normal|extend|forced|only|geonames|getty/i.test((req.query.remote ?? '').toString()) ? + req.query.remote.toString().toLowerCase() : 'skip') as RemoteMode; + const withoutDB = /only|geonames|getty/i.test(remoteMode); + const extend = (remoteMode === 'extend' || remoteMode === 'only' || remoteMode === 'forced'); + const client = (req.query.client ? req.query.client.toString().toLowerCase() : ''); + const svc = (!client || client === 'sa' || client === 'web'); + const limit = Math.min(toInt(req.query.limit, DEFAULT_MATCH_LIMIT), MAX_MATCH_LIMIT); + const noTrace = toBoolean(req.query.notrace, false, true) || remoteMode === 'only'; +// const dbUpdate = DB_UPDATE && !noTrace; + + const parsed = parseSearchString(q, version < 3 ? 'loose' : 'strict'); + const result = new SearchResult(q, parsed.normalizedSearch); + let consultRemoteData = false; + let remoteResults: RemoteSearchResults; + let dbMatchedOnlyBySound = false; + let dbMatches: LocationMap; + let dbError: string; +// let gotBetterMatchesFromRemoteData = false; + + for (let attempt = 0; attempt < 2; ++attempt) { + const connection = await pool.getConnection(); + + if (/forced|only|geonames|getty/i.test(remoteMode) || + (remoteMode !== 'skip' && !(await hasSearchBeenDoneRecently(connection, parsed.normalizedSearch, extend)))) { + consultRemoteData = true; + } + + if (startTime / 1000 > lastInit + REFRESH_TIME_FOR_INIT_DATA) + await initAtlas(true); + + if (withoutDB) + dbMatches = undefined; + else { + try { + dbMatches = await doDataBaseSearch(connection, parsed, extend, limit + 1, true, lang); + dbMatchedOnlyBySound = true; + + for (const location of dbMatches.values) { + if (!location.matchedBySound) { + dbMatchedOnlyBySound = false; + break; + } + } + + dbError = undefined; + } + catch (err) { + dbError = err.toString(); + + if (attempt === 0) + continue; + } + } + + connection.release(); + + if (consultRemoteData) { + const doGeonames = remoteMode !== 'getty'; + const doGetty = remoteMode !== 'geonames'; + + remoteResults = await remoteSourcesSearch(parsed, doGeonames, doGetty, noTrace); + + if (remoteResults.matches > 0 && dbMatchedOnlyBySound) { + // gotBetterMatchesFromRemoteData = true; + dbMatches = undefined; + } + } + + break; + } + + const mergedMatches = new LocationArrayMap(); + + if (dbMatches) + copyAndMergeLocations(mergedMatches, dbMatches); + + if (remoteResults) { + if (remoteResults.geoNamesMatches) + copyAndMergeLocations(mergedMatches, remoteResults.geoNamesMatches); + + if (remoteResults.gettyMatches) + copyAndMergeLocations(mergedMatches, remoteResults.gettyMatches); + } + + const uniqueMatches = eliminateDuplicatesAndSort(mergedMatches, limit + 1); + + if (uniqueMatches.length > limit) { + uniqueMatches.length = limit; + result.limitReached = true; + } + + result.matches = uniqueMatches; + + const { celestial, suggestions } = summarizeResults(result, remoteResults, dbError, extend, version, parsed, svc); + +// if (!dbError) +// await updateDbIfRequired(uniqueMatches, remoteResults, parsed.normalizedSearch, gotBetterMatchesFromRemoteData, extend, dbUpdate && !noTrace); + + const log = createCompactLogSummary(result, remoteResults, dbMatches ? dbMatches.size : 0, dbError, startTime, + client, version, celestial, suggestions); + + logMessage(log, noTrace); + + result.time = processMillis() - startTime; + + if (plainText) { + res.set('Content-Type', 'text/plain'); + res.send(result.toPlainText()); + } + else if (callback) + res.jsonp(result); + else + res.send(result); +})); + +function copyAndMergeLocations(destination: LocationArrayMap, source: LocationMap): void { + source.keys.forEach(key => { + const location = source.get(key); + let locations: AtlasLocation[]; + + key = key.replace(/\(\d+\)$/, ''); + + if (destination.has(key)) + locations = destination.get(key); + else { + locations = []; + destination.set(key, locations); + } + + locations.push(location); + }); +} + +const MATCH_ADM = /^A\.ADM/i; +const MATCH_PPL = /^P\.PPL/i; +const MATCH_PPLX = /^P\.PPL\w/i; + +function eliminateDuplicatesAndSort(mergedMatches: LocationArrayMap, limit: number): AtlasLocation[] { + const keys = mergedMatches.keys.sort(); + + keys.forEach(key => { + const locations = mergedMatches.get(key); + + for (let i = 0; i < locations.length - 1; ++i) { + const location1 = locations[i]; + + if (!location1) + continue; + + const city1 = location1.city; + const county1 = location1.county; + const state1 = location1.state; + const country1 = location1.country; + const latitude1 = location1.latitude; + const longitude1 = location1.longitude; + let zone1 = location1.zone; + const zip1 = location1.zip; + const rank1 = location1.rank; + let placeType1 = location1.placeType; + const source1 = location1.source; + const geonamesID1 = location1.geonamesID; + + if (!zone1) + zone1 = '?'; + + for (let j = i + 1; j < locations.length; ++j) { + const location2 = locations[j]; + + if (!location2) + continue; + + const county2 = location2.county; + const state2 = location2.state; + const latitude2 = location2.latitude; + const longitude2 = location2.longitude; + let zone2 = location2.zone; + const zip2 = location2.zip; + const rank2 = location2.rank; + let placeType2 = location2.placeType; + const source2 = location2.source; + const geonamesID2 = location2.geonamesID; + + if (zone2 == null) + zone2 = '?'; + + if (MATCH_ADM.test(placeType1) && MATCH_PPL.test(placeType2)) + placeType1 = placeType2; + + if (MATCH_ADM.test(placeType2) && MATCH_PPL.test(placeType1)) + placeType2 = placeType1; + + if (MATCH_PPL.test(placeType1) && MATCH_PPLX.test(placeType2)) + placeType1 = placeType2; + + if (MATCH_PPL.test(placeType2) && MATCH_PPLX.test(placeType1)) + placeType2 = placeType1; + + const distance = roughDistanceBetweenLocationsInKm(latitude1, longitude1, latitude2, longitude2); + + // If locations are close and one location has a questionable time zone, but the other is more + // certain, use the more certain time zone for both locations. + if (distance < 10) { + if (zone1.endsWith('?') && !zone2.endsWith('?')) + location1.zone = zone2; + else if (zone2.endsWith('?') && !zone1.endsWith('?')) + location2.zone = zone1; + } + + // Newer GeoNames data for the same location should replace older. + if (geonamesID1 && geonamesID1 === geonamesID2) { + if (source1 > source2) { + locations[j] = undefined; + location1.rank = Math.max(rank1, rank2); + location1.zip = (zip1 || zip2); + location1.source = source2; + location1.useAsUpdate = !location1.isCloseMatch(location2); + } + else { + locations[i] = undefined; + location2.rank = Math.max(rank1, rank2); + location1.zip = (zip2 || zip1); + location2.source = source1; + location2.useAsUpdate = (source2 > source1 && !location2.isCloseMatch(location1)); + // After eliminating location1 (index i), end j loop since there's nothing left from the outer loop for inner + // loop locations to be compared to. + break; + } + } + else if (distance < 10 && placeType2 === 'T.PK' && placeType1 === 'T.MT') { + locations[i] = undefined; + break; + } + // Favor peak (T.PK) place types over mountain (T.MT) place types. + else if (distance < 10 && placeType1 === 'T.PK' && placeType2 === 'T.MT') { + locations[j] = undefined; + } + else if (placeType1 !== placeType2) { + // Do nothing - differing place types of non-city items will be noted. + } + else if (state1 !== state2) { + if (distance < 10 && state1 && state2) + svcApiConsole.warn(`Possible detail conflict for same location: ${city1}, ${state1}/${state2}, ${country1}`); + + if (rank2 > rank1) { + locations[i] = undefined; + break; + } + else if (rank1 > rank2 || !state2) { + locations[j] = undefined; + } + else if (!state1) { + locations[i] = undefined; + break; + } + else { + location1.showState = true; + location2.showState = true; + } + } + else if (county1 !== county2) { + if (distance < 10 && county1 && county2) + svcApiConsole.warn(`Possible detail conflict for same location: ${city1}, ${county1}/${county2}, ${state1}, ${country1}`); + + if (rank2 > rank1) { + locations[i] = undefined; + break; + } + else if (rank1 > rank2 || !county2) + locations[j] = undefined; + else if (!county1) { + locations[i] = undefined; + break; + } + else { + location1.showCounty = true; + location2.showCounty = true; + } + } + else if (rank2 > rank1) { + if (source1.startsWith('GEO') && !source2.startsWith('GEO')) { + // Favor SVC's database entry, but keep higher rank. + locations[j] = undefined; + location1.rank = rank2; + } + else { + locations[i] = undefined; + break; + } + } + else if ((zip1 && !zip2) || rank1 > rank2) { + if (source2.startsWith('GEO') && !source1.startsWith('GEO')) { + // Favor SVC's database entry, but keep higher rank. + locations[i] = undefined; + location2.rank = Math.max(rank1, rank2); + location2.zip = (zip1 || zip2); + break; + } + else + locations[j] = undefined; + } + else if (source1.startsWith('GEO') && !source2.startsWith('GEO')) + locations[j] = undefined; + else { + locations[i] = undefined; + break; + } + } + } + }); + + const uniqueMatches: AtlasLocation[] = []; + + keys.forEach(key => { + const locations = mergedMatches.get(key); + + locations.forEach(location => { + if (location && uniqueMatches.length < limit) + uniqueMatches.push(location); + }); + }); + + return uniqueMatches.sort((a, b) => a.compareTo(b)); +} + +async function remoteSourcesSearch(parsed: ParsedSearchString, doGeonames: boolean, doGetty: boolean, noTrace: boolean): Promise { + const results = {} as RemoteSearchResults; + const promises: Promise[] = []; + let geoNamesIndex = -1; + let gettyIndex = -1; + let nextIndex = 0; + let noErrors = true; + let matches = 0; + + if (doGeonames) { + results.geoNamesMetrics = {} as GeonamesMetrics; + geoNamesIndex = nextIndex++; + promises.push(geonamesSearch(parsed.targetCity, parsed.targetState, parsed.postalCode, results.geoNamesMetrics, noTrace)); + } + + if (doGetty && !parsed.postalCode) { + results.gettyMetrics = {} as GettyMetrics; + gettyIndex = nextIndex; /* ++ */ // TODO: Put back trailing ++ if another remote source is added. + promises.push(gettySearch(parsed.targetCity, parsed.targetState, results.gettyMetrics, noTrace)); + } + + const locationsOrErrors = await Promise.all(promises.map(promise => promise.catch(err => err))); + + if (geoNamesIndex >= 0) { + if (locationsOrErrors[geoNamesIndex] instanceof Error) { + results.geoNamesError = (locationsOrErrors[geoNamesIndex] as Error).message; + noErrors = false; + } + else { + results.geoNamesMatches = locationsOrErrors[geoNamesIndex]; + matches += results.geoNamesMatches.size; + } + } + + if (gettyIndex >= 0) { + if (locationsOrErrors[gettyIndex] instanceof Error) { + results.gettyError = (locationsOrErrors[gettyIndex] as Error).message; + noErrors = false; + } + else { + results.gettyMatches = locationsOrErrors[gettyIndex]; + matches += results.gettyMatches.size; + } + } + + results.noErrors = noErrors; + results.matches = matches; + + return results; +} + +function summarizeResults(result: SearchResult, remoteResults: RemoteSearchResults, dbError: string, + extend: boolean, version: number, parsed: ParsedSearchString, + svc: boolean): { celestial: boolean, suggestions: string } { + if (remoteResults) { + if (remoteResults.geoNamesMetrics && !remoteResults.geoNamesError) { + const metrics = remoteResults.geoNamesMetrics; + const retrievalTime = formatVariablePrecision(metrics.retrievalTime / 1000); + + result.appendInfoLine(`GeoName raw matches: ${metrics.rawCount}, filtered matches: ${metrics.matchedCount}, \ +retrieval time: ${retrievalTime}s.`); + } + + if (remoteResults.gettyMetrics && !remoteResults.gettyError) { + const metrics = remoteResults.gettyMetrics; + const totalTime = formatVariablePrecision(metrics.totalTime / 1000); + const preliminaryTime = formatVariablePrecision(metrics.preliminaryTime / 1000); + const retrievalTime = formatVariablePrecision(metrics.retrievalTime / 1000); + + if (metrics.failedSyntax) + result.appendInfoLine('Getty failed search syntax: ' + metrics.failedSyntax); + + result.appendInfoLine(`Getty remote data: ${metrics.retrievedCount}\ +${metrics.retrievedCount === metrics.matchedCount ? '' : ' of ' + metrics.matchedCount} \ +item${metrics.matchedCount === 1 ? '' : 's'} retrieved, total time: ${totalTime}s, preliminary time: \ +${preliminaryTime}s, retrieval time: ${retrievalTime}s.`); + } + } + + // Returning one error will suffice. + if (dbError) + result.error = dbError; + else + result.error = remoteResults && (remoteResults.geoNamesError || remoteResults.gettyError); + + if (remoteResults) { + if (remoteResults.geoNamesError && (!extend || remoteResults.gettyError)) + result.appendWarningLine('Supplementary data temporarily unavailable.'); + else if (remoteResults.geoNamesError || remoteResults.gettyError) + result.appendWarningLine('Some supplementary data temporarily unavailable.'); + } + + let celestial = false; + + if (version > 2) + celestial = checkCelestial(parsed.targetCity, result, svc); + + return { celestial, suggestions: '' }; +} + +function createCompactLogSummary(result: SearchResult, remoteResults: RemoteSearchResults, dbMatchCount: number, + dbError: string, startTime: number, client: string, version: number, + celestial: boolean, suggestions: string): string { + const log = [result.originalSearch + ': ' + result.count]; + + if (result.limitReached) + log.push('+'); + + if (remoteResults) { + log.push('('); + log.push(dbMatchCount.toString()); + log.push(';'); + + if (remoteResults.geoNamesMatches) + log.push(remoteResults.geoNamesMatches.size.toString()); + else + log.push('-'); + + log.push(';'); + + if (remoteResults.gettyMatches) + log.push(remoteResults.gettyMatches.size.toString()); + else + log.push('-'); + + log.push(')'); + } + else + log.push('(db)'); + + if (dbError || (remoteResults && !remoteResults.noErrors)) { + log.push('['); + + if (!remoteResults) + log.push(dbError); + else { + if (dbError) + log.push(dbError); + else + log.push('-'); + + log.push(';'); + + if (remoteResults.geoNamesError) + log.push(remoteResults.geoNamesError); + else + log.push('-'); + + log.push(';'); + + if (remoteResults.gettyError) + log.push(remoteResults.gettyError); + else + log.push('-'); + } + + log.push(']'); + } + + log.push('['); + log.push(formatVariablePrecision((processMillis() - startTime) / 1000) + 's'); + + if (client === 'sa') + log.push(';sa'); + + if (version >= 3) { + log.push(';v'); + log.push(version.toString()); + } + + if (celestial) + log.push(';cele'); + + if (suggestions) + log.push(';sug:' + suggestions); + + log.push(']'); + + return log.join(''); +} + +function checkCelestial(targetCity: string, result: SearchResult, svc: boolean): boolean { + if (targetCity && celestialNames.has(makePlainASCII_UC(targetCity))) { + result.appendWarningLine('This search is for geographic locations only.'); + + if (svc) { + result.appendWarningLine('Use Sky → Show Names → One Specific Object... to find celestial objects.'); + result.appendWarningLine('Check the Help page for more details.'); + result.appendWarningLine(''); + } + + return true; + } + + return false; +} + +notFoundForEverythingElse(router); diff --git a/server/app/atlas_database.ts b/server/app/atlas_database.ts new file mode 100644 index 0000000..f54e96d --- /dev/null +++ b/server/app/atlas_database.ts @@ -0,0 +1,267 @@ +import { doubleMetaphone } from './double-metaphone'; +import { Pool, PoolConnection } from './mysql-await-async'; +import { + closeMatchForState, code3ToName, countyStateCleanUp, getFlagCode, LocationMap, makeLocationKey, + ParsedSearchString, simplify, closeMatchForCity +} from './gazetteer'; +import { AtlasLocation } from './atlas-location'; +import { MIN_EXTERNAL_SOURCE } from './common'; +import { svcApiConsole } from './svc-api-logger'; +import { toBoolean } from '@tubular/util'; + +export const pool = new Pool({ + host: (toBoolean(process.env.DB_REMOTE) ? 'skyviewcafe.com' : '127.0.0.1'), + user: 'skyview', + password: process.env.DB_PWD, + database: 'skyviewcafe' +}); + +enum MatchType { EXACT_MATCH, EXACT_MATCH_ALT, STARTS_WITH, SOUNDS_LIKE } + +const NO_RESULTS_YET = -1; +const MAX_MONTHS_BEFORE_REDOING_EXTENDED_SEARCH = 12; +const ZIP_RANK = 9; + +pool.on('connection', connection => { + // noinspection JSIgnoredPromiseFromCall + connection.query("SET NAMES 'utf8'"); +}); + +export function logMessage(message: string, noTrace = false): void { + svcApiConsole.info(message); + + if (!noTrace) + logMessageAux(message, false); +} + +export function logWarning(message: string, noTrace = false): void { + svcApiConsole.warn(message); + + if (!noTrace) + logMessageAux(message, true); +} + +function logMessageAux(message: string, asWarning: boolean): void { + setTimeout(async () => { + try { + await pool.queryResults('INSERT INTO atlas_log (warning, message) VALUES (?, ?)', [asWarning, message]); + } + catch (err) { + console.error('Writing to atlas_log failed.'); + } + }); +} + +export async function hasSearchBeenDoneRecently(connection: PoolConnection, searchStr: string, extended: boolean): Promise { + return await logSearchResults(connection, searchStr, extended, NO_RESULTS_YET, false); +} + +export async function logSearchResults(connection: PoolConnection, searchStr: string, extended: boolean, matchCount: number, dbUpdate = true): Promise { + let dbHits = 0; + let ageMonths = -1; + let found = false; + let wasExtended = false; + let matches = 0; + + const results = await connection.queryResults('SELECT extended, hits, matches, TIMESTAMPDIFF(MONTH, time_stamp, NOW()) as months FROM atlas_searches2 WHERE search_string = ?', + [searchStr]); + + if (results && results.length > 0) { + wasExtended = results[0].extended; + dbHits = results[0].hits; + matches = results[0].matches; + ageMonths = results[0].months; + + if (ageMonths < MAX_MONTHS_BEFORE_REDOING_EXTENDED_SEARCH && (wasExtended || !extended)) + found = true; + } + + if (matchCount >= 0 && dbUpdate) { + if (wasExtended) + extended = true; + + if (matchCount < matches) + matchCount = matches; + + let query: string; + let values: any[]; + + if (!found && ageMonths < 0) { + query = 'INSERT INTO atlas_searches2 (search_string, extended, hits, matches) VALUES (?, ?, 1, ?)'; + values = [searchStr, extended, matchCount]; + } + else { + query = 'UPDATE atlas_searches2 SET hits = ?, extended = ? WHERE search_string = ?'; + values = [++dbHits, extended && dbUpdate, searchStr]; + } + + await pool.queryResults(query, values); + } + + return found; +} + +export async function doDataBaseSearch(connection: PoolConnection, parsed: ParsedSearchString, extendedSearch: boolean, + maxMatches: number, canMatchBySound = true, lang?: string): Promise { + const simplifiedCity = simplify(parsed.targetCity); + const examined = new Set(); + const matches = new LocationMap(); + + for (let pass = 0; pass < 2; ++pass) { + const condition = (pass === 0 ? ' AND rank > 0' : ''); + + examined.clear(); + + for (let matchType: number = MatchType.EXACT_MATCH; matchType <= MatchType.SOUNDS_LIKE; ++matchType) { + let rankAdjust = 0; + let query: string; + let values: any[]; + let fromAlt = false; + + switch (matchType) { + case MatchType.EXACT_MATCH: + if (parsed.postalCode) { + query = 'SELECT gazetteer_id FROM gazetteer_postal WHERE code = ?'; + values = [parsed.postalCode]; + fromAlt = true; + } + else { + rankAdjust = 1; + values = [simplifiedCity]; + + if (lang && lang !== 'en') { + values.push(lang); + query = 'SELECT gazetteer_id FROM gazetteer_alt_names WHERE key_name = ? AND lang = ? AND colloquial = 0 AND historic = 0'; + fromAlt = true; + } + else + query = 'SELECT * FROM gazetteer WHERE key_name = ?' + condition; + } + break; + + case MatchType.EXACT_MATCH_ALT: + fromAlt = true; + query = `SELECT gazetteer_id FROM gazetteer_alt_names WHERE key_name = ? AND (lang = '' OR lang = 'en' OR lang = ?)`; + values = [simplifiedCity, lang]; + break; + + case MatchType.STARTS_WITH: + values = [simplifiedCity, simplifiedCity + '~']; + + if (lang && lang !== 'en') { + values.push(lang); + query = 'SELECT * FROM gazetteer_alt_names WHERE key_name >= ? AND key_name < ? AND lang = ?'; + fromAlt = true; + } + else + query = 'SELECT * FROM gazetteer WHERE key_name >= ? AND key_name < ? ' + condition; + + break; + + case MatchType.SOUNDS_LIKE: + if (/\d/.test(parsed.targetCity) || !canMatchBySound) + continue; + + rankAdjust = -1; + query = 'SELECT * FROM gazetteer WHERE mphone1 = ? OR mphone2 = ?' + condition; + values = doubleMetaphone(parsed.targetCity); + break; + } + + let results = (await connection.queryResults(query, values)) || []; + + if (fromAlt && results.length > 0) { + values = [results.map((row: any) => row.gazetteer_id).join(', ')]; + query = `SELECT * FROM gazetteer WHERE id IN (${values[0]})` + condition; + results = (await connection.queryResults(query)) || []; + } + + for (const result of results) { + const id = result.id; + + if (examined.has(id)) + continue; + + examined.add(id); + + const city = result.name; + const county = result.admin2; + const state = result.admin1; + const country = result.country; + const longCountry = code3ToName[country]; + const latitude: number = result.latitude; + const longitude: number = result.longitude; + const elevation: number = result.elevation; + const zone = result.timezone; + let zip = ''; + let rank: number = result.rank; + const placeType = result.feature_code; + const source = result.source; + const geonamesID: number = result.geonames_id; + + if (!parsed.postalCode && ((source >= MIN_EXTERNAL_SOURCE && !extendedSearch && pass === 0) || + !closeMatchForState(parsed.targetState, state, country))) + continue; + + if (parsed.postalCode) { + rank = ZIP_RANK; + zip = parsed.postalCode; + + if (results.length > 1) { + rank += parsed.targetCity && closeMatchForCity(parsed.targetCity, city) ? 2 : 0; + rank += parsed.targetCity && closeMatchForState(parsed.targetCity, state, country) ? 1 : 0; + rank += parsed.targetState && closeMatchForState(parsed.targetState, state, country) ? 1 : 0; + rank += parsed.targetState && closeMatchForCity(parsed.targetState, city) ? 1 : 0; + } + } + else { + rank += rankAdjust; + + if (rank >= ZIP_RANK) + rank = ZIP_RANK - 1; + else if (rank < 0) + rank = 0; + } + + const location = new AtlasLocation(); + + location.city = city; + location.county = countyStateCleanUp(county); + location.state = countyStateCleanUp(state); + location.country = country; + location.longCountry = longCountry; + location.flagCode = getFlagCode(country, state); + location.latitude = latitude; + location.longitude = longitude; + location.elevation = elevation; + location.zone = zone; + location.zip = zip; + location.rank = rank; + location.placeType = placeType; + location.source = source; + location.geonamesID = geonamesID; + + if (matchType === MatchType.EXACT_MATCH_ALT) + location.matchedByAlternateName = true; + else if (matchType === MatchType.SOUNDS_LIKE) + location.matchedBySound = true; + + const key = makeLocationKey(city, state, country, matches); + + matches.set(key, location); + + if (matches.size > maxMatches * 4) + break; + } + + // Skip SOUNDS_LIKE search step on first pass, or if better matches have already been found. Only one step needed for postal codes. + if (((pass === 0 || matches.size > 0) && matchType >= MatchType.STARTS_WITH) || parsed.postalCode) + break; + } + + if (parsed.postalCode) + break; + } + + return matches; +} diff --git a/server/app/common.ts b/server/app/common.ts new file mode 100644 index 0000000..2cd349b --- /dev/null +++ b/server/app/common.ts @@ -0,0 +1,74 @@ +import { NextFunction, Request, Response, Router } from 'express'; +import { isNil } from 'lodash'; +import { createReadStream } from 'fs'; + +export const MIN_EXTERNAL_SOURCE = 100; +export const SOURCE_GEONAMES_POSTAL_UPDATE = 101; +export const SOURCE_GEONAMES_GENERAL_UPDATE = 103; +export const SOURCE_GETTY_UPDATE = 104; + +export function notFound(res: Response): void { + res.status(403).send('Not found'); +} + +export function formatVariablePrecision(value: number, maxDecimals = 3): string { + let result = value.toFixed(maxDecimals); + + if (result.substr(-1) === '0') + result = result.replace(/\.?0+$/, ''); + + return result; +} + +export function notFoundForEverythingElse(router: Router): void { + router.get('*', (req: Request, res: Response) => notFound(res)); +} + +// noinspection JSVoidFunctionReturnValueUsed +export const asyncHandler = (fn: (req: Request, res: Response, next: NextFunction) => void) => + (req: Request, res: Response, next: NextFunction): Promise => + Promise.resolve(fn(req, res, next)).catch(next); + +export function eqci(s1: string, s2: string): boolean { + return s1 === s2 || isNil(s1) && isNil(s2) || s1.localeCompare(s2, undefined, { usage: 'search', sensitivity: 'base' }) === 0; +} + +export class PromiseTimeoutError extends Error {} + +export function timedPromise(promise: Promise, maxTime: number, errorResponse?: any): Promise { + if (typeof errorResponse === 'string') + errorResponse = new PromiseTimeoutError(errorResponse); + + const timer = new Promise((resolve, reject) => setTimeout(() => reject(errorResponse), maxTime)); + + return Promise.race([promise, timer]); +} + +export async function getFileContents(path: string, encoding?: string): Promise { + if (!encoding) + encoding = 'utf8'; + + return new Promise((resolve, reject) => { + const input = createReadStream(path, { encoding: encoding as any }); + let content = ''; + + input.on('error', err => { + reject(new Error(`Error reading ${path}: ${err.toString()}`)); + }); + input.on('data', (data: Buffer) => { + content += data.toString(encoding as any); + }); + input.on('end', () => { + input.close(); + resolve(content); + }); + }); +} + +export function escapeRegExp(s: string): string { + return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + +export function getRemoteAddress(req: Request): string { + return (req.headers['x-real-ip'] as string) || req.connection.remoteAddress; +} diff --git a/server/app/data/celestial.txt b/server/app/data/celestial.txt new file mode 100644 index 0000000..b28c76f --- /dev/null +++ b/server/app/data/celestial.txt @@ -0,0 +1,208 @@ +Acamar +Achernar +Acrux +Adara +Agena +al Mizar +Albireo +Alcor +Alcyone +Aldebaran +Alderamin +Algenib +Algieba +Algol +Alhena +Alioth +Alkaid +Almaak +Alnair +Alnath +Alnilam +Alnitak +Alpha Centauri +Alphard +Alphekka +Alpheratz +Alshain +Altair +Andromeda +Andromeda Galaxy +Andromeda Nebula +Ankaa +Antares +Antlia +Apus +Aquarius +Aquila +Ara +Arcturus +Aries +Arneb +Auriga +Bellatrix +Betelgeuse +Big Dipper +Boötes +Caelum +Camelopardalis +Cancer +Canes Venatici +Canis Major +Canis Minor +Canopus +Capella +Capricorn +Capricornus +Carina +Cassiopeia +Castor +Centaurus +Cepheus +Cetus +Chameleon +Circinus +Columba +Coma Berenices +Cor Caroli +Corona Australis +Corona Borealis +Corvus +Crab Nebula +Crater +Crux +Cygnus +Delphinus +Deneb +Deneb Algenubi +Denebola +Dheneb +Diphda +Dog Star +Dorado +Draco +Dubhe +Earth +Enif +Equulues +Eridanus +Etamin +Fomalhaut +Fornax +Gemini +Grus +Hamal +Hercules +Horologium +Horsehead Nebula +Hydra +Hydrus +Indus +Izar +Jupiter +Kaus Australis +Kocab +Lacerta +Leo +Leo Minor +Lepus +Libra +Little Dipper +Luna +Lupus +Lynx +Lyra +Markab +Mars +Megrez +Menkar +Mensa +Merach +Merak +Mercury +Microscopium +Milky Way +Mintaka +Mira +Mirac +Mirach +Mirak +Mirphak +Mizar +Monoceros +Moon +Musca +Neptune +Nihal +Norma +North Star +Nunki +Octans +Ophiuchus +Orion +Pavo +Pegasus +Perseus +Phad +Pictor +Pisces +Piscis Austrinus +Pleiades +Pluto +Polaris +Pollux +Procyon +Proxima Centauri +Puppis +Pyxis +Rasalgethi +Rasalhague +Regulus +Reticulum +Rigel +Sadalmelik +Sagitta +Sagittarius +Saiph +Saturn +Scheat +Scorpius +Sculptor +Scutum +Serpens +Serpens Caput +Serpens Cauda +Sextans +Shaula +Shedir +Sirius +Sol +Southern Cross +Spica +Sun +Tarazed +Taurus +Telescopium +The Big Dipper +The Dog Star +The Little Dipper +The Milky Way +The Moon +The North Star +The Southern Cross +The Sun +Thuban +Triangulum +Triangulum Australe +Tucana +Unukalhai +Uranus +Ursa Major +Ursa Minor +Vega +Vela +Venus +Vindemiatrix +Virgo +Volans +Vulpecula diff --git a/server/app/double-metaphone.ts b/server/app/double-metaphone.ts new file mode 100644 index 0000000..e80fc0b --- /dev/null +++ b/server/app/double-metaphone.ts @@ -0,0 +1,1045 @@ +// noinspection CommaExpressionJS +/* Adapted from https://github.com/words/double-metaphone. */ + +// Match vowels (including `Y`). + +import unidecode from 'unidecode-plus'; + +const vowels = /[AEIOUY]/; + +// Match few Slavo-Germanic values. +const slavoGermanic = /W|K|CZ|WITZ/; + +// Match few Germanic values. +const germanic = /^(VAN |VON |SCH)/; + +// Match initial values of which the first character should be skipped. +const initialExceptions = /^(GN|KN|PN|WR|PS)/; + +// Match initial Greek-like values of which the `CH` sounds like `K`. +const initialGreekCh = /^CH(IA|EM|OR([^E])|YM|ARAC|ARIS)/; + +// Match Greek-like values of which the `CH` sounds like `K`. +const greekCh = /ORCHES|ARCHIT|ORCHID/; + +// Match values which when following `CH`, transform `CH` to sound like `K`. +const chForKh = /[ BFHLMNRVW]/; + +// Match values which when preceding a vowel and `UGH`, sound like `F`. +const gForF = /[CGLRT]/; + +// Match initial values which sound like either `K` or `J`. +const initialGForKj = /Y[\s\S]|E[BILPRSY]|I[BELN]/; + +// Match initial values which sound like either `K` or `J`. +const initialAngerException = /^[DMR]ANGER/; + +// Match values which when following `GY`, do not sound like `K` or `J`. +const gForKj = /[EGIR]/; + +// Match values which when following `J`, do not sound `J`. +const jForJException = /[LTKSNMBZ]/; + +// Match values which might sound like `L`. +const alle = /AS|OS/; + +// Match Germanic values preceding `SH` which sound like `S`. +const hForS = /EIM|OEK|OLM|OLZ/; + +// Match Dutch values following `SCH` which sound like either `X` and `SK`, +// or `SK`. +const dutchSch = /E[DMNR]|UY|OO/; + +/** + * Get the phonetics according to the Double Metaphone algorithm from a value. + */ +export function doubleMetaphone(value: string): string[] { + let primary = ''; + let secondary = ''; + let index = 0; + const length = value.length; + const last = length - 1; + let subvalue: string; + let next: string; + let previous: string; + let nextNext: string; + + // KS: unidecode() call is a change from the original code. + value = unidecode(String(value).toUpperCase(), { skipRanges: [[0xC7, 0xC7], [0xD1, 0xD1]] }) + ' '; + const isSlavoGermanic = slavoGermanic.test(value); + const isGermanic = germanic.test(value); + const characters = value.split(''); + + // Skip this at beginning of word. + if (initialExceptions.test(value)) { + index++; + } + + // Initial X is pronounced Z, which maps to S. Such as `Xavier`. + if (characters[0] === 'X') { + primary += 'S'; + secondary += 'S'; + index++; + } + + while (index < length) { + previous = characters[index - 1]; + next = characters[index + 1]; + nextNext = characters[index + 2]; + + switch (characters[index]) { + case 'A': + case 'E': + case 'I': + case 'O': + case 'U': + case 'Y': + case 'À': + case 'Ê': + case 'É': + if (index === 0) { + // All initial vowels now map to `A`. + primary += 'A'; + secondary += 'A'; + } + + index++; + + break; + case 'B': + primary += 'P'; + secondary += 'P'; + + if (next === 'B') { + index++; + } + + index++; + + break; + case 'Ç': + primary += 'S'; + secondary += 'S'; + index++; + + break; + case 'C': + // Various Germanic: + if ( + previous === 'A' && + next === 'H' && + nextNext !== 'I' && + !vowels.test(characters[index - 2]) && + (nextNext !== 'E' || + ((subvalue = value.slice(index - 2, index + 4)) && + (subvalue === 'BACHER' || subvalue === 'MACHER'))) + ) { + primary += 'K'; + secondary += 'K'; + index += 2; + + break; + } + + // Special case for `Caesar`. + if (index === 0 && value.slice(index + 1, index + 6) === 'AESAR') { + primary += 'S'; + secondary += 'S'; + index += 2; + + break; + } + + // Italian `Chianti`. + if (value.slice(index + 1, index + 4) === 'HIA') { + primary += 'K'; + secondary += 'K'; + index += 2; + + break; + } + + if (next === 'H') { + // Find `Michael`. + if (index > 0 && nextNext === 'A' && characters[index + 3] === 'E') { + primary += 'K'; + secondary += 'X'; + index += 2; + + break; + } + + // Greek roots such as `chemistry`, `chorus`. + if (index === 0 && initialGreekCh.test(value)) { + primary += 'K'; + secondary += 'K'; + index += 2; + + break; + } + + // Germanic, Greek, or otherwise `CH` for `KH` sound. + if ( + isGermanic || + // Such as 'architect' but not 'arch', orchestra', 'orchid'. + greekCh.test(value.slice(index - 2, index + 4)) || + nextNext === 'T' || + nextNext === 'S' || + ((index === 0 || + previous === 'A' || + previous === 'E' || + previous === 'O' || + previous === 'U') && + // Such as `wachtler`, `weschsler`, but not `tichner`. + chForKh.test(nextNext)) + ) { + primary += 'K'; + secondary += 'K'; + } + else if (index === 0) { + primary += 'X'; + secondary += 'X'; + // Such as 'McHugh'. + } + else if (value.slice(0, 2) === 'MC') { + // Bug? Why matching absolute? what about McHiccup? + primary += 'K'; + secondary += 'K'; + } + else { + primary += 'X'; + secondary += 'K'; + } + + index += 2; + + break; + } + + // Such as `Czerny`. + if (next === 'Z' && value.slice(index - 2, index) !== 'WI') { + primary += 'S'; + secondary += 'X'; + index += 2; + + break; + } + + // Such as `Focaccia`. + if (value.slice(index + 1, index + 4) === 'CIA') { + primary += 'X'; + secondary += 'X'; + index += 3; + + break; + } + + // Double `C`, but not `McClellan`. + if (next === 'C' && !(index === 1 && characters[0] === 'M')) { + // Such as `Bellocchio`, but not `Bacchus`. + if ( + (nextNext === 'I' || nextNext === 'E' || nextNext === 'H') && + value.slice(index + 2, index + 4) !== 'HU' + ) { + subvalue = value.slice(index - 1, index + 4); + + // Such as `Accident`, `Accede`, `Succeed`. + if ( + (index === 1 && previous === 'A') || + subvalue === 'UCCEE' || + subvalue === 'UCCES' + ) { + primary += 'KS'; + secondary += 'KS'; + // Such as `Bacci`, `Bertucci`, other Italian. + } + else { + primary += 'X'; + secondary += 'X'; + } + + index += 3; + + break; + } + else { + // Pierce's rule. + primary += 'K'; + secondary += 'K'; + index += 2; + + break; + } + } + + if (next === 'G' || next === 'K' || next === 'Q') { + primary += 'K'; + secondary += 'K'; + index += 2; + + break; + } + + // Italian. + if ( + next === 'I' && + // Bug: The original algorithm also calls for A (as in CIA), which is + // already taken care of above. + (nextNext === 'E' || nextNext === 'O') + ) { + primary += 'S'; + secondary += 'X'; + index += 2; + + break; + } + + if (next === 'I' || next === 'E' || next === 'Y') { + primary += 'S'; + secondary += 'S'; + index += 2; + + break; + } + + primary += 'K'; + secondary += 'K'; + + // Skip two extra characters ahead in `Mac Caffrey`, `Mac Gregor`. + if ( + next === ' ' && + (nextNext === 'C' || nextNext === 'G' || nextNext === 'Q') + ) { + index += 3; + break; + } + + // Bug: Already covered above. + // if ( + // next === 'K' || + // next === 'Q' || + // (next === 'C' && nextnext !== 'E' && nextnext !== 'I') + // ) { + // index++; + // } + + index++; + + break; + case 'D': + if (next === 'G') { + // Such as `edge`. + if (nextNext === 'E' || nextNext === 'I' || nextNext === 'Y') { + primary += 'J'; + secondary += 'J'; + index += 3; + // Such as `Edgar`. + } + else { + primary += 'TK'; + secondary += 'TK'; + index += 2; + } + + break; + } + + if (next === 'T' || next === 'D') { + primary += 'T'; + secondary += 'T'; + index += 2; + + break; + } + + primary += 'T'; + secondary += 'T'; + index++; + + break; + case 'F': + if (next === 'F') { + index++; + } + + index++; + primary += 'F'; + secondary += 'F'; + + break; + case 'G': + if (next === 'H') { + if (index > 0 && !vowels.test(previous)) { + primary += 'K'; + secondary += 'K'; + index += 2; + + break; + } + + // Such as `Ghislane`, `Ghiradelli`. + if (index === 0) { + if (nextNext === 'I') { + primary += 'J'; + secondary += 'J'; + } + else { + primary += 'K'; + secondary += 'K'; + } + + index += 2; + + break; + } + + // Parker's rule (with some further refinements). + if ( + // Such as `Hugh`. The comma is not a bug. + ((subvalue = characters[index - 2]), subvalue === 'B' || subvalue === 'H' || subvalue === 'D') || + // Such as `bough`. The comma is not a bug. + ((subvalue = characters[index - 3]), subvalue === 'B' || subvalue === 'H' || subvalue === 'D') || + // Such as `Broughton`. The comma is not a bug. + ((subvalue = characters[index - 4]), subvalue === 'B' || subvalue === 'H') + ) { + index += 2; + + break; + } + + // Such as `laugh`, `McLaughlin`, `cough`, `gough`, `rough`, `tough`. + if ( + index > 2 && + previous === 'U' && + gForF.test(characters[index - 3]) + ) { + primary += 'F'; + secondary += 'F'; + } + else if (index > 0 && previous !== 'I') { + primary += 'K'; + secondary += 'K'; + } + + index += 2; + + break; + } + + if (next === 'N') { + if (index === 1 && vowels.test(characters[0]) && !isSlavoGermanic) { + primary += 'KN'; + secondary += 'N'; + // Not like `Cagney`. + } + else if ( + value.slice(index + 2, index + 4) !== 'EY' && + value.slice(index + 1) !== 'Y' && + !isSlavoGermanic + ) { + primary += 'N'; + secondary += 'KN'; + } + else { + primary += 'KN'; + secondary += 'KN'; + } + + index += 2; + + break; + } + + // Such as `Tagliaro`. + if (value.slice(index + 1, index + 3) === 'LI' && !isSlavoGermanic) { + primary += 'KL'; + secondary += 'L'; + index += 2; + + break; + } + + // -ges-, -gep-, -gel- at beginning. + if (index === 0 && initialGForKj.test(value.slice(1, 3))) { + primary += 'K'; + secondary += 'J'; + index += 2; + + break; + } + + // -ger-, -gy-. + if ( + (value.slice(index + 1, index + 3) === 'ER' && + previous !== 'I' && + previous !== 'E' && + !initialAngerException.test(value.slice(0, 6))) || + (next === 'Y' && !gForKj.test(previous)) + ) { + primary += 'K'; + secondary += 'J'; + index += 2; + + break; + } + + // Italian such as `biaggi`. + if ( + next === 'E' || + next === 'I' || + next === 'Y' || + ((previous === 'A' || previous === 'O') && + next === 'G' && + nextNext === 'I') + ) { + // Obvious Germanic. + if (value.slice(index + 1, index + 3) === 'ET' || isGermanic) { + primary += 'K'; + secondary += 'K'; + } + else { + primary += 'J'; + + // Always soft if French ending. + secondary += + value.slice(index + 1, index + 5) === 'IER ' ? 'J' : 'K'; + } + + index += 2; + + break; + } + + if (next === 'G') { + index++; + } + + index++; + + primary += 'K'; + secondary += 'K'; + + break; + case 'H': + // Only keep if first & before vowel or btw. 2 vowels. + if (vowels.test(next) && (index === 0 || vowels.test(previous))) { + primary += 'H'; + secondary += 'H'; + + index++; + } + + index++; + + break; + case 'J': + // Obvious Spanish, `jose`, `San Jacinto`. + if ( + value.slice(index, index + 4) === 'JOSE' || + value.slice(0, 4) === 'SAN ' + ) { + if ( + value.slice(0, 4) === 'SAN ' || + (index === 0 && characters[index + 4] === ' ') + ) { + primary += 'H'; + secondary += 'H'; + } + else { + primary += 'J'; + secondary += 'H'; + } + + index++; + + break; + } + + if ( + index === 0 + // Bug: unreachable (see previous statement). + // && value.slice(index, index + 4) !== 'JOSE'. + ) { + primary += 'J'; + + // Such as `Yankelovich` or `Jankelowicz`. + secondary += 'A'; + // Spanish pron. of such as `bajador`. + } + else if ( + !isSlavoGermanic && + (next === 'A' || next === 'O') && + vowels.test(previous) + ) { + primary += 'J'; + secondary += 'H'; + } + else if (index === last) { + primary += 'J'; + } + else if ( + previous !== 'S' && + previous !== 'K' && + previous !== 'L' && + !jForJException.test(next) + ) { + primary += 'J'; + secondary += 'J'; + // It could happen. + } + else if (next === 'J') { + index++; + } + + index++; + + break; + case 'K': + if (next === 'K') { + index++; + } + + primary += 'K'; + secondary += 'K'; + index++; + + break; + case 'L': + if (next === 'L') { + // Spanish such as `cabrillo`, `gallegos`. + if ( + (index === length - 3 && + ((previous === 'A' && nextNext === 'E') || + (previous === 'I' && + (nextNext === 'O' || nextNext === 'A')))) || + (previous === 'A' && + nextNext === 'E' && + (characters[last] === 'A' || + characters[last] === 'O' || + alle.test(value.slice(last - 1, length)))) + ) { + primary += 'L'; + index += 2; + + break; + } + + index++; + } + + primary += 'L'; + secondary += 'L'; + index++; + + break; + case 'M': + if ( + next === 'M' || + // Such as `dumb`, `thumb`. + (previous === 'U' && + next === 'B' && + (index + 1 === last || value.slice(index + 2, index + 4) === 'ER')) + ) { + index++; + } + + index++; + primary += 'M'; + secondary += 'M'; + + break; + case 'N': + if (next === 'N') { + index++; + } + + index++; + primary += 'N'; + secondary += 'N'; + + break; + case 'Ñ': + index++; + primary += 'N'; + secondary += 'N'; + + break; + case 'P': + if (next === 'H') { + primary += 'F'; + secondary += 'F'; + index += 2; + + break; + } + + // Also account for `campbell` and `raspberry`. + subvalue = next; + + if (subvalue === 'P' || subvalue === 'B') { + index++; + } + + index++; + + primary += 'P'; + secondary += 'P'; + + break; + case 'Q': + if (next === 'Q') { + index++; + } + + index++; + primary += 'K'; + secondary += 'K'; + + break; + case 'R': + // French such as `Rogier`, but exclude `Hochmeier`. + if ( + index === last && + !isSlavoGermanic && + previous === 'E' && + characters[index - 2] === 'I' && + characters[index - 4] !== 'M' && + characters[index - 3] !== 'E' && + characters[index - 3] !== 'A' + ) { + secondary += 'R'; + } + else { + primary += 'R'; + secondary += 'R'; + } + + if (next === 'R') { + index++; + } + + index++; + + break; + case 'S': + // Special cases `island`, `isle`, `carlisle`, `carlysle`. + if (next === 'L' && (previous === 'I' || previous === 'Y')) { + index++; + + break; + } + + // Special case `sugar-`. + if (index === 0 && value.slice(1, 5) === 'UGAR') { + primary += 'X'; + secondary += 'S'; + index++; + + break; + } + + if (next === 'H') { + // Germanic. + if (hForS.test(value.slice(index + 1, index + 5))) { + primary += 'S'; + secondary += 'S'; + } + else { + primary += 'X'; + secondary += 'X'; + } + + index += 2; + break; + } + + if ( + next === 'I' && + (nextNext === 'O' || nextNext === 'A') + // Bug: Already covered by previous branch + // || value.slice(index, index + 4) === 'SIAN' + ) { + if (isSlavoGermanic) { + primary += 'S'; + secondary += 'S'; + } + else { + primary += 'S'; + secondary += 'X'; + } + + index += 3; + + break; + } + + // German & Anglicization's, such as `Smith` match `Schmidt`, `snider` + // match `Schneider`. Also, -sz- in slavic language although in + // hungarian it is pronounced `s`. + if ( + next === 'Z' || + (index === 0 && + (next === 'L' || next === 'M' || next === 'N' || next === 'W')) + ) { + primary += 'S'; + secondary += 'X'; + + if (next === 'Z') { + index++; + } + + index++; + + break; + } + + if (next === 'C') { + // Schlesinger's rule. + if (nextNext === 'H') { + subvalue = value.slice(index + 3, index + 5); + + // Dutch origin, such as `school`, `schooner`. + if (dutchSch.test(subvalue)) { + // Such as `schermerhorn`, `schenker`. + if (subvalue === 'ER' || subvalue === 'EN') { + primary += 'X'; + secondary += 'SK'; + } + else { + primary += 'SK'; + secondary += 'SK'; + } + + index += 3; + + break; + } + + if ( + index === 0 && + !vowels.test(characters[3]) && + characters[3] !== 'W' + ) { + primary += 'X'; + secondary += 'S'; + } + else { + primary += 'X'; + secondary += 'X'; + } + + index += 3; + + break; + } + + if (nextNext === 'I' || nextNext === 'E' || nextNext === 'Y') { + primary += 'S'; + secondary += 'S'; + index += 3; + break; + } + + primary += 'SK'; + secondary += 'SK'; + index += 3; + + break; + } + + subvalue = value.slice(index - 2, index); + + // French such as `resnais`, `artois`. + if (index === last && (subvalue === 'AI' || subvalue === 'OI')) { + secondary += 'S'; + } + else { + primary += 'S'; + secondary += 'S'; + } + + if ( + next === 'S' + // Bug: already taken care of by `German & Anglicization's` above: + // || next === 'Z' + ) { + index++; + } + + index++; + + break; + case 'T': + if (next === 'I' && nextNext === 'O' && characters[index + 3] === 'N') { + primary += 'X'; + secondary += 'X'; + index += 3; + + break; + } + + subvalue = value.slice(index + 1, index + 3); + + if ( + (next === 'I' && nextNext === 'A') || + (next === 'C' && nextNext === 'H') + ) { + primary += 'X'; + secondary += 'X'; + index += 3; + + break; + } + + if (next === 'H' || (next === 'T' && nextNext === 'H')) { + // Special case `Thomas`, `Thames` or Germanic. + if ( + isGermanic || + ((nextNext === 'O' || nextNext === 'A') && + characters[index + 3] === 'M') + ) { + primary += 'T'; + secondary += 'T'; + } + else { + primary += '0'; + secondary += 'T'; + } + + index += 2; + + break; + } + + if (next === 'T' || next === 'D') { + index++; + } + + index++; + primary += 'T'; + secondary += 'T'; + + break; + case 'V': + if (next === 'V') { + index++; + } + + primary += 'F'; + secondary += 'F'; + index++; + + break; + case 'W': + // Can also be in middle of word (as already taken care of for initial). + if (next === 'R') { + primary += 'R'; + secondary += 'R'; + index += 2; + + break; + } + + if (index === 0) { + // `Wasserman` should match `Vasserman`. + if (vowels.test(next)) { + primary += 'A'; + secondary += 'F'; + } + else if (next === 'H') { + // Need `Uomo` to match `Womo`. + primary += 'A'; + secondary += 'A'; + } + } + + // `Arnow` should match `Arnoff`. + if ( + ((previous === 'E' || previous === 'O') && + next === 'S' && + nextNext === 'K' && + (characters[index + 3] === 'I' || characters[index + 3] === 'Y')) || + // Maybe a bug? Shouldn't this be general Germanic? + value.slice(0, 3) === 'SCH' || + (index === last && vowels.test(previous)) + ) { + secondary += 'F'; + index++; + + break; + } + + // Polish such as `Filipowicz`. + if ( + next === 'I' && + (nextNext === 'C' || nextNext === 'T') && + characters[index + 3] === 'Z' + ) { + primary += 'TS'; + secondary += 'FX'; + index += 4; + + break; + } + + index++; + + break; + case 'X': + // French such as `breaux`. + if ( + !( + index === last && + // Bug: IAU and EAU also match by AU + // (/IAU|EAU/.test(value.slice(index - 3, index))) || + previous === 'U' && + (characters[index - 2] === 'A' || characters[index - 2] === 'O') + ) + ) { + primary += 'KS'; + secondary += 'KS'; + } + + if (next === 'C' || next === 'X') { + index++; + } + + index++; + + break; + case 'Z': + // Chinese pinyin such as `Zhao`. + if (next === 'H') { + primary += 'J'; + secondary += 'J'; + index += 2; + + break; + } + else if ( + (next === 'Z' && + (nextNext === 'A' || nextNext === 'I' || nextNext === 'O')) || + (isSlavoGermanic && index > 0 && previous !== 'T') + ) { + primary += 'S'; + secondary += 'TS'; + } + else { + primary += 'S'; + secondary += 'S'; + } + + if (next === 'Z') { + index++; + } + + index++; + + break; + default: + index++; + } + } + + return [primary, secondary]; +} diff --git a/server/app/gazetteer.ts b/server/app/gazetteer.ts new file mode 100644 index 0000000..2d4dc4d --- /dev/null +++ b/server/app/gazetteer.ts @@ -0,0 +1,649 @@ +import { readdirSync } from 'fs'; +import { eqci, getFileContents } from './common'; +import { AtlasLocation } from './atlas-location'; +import { decode } from 'html-entities'; +import { MapClass } from './map-class'; +import { logWarning, pool } from './atlas_database'; +import { acos, cos_deg, PI, sin_deg } from '@tubular/math'; +import { join as pathJoin } from 'path'; +import { PoolConnection } from './mysql-await-async'; +import { svcApiConsole } from './svc-api-logger'; +import { asLines, makePlainASCII_UC, toNumber } from '@tubular/util'; +import { requestText } from 'by-request'; + +export interface ParsedSearchString { + postalCode: string; + targetCity: string; + targetState: string; + actualSearch: string; + normalizedSearch: string; +} + +export interface NameAndCode { + name: string; + code: string; +} + +export type ParseMode = 'loose' | 'strict'; + +const TRAILING_STATE_PATTERN = /(.+)\b(\w{2,3})$/; +const usTerritories = ['AS', 'FM', 'GU', 'MH', 'MP', 'PW', 'VI']; +const canadianProvinceAbbrs = ['AB', 'BC', 'MB', 'NB', 'NF', '', 'NS', 'ON', 'PE', 'QC', 'SK', 'YT', 'NT', 'NU']; + +interface ProcessedNames { + city: string; + variant: string; + county: string; + state: string; + longState: string; + country: string; + longCountry: string; + continent: string; +} + +export class LocationMap extends MapClass { } + +export const longStates: Record = {}; +export const stateAbbreviations: Record = {}; +export const altFormToStd: Record = {}; +export const code3ToName: Record = {}; +export const code3ToNameByLang: Record> = {}; +export const nameToCode3: Record = {}; +export const code2ToCode3: Record = {}; +export const code3ToCode2: Record = {}; +export const admin1s: Record = {}; +export const admin2s: Record = {}; +export const postalPatterns = new Map(); + +export const usCounties = new Set(); +export const celestialNames = new Set(); + +interface CountryIn { + id: number; + name: string; + iso2: string; + iso3: string; + key_name: string; + geonames_id: string; + postal_regex: string; +} + +interface AdminIn { + id: number; + name: string; + key_name: string; + geonames_id: string; +} + +export async function initGazetteer(): Promise { + let connection: PoolConnection; + + try { + await initFlagCodes(); + connection = await pool.getConnection(); + + let rows = (await connection.query('SELECT * FROM gazetteer_countries')).results; + + for (const row of rows as CountryIn[]) { + nameToCode3[simplify(row.name).substr(0, 40)] = row.iso3; + code3ToName[row.iso3] = row.name; + + if (row.iso2) { + code2ToCode3[row.iso2] = row.iso3; + code3ToCode2[row.iso3] = row.iso2; + } + + if (row.postal_regex) + postalPatterns.set(row.iso3, new RegExp(row.postal_regex, 'i')); + } + + rows = (await connection.query('SELECT * FROM gazetteer_admin1')).results; + + for (const row of rows as AdminIn[]) { + admin1s[row.key_name] = row.name; + + if (row.key_name.startsWith('USA.')) + longStates[row.key_name.substr(4)] = row.name; + } + + rows = (await connection.query('SELECT * FROM gazetteer_admin2')).results; + + for (const row of rows as AdminIn[]) { + admin2s[row.key_name] = row.name; + + if (row.key_name.startsWith('USA.')) + usCounties.add(standardizeShortCountyName(row.name) + ', ' + row.key_name.substr(4, 2)); + } + + usCounties.add('Washington, DC'); + + const lines = asLines(await getFileContents('app/data/celestial.txt', 'utf8')); + + lines.forEach(line => celestialNames.add(makePlainASCII_UC(line.trim()))); + } + catch (err) { + svcApiConsole.error('Gazetteer init error: ' + err); + } + + connection?.release(); +} + +const flagCodes = new Set(); + +async function initFlagCodes(): Promise { + try { + const flagFiles = readdirSync(pathJoin(__dirname, '../../public/assets/resources/flags')); + let $: string[]; + + flagFiles.forEach(file => { + if (($ = /^(\w+)\.png$/.exec(file))) + flagCodes.add($[1]); + }); + + if (flagCodes.size) { + svcApiConsole.info('Flag codes obtained from local directory'); + return; + } + } + catch (err) { /* Ignore error, proceed to remote retrieval. */ } + + try { + const lines = (await requestText('https://skyviewcafe.com/assets/resources/flags/')).split(/\r\n|\n|\r/); + + lines.forEach(line => { + const $ = />(\w+)\.png= 0) + s = s.substring(0, pos).trim(); + + s = makePlainASCII_UC(s); + + let sb: string[] = []; + + for (let i = 0; i < s.length; ++i) { + const ch = s.charAt(i); + + if (ch === '-' || ch === '.') + sb.push(' '); + else if (ch === ' ' || /[\dA-Z]/i.test(ch)) + sb.push(ch); + } + + s = sb.join(''); + + if (processAbbreviations) { + if (asVariant) { + const $ = VARIANT_START.exec(s); + + if ($) + s = $[3]; + } + else if (s.startsWith('FORT ')) + s = 'FT' + s.substring(5); + else if (s.startsWith('MOUNT ')) + s = 'MT' + s.substring(6); + else if (s.startsWith('POINT ')) + s = 'PT' + s.substring(6); + + if (s.startsWith('SAINT ')) + s = 'ST' + s.substring(6); + else if (s.startsWith('SAINTE ')) + s = 'STE' + s.substring(7); + } + + sb = []; + + for (let i = 0; i < s.length && sb.length < 40; ++i) { + const ch = s.charAt(i); + + if (ch !== ' ') + sb.push(ch); + } + + return sb.join(''); +} + +function startsWithICND(testee: string, test: string): boolean { // Ignore Case aNd Diacriticals + if (!testee || !test) + return false; + + testee = simplify(testee); + test = simplify(test); + + return testee.startsWith(test); +} + +export function closeMatchForCity(target: string, candidate: string): boolean { + if (!target || !candidate) + return false; + + target = simplify(target); + candidate = simplify(candidate); + + return candidate.startsWith(target); +} + +export function closeMatchForState(target: string, state: string, country: string): boolean { + if (!target) + return true; + + const longState = longStates[state]; + const longCountry = code3ToName[country]; + const code2 = code3ToCode2[country]; + + return (startsWithICND(state, target) || + startsWithICND(country, target) || + startsWithICND(longState, target) || + startsWithICND(longCountry, target) || + (country === 'GBR' && startsWithICND('Great Britain', target)) || + (country === 'GBR' && startsWithICND('England', target)) || + startsWithICND(code2, target)); +} + +const CLEANUP1 = /^((County(\s+of)?)|((Provincia|Prov\xC3\xADncia|Province|Regi\xC3\xB3n Metropolitana|Distrito|Regi\xC3\xB3n)\s+(de|del|de la|des|di)))/i; +const CLEANUP2 = /\s+(province|administrative region|national capital region|prefecture|oblast'|oblast|kray|county|district|department|governorate|metropolitan area|territory)$/; +const CLEANUP3 = /\s+(region|republic)$/; + +export function countyStateCleanUp(s: string): string { + s = s.replace(CLEANUP1, ''); + s = s.replace(CLEANUP2, ''); + s = s.replace(CLEANUP3, '').trim(); + + return s; +} + +export function isRecognizedUSCounty(county: string, state: string): boolean { + return usCounties.has(county + ', ' + state); +} + +export function standardizeShortCountyName(county: string): string { + if (!county) + return county; + + county = county.trim(); + county = county.replace(/ \(.*\)/g, ''); + county = county.replace(/\s+/g, ' '); + county = county.replace(/\s*?-\s*?\b/g, '-'); + county = county.replace(/City and (Borough|County) of /i, ''); + county = county.replace(/ (Borough|Census Area|County|Division|Municipality|Parish|City and Borough)/ig, ''); + county = county.replace(/Aleutian Islands/i, 'Aleutians West'); + county = county.replace(/Juneau City and/i, 'Juneau'); + county = county.replace(/Coös/i, 'Coos'); + county = county.replace(/De Kalb/i, 'DeKalb'); + county = county.replace(/De Soto/i, 'DeSoto'); + county = county.replace(/De Witt/i, 'DeWitt'); + county = county.replace(/Du Page/i, 'DuPage'); + county = county.replace(/^La(Crosse|Moure|Paz|Plate|Porte|Salle)/i, 'La $1'); + county = county.replace(/Skagway-Yakutat-Angoon/i, 'Skagway-Hoonah-Angoon'); + county = county.replace(/Grays Harbor/i, "Gray's Harbor"); + county = county.replace(/OBrien/i, "O'Brien"); + county = county.replace(/Prince Georges/i, "Prince George's"); + county = county.replace(/Queen Annes"/, "Queen Anne's"); + county = county.replace(/Scotts Bluff/i, "Scott's Bluff"); + county = county.replace(/^(St. |St )/i, 'Saint '); + county = county.replace(/Saint Johns/i, "Saint John's"); + county = county.replace(/Saint Marys/i, "Saint Mary's"); + county = county.replace(/BronxCounty/i, 'Bronx'); + + const $ = /^Mc([a-z])(.*)/.exec(county); + + if ($) + county = 'Mc' + $[1].toUpperCase() + $[2]; + + return county; +} + +export function containsMatchingLocation(matches: LocationMap, location: AtlasLocation): boolean { + return matches.values.findIndex(location2 => + location2.city === location.city && + location2.county === location.county && + location2.state === location.state && + location2.country === location.country) >= 0; +} + +export function fixRearrangedName(name: string): { name: string, variant: string } { + let variant: string; + let $: string[]; + + if (($ = /(.+), (\w)(.*')/.exec(name))) { + variant = $[1]; + name = $[2].toUpperCase() + $[3] + variant; + } + else if (($ = /(.+), (\w)(.*)/.exec(name))) { + variant = $[1]; + name = $[2].toUpperCase() + $[3] + ' ' + variant; + } + + return { name, variant }; +} + +export function getCode3ForCountry(country: string): string { + country = simplify(country).substr(0, 20); + + return nameToCode3[country]; +} + +const APARTMENTS_ETC = new RegExp('\\b((mobile|trailer|vehicle)\\s+(acre|city|community|corral|court|estate|garden|grove|harbor|haven|' + + 'home|inn|lodge|lot|manor|park|plaza|ranch|resort|terrace|town|villa|village)s?)|' + + '((apartment|condominium|\\(subdivision\\))s?)\\b', 'i'); +const IGNORED_PLACES = new RegExp('bloomingtonmn|census designated place|colonia \\(|colonia number|condominium|circonscription electorale d|' + + 'election precinct|\\(historical\\)|mobilehome|subdivision|unorganized territory|\\{|\\}', 'i'); + +export function processPlaceNames(city: string, county: string, state: string, country: string, continent: string, + decodeHTML = false, noTrace = true): ProcessedNames { + let abbrevState: string; + let longState: string; + let longCountry: string; + let origCounty: string; + let variant: string; + + if (decodeHTML) { + city = decode(city); + county = decode(county); + state = decode(state); + country = decode(country); + continent = decode(continent); + } + + if (/\b\d+[a-z]/i.test(city)) + return null; + + if (APARTMENTS_ETC.test(city)) + return null; + + if (IGNORED_PLACES.test(city)) + return null; + + if (/\bParis \d\d\b/i.test(city)) + return null; + + ({ name: city, variant } = fixRearrangedName(city)); + + if (/,/.test(city)) + logWarning(`City name "${city}" (${state}, ${country}) contains a comma.`, noTrace); + + let $: string[]; + + if (!variant && ($ = /^(lake|mount|(?:mt\.?)|the|la|las|el|le|los)\b(.+)/i.exec(city))) + variant = $[2].trim(); + + const altForm = altFormToStd[simplify(country)]; + + if (altForm) + country = altForm; + + state = countyStateCleanUp(state); + county = countyStateCleanUp(county); + + longState = state; + longCountry = country; + const code3 = getCode3ForCountry(country); + + if (code3) { + country = code3; + } + else if (code3ToName[country]) { + longCountry = code3ToName[country]; + } + else { + logWarning(`Failed to recognize country "${country}" for city "${city}, ${state}".`, noTrace); + country = country.replace(/^(.{0,2}).*$/, '$1?'); + } + + if (state.toLowerCase().endsWith(' state')) { + state = state.substr(0, state.length - 6); + } + + if (country === 'USA' || country === 'CAN') { + if (state && longStates[state]) + longState = longStates[state]; + else if (state) { + abbrevState = stateAbbreviations[makePlainASCII_UC(state)]; + + if (abbrevState) { + abbrevState = state; + abbrevState = abbrevState.replace(/ (state|province)$/i, ''); + abbrevState = stateAbbreviations[makePlainASCII_UC(abbrevState)]; + } + + if (abbrevState) + state = abbrevState; + else + logWarning(`Failed to recognize state/province "${state}" in country ${country}.`, noTrace); + } + + if (county && country === 'USA' && usTerritories.includes(state)) { + origCounty = county; + county = standardizeShortCountyName(county); + + if (!isRecognizedUSCounty(county, state)) { + county = origCounty; + + if (county === 'District of Columbia') + county = 'Washington'; + + county = county.replace(/^City of /i, ''); + county = county.replace(/\s(Indep. City|Independent City|Independent|City|Division|Municipality)$/i, ''); + + if (county !== origCounty) { + if (simplify(origCounty) === simplify(city) || simplify(county) === simplify(city)) { + // City is its own county in a sense -- and independent city. Blank out the redundancy. + county = undefined; + } + // Otherwise, this is probably a neighborhood in an independent city. We'll treat + // the independent city as a county, being that it's a higher administrative level, + // adding "City of" where appropriate. + else if (/city|division|municipality/i.test(city)) + county = 'City of ' + county; + } + else + logWarning(`Failed to recognize US county "${county}" for city "${city}".`, noTrace); + } + } + } + + return { city, variant, county, state, longState, country, longCountry, continent }; +} + +export function getFlagCode(country: string, state: string): string { + let code; + + if (country === 'GBR' && eqci(state, 'England')) + code = 'england'; + else if (country === 'GBR' && eqci(state, 'Scotland')) + code = 'scotland'; + else if (country === 'GBR' && eqci(state, 'Wales')) + code = 'wales'; + else if (country === 'ESP' && eqci(state, 'Catalonia')) + code = 'catalonia'; + else + code = code3ToCode2[country]; + + if (code) { + code = code.toLowerCase(); + + if (!flagCodes.has(code)) + code = undefined; + } + else + code = undefined; + + return code; +} + +export function roughDistanceBetweenLocationsInKm(lat1: number, long1: number, lat2: number, long2: number): number { + let deltaRad = acos(sin_deg(lat1) * sin_deg(lat2) + cos_deg(lat1) * cos_deg(lat2) * cos_deg(long1 - long2)); + + while (deltaRad > PI) + deltaRad -= PI; + + while (deltaRad < -PI) + deltaRad += PI; + + return deltaRad * 6378.14; // deltaRad * radius_of_earth_in_km +} + +export function makeLocationKey(city: string, state: string, country: string, otherLocations: LocationMap): string { + let key: string; + let index = 1; + + city = simplify(city, false); + + if (state && (country === 'USA' || country === 'CAN')) + key = city + ',' + state; + else + key = city + ',' + country; + + const baseKey = key; + + while (otherLocations.has(key)) { + ++index; + key = baseKey + '(' + index + ')'; + } + + return key; +} + +function isPostalCode(s: string): boolean { + for (const regex of postalPatterns.values()) { + if (regex.test(s)) + return true; + } + + return false; +} + +export function parseSearchString(q: string, mode: ParseMode): ParsedSearchString { + const parsed = { actualSearch: q } as ParsedSearchString; + const parts = q.split(',').map(part => part.trim()); + const altParts = q.split(/\s+/).map(part => part.trim()).filter(part => !/,/.test(part)); + let postalCode = ''; + let targetCity = parts[0]; + let targetState = parts[1]; + let targetCountry = parts[2]; + let $: string[]; + + if (altParts.length > 1) { + if (isPostalCode(altParts[0])) { + postalCode = altParts[0]; + targetCity = ''; + targetState = altParts[1]; + } + else if (isPostalCode(altParts[1])) { + postalCode = altParts[1]; + targetCity = altParts[0]; + targetState = ''; + } + } + + if (!postalCode) { + if (isPostalCode(targetCity)) { + postalCode = targetCity; + targetCity = ''; + } + else if (targetState && isPostalCode(targetState)) { + postalCode = targetState; + targetState = ''; + } + else + targetCity = makePlainASCII_UC(targetCity); + } + + targetState = makePlainASCII_UC(targetState); + targetCountry = makePlainASCII_UC(targetCountry); + + if (targetCountry) + targetState = targetCountry; + + if (mode === 'loose' && !targetState && ($ = TRAILING_STATE_PATTERN.exec(targetCity))) { + const start = $[1].trim(); + const end = $[2]; + + if (longStates[end] || code3ToName[end]) { + targetCity = start; + targetState = end; + } + } + + parsed.postalCode = postalCode; + parsed.targetCity = targetCity; + parsed.targetState = targetState; + parsed.normalizedSearch = postalCode || targetCity; + + if (targetState) + parsed.normalizedSearch += ', ' + targetState; + else if (postalCode && targetCity) + parsed.normalizedSearch = targetCity + ', ' + postalCode; + + return parsed; +} + +const CENSUS_AREAS = new RegExp( + '(Aleutians West|Bethel|Dillingham|Nome|Prince of Wales-Outer Ketchikan|' + + 'Skagway-Hoonah-Angoon|Southeast Fairbanks|Valdez-Cordova|Wade Hampton|' + + 'Wrangell-Petersburg|Yukon-Koyukuk)', 'i'); + +export function adjustUSCountyName(county: string, state: string): string { + if (/ (Division|Census Area|Borough|Parish|County)$/i.test(county)) + return county; + + if (state === 'AK') { + if (/Anchorage|Juneau/i.test(county)) { + county += ' Division'; + } + else if (CENSUS_AREAS.test(county)) + county += ' Census Area'; + else + county += ' Borough'; + } + else if (state === 'LA') + county += ' Parish'; + else + county += ' County'; + + return county; +} + +export function getStatesProvincesAndCountries(): NameAndCode[] { + const usStates: NameAndCode[] = Object.keys(admin1s).filter(key => key.startsWith('USA')).map(key => + ({ name: admin1s[key], code: key.substr(4) })); + const canadianProvinces: NameAndCode[] = Object.keys(admin1s).filter(key => key.startsWith('CAN')).map(key => + ({ name: admin1s[key], code: canadianProvinceAbbrs[toNumber(key.substr(4)) - 1] })); + const countries: NameAndCode[] = []; + const results: NameAndCode[] = []; + + usStates.sort((a, b) => a.name.localeCompare(b.name, 'en')); + results.push(...usStates); + + canadianProvinces.sort((a, b) => a.name.localeCompare(b.name, 'en')); + results.push(null, ...canadianProvinces); + + Object.keys(code3ToName).forEach(code => { + if (!/^(NML|XX.|(.*[^A-Z].*))$/.test(code)) + countries.push({ name: code3ToName[code], code }); + }); + + countries.sort((a, b) => a.name.localeCompare(b.name, 'en')); + results.push(null, ...countries); + + return results; +} diff --git a/server/app/geonames-search.ts b/server/app/geonames-search.ts new file mode 100644 index 0000000..57e76e3 --- /dev/null +++ b/server/app/geonames-search.ts @@ -0,0 +1,139 @@ +import { + closeMatchForCity, closeMatchForState, code2ToCode3, containsMatchingLocation, getFlagCode, LocationMap, + makeLocationKey, processPlaceNames, standardizeShortCountyName +} from './gazetteer'; +import { timedPromise } from './common'; +import { AtlasLocation } from './atlas-location'; +import { processMillis, toInt } from '@tubular/util'; +import { requestJson } from 'by-request'; + +export interface GeonamesMetrics { + retrievalTime: number; + rawCount: number; + matchedCount: number; +} + +const MAX_TIME_GEONAMES = 20; // seconds +const FAKE_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:98.0) Gecko/20100101 Firefox/98.0'; + +export async function geonamesSearch(targetCity: string, targetState: string, postalCode: string, metrics: GeonamesMetrics, noTrace: boolean): Promise { + return timedPromise(geoNamesSearchAux(targetCity, targetState, postalCode, metrics, noTrace), MAX_TIME_GEONAMES * 1000, 'GeoNames search timed out'); +} + +async function geoNamesSearchAux(targetCity: string, targetState: string, postalCode: string, metrics: GeonamesMetrics, noTrace: boolean): Promise { + const startTime = processMillis(); + const keyedPlaces = new LocationMap(); + + targetCity = targetCity.replace(/^mt\b/i, 'mount'); + metrics = metrics || {} as GeonamesMetrics; + metrics.matchedCount = 0; + + let url = `http://api.geonames.org/${postalCode ? 'postalCodeSearchJSON' : 'searchJSON'}?username=skyview&style=full`; + + if (postalCode) + url += '&postalcode='; + else { + url += '&isNameRequired=true' + // Remove &featureCode=PRK for now -- too many obscure matches. + + '&featureCode=LK&featureCode=MILB&featureCode=PPL&featureCode=PPLA&featureCode=PPLA2&featureCode=PPLA3' + + '&featureCode=PPLA4&featureCode=PPLC&featureCode=PPLF&featureCode=PPLG&featureCode=PPLL&featureCode=PPLQ&featureCode=PPLR' + + '&featureCode=PPLS&featureCode=PPLW&featureCode=PPLX&featureCode=ASTR&featureCode=ATHF&featureCode=CTRS&featureCode=OBS' + + '&featureCode=STNB&featureCode=ATOL&featureCode=CAPE&featureCode=ISL&featureCode=MT&featureCode=PK' + + '&name_startsWith='; + } + + url += encodeURIComponent(postalCode || targetCity); + + let geonames: any[]; + const options = { headers: { 'User-Agent': FAKE_USER_AGENT } }; + let results: any; + + try { + results = await requestJson(url, options); + } + catch (err) { + throw new Error('GeoNames error: ' + err); + } + + if (results) { + if (!postalCode && results.totalResultsCount > 0 && Array.isArray(results.geonames)) + geonames = results.geonames; + else if (postalCode && Array.isArray(results.postalCodes)) + geonames = results.postalCodes; + } + + if (geonames) { + metrics.rawCount = geonames.length; + + for (const geoname of geonames) { + const city: string = postalCode ? geoname.placeName : geoname.name; + let county: string = geoname.adminName2; + let state: string; + let country: string = geoname.countryCode; + const continent: string = geoname.continentCode; + const placeType = (postalCode ? 'P.PPL' : geoname.fcl + '.' + geoname.fcode); + + if (continent === 'AN') + country = 'ATA'; + + if (country && code2ToCode3[country]) + country = code2ToCode3[country]; + + if (country === 'USA') { + county = standardizeShortCountyName(county); + state = geoname.adminCode1; + } + else + state = geoname.adminName1; + + const names = processPlaceNames(city, county, state, country, continent, false, noTrace); + + if (!names) + continue; + + if ((postalCode || closeMatchForCity(targetCity, names.city) || closeMatchForCity(targetCity, names.variant)) && + closeMatchForState(targetState, state, country)) { + const location = new AtlasLocation(); + const population = toInt(geoname.population); + let rank = 0; + + if (placeType.startsWith('A.') || placeType.startsWith('P.')) { + ++rank; + + if (placeType.endsWith('PPLC')) + ++rank; + + if (population > 0) + rank += (population >= 1000000 ? 2 : 1); + } + + location.city = names.city; + location.county = names.county; + location.state = names.state; + location.country = names.country; + location.longCountry = names.longCountry; + location.flagCode = getFlagCode(names.country, names.state); + location.rank = rank; + location.placeType = placeType; + location.latitude = geoname.lat; + location.longitude = geoname.lng; + location.zone = geoname.timezone && geoname.timezone.timeZoneId; + location.zip = (postalCode ? geoname.postalcode : undefined); + location.variant = names.variant; + location.source = (postalCode ? 'GEOZ' : 'GEON'); + location.geonamesID = geoname.geonameId; + + if (!containsMatchingLocation(keyedPlaces, location)) { + keyedPlaces.set(makeLocationKey(location.city, location.state, location.country, keyedPlaces), location); + ++metrics.matchedCount; + } + } + } + } + else + metrics.rawCount = 0; + + metrics.retrievalTime = processMillis() - startTime; + + return keyedPlaces; +} diff --git a/server/app/getty-search.ts b/server/app/getty-search.ts new file mode 100644 index 0000000..1381a2b --- /dev/null +++ b/server/app/getty-search.ts @@ -0,0 +1,402 @@ +import { closeMatchForCity, closeMatchForState, containsMatchingLocation, fixRearrangedName, getCode3ForCountry, + getFlagCode, LocationMap, makeLocationKey, processPlaceNames } from './gazetteer'; +import { timedPromise } from './common'; +import { AtlasLocation } from './atlas-location'; +import { getTimeZone } from './timezones'; +import { toNumber, toInt, processMillis } from '@tubular/util'; +import { requestText } from 'by-request'; + +export interface GettyMetrics { + totalTime: number; + preliminaryTime: number; + retrievalTime: number; + matchedCount: number; + retrievedCount: number; + complete: boolean; + failedSyntax: string; +} + +const MAX_TIME_GETTY = 110; // seconds +const PREFERRED_RETRIEVAL_TIME_GETTY = 40; // seconds +const FAKE_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:98.0) Gecko/20100101 Firefox/98.0'; + +export async function gettySearch(targetCity: string, targetState: string, metrics: GettyMetrics, noTrace: boolean): Promise { + return timedPromise(gettySearchAux(targetCity, targetState, metrics, noTrace), MAX_TIME_GETTY * 1000, 'Getty search timed out'); +} + +async function gettySearchAux(targetCity: string, targetState: string, metrics: GettyMetrics, noTrace: boolean): Promise { + const startTime = processMillis(); + const keyedPlaces = await gettyPreliminarySearch(targetCity, targetState, metrics, noTrace); + const originalKeys = keyedPlaces.keys; + const itemCount = keyedPlaces.size; + const matches = new LocationMap(); + const retrievalStartTime = processMillis(); + let goodFormat: boolean; + let latitude = 0.0; + let location: AtlasLocation; + let longitude = 0.0; + let retrieved = 0; + let hasCoordinates = 0; + let $: string[]; + + for (let i = 0; i < originalKeys.length; ++i) { + let key = originalKeys[i]; + const url = 'http://www.getty.edu/vow/TGNFullDisplay?find=&place=&nation=&english=Y&subjectid=' + key; + const options = { headers: { 'User-Agent': FAKE_USER_AGENT, Referer: 'http://www.getty.edu/vow/TGNServlet' } }; + let lines: string[]; + + try { + lines = (await requestText(url, options)).split(/\r\n|\n|\r/); + } + catch (err) { + throw new Error('Getty secondary error: ' + err); + } + + let pending = false; + let gotLat = false; + let gotLong = false; + + goodFormat = false; + + for (const line of lines) { + if (($ = /ID: (\d+)<\/B>/.exec(line)) && key === $[1]) { + pending = true; + goodFormat = true; + ++retrieved; + } + else if (pending && ($ = /Lat:\s*([-.0-9]+).*decimal degrees { + let keyedPlaces = new LocationMap(); + const altKeyedPlaces = new LocationMap(); + let matchCount = 0; + let nextItem = 1; + let page = 0; + let theresMore = false; + let goodFormat: boolean; + + do { + ++page; + goodFormat = false; + + let altNames: string; + let asAlternate: boolean; + let city: string; + let continent: string; + let country: string; + let county: string; + let hierarchy: string; + let key: string; + let longCountry: string; + let longState: string; + let isMatch: boolean; + let placeType: string = null; + let stage: Stage; + let state: string; + let url: string; + let variant: string; + let vernacular: string; + let searchStr = targetCity.toLowerCase().replace(' ', '-') + '*'; + let $: string[]; + + searchStr = searchStr.replace(/^mt\b/, 'mount'); + + url = 'http://www.getty.edu/' + + 'vow/TGNServlet' + + '?nation=' + + '&english=Y' + + '&find=' + encodeURIComponent(searchStr).replace('*', '%2A') + + '&place=atoll%2C+cape%2C+city%2C+county%2C+dependent+state%2C+inhabited+place%2C+island%2C+mountain%2C+' + + 'nation%2C+neighborhood%2C+park%2C+peak%2C+province%2C+state%2C+suburb%2C+town%2C+township%2C+village'; + + if (page > 1) + url += '&prev_page=' + (page - 1); + + url += '&page=' + page; + + const options = { headers: { 'User-Agent': FAKE_USER_AGENT, Referer: 'http://www.getty.edu/research/tools/vocabularies/tgn/index.html' } }; + let lines: string[]; + + try { + lines = (await requestText(url, options)).split(/\r\n|\n|\r/); + } + catch (err) { + throw new Error('Getty preliminary error: ' + err); + } + + for (let i = 0; i < lines.length; ++i) { + let line = lines[i]; + + if (matchCount === 0 && /Your search has produced (no|too many) results\./i.test(line)) { + goodFormat = true; + + break; + } + else if (matchCount === 0 && /Your search has invalid syntax\./i.test(line)) { + goodFormat = true; // The Getty output format is good -- it's our input format that's bad. + + if (metrics != null) + metrics.failedSyntax = searchStr; + + break; + } + else if (matchCount === 0 && /Server Error/i.test(line)) { + throw new Error('Getty server error'); + } + else if (/global_next.gif/i.test(line)) { + theresMore = true; + } + else if (($ = /(\d+)\.  <\/B><\/SPAN><\/TD>/.exec(line)) && + toInt($[1]) === nextItem) { + ++nextItem; + + stage = Stage.LOOKING_FOR_ID_CODE; + city = undefined; + key = '0'; + hierarchy = undefined; + altNames = ''; + asAlternate = false; + vernacular = undefined; + + while (++i < lines.length) { + line = lines[i].trim(); + + if (stage === Stage.LOOKING_FOR_ID_CODE && ($ = //.exec(line))) { + key = $[1]; + stage = Stage.LOOKING_FOR_PLACE_NAME; + } + else if (stage === Stage.LOOKING_FOR_PLACE_NAME && ($ = /(.+)(.+)<\/B><\/A> \.\.\.\.\.\.\.\.\.\. \((.+)\)/.exec(line))) { + city = $[2]; + placeType = $[3]; + stage = Stage.LOOKING_FOR_HIERARCHY; + } + else if (stage === Stage.LOOKING_FOR_HIERARCHY && ($ = /\((.+)\) \[\d+]/.exec(line))) { + hierarchy = $[1]; + // It sucks having commas as part of real data which is itself delimited by commas! (Foobar, Republic of). + hierarchy = hierarchy.replace(/(, )(.[^,]+?), ([^,]+? (ar-|da|de|du|d'|La|la|Le|le|Las|las|Les|les|Los|los|of|The|the|van))(,|$)/g, '$1$3 2$5'); + + if (/Indonesia/.test(hierarchy)) + hierarchy = hierarchy.replace(/(, Daerah Tingkat I)|(, Pulau)/, ''); + + stage = Stage.LOOKING_FOR_EXTRAS_OR_END; + } + else if (stage === Stage.LOOKING_FOR_EXTRAS_OR_END) { + if (!vernacular && ($ = /Vernacular: (.+?)(<|$)/.exec(line))) { + vernacular = $[1].trim(); + } + else if (($ = /(\D.+)<\/B>
/.exec(line))) { + if (altNames) + altNames += ';'; + + altNames += $[1]; + } + else if (($ = /(\d+)\.  <\/B><\/SPAN><\/TD>/.exec(line)) && + toInt($[1]) === nextItem) { + --i; // We'll want to parse this same line again as the first line of the next city. + stage = Stage.PLACE_HAS_BEEN_PARSED; + break; + } + else if (/<\/TABLE>/.test(line)) { + stage = Stage.PLACE_HAS_BEEN_PARSED; + break; + } + } + } + + if (stage === Stage.PLACE_HAS_BEEN_PARSED) { + goodFormat = true; + isMatch = false; + continent = undefined; + state = undefined; + county = undefined; + + if (($ = /(.+?), (.+?), (.+?), (.+?), (.+?)(,|$)/.exec(hierarchy))) { + continent = $[2]; + country = $[3]; + state = $[4]; + county = $[5]; + } + else if (($ = /(.+?), (.+?), (.+?), (.+?)(,|$)/.exec(hierarchy))) { + continent = $[2]; + country = $[3]; + state = $[4]; + } + else if (($ = /(.+?), (.+?), (.+?)(,|$)/.exec(hierarchy))) { + continent = $[2]; + country = $[3]; + } + else if (($ = /(.+?), (.+?)(,|$)/.exec(hierarchy))) { + continent = $[2]; + + if (/Antarctica/i.test(hierarchy)) + country = 'ATA'; + else { + const possibleCountry = fixRearrangedName(city).name; + + if (getCode3ForCountry(possibleCountry)) { + city = possibleCountry; + country = possibleCountry; + } + else + country = undefined; + } + } + else + country = city; + + const names = processPlaceNames(city, county, state, country, continent, true, noTrace); + + if (!names) + continue; + + city = names.city; + variant = names.variant; + county = names.county; + state = names.state; + longState = names.longState; + country = names.country; + longCountry = names.longCountry; + + if (placeType === 'nation' || placeType === 'dependent state') { + city = longCountry; + + if (closeMatchForCity(targetCity, country) || closeMatchForCity(targetCity, longCountry)) + isMatch = true; + } + else if (placeType === 'state' || placeType === 'province') { + city = longState; + + if (closeMatchForCity(targetCity, state) || closeMatchForCity(targetCity, longState)) + isMatch = true; + } + else { + if (closeMatchForCity(targetCity, city) || closeMatchForCity(targetCity, variant)) + isMatch = true; + else if (closeMatchForCity(targetCity, vernacular)) { + city = vernacular; + isMatch = true; + } + else if (altNames) { + for (const altName of altNames.split(';')) { + if (closeMatchForCity(targetCity, altName)) { + city = altName; + isMatch = true; + asAlternate = true; + + break; + } + } + } + } + + if (isMatch && closeMatchForState(targetState, state, country)) { + if (placeType === 'cape') + placeType = 'T.CAPE'; + else if (placeType === 'park') + placeType = 'L.PRK'; + else if (placeType === 'peak') + placeType = 'T.PK'; + else if (placeType === 'county') + placeType = 'A.ADM2'; + else if (placeType === 'atoll' || placeType === 'island') + placeType = 'T.ISL'; + else if (placeType === 'mountain') + placeType = 'T.MT'; + else if (placeType === 'dependent state' || placeType === 'nation') + placeType = 'A.ADM0'; + else if (placeType === 'province' || placeType === 'state') + placeType = 'A.ADM1'; + else + placeType = 'P.PPL'; + + const location = new AtlasLocation(); + + location.city = city; + location.county = county; + location.state = state; + location.country = country; + location.longCountry = longCountry; + location.flagCode = getFlagCode(country, state); + location.placeType = placeType; + location.variant = variant; + location.source = 'GTTY'; + location.rank = 0; // TODO: Can be improved? + + if (!containsMatchingLocation(keyedPlaces, location) && + !containsMatchingLocation(altKeyedPlaces, location)) { + ++matchCount; + location.zone = getTimeZone(location); + + if (asAlternate) + altKeyedPlaces.set(key, location); + else + keyedPlaces.set(key, location); + } + } + } + } + } + + // Never read more than 6 pages, and don't keep going if at least + // 50 matches have been found. If the match rate is high in the first + // two of pages or more, don't go any further than that. + } while (theresMore && page < 6 && matchCount < 50 && !(page > 1 && matchCount >= page * 12)); + + if (matchCount === 0 && !goodFormat) + throw new Error('Failed to parse Getty data.'); + + if (keyedPlaces.size === 0) + keyedPlaces = altKeyedPlaces; + else if (keyedPlaces.size + altKeyedPlaces.size < 25) + altKeyedPlaces.forEach((value, key) => keyedPlaces.set(key, value)); + + return keyedPlaces; +} diff --git a/server/app/ip-to-location.ts b/server/app/ip-to-location.ts new file mode 100644 index 0000000..aa75b38 --- /dev/null +++ b/server/app/ip-to-location.ts @@ -0,0 +1,73 @@ +import { Request, Response, Router } from 'express'; +import http from 'http'; +import querystring from 'querystring'; +import requestIp from 'request-ip'; +import { notFound, notFoundForEverythingElse } from './common'; +import { processMillis } from '@tubular/util'; + +export const router = Router(); + +const MAX_PER_MINUTE = 140; +const times: number[] = []; + +router.get('/json/*', (req: Request, res: Response) => { + const [url, paramStr] = req.url.split('?'); + const params = querystring.parse(paramStr); + const $ = /^\/json(\/(.*))?$/.exec(url); + + if ($) { + const now = processMillis(); + + if (times.length === MAX_PER_MINUTE && times[0] > now - 60000) { + if (params.callback) + res.jsonp({ message: 'busy', status: 'fail' }); + else + res.send({ message: 'busy', status: 'fail' }); + } + else { + times.push(now); + + if (times.length > MAX_PER_MINUTE) { + times.shift(); + } + + let address = $[2]; + + if (!address) { + address = requestIp.getClientIp(req); + + if (address && /:/.test(address)) { + address = encodeURIComponent(address); + } + } + + if (!address) { + address = ''; + } + + const options = { + hostname: 'ip-api.com', + port: 80, + path: '/json/' + address + (paramStr ? '?' + paramStr : ''), + method: req.method, + headers: req.headers + }; + + const proxy = http.request(options, function (res2) { + res.writeHead(res2.statusCode, res2.headers); + res2.pipe(res, { + end: true + }); + }); + + req.pipe(proxy, { + end: true + }); + } + } + else { + notFound(res); + } +}); + +notFoundForEverythingElse(router); diff --git a/server/app/log-access.ts b/server/app/log-access.ts new file mode 100644 index 0000000..c3c4fb8 --- /dev/null +++ b/server/app/log-access.ts @@ -0,0 +1,36 @@ +import { Request, Response, Router } from 'express'; +import auth from 'basic-auth'; +import { existsSync } from 'fs'; +import { join as pathJoin } from 'path'; +import { asyncHandler, getFileContents } from './common'; + +export const router = Router(); + +router.get('/', asyncHandler(async (req: Request, res: Response) => { + const user = auth(req); + + if (!user || !process.env.DB_PWD || user.name !== 'admin' || user.pass !== process.env.DB_PWD) { + res.set('WWW-Authenticate', 'Basic realm="skyviewcafe.com"'); + res.status(401).send('Not authorized'); + return; + } + + res.set('Content-Type', 'text/plain'); + + if (process.env.SVC_API_LOG) { + const path = pathJoin(__dirname, process.env.SVC_API_LOG); + + if (existsSync(path)) { + try { + res.send(await getFileContents(path, 'utf8')); + } + catch (err) { + res.send('Error reading log file.'); + } + } + else + res.send('Log file not present.'); + } + else + res.send('Log file not defined.'); +})); diff --git a/server/app/map-class.ts b/server/app/map-class.ts new file mode 100644 index 0000000..599ea14 --- /dev/null +++ b/server/app/map-class.ts @@ -0,0 +1,42 @@ +export class MapClass { + map = new Map(); + + clear(): void { + this.map.clear(); + } + + delete(key: T): boolean { + return this.map.delete(key); + } + + get entries(): [T, U][] { + return Array.from(this.map.entries()); + } + + forEach(callback: (value: U, key?: T, map?: Map) => void): void { + this.map.forEach(callback); + } + + get(key: T): U { + return this.map.get(key); + } + + has(key: T): boolean { + return this.map.has(key); + } + + get keys(): T[] { + return Array.from(this.map.keys()); + } + + set(key: T, value: U): MapClass { + this.map.set(key, value); + return this; + } + + get size(): number { return this.map.size; } + + get values(): U[] { + return Array.from(this.map.values()); + } +} diff --git a/server/app/maps-api.ts b/server/app/maps-api.ts new file mode 100644 index 0000000..3c11e17 --- /dev/null +++ b/server/app/maps-api.ts @@ -0,0 +1,170 @@ +import { Request, Response, Router } from 'express'; +import https from 'https'; +// eslint-disable-next-line n/no-deprecated-api +import { parse as parseUrl } from 'url'; +import { asyncHandler, escapeRegExp, getRemoteAddress, notFound, notFoundForEverythingElse } from './common'; +import { getPublicIp } from './public-ip'; +import { requestText } from 'by-request'; +import { processMillis } from '@tubular/util'; + +export const router = Router(); + +const GOOGLE_API_KEY = process.env.GOOGLE_API_KEY; +let fakeApiKey = GOOGLE_API_KEY; +const scramble = 'LX-IlYd0ZRQsij6eCO3cxFhk5bpNMq1a2SrPoV_9Et7mAywGfBnuJvWzHTg8DKU4'; + +if (GOOGLE_API_KEY && GOOGLE_API_KEY.length > 3) { + fakeApiKey = GOOGLE_API_KEY.substr(0, 3); + + for (let i = 3; i < GOOGLE_API_KEY.length; ++i) { + const cc = GOOGLE_API_KEY.charCodeAt(i); + let index; + + if (cc === 45) + index = 62; + else if (cc === 95) + index = 63; + else if (cc < 65) + index = cc + 4; + else if (cc < 97) + index = cc - 64; + else + index = cc - 71; + + fakeApiKey += scramble.charAt(index); + } +} + +const ADDED_CLIENT_MAPS_SCRIPT = ` +function setSvcMapsApiKey(k) { + var s = '${scramble}'; + window.svcOrigKey = k; + window.svcModKey = k.substr(0, 3); + + for (var i = 3; i < k.length; ++i) { + var c = k.charAt(i); + var n = s.indexOf(c); + + if (n >= 0) { + if (n < 26) + c = String.fromCharCode(n + 64); + else if (n < 52) + c = String.fromCharCode(n + 71); + else if (n < 62) + c = String.fromCharCode(n - 4); + else if (n === 62) + c = '-'; + else + c = '_'; + } + + window.svcModKey += c; + } + + return window.svcModKey; +}`.replace(/\n+/g, ' ').replace(/ +/g, ' ').replace(/(\W) (?=\w)/g, '$1').replace(/(.) (?=\W)/g, '$1').trim(); + +const authorizedIps: Record = {}; +const ALLOWED_IP_AGE = 7200000; // two hours +const MAX_AUTHORIZATION_DELAY = 30000; // half minute + +router.get('/script/', asyncHandler(async (req: Request, res: Response) => { + const url = `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_API_KEY}&callback=initGoogleMaps`; + let script = await requestText(url); + + script = script.replace(new RegExp(`['"]${GOOGLE_API_KEY}['"]`, 'g'), `setSvcMapsApiKey('${fakeApiKey}')`).trim(); + script += '\n' + ADDED_CLIENT_MAPS_SCRIPT; + + res.set('Content-Type', 'text/javascript'); + res.send(script); +})); + +router.get('/proxy*', asyncHandler(async (req: Request, res: Response) => { + if (!(await isAuthorized(req))) { + res.status(401).send('Not authorized'); + return; + } + + let url = req.originalUrl; + const $ = /^\/maps\/proxy(.*)$/.exec(url); + + if ($) + url = `https://maps.googleapis.com${$[1]}`; + else { + notFound(res); + return; + } + + maintainAuthorizedIps(); + + url = url.replace(new RegExp(escapeRegExp(fakeApiKey), 'g'), GOOGLE_API_KEY); + + const options = parseUrl(url); + const publicIp = await getPublicIp(); + const referer = `https://${publicIp}/`; + + (options as any).headers = { + 'user-agent': req.headers['user-agent'], + referer + }; + + const proxy = https.request(options, function (res2) { + res.writeHead(res2.statusCode, res2.headers); + res2.pipe(res, { + end: true + }); + }); + + req.pipe(proxy, { + end: true + }); +})); + +router.get('/ping/', (req: Request, res: Response) => { + const remoteAddr = getRemoteAddress(req); + + if (remoteAddr) + authorizedIps[remoteAddr] = processMillis(); + + if (req.query.callback) + res.jsonp('ok'); + else + res.json('ok'); + + maintainAuthorizedIps(); +}); + +async function isAuthorized(req: Request): Promise { + const remoteAddr = getRemoteAddress(req); + + if (authorizedIps[remoteAddr]) + return Promise.resolve(true); + + return new Promise(resolve => { + const start = processMillis(); + const checkInterval = setInterval(() => { + if (authorizedIps[remoteAddr]) { + clearInterval(checkInterval); + resolve(true); + } + else if (processMillis() > start + MAX_AUTHORIZATION_DELAY) { + clearInterval(checkInterval); + resolve(false); + } + }, 50); + }); +} + +function maintainAuthorizedIps(): void { + const now = processMillis(); + const ips = Object.keys(authorizedIps); + + ips.forEach(ip => { + const time = authorizedIps[ip]; + + if (now > time + ALLOWED_IP_AGE) + delete authorizedIps[ip]; + }); +} + +notFoundForEverythingElse(router); diff --git a/server/app/mysql-await-async.ts b/server/app/mysql-await-async.ts new file mode 100644 index 0000000..9f04cca --- /dev/null +++ b/server/app/mysql-await-async.ts @@ -0,0 +1,143 @@ +/* eslint-disable n/no-deprecated-api */ +// noinspection JSDeprecatedSymbols + +import mysql, { + FieldInfo, MysqlError, PoolConnection as _PoolConnection, QueryOptions, Pool as _Pool, PoolConfig } from 'mysql'; +import { parse as parseUrl } from 'url'; + +export interface FullQueryResults { + err: MysqlError | null; + results: any; + fields: FieldInfo[]; +} + +export class Pool { + private _pool: _Pool; + private readonly dbName: string; + + constructor(config: PoolConfig | string, private consoleLogErrors = true) { + this._pool = mysql.createPool(config); + + if (typeof config === 'string') + this.dbName = parseUrl(config).path; + else + this.dbName = config.database; + } + + getConnection(): Promise { + return new Promise((resolve, reject) => { + this._pool.getConnection((err, connection) => { + if (err) { + this.logError(err); + reject(err); + } + else + resolve(new PoolConnection(connection, this)); + }); + }); + } + + on(ev: 'acquire' | 'connection' | 'release', callback: (connection: PoolConnection) => void): Pool; + on(ev: 'error', callback: (err: MysqlError) => void): Pool; + on(ev: 'enqueue', callback: (err?: MysqlError) => void): Pool; + on(ev: string, callback: (...args: any[]) => void): Pool { + this._pool.on(ev, (...args: any[]) => { + if (ev === 'error') + this.logError(args[0]); + + if (args[0] && /^(acquire|connection|release)$/.test(ev)) + callback(new PoolConnection(args[0])); + else + // eslint-disable-next-line n/no-callback-literal + callback(...args); + }); + + return this; + } + + query(sqlStringOrOptions: string | QueryOptions, values?: any): Promise { + return new Promise(resolve => { + const args = typeof sqlStringOrOptions === 'string' ? + [sqlStringOrOptions, values] : [sqlStringOrOptions]; + + (this._pool.query as any)(...args, (err: MysqlError, results: any, fields: FieldInfo[]) => { + this.logError(err); + resolve({ err, results, fields }); + }); + }); + } + + queryResults(sqlStringOrOptions: string | QueryOptions, values?: any): Promise { + return new Promise((resolve, reject) => { + const args = typeof sqlStringOrOptions === 'string' ? + [sqlStringOrOptions, values] : [sqlStringOrOptions]; + + (this._pool.query as any)(...args, (err: MysqlError, results: any) => { + if (err) { + this.logError(err); + reject(err); + } + else + resolve(results); + }); + }); + } + + logError(err: MysqlError): void { + if (err && this.consoleLogErrors) { + const name = this.dbName ? ` "${this.dbName}"` : ''; + + if (err.code === 'PROTOCOL_CONNECTION_LOST') + console.error(`Database${name} connection was closed.`); + else if (err.code === 'ER_CON_COUNT_ERROR') + console.error(`Database${name} has too many connections.`); + else if (err.code === 'ECONNREFUSED') + console.error(`Database${name} connection was refused.`); + else if (err.code === 'ENOTFOUND') + console.error(`Address ${(err as any).host} for database${name} not found.`); + else + console.error(`Database${name} error: ${err.code}`); + } + } +} + +export class PoolConnection { + constructor(private connection: _PoolConnection, private parent?: Pool) { } + + query(sqlStringOrOptions: string | QueryOptions, values?: any): Promise { + return new Promise(resolve => { + const args = typeof sqlStringOrOptions === 'string' ? + [sqlStringOrOptions, values] : [sqlStringOrOptions]; + + (this.connection.query as any)(...args, (err: MysqlError, results: any, fields: FieldInfo[]) => { + this.logError(err); + resolve({ err, results, fields }); + }); + }); + } + + queryResults(sqlStringOrOptions: string | QueryOptions, values?: any): Promise { + return new Promise((resolve, reject) => { + const args = typeof sqlStringOrOptions === 'string' ? + [sqlStringOrOptions, values] : [sqlStringOrOptions]; + + (this.connection.query as any)(...args, (err: MysqlError, results: any) => { + if (err) { + this.logError(err); + reject(err); + } + else + resolve(results); + }); + }); + } + + release(): void { + this.connection.release(); + } + + private logError(err: MysqlError): void { + if (err && this.parent) + this.parent.logError(err); + } +} diff --git a/server/app/public-ip.ts b/server/app/public-ip.ts new file mode 100644 index 0000000..eb3060b --- /dev/null +++ b/server/app/public-ip.ts @@ -0,0 +1,25 @@ +import * as publicIp from 'public-ip'; +import { svcApiConsole } from './svc-api-logger'; +import { processMillis } from '@tubular/util'; + +const REFRESH_TIME = 3600000; // One hour + +let lastIp: string; +let lastIpTime = -REFRESH_TIME; + +export async function getPublicIp(): Promise { + const now = processMillis(); + + if (!lastIp || now >= lastIpTime + REFRESH_TIME) { + const currentIp = await publicIp.v4(); + + if (lastIp !== currentIp) { + lastIp = currentIp; + svcApiConsole.info('Public IP is ' + lastIp); + } + + lastIpTime = now; + } + + return lastIp; +} diff --git a/server/app/search-result.ts b/server/app/search-result.ts new file mode 100644 index 0000000..7ebacb1 --- /dev/null +++ b/server/app/search-result.ts @@ -0,0 +1,74 @@ +import { AtlasLocation } from './atlas-location'; +import { formatVariablePrecision } from './common'; + +export class SearchResult { + originalSearch: string; + normalizedSearch: string; + time: number; + error: string; + warning: string; + info: string; + limitReached: boolean; + matches: AtlasLocation[]; + + constructor(originalSearch?: string, normalizedSearch?: string) { + this.originalSearch = originalSearch; + this.normalizedSearch = normalizedSearch; + } + + get count(): number { + return this.matches ? this.matches.length : 0; + } + + set count(newValue: number) { /* Allow but ignore so this can be set via JSON without causing an error. */ } + + appendInfoLine(line: string): void { + if (this.info) + this.info += '\n' + line; + else + this.info = line; + } + + appendWarningLine(line: string): void { + if (this.warning) + this.warning += '\n' + line; + else + this.warning = line; + } + + toJSON(): any { + const copy: any = {}; + + Object.assign(copy, this); + copy.count = this.count; + + return copy; + } + + toPlainText(): string { + const text: string[] = []; + + text.push(`originalSearch: ${this.originalSearch}`); + text.push(`normalizedSearch: ${this.normalizedSearch}`); + text.push(`time: ${formatVariablePrecision(this.time / 1000)}s`); + + if (this.error) + text.push(`error: ${this.error}`); + else { + if (this.warning) + text.push(`warning: ${this.warning.replace('\n', '\u23CE\n')}`); + + if (this.info) + text.push(`info: ${this.info.replace('\n', '\u23CE\n')}`); + + text.push(`count: ${this.count}` + (this.limitReached ? ' (limit reached)' : '')); + + if (this.matches) + this.matches.forEach(match => text.push(match.toString())); + } + + text.push(''); + + return text.join('\n'); + } +} diff --git a/server/app/states.ts b/server/app/states.ts new file mode 100644 index 0000000..683432f --- /dev/null +++ b/server/app/states.ts @@ -0,0 +1,27 @@ +import { Request, Response, Router } from 'express'; +import { getStatesProvincesAndCountries } from './gazetteer'; +import { toBoolean } from '@tubular/util'; + +export const router = Router(); + +router.get('/', (req: Request, res: Response) => { + const plainText = toBoolean(req.query.pt, false, true); + const response = ['']; + + response.push(...getStatesProvincesAndCountries().map(nameAndCode => { + if (nameAndCode) + return `${nameAndCode.name} - ${nameAndCode.code}`; + else + return ' ---'; + })); + + if (plainText) { + res.set('Content-Type', 'text/plain'); + response.push(''); + res.send(response.join('\n')); + } + else if (req.query.callback) + res.jsonp(response); + else + res.send(response); +}); diff --git a/server/app/svc-api-logger.ts b/server/app/svc-api-logger.ts new file mode 100644 index 0000000..b659d8c --- /dev/null +++ b/server/app/svc-api-logger.ts @@ -0,0 +1,193 @@ +import rfs from 'rotating-file-stream'; +import { join as pathJoin } from 'path'; +import stream, { Writable } from 'stream'; +import fs, { WriteStream } from 'fs'; +import { Request, Response } from 'express'; +import * as util from 'util'; +import { formatDateTime, zeroPad } from '@tubular/util'; + +export let svcApiLogStream: Writable | WriteStream = process.stdout; + +const INTERVAL_DAYS = 7; +const MAX_FILES = 10; + +if (process.env.SVC_API_LOG) { + const options: any = { + interval: INTERVAL_DAYS + 'd', + maxFiles: MAX_FILES, + maxSize: '256K', + rotationTime: true + }; + const fullLogPath = pathJoin(__dirname, process.env.SVC_API_LOG); + const intervalMillis = INTERVAL_DAYS * 86400000; + let logPath: string; + let logFile = fullLogPath; + let ext = ''; + let separator = ''; + let $ = /(.*)([/\\])(.+)/.exec(logFile); + + if ($) { + logPath = $[1]; + separator = $[2]; + logFile = $[3]; + + if (logPath) + options.path = logPath; + } + + let logCreation = fs.existsSync(logPath) && fs.statSync(logPath).mtimeMs; + + if (($ = /(.*)(\..*)/.exec(logFile))) { + logFile = $[1]; + ext = $[2]; + } + + const fileName = (time: Date, index: number): string => { + if (!time) + return logFile + ext; + else { + const date = new Date(+time - time.getTimezoneOffset() * 60000); + + return `${logFile}-${date.toISOString().substr(0, 10)}_${zeroPad(index, 2)}${ext}`; + } + }; + + let fileStream = (rfs as any)(fileName, options); + + svcApiLogStream = new stream.Writable(); + svcApiLogStream._write = async (chunk: any, encoding: string, done: (error?: Error) => void): Promise => { + // rotating-file-stream isn't doing as complete a job as I'd hope for in rotating file names + // and cleaning up files, so the code below takes over some of that work. + const now = Date.now(); + let checkMaxFiles = false; + + if (logCreation && now > logCreation + intervalMillis) { + const nowDate = new Date(now); + let index = 0; + let datedFilePath: string; + + do { + datedFilePath = logPath + separator + fileName(nowDate, index++); + } while (fs.existsSync(datedFilePath)); + + if (fileStream.close) + fileStream.close(); + else if (fileStream.end) { + await new Promise(resolve => { + fileStream.end(() => resolve()); + }); + } + + logCreation = now; + fs.renameSync(fullLogPath, datedFilePath); + fileStream = (rfs as any)(fileName, options); + checkMaxFiles = true; + } + + let output: any; + + if (chunk instanceof Buffer) { + try { + output = chunk.toString((encoding === 'buffer' ? 'utf8' : encoding) as any); + } + catch (err) { + // Unknown encoding? + output = chunk.toString('utf8'); + } + } + else + output = chunk.toString(); + + try { + fileStream.write(output, () => { + if (checkMaxFiles) { + const files = fs.readdirSync(logPath).sort().filter(name => name.startsWith(logFile + '-')); + + while (files.length > MAX_FILES - 1) { + fs.unlinkSync(logPath + separator + files[0]); + files.splice(0, 1); + } + } + }); + } + catch (err) { /* ignore errors writing to log file */ } + + process.stdout.write(output); + done(); + }; +} + +// Only log requests that are for SVC API calls, not for static files pulled from the "public" folder. +export function svcApiSkipFilter(req: Request, _res: Response): boolean { + return !/^\/?(atlas|atlasdb|ip|maps|states|timeservices|zoneloc)(\/|\?|$)/.test(req.baseUrl) || + (req.baseUrl === '/maps' && !/^\/ping(\/|$)/.test(req.url)); +} + +function argsToString(...args: any[]): string { + let result = ''; + + if (args.length > 0) + result += ': ' + util.format(args[0], ...(args.splice(1))); + + return result + '\n'; +} + +export function getLogDate(): string { + return formatDateTime(new Date()) + ' - '; +} + +class SvcApiConsole { + assert(assertion: boolean, ...args: any[]): void { + if (!assertion) { + this.error(...args); + this.trace(); + } + } + + // noinspection JSMethodCanBeStatic + debug(...args: any): void { + svcApiLogStream.write(getLogDate() + 'DEBUG' + argsToString(...args)); + } + + // noinspection JSMethodCanBeStatic + error(...args: any): void { + svcApiLogStream.write(getLogDate() + 'ERROR' + argsToString(...args)); + } + + // noinspection JSMethodCanBeStatic + info(...args: any): void { + svcApiLogStream.write(getLogDate() + 'INFO' + argsToString(...args)); + } + + // noinspection JSMethodCanBeStatic + log(...args: any): void { + svcApiLogStream.write(getLogDate() + 'LOG' + argsToString(...args)); + } + + // noinspection JSMethodCanBeStatic + trace(): void { + let stack = ''; + + try { + // noinspection ExceptionCaughtLocallyJS + throw new Error(''); + } + catch (err) { + stack = err.stack || ''; + } + + const lines = stack.split('\n'); + + svcApiLogStream.write(getLogDate() + 'TRACE:\n' + lines.splice(2).join('\n')); + } + + // noinspection JSMethodCanBeStatic + warn(...args: any): void { + svcApiLogStream.write(getLogDate() + 'WARN' + argsToString(...args)); + } +} + +export const svcApiConsole = new SvcApiConsole(); + +if (!(process.hrtime as any).bigint) + svcApiConsole.warn('Environment does not support process.hrtime.bigint'); diff --git a/server/app/timezones.ts b/server/app/timezones.ts new file mode 100644 index 0000000..f0e9ae4 --- /dev/null +++ b/server/app/timezones.ts @@ -0,0 +1,46 @@ +import { pool } from './atlas_database'; +import { AtlasLocation } from './atlas-location'; +import { simplify } from './gazetteer'; + +const zoneLookup: Record = {}; + +export async function initTimezones(): Promise { + const results: any[] = await pool.queryResults('SELECT location, zones FROM zone_lookup WHERE 1'); + + results.forEach(result => { + zoneLookup[result.location] = result.zones.split(','); + }); +} + +export function getTimeZone(location: AtlasLocation): string { + const county = location.county; + const state = location.state; + const country = location.country; + let key = simplify(country); + let zones = zoneLookup[key]; + let zones2: string[]; + let zone; + + if ((!zones || zones.length > 1) && state) { + key += ':' + simplify(state); + zones2 = zoneLookup[key]; + zones = (zones2 || zones); + + if ((!zones || zones.length > 1) && county) { + key += ':' + simplify(county); + zones2 = zoneLookup[key]; + zones = (zones2 || zones); + } + } + + if (!zones || zones.length === 0) + zone = undefined; + else { + zone = zones[0]; + + if (zones.length > 1) + zone += '?'; + } + + return zone; +} diff --git a/server/app/zone-for-location.ts b/server/app/zone-for-location.ts new file mode 100644 index 0000000..61cbfe8 --- /dev/null +++ b/server/app/zone-for-location.ts @@ -0,0 +1,105 @@ +import { Request, Response, Router } from 'express'; +import { processMillis, toBoolean, toNumber } from '@tubular/util'; +import { asyncHandler } from './common'; +import { requestJson } from 'by-request'; +import { pool } from './atlas_database'; +import { PoolConnection } from './mysql-await-async'; +import { Timezone } from '@tubular/time'; + +export const router = Router(); + +export interface TzInfo { + country?: string; + dstOffset?: number; + errorMessage?: string; + fromDb?: boolean; + rawOffset?: number; + status?: string; + timeZoneId?: string; + timeZoneName?: string; +} + +export async function getTimezoneForLocation(lat: number, lon: number, time = 0): Promise { + if (time === 0) + time = Math.floor(processMillis() / 1000); + + let connection: PoolConnection; + + try { + connection = await pool.getConnection(); + + zoneLoop: + for (const span of [0.05, 0.1, 0.25, 0.5]) { + const query = 'SELECT time_zone, country FROM atlas2 WHERE latitude >= ? AND latitude <= ? AND longitude >= ? AND longitude <= ?'; + const results = (await connection.queryResults(query, [lat - span, lat + span, lon - span, lon + span])) || []; + let timeZoneId: string; + let country: string; + + for (const result of results) { + if (result.time_zone) { + if (!timeZoneId) + timeZoneId = result.time_zone; + else if (timeZoneId !== result.time_zone) + break zoneLoop; + + if (!country) + country = result.country; + else if (country !== result.country) + break zoneLoop; + } + } + + if (timeZoneId) { + connection.release(); + const zone = Timezone.getTimezone(timeZoneId); + + return { + timeZoneId, + country, + dstOffset: zone.dstOffset, + rawOffset: zone.utcOffset, + status: 'OK', + fromDb: true + }; + } + } + } + catch { + if (connection) { + try { + connection.release(); + } + catch {} + } + } + + const key = encodeURIComponent(process.env.GOOGLE_API_KEY); + const url = `https://maps.googleapis.com/maps/api/timezone/json?location=${lat},${lon}×tamp=${time}&key=${key}`; + let data: TzInfo; + + try { + data = await requestJson(url); + } + catch (err) { + data = { status: 'ERROR', errorMessage: err.toString() }; + } + + return data; +} + +router.get('/', asyncHandler(async (req: Request, res: Response) => { + const lat = toNumber(req.query.lat); + const lon = toNumber(req.query.lon); + const time = toNumber(req.query.timestamp); + const plainText = toBoolean(req.query.pt, false, true); + const data = await getTimezoneForLocation(lat, lon, time); + + if (plainText) { + res.set('Content-Type', 'text/plain'); + res.send(JSON.stringify(data)); + } + else if (req.query.callback) + res.jsonp(data); + else + res.send(data); +})); diff --git a/server/package-lock.json b/server/package-lock.json new file mode 100644 index 0000000..19ce20e --- /dev/null +++ b/server/package-lock.json @@ -0,0 +1,8328 @@ +{ + "name": "svc-api", + "version": "1.9.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "svc-api", + "version": "1.9.0", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@tubular/math": "^3.1.0", + "@tubular/time": "^3.8.1", + "@tubular/util": "^4.8.1", + "basic-auth": "^2.0.1", + "by-request": "^1.3.3", + "dotenv": "^16.0.0", + "express": "^4.17.3", + "follow-redirects": "^1.14.9", + "html-entities": "^2.3.3", + "iconv-lite": "^0.6.3", + "lodash": "^4.17.21", + "morgan": "^1.10.0", + "mysql": "^2.18.1", + "public-ip": "^4.0.4", + "request-ip": "^2.1.3", + "rotating-file-stream": "^1.4.6", + "serve-index": "^1.9.1", + "unidecode-plus": "^1.0.4" + }, + "devDependencies": { + "@types/basic-auth": "^1.1.3", + "@types/express": "^4.17.13", + "@types/follow-redirects": "^1.14.1", + "@types/html-entities": "^1.3.4", + "@types/iconv-lite": "0.0.1", + "@types/lodash": "^4.14.181", + "@types/morgan": "^1.9.3", + "@types/mysql": "^2.15.21", + "@types/request-ip": "0.0.37", + "@types/serve-index": "^1.9.1", + "@typescript-eslint/eslint-plugin": "^5.23.0", + "@typescript-eslint/parser": "^5.23.0", + "eslint": "^8.15.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-chai-friendly": "^0.7.2", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jasmine": "^4.1.3", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.0.0", + "patch-package": "^6.4.7", + "ts-node-dev": "^1.1.8", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.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/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, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "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": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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/@eslint/eslintrc": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", + "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.9.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" + } + }, + "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 + }, + "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, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "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 + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", + "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==" + }, + "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, + "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, + "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, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@tubular/math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@tubular/math/-/math-3.1.0.tgz", + "integrity": "sha512-a7loxb8zHLxhq3mMSZbro2JNMxR2Vf8DoRy762RNCUKx3Ifd/pB024MVKsDF/5CVywdS5SvhavVtLtmpMRkmPQ==", + "engines": { + "node": ">=10.24.1" + } + }, + "node_modules/@tubular/time": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@tubular/time/-/time-3.8.1.tgz", + "integrity": "sha512-/3BVk58gG77FG7IklBvsUF8/sTg3JTsZHbYGYAgi9Y/qpZnGvRwJOOmS0TLRzfGr4D8XMr282PHXnec77rniYQ==", + "dependencies": { + "@tubular/math": "^3.1.0", + "@tubular/util": "^4.4.0" + }, + "engines": { + "node": ">=10.24.1" + }, + "optionalDependencies": { + "by-request": "^1.2.7", + "json-z": "^3.3.2" + } + }, + "node_modules/@tubular/util": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@tubular/util/-/util-4.8.1.tgz", + "integrity": "sha512-31q8NbItdjuPMDmm1Z6+9Il+fgRTV1/RxXChBCGGtTqFfAJl8pFmPc6Zpqo3ShOOyZsuIH+B0grJo7ie3KLH0Q==", + "engines": { + "node": ">=10.24.1" + } + }, + "node_modules/@types/basic-auth": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/basic-auth/-/basic-auth-1.1.3.tgz", + "integrity": "sha512-W3rv6J0IGlxqgE2eQ2pTb0gBjaGtejQpJ6uaCjz3UQ65+TFTPC5/lAE+POfx1YLdjtxvejJzsIAfd3MxWiVmfg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/follow-redirects": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@types/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-THBEFwqsLuU/K62B5JRwab9NW97cFmL4Iy34NTMX0bMycQVzq2q7PKOkhfivIwxdpa/J72RppgC42vCHfwKJ0Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/html-entities": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/html-entities/-/html-entities-1.3.4.tgz", + "integrity": "sha512-Ut62LV90H9tgXwyhmfR8U6yCw/6xeo26IlsbAJJfqPomaqDN2zoLb2Z+cbmy5AycJFhwNJDdH0zqjQp7Ox/eXg==", + "deprecated": "This is a stub types definition. html-entities provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "html-entities": "*" + } + }, + "node_modules/@types/iconv-lite": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@types/iconv-lite/-/iconv-lite-0.0.1.tgz", + "integrity": "sha1-qjuL2ivlErGuCgV7lC6GnDcKVWk=", + "deprecated": "This is a stub types definition for iconv-lite (https://github.com/ashtuchkin/iconv-lite). iconv-lite provides its own type definitions, so you don\\'t need @types/iconv-lite installed!", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.14.181", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", + "integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/morgan": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.3.tgz", + "integrity": "sha512-BiLcfVqGBZCyNCnCH3F4o2GmDLrpy0HeBVnNlyZG4fo88ZiE9SoiBe3C+2ezuwbjlEyT+PDZ17//TAlRxAn75Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/mysql": { + "version": "2.15.21", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.21.tgz", + "integrity": "sha512-NPotx5CVful7yB+qZbWtXL2fA4e7aEHkihHLjklc6ID8aq7bhguHgeIoC1EmSNTAuCgI6ZXrjt2ZSaXnYX0EUg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/request-ip": { + "version": "0.0.37", + "resolved": "https://registry.npmjs.org/@types/request-ip/-/request-ip-0.0.37.tgz", + "integrity": "sha512-uw6/i3rQnpznxD7LtLaeuZytLhKZK6bRoTS6XVJlwxIOoOpEBU7bgKoVXDNtOg4Xl6riUKHa9bjMVrL6ESqYlQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", + "dev": true + }, + "node_modules/@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.23.0.tgz", + "integrity": "sha512-hEcSmG4XodSLiAp1uxv/OQSGsDY6QN3TcRU32gANp+19wGE1QQZLRS8/GV58VRUoXhnkuJ3ZxNQ3T6Z6zM59DA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/type-utils": "5.23.0", + "@typescript-eslint/utils": "5.23.0", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.23.0.tgz", + "integrity": "sha512-V06cYUkqcGqpFjb8ttVgzNF53tgbB/KoQT/iB++DOIExKmzI9vBJKjZKt/6FuV9c+zrDsvJKbJ2DOCYwX91cbw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", + "debug": "^4.3.2" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.23.0.tgz", + "integrity": "sha512-EhjaFELQHCRb5wTwlGsNMvzK9b8Oco4aYNleeDlNuL6qXWDF47ch4EhVNPh8Rdhf9tmqbN4sWDk/8g+Z/J8JVw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.23.0.tgz", + "integrity": "sha512-iuI05JsJl/SUnOTXA9f4oI+/4qS/Zcgk+s2ir+lRmXI+80D8GaGwoUqs4p+X+4AxDolPpEpVUdlEH4ADxFy4gw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.23.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.23.0.tgz", + "integrity": "sha512-NfBsV/h4dir/8mJwdZz7JFibaKC3E/QdeMEDJhiAE3/eMkoniZ7MjbEMCGXw6MZnZDMN3G9S0mH/6WUIj91dmw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.23.0.tgz", + "integrity": "sha512-xE9e0lrHhI647SlGMl+m+3E3CKPF1wzvvOEWnuE3CCjjT7UiRnDGJxmAcVKJIlFgK6DY9RB98eLr1OPigPEOGg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.23.0.tgz", + "integrity": "sha512-dbgaKN21drqpkbbedGMNPCtRPZo1IOUr5EI9Jrrh99r5UW5Q0dz46RKXeSBoPV+56R6dFKpbrdhgUNSJsDDRZA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.23.0.tgz", + "integrity": "sha512-Vd4mFNchU62sJB8pX19ZSPog05B0Y0CE2UxAZPT5k4iqhRYjPnqyY3woMxCd0++t9OTqkgjST+1ydLBi7e2Fvg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.23.0", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "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, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "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/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/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", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "node_modules/array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + }, + "node_modules/bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/builtins": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-4.1.0.tgz", + "integrity": "sha512-1bPRZQtmKaO6h7qV1YHXNtr6nCK28k0Zo95KM4dXfILcZZwoHJBN1m3lfLv9LPkcOZlrSr+J1bzMaZFO98Yq0w==", + "dev": true, + "peer": true, + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/by-request": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/by-request/-/by-request-1.3.3.tgz", + "integrity": "sha512-lIrx8Q/eo5bOxqYHiWjmQcQ20PJjZ/8ZQTHTJWXZZgLVw+LJPoMbTG2xIwyU+5naX1bm4Cz/tP3VW3qM4tABSA==", + "dependencies": { + "@tubular/util": "^4.6.0", + "@types/follow-redirects": "^1.13.1", + "follow-redirects": "^1.14.7", + "http-status-codes": "^2.2.0", + "iconv-lite": "^0.6.3", + "lodash": "^4.17.21", + "temp": "^0.9.4" + }, + "engines": { + "node": ">=10.17" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "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", + "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" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "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/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/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "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", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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 + }, + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.1.tgz", + "integrity": "sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dns-socket": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/dns-socket/-/dns-socket-4.2.2.tgz", + "integrity": "sha512-BDeBd8najI4/lS00HSKpdFia+OvUMytaVjfzR9n5Lq8MlZRSvtbI+uLtx1+XmQFls5wFU9dssccTmQQ6nfpjdg==", + "dependencies": { + "dns-packet": "^5.2.4" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dotenv": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", + "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==", + "engines": { + "node": ">=12" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "node_modules/dynamic-dedupe": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", + "integrity": "sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE=", + "dev": true, + "dependencies": { + "xtend": "^4.0.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-abstract": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", + "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", + "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.2.3", + "@humanwhocodes/config-array": "^0.9.2", + "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.3.2", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "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", + "v8-compile-cache": "^2.0.3" + }, + "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-standard": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz", + "integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==", + "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" + } + ], + "peerDependencies": { + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0", + "eslint-plugin-promise": "^6.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-chai-friendly": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.2.tgz", + "integrity": "sha512-LOIfGx5sZZ5FwM1shr2GlYAWV9Omdi+1/3byuVagvQNoGUuU0iHhp7AfjA1uR+4dJ4Isfb4+FwBJgQajIw9iAg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "eslint": ">=3.0.0" + } + }, + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-jasmine": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-4.1.3.tgz", + "integrity": "sha512-q8j8KnLH/4uwmPELFZvEyfEcuCuGxXScJaRdqHjOjz064GcfX6aoFbzy5VohZ5QYk2+WvoqMoqDSb9nRLf89GQ==", + "dev": true, + "engines": { + "node": ">=8", + "npm": ">=6" + } + }, + "node_modules/eslint-plugin-n": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.2.0.tgz", + "integrity": "sha512-lWLg++jGwC88GDGGBX3CMkk0GIWq0y41aH51lavWApOKcMQcYoL3Ayd0lEdtD3SnQtR+3qBvWQS3qGbR2BxRWg==", + "dev": true, + "peer": true, + "dependencies": { + "builtins": "^4.0.0", + "eslint-plugin-es": "^4.1.0", + "eslint-utils": "^3.0.0", + "ignore": "^5.1.1", + "is-core-module": "^2.3.0", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/eslint-plugin-es": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", + "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "dev": true, + "peer": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-n/node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "peer": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-n/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-n/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, + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-node/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/eslint-plugin-promise": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.0.0.tgz", + "integrity": "sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": 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, + "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, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "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 + }, + "node_modules/eslint/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, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/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, + "engines": { + "node": ">=4.0" + } + }, + "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, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/espree": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "dev": true, + "dependencies": { + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.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.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.9.7", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/express/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "dependencies": { + "micromatch": "^4.0.2" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "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.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "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==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/html-entities": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-status-codes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz", + "integrity": "sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng==" + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is_js": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz", + "integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0=" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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-glob": { + "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" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-ip": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", + "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", + "dependencies": { + "ip-regex": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-z": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json-z/-/json-z-3.3.2.tgz", + "integrity": "sha512-wMfAqXqQyo+KYExh0KI0wjTa3JskKdpL2O7K854CAOeXNumC5XyFg44pzfBXSh22ynSzyaP2IyHKnjBX+Ysx+g==", + "optional": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json-z": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/morgan/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/morgan/node_modules/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 + }, + "node_modules/mysql": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", + "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", + "dependencies": { + "bignumber.js": "9.0.0", + "readable-stream": "2.3.7", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_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/normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "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/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/patch-package": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", + "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", + "dev": true, + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "npm": ">5" + } + }, + "node_modules/patch-package/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/patch-package/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/patch-package/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/patch-package/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/patch-package/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/patch-package/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/patch-package/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/patch-package/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/patch-package/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/patch-package/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/patch-package/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/patch-package/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/patch-package/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/patch-package/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "engines": { + "node": ">=4" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/public-ip": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/public-ip/-/public-ip-4.0.4.tgz", + "integrity": "sha512-EJ0VMV2vF6Cu7BIPo3IMW1Maq6ME+fbR0NcPmqDfpfNGIRPue1X8QrGjrg/rfjDkOsIkKHIf2S5FlEa48hFMTA==", + "dependencies": { + "dns-socket": "^4.2.2", + "got": "^9.6.0", + "is-ip": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/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.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "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, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/request-ip": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.3.tgz", + "integrity": "sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ==", + "dependencies": { + "is_js": "^0.9.0" + } + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rotating-file-stream": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/rotating-file-stream/-/rotating-file-stream-1.4.6.tgz", + "integrity": "sha512-QS7vGxBK6sGc1mCqlmAuwV4J0fmmVCKaUgMvKbkTueZr4jdkXN3bSpTEOQxtdtAVEzi1aUqdHzwIQ0ejNn+CQg==", + "deprecated": "please use version 2.x", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "1.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "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/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/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.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", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "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/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "engines": { + "node": ">=6" + } + }, + "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/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" + } + }, + "node_modules/ts-node-dev": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-1.1.8.tgz", + "integrity": "sha512-Q/m3vEwzYwLZKmV6/0VlFxcZzVV/xcgOt+Tx/VjaaRHyiBcFlV0541yrT09QjzzCxlDZ34OzKjrFAynlmtflEg==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.1", + "dynamic-dedupe": "^0.3.0", + "minimist": "^1.2.5", + "mkdirp": "^1.0.4", + "resolve": "^1.0.0", + "rimraf": "^2.6.1", + "source-map-support": "^0.5.12", + "tree-kill": "^1.2.2", + "ts-node": "^9.0.0", + "tsconfig": "^7.0.0" + }, + "bin": { + "ts-node-dev": "lib/bin.js", + "tsnd": "lib/bin.js" + }, + "engines": { + "node": ">=0.8.0" + }, + "peerDependencies": { + "node-notifier": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/ts-node-dev/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/ts-node-dev/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/tsconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", + "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", + "dev": true, + "dependencies": { + "@types/strip-bom": "^3.0.0", + "@types/strip-json-comments": "0.0.30", + "strip-bom": "^3.0.0", + "strip-json-comments": "^2.0.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" + } + }, + "node_modules/tslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/tslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/tslint/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/tslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/tslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unidecode-plus": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unidecode-plus/-/unidecode-plus-1.0.4.tgz", + "integrity": "sha512-KG6C6EFzic7ViDmuI2Z0R7e6fnALtTWUkTH5QrL0Pl9EGRWwwwGmskXaItkerfl5CD5H9p9M/kbaMxX7TJRuOQ==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "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/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "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-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "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/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" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/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/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "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 + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@eslint/eslintrc": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.3.tgz", + "integrity": "sha512-uGo44hIwoLGNyduRpjdEpovcbMdd+Nv7amtmJxnKmI8xj6yd5LncmSwDa5NgX/41lIFJtkjD6YdVfgEzPfJ5UA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.3.2", + "globals": "^13.9.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 + }, + "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, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, + "@humanwhocodes/config-array": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@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 + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", + "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==" + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@tubular/math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@tubular/math/-/math-3.1.0.tgz", + "integrity": "sha512-a7loxb8zHLxhq3mMSZbro2JNMxR2Vf8DoRy762RNCUKx3Ifd/pB024MVKsDF/5CVywdS5SvhavVtLtmpMRkmPQ==" + }, + "@tubular/time": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@tubular/time/-/time-3.8.1.tgz", + "integrity": "sha512-/3BVk58gG77FG7IklBvsUF8/sTg3JTsZHbYGYAgi9Y/qpZnGvRwJOOmS0TLRzfGr4D8XMr282PHXnec77rniYQ==", + "requires": { + "@tubular/math": "^3.1.0", + "@tubular/util": "^4.4.0", + "by-request": "^1.2.7", + "json-z": "^3.3.2" + } + }, + "@tubular/util": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@tubular/util/-/util-4.8.1.tgz", + "integrity": "sha512-31q8NbItdjuPMDmm1Z6+9Il+fgRTV1/RxXChBCGGtTqFfAJl8pFmPc6Zpqo3ShOOyZsuIH+B0grJo7ie3KLH0Q==" + }, + "@types/basic-auth": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/basic-auth/-/basic-auth-1.1.3.tgz", + "integrity": "sha512-W3rv6J0IGlxqgE2eQ2pTb0gBjaGtejQpJ6uaCjz3UQ65+TFTPC5/lAE+POfx1YLdjtxvejJzsIAfd3MxWiVmfg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/follow-redirects": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@types/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-THBEFwqsLuU/K62B5JRwab9NW97cFmL4Iy34NTMX0bMycQVzq2q7PKOkhfivIwxdpa/J72RppgC42vCHfwKJ0Q==", + "requires": { + "@types/node": "*" + } + }, + "@types/html-entities": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/html-entities/-/html-entities-1.3.4.tgz", + "integrity": "sha512-Ut62LV90H9tgXwyhmfR8U6yCw/6xeo26IlsbAJJfqPomaqDN2zoLb2Z+cbmy5AycJFhwNJDdH0zqjQp7Ox/eXg==", + "dev": true, + "requires": { + "html-entities": "*" + } + }, + "@types/iconv-lite": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@types/iconv-lite/-/iconv-lite-0.0.1.tgz", + "integrity": "sha1-qjuL2ivlErGuCgV7lC6GnDcKVWk=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/lodash": { + "version": "4.14.181", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz", + "integrity": "sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==", + "dev": true + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "@types/morgan": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.3.tgz", + "integrity": "sha512-BiLcfVqGBZCyNCnCH3F4o2GmDLrpy0HeBVnNlyZG4fo88ZiE9SoiBe3C+2ezuwbjlEyT+PDZ17//TAlRxAn75Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/mysql": { + "version": "2.15.21", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.21.tgz", + "integrity": "sha512-NPotx5CVful7yB+qZbWtXL2fA4e7aEHkihHLjklc6ID8aq7bhguHgeIoC1EmSNTAuCgI6ZXrjt2ZSaXnYX0EUg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "@types/request-ip": { + "version": "0.0.37", + "resolved": "https://registry.npmjs.org/@types/request-ip/-/request-ip-0.0.37.tgz", + "integrity": "sha512-uw6/i3rQnpznxD7LtLaeuZytLhKZK6bRoTS6XVJlwxIOoOpEBU7bgKoVXDNtOg4Xl6riUKHa9bjMVrL6ESqYlQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", + "dev": true + }, + "@types/strip-json-comments": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", + "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.23.0.tgz", + "integrity": "sha512-hEcSmG4XodSLiAp1uxv/OQSGsDY6QN3TcRU32gANp+19wGE1QQZLRS8/GV58VRUoXhnkuJ3ZxNQ3T6Z6zM59DA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/type-utils": "5.23.0", + "@typescript-eslint/utils": "5.23.0", + "debug": "^4.3.2", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.2.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/parser": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.23.0.tgz", + "integrity": "sha512-V06cYUkqcGqpFjb8ttVgzNF53tgbB/KoQT/iB++DOIExKmzI9vBJKjZKt/6FuV9c+zrDsvJKbJ2DOCYwX91cbw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", + "debug": "^4.3.2" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.23.0.tgz", + "integrity": "sha512-EhjaFELQHCRb5wTwlGsNMvzK9b8Oco4aYNleeDlNuL6qXWDF47ch4EhVNPh8Rdhf9tmqbN4sWDk/8g+Z/J8JVw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.23.0.tgz", + "integrity": "sha512-iuI05JsJl/SUnOTXA9f4oI+/4qS/Zcgk+s2ir+lRmXI+80D8GaGwoUqs4p+X+4AxDolPpEpVUdlEH4ADxFy4gw==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "5.23.0", + "debug": "^4.3.2", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.23.0.tgz", + "integrity": "sha512-NfBsV/h4dir/8mJwdZz7JFibaKC3E/QdeMEDJhiAE3/eMkoniZ7MjbEMCGXw6MZnZDMN3G9S0mH/6WUIj91dmw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.23.0.tgz", + "integrity": "sha512-xE9e0lrHhI647SlGMl+m+3E3CKPF1wzvvOEWnuE3CCjjT7UiRnDGJxmAcVKJIlFgK6DY9RB98eLr1OPigPEOGg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/visitor-keys": "5.23.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.23.0.tgz", + "integrity": "sha512-dbgaKN21drqpkbbedGMNPCtRPZo1IOUr5EI9Jrrh99r5UW5Q0dz46RKXeSBoPV+56R6dFKpbrdhgUNSJsDDRZA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.23.0", + "@typescript-eslint/types": "5.23.0", + "@typescript-eslint/typescript-estree": "5.23.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.23.0.tgz", + "integrity": "sha512-Vd4mFNchU62sJB8pX19ZSPog05B0Y0CE2UxAZPT5k4iqhRYjPnqyY3woMxCd0++t9OTqkgjST+1ydLBi7e2Fvg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.23.0", + "eslint-visitor-keys": "^3.0.0" + } + }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "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, + "requires": {} + }, + "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": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "argparse": { + "version": "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" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=" + }, + "bignumber.js": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", + "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==" + }, + "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 + }, + "body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "requires": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.9.7", + "raw-body": "2.4.3", + "type-is": "~1.6.18" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "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 + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtins": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-4.1.0.tgz", + "integrity": "sha512-1bPRZQtmKaO6h7qV1YHXNtr6nCK28k0Zo95KM4dXfILcZZwoHJBN1m3lfLv9LPkcOZlrSr+J1bzMaZFO98Yq0w==", + "dev": true, + "peer": true, + "requires": { + "semver": "^7.0.0" + } + }, + "by-request": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/by-request/-/by-request-1.3.3.tgz", + "integrity": "sha512-lIrx8Q/eo5bOxqYHiWjmQcQ20PJjZ/8ZQTHTJWXZZgLVw+LJPoMbTG2xIwyU+5naX1bm4Cz/tP3VW3qM4tABSA==", + "requires": { + "@tubular/util": "^4.6.0", + "@types/follow-redirects": "^1.13.1", + "follow-redirects": "^1.14.7", + "http-status-codes": "^2.2.0", + "iconv-lite": "^0.6.3", + "lodash": "^4.17.21", + "temp": "^0.9.4" + } + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "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" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "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 + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "requires": { + "safe-buffer": "5.2.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "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" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "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 + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "dns-packet": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.1.tgz", + "integrity": "sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw==", + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "dns-socket": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/dns-socket/-/dns-socket-4.2.2.tgz", + "integrity": "sha512-BDeBd8najI4/lS00HSKpdFia+OvUMytaVjfzR9n5Lq8MlZRSvtbI+uLtx1+XmQFls5wFU9dssccTmQQ6nfpjdg==", + "requires": { + "dns-packet": "^5.2.4" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dotenv": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.0.tgz", + "integrity": "sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "dynamic-dedupe": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", + "integrity": "sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE=", + "dev": true, + "requires": { + "xtend": "^4.0.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "es-abstract": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz", + "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "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 + }, + "eslint": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.15.0.tgz", + "integrity": "sha512-GG5USZ1jhCu8HJkzGgeK8/+RGnHaNYZGrGDzUtigK3BsGESW/rs2az23XqE0WVwDxy1VRvvjSSGu5nB0Bu+6SA==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.2.3", + "@humanwhocodes/config-array": "^0.9.2", + "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.3.2", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.6.0", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "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", + "v8-compile-cache": "^2.0.3" + }, + "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 + }, + "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, + "requires": { + "esrecurse": "^4.3.0", + "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 + }, + "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, + "requires": { + "is-glob": "^4.0.3" + } + }, + "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, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, + "eslint-config-standard": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz", + "integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==", + "dev": true, + "requires": {} + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-chai-friendly": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.7.2.tgz", + "integrity": "sha512-LOIfGx5sZZ5FwM1shr2GlYAWV9Omdi+1/3byuVagvQNoGUuU0iHhp7AfjA1uR+4dJ4Isfb4+FwBJgQajIw9iAg==", + "dev": true, + "requires": {} + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-jasmine": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-4.1.3.tgz", + "integrity": "sha512-q8j8KnLH/4uwmPELFZvEyfEcuCuGxXScJaRdqHjOjz064GcfX6aoFbzy5VohZ5QYk2+WvoqMoqDSb9nRLf89GQ==", + "dev": true + }, + "eslint-plugin-n": { + "version": "15.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.2.0.tgz", + "integrity": "sha512-lWLg++jGwC88GDGGBX3CMkk0GIWq0y41aH51lavWApOKcMQcYoL3Ayd0lEdtD3SnQtR+3qBvWQS3qGbR2BxRWg==", + "dev": true, + "peer": true, + "requires": { + "builtins": "^4.0.0", + "eslint-plugin-es": "^4.1.0", + "eslint-utils": "^3.0.0", + "ignore": "^5.1.1", + "is-core-module": "^2.3.0", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.3.0" + }, + "dependencies": { + "eslint-plugin-es": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", + "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "dev": true, + "peer": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "peer": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + } + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "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, + "peer": true + } + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-promise": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.0.0.tgz", + "integrity": "sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw==", + "dev": true, + "requires": {} + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": 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 + } + } + }, + "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 + }, + "espree": { + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "dev": true, + "requires": { + "acorn": "^8.7.1", + "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, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", + "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.19.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.4.2", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.9.7", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.17.2", + "serve-static": "1.14.2", + "setprototypeof": "1.2.0", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "requires": { + "micromatch": "^4.0.2" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "html-entities": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + } + }, + "http-status-codes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz", + "integrity": "sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng==" + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "ip-regex": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is_js": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/is_js/-/is_js-0.9.0.tgz", + "integrity": "sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0=" + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-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-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-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-ip": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", + "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", + "requires": { + "ip-regex": "^4.0.0" + } + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.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" + } + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-z": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json-z/-/json-z-3.3.2.tgz", + "integrity": "sha512-wMfAqXqQyo+KYExh0KI0wjTa3JskKdpL2O7K854CAOeXNumC5XyFg44pzfBXSh22ynSzyaP2IyHKnjBX+Ysx+g==", + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "requires": { + "json-buffer": "3.0.0" + } + }, + "klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "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 + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "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 + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "requires": { + "minimist": "^1.2.6" + } + }, + "morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "requires": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "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 + }, + "mysql": { + "version": "2.18.1", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", + "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", + "requires": { + "bignumber.js": "9.0.0", + "readable-stream": "2.3.7", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==" + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "requires": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "patch-package": { + "version": "6.4.7", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz", + "integrity": "sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==", + "dev": true, + "requires": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^7.0.1", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.0", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "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 + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "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" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "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" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-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 + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "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 + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "public-ip": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/public-ip/-/public-ip-4.0.4.tgz", + "integrity": "sha512-EJ0VMV2vF6Cu7BIPo3IMW1Maq6ME+fbR0NcPmqDfpfNGIRPue1X8QrGjrg/rfjDkOsIkKHIf2S5FlEa48hFMTA==", + "requires": { + "dns-socket": "^4.2.2", + "got": "^9.6.0", + "is-ip": "^3.1.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" + }, + "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 + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", + "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "requires": { + "bytes": "3.1.2", + "http-errors": "1.8.1", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "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" + } + }, + "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 + }, + "request-ip": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-2.1.3.tgz", + "integrity": "sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ==", + "requires": { + "is_js": "^0.9.0" + } + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "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 + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "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" + } + }, + "rotating-file-stream": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/rotating-file-stream/-/rotating-file-stream-1.4.6.tgz", + "integrity": "sha512-QS7vGxBK6sGc1mCqlmAuwV4J0fmmVCKaUgMvKbkTueZr4jdkXN3bSpTEOQxtdtAVEzi1aUqdHzwIQ0ejNn+CQg==" + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "send": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", + "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "1.8.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + } + } + }, + "serve-static": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", + "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.2" + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "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 + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "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.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" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "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==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "strip-ansi": { + "version": "6.0.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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "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 + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", + "requires": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + }, + "ts-node-dev": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-1.1.8.tgz", + "integrity": "sha512-Q/m3vEwzYwLZKmV6/0VlFxcZzVV/xcgOt+Tx/VjaaRHyiBcFlV0541yrT09QjzzCxlDZ34OzKjrFAynlmtflEg==", + "dev": true, + "requires": { + "chokidar": "^3.5.1", + "dynamic-dedupe": "^0.3.0", + "minimist": "^1.2.5", + "mkdirp": "^1.0.4", + "resolve": "^1.0.0", + "rimraf": "^2.6.1", + "source-map-support": "^0.5.12", + "tree-kill": "^1.2.2", + "ts-node": "^9.0.0", + "tsconfig": "^7.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "tsconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", + "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", + "dev": true, + "requires": { + "@types/strip-bom": "^3.0.0", + "@types/strip-json-comments": "0.0.30", + "strip-bom": "^3.0.0", + "strip-json-comments": "^2.0.0" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "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 + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "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" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "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 + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typescript": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", + "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", + "dev": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "unidecode-plus": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unidecode-plus/-/unidecode-plus-1.0.4.tgz", + "integrity": "sha512-KG6C6EFzic7ViDmuI2Z0R7e6fnALtTWUkTH5QrL0Pl9EGRWwwwGmskXaItkerfl5CD5H9p9M/kbaMxX7TJRuOQ==" + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "requires": { + "prepend-http": "^2.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "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-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "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 + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/server/package.json b/server/package.json new file mode 100644 index 0000000..9b30b32 --- /dev/null +++ b/server/package.json @@ -0,0 +1,65 @@ +{ + "name": "svc-api", + "version": "1.9.0", + "description": "SVC API", + "main": "index.js", + "scripts": { + "tsc": "tsc", + "dev": "ts-node-dev --respawn --transpile-only ./app/app.ts", + "build": "tsc", + "start": "tsc && node -r dotenv/config build/app.js", + "postinstall": "patch-package", + "lint": "eslint \"**/*.ts\"" + }, + "author": "Kerry Shetline ", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/kshetline/svc-api.git" + }, + "dependencies": { + "@tubular/math": "^3.1.0", + "@tubular/time": "^3.8.1", + "@tubular/util": "^4.8.1", + "basic-auth": "^2.0.1", + "by-request": "^1.3.3", + "dotenv": "^16.0.0", + "express": "^4.17.3", + "follow-redirects": "^1.14.9", + "html-entities": "^2.3.3", + "iconv-lite": "^0.6.3", + "lodash": "^4.17.21", + "morgan": "^1.10.0", + "mysql": "^2.18.1", + "public-ip": "^4.0.4", + "request-ip": "^2.1.3", + "rotating-file-stream": "^1.4.6", + "serve-index": "^1.9.1", + "unidecode-plus": "^1.0.4" + }, + "devDependencies": { + "@types/basic-auth": "^1.1.3", + "@types/express": "^4.17.13", + "@types/follow-redirects": "^1.14.1", + "@types/html-entities": "^1.3.4", + "@types/iconv-lite": "0.0.1", + "@types/lodash": "^4.14.181", + "@types/morgan": "^1.9.3", + "@types/mysql": "^2.15.21", + "@types/request-ip": "0.0.37", + "@types/serve-index": "^1.9.1", + "@typescript-eslint/eslint-plugin": "^5.23.0", + "@typescript-eslint/parser": "^5.23.0", + "eslint": "^8.15.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-chai-friendly": "^0.7.2", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jasmine": "^4.1.3", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.0.0", + "patch-package": "^6.4.7", + "ts-node-dev": "^1.1.8", + "tslint": "^6.1.3", + "typescript": "^4.5.5" + } +} diff --git a/server/patches/express+4.17.1.patch b/server/patches/express+4.17.1.patch new file mode 100644 index 0000000..d266410 --- /dev/null +++ b/server/patches/express+4.17.1.patch @@ -0,0 +1,22 @@ +diff --git a/node_modules/express/lib/response.js b/node_modules/express/lib/response.js +index c9f08cd..391d82d 100644 +--- a/node_modules/express/lib/response.js ++++ b/node_modules/express/lib/response.js +@@ -301,7 +301,7 @@ res.jsonp = function jsonp(obj) { + var replacer = app.get('json replacer'); + var spaces = app.get('json spaces'); + var body = stringify(val, replacer, spaces, escape) +- var callback = this.req.query[app.get('jsonp callback name')]; ++ var callback = this.req.query[app.get('jsonp callback name') || 'callback']; // KS patch + + // content-type + if (!this.get('Content-Type')) { +@@ -317,7 +317,7 @@ res.jsonp = function jsonp(obj) { + // jsonp + if (typeof callback === 'string' && callback.length !== 0) { + this.set('X-Content-Type-Options', 'nosniff'); +- this.set('Content-Type', 'text/javascript'); ++ this.set('Content-Type', 'application/javascript'); // KS patch + + // restrict callback charset + callback = callback.replace(/[^\[\]\w$.]/g, ''); diff --git a/server/tsconfig.json b/server/tsconfig.json new file mode 100644 index 0000000..c9f24fa --- /dev/null +++ b/server/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2018", + "module": "commonjs", + "sourceMap": true, + "outDir": "./build", + "noImplicitAny": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": true, + "noImplicitReturns": true, + "moduleResolution": "node", + "esModuleInterop": true + }, + "include": ["../ambient.d.ts", "./app/**/*"], + "exclude": ["node_modules", "**/*.spec.ts"] +} diff --git a/src/app/app.component.html b/src/app/app.component.html index 6ebe9f3..16156d5 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -4,7 +4,7 @@
lunar eclipse

Sky View Café NP

- Version 1.14.8

+ Version 1.15.0

Copyright © 2016-2022 Kerry Shetline.
diff --git a/src/app/app.service.ts b/src/app/app.service.ts index d973f43..c11034d 100755 --- a/src/app/app.service.ts +++ b/src/app/app.service.ts @@ -121,7 +121,7 @@ export class AppService { private readonly debouncedSaveSettings: () => void; private knownIanaTimezones: Set; private _clockFloating = min(window.screen.width, window.screen.height) < 768; - private _clockPosition = '{"x":730,y:"0"}'; + private _clockPosition = ''; private _clockStyle = ClockStyle.ISO; private _latLongStyle = LatLongStyle.DEGREES_AND_MINUTES; private _northAzimuth = false; @@ -172,7 +172,10 @@ export class AppService { const savedSettings = localStorage.getItem('allSettings'); if (savedSettings) { - this.allSettings = JSON.parse(savedSettings); + try { + this.allSettings = JSON.parse(savedSettings); + } + catch {} const appSettings = this.allSettings[VIEW_APP]; @@ -399,7 +402,7 @@ export class AppService { } catch {} - return { x: 730, y: 0 }; + return { x: window.innerWidth - 665, y: 30 }; } get clockStyle(): ClockStyle { return this._clockStyle; } diff --git a/src/app/svc/generic-planetary-view.directive.ts b/src/app/svc/generic-planetary-view.directive.ts index febf2ca..7bd47b9 100644 --- a/src/app/svc/generic-planetary-view.directive.ts +++ b/src/app/svc/generic-planetary-view.directive.ts @@ -8,7 +8,7 @@ import { abs, Angle, cos_deg, floor, FMT_MINS, FMT_SECS, intersects, max, min, mod2, Point, Rectangle, round, sin_deg, SphericalPosition, SphericalPosition3D, sqrt, TWO_PI, union } from '@tubular/math'; -import { getTextWidth, toDefaultLocaleFixed } from '@tubular/util'; +import { blendColors, getTextWidth, toDefaultLocaleFixed } from '@tubular/util'; import { AppService, CurrentTab, PROPERTY_NORTH_AZIMUTH, UserSetting, VIEW_APP } from '../app.service'; import { DrawingContext, GenericViewDirective } from './generic-view.directive'; @@ -85,10 +85,11 @@ export const MARQUEE_KM = 1; export const MARQUEE_MILES = 2; // These color specifications are left incomplete so that the alpha value can be varied. -const SHADED_MOON = 'rgba(102,153,204,'; -const INTERMEDIATE_MOON = 'rgba(178,204,229,'; -const ILLUMINATED_MOON = 'rgba(255,255,255,'; -const ILLUMINATED_MOON_PRINT = 'rgba(221,221,187,'; +const SHADED_MOON = 'rgba(102,153,204'; +const INTERMEDIATE_MOON = 'rgba(178,204,229'; +const ILLUMINATED_MOON = 'rgba(255,255,255'; +const ILLUMINATED_MOON_PRINT = 'rgba(221,221,187'; +const ECLIPSED_MOON = '#850E'; export interface DrawingContextPlanetary extends DrawingContext { size: number; @@ -310,6 +311,22 @@ export abstract class GenericPlanetaryViewDirective extends GenericViewDirective const sin_sa = sin_deg(shadeAngle); const cos_sa = cos_deg(shadeAngle); const r02 = r0 * r0; + let calcColor = false; + + if (abs(mod2(phase, 360)) < 20.0) + color = SHADED_MOON; + else if (abs(phase - 180.0) < 20.0) { + color = (dc.inkSaver ? ILLUMINATED_MOON_PRINT : ILLUMINATED_MOON); + + if (abs(phase - 180.0) < 3.0) { + const ei = dc.ss.getLunarEclipseInfo(dc.jde); + + if (ei.inUmbra) + color = blendColors(ECLIPSED_MOON, color + ',0.93)', ei.totality).replace(/,[^,]+\)/, ''); + } + } + else + calcColor = true; for (let dy = -r0 - 1; dy <= r0 + 1; ++dy) { for (let dx = -r0 - 1; dx <= r0 + 1; ++dx) { @@ -323,12 +340,7 @@ export abstract class GenericPlanetaryViewDirective extends GenericViewDirective if (r > r0) alpha = 1.0 - r + r0; - if (abs(mod2(phase, 360)) < 20.0) { - color = SHADED_MOON; - } - else if (abs(phase - 180.0) < 20.0) - color = (dc.inkSaver ? ILLUMINATED_MOON_PRINT : ILLUMINATED_MOON); - else { + if (calcColor) { const lineWidth = 2 * sqrt(max(r02 - rot_y * rot_y, 0.0)) + 1.0; const inset = rot_x + (lineWidth - 1.0) / 2; const shadowWidth = coverage * lineWidth; @@ -349,7 +361,7 @@ export abstract class GenericPlanetaryViewDirective extends GenericViewDirective color = (dc.inkSaver ? ILLUMINATED_MOON_PRINT : ILLUMINATED_MOON); } - dc.context.fillStyle = color + alpha + ')'; + dc.context.fillStyle = `${color},${alpha}`; dc.context.fillRect(x + dx, y + dy, 1, 1); } } diff --git a/src/app/svc/moon-drawer.ts b/src/app/svc/moon-drawer.ts index 844c39c..0db5316 100644 --- a/src/app/svc/moon-drawer.ts +++ b/src/app/svc/moon-drawer.ts @@ -1,216 +1,169 @@ -import { ISkyObserver, MOON, SolarSystem } from '@tubular/astronomy'; -import { abs, Angle, ceil, floor, interpolate, max, round, sqrt, TWO_PI, Unit } from '@tubular/math'; -import { getPixel, setPixel } from '@tubular/util'; +import { ISkyObserver, KM_PER_AU, SolarSystem } from '@tubular/astronomy'; +import { abs, Angle, cos_deg, PI, sin_deg, to_radian, Unit } from '@tubular/math'; +import { fillCircle, strokeCircle } from '@tubular/util'; +import { + AmbientLight, CanvasTexture, Mesh, MeshPhongMaterial, PerspectiveCamera, PointLight, Scene, SphereGeometry, + sRGBEncoding, WebGLRenderer +} from 'three'; + +const MAX_LUNAR_ANGULAR_DIAMETER = 34; // In arc-minutes, rounded up from 33.66. +const MOON_RADIUS = 1737.4; // km export class MoonDrawer { - private moonPixels: ImageData; + private camera: PerspectiveCamera; private canvas: HTMLCanvasElement; + private earthShine: AmbientLight; + private moonMesh: Mesh; + private renderer: WebGLRenderer; + private rendererHost: HTMLElement; private scaledBuffer: ImageData; + private scene: Scene; + private shadowCanvas: HTMLCanvasElement; + private sun: PointLight; + private webGlRendererSize = 0; static getMoonDrawer(): Promise { return new Promise((resolve, reject) => { const image = new Image(); image.onload = (): void => { - resolve(new MoonDrawer(image)); + const image2 = new Image(); + + image2.onload = (): void => { + resolve(new MoonDrawer(image, image2)); + }; + image2.onerror = (reason): void => { + console.warn('Moon bump map failed to load:', reason); + resolve(new MoonDrawer(image)); + }; + + image2.src = 'assets/resources/moon_map_bump.jpg'; }; - image.onerror = (): void => { - reject(new Error('Moon image failed to load from: ' + image.src)); + image.onerror = (reason): void => { + reject(new Error('Moon map failed to load: ' + reason)); }; - image.src = 'assets/resources/full_moon.jpg'; + image.src = 'assets/resources/moon_map.jpg'; }); } - constructor(private moonImage: HTMLImageElement) { - const size = moonImage.width; // height should be identical. - const canvas = document.createElement('canvas'); - - canvas.width = size; - canvas.height = size; - canvas.style.width = size + 'px'; - canvas.style.height = size + 'px'; - - const context = canvas.getContext('2d'); - - context.drawImage(this.moonImage, 0, 0); - this.moonPixels = context.getImageData(0, 0, size, size); - } - - private getPixel(x: number, y: number): number { - const size = this.moonPixels.width; - - // The upper-left hand corner should be a neutral gray that can be substituted - // for any off-the-edge pixel requests. - if (x < 0 || x >= size || y < 0 || y >= size) - return this.moonPixels.data[0]; - - return this.moonPixels.data[(y * size + x) * 4]; - } - - private getPixelLevel(x: number, y: number): number { - const x0 = floor(x); - const x1 = x0 + 1; - const dx = x - x0; - const y0 = floor(y); - const y1 = y0 + 1; - const dy = y - y0; - - const v0 = this.getPixel(x0, y0) * (1.0 - dx) + this.getPixel(x1, y0) * dx; - const v1 = this.getPixel(x0, y1) * (1.0 - dx) + this.getPixel(x1, y1) * dx; - - return v0 * (1.0 - dy) + v1 * dy; - } + constructor(private moonImage: HTMLImageElement, private moonBumps?: HTMLImageElement) {} drawMoon(context: CanvasRenderingContext2D, solarSystem: SolarSystem, time_JDE: number, cx: number, cy: number, size: number, pixelsPerArcSec: number, pixelRatio = 1, parallacticAngle?: Angle, observer?: ISkyObserver, showEclipses?: boolean): void { - const originalImageSize = this.moonPixels.width; + if (!this.renderer) + this.setUpRenderer(); - if (size === 0 && observer) - size = ceil(solarSystem.getAngularDiameter(MOON, time_JDE, observer) * pixelsPerArcSec); + if (size === 0) + size = MAX_LUNAR_ANGULAR_DIAMETER * pixelsPerArcSec * 60; - pixelsPerArcSec *= pixelRatio; - size *= pixelRatio; - // Make sure that the size is odd, so that one pixel can be the exact center of the image. - size += (size + 1) % 2; + const targetSize = size; - if (size < 3) - size = 3; + if (!pixelsPerArcSec) + pixelsPerArcSec = size / MAX_LUNAR_ANGULAR_DIAMETER / 60; - const phase = solarSystem.getLunarPhase(time_JDE); - const illum = solarSystem.getLunarIlluminatedFraction(time_JDE); - const waxing = phase < 180.0; - const r0 = floor(size / 2); - const r2 = round((r0 + 0.5) * (r0 + 0.5)); - let x: number, y: number; - let xmax: number, xmax2: number; - let lineWidth; - let shadowWidth; - let shadowEdge; - let gray; - const parallactic = Boolean(parallacticAngle); - let sin_pa = 0.0; - let cos_pa = 1.0; - let eclipsed = false; - let u2 = 0; // umbral radius, squared - let p2 = 0; // penumbral radius, squared - let sx = 0, sy = 0; // shadow center - let sdx: number, sdy: number; // offset shadow center - let pixel: number; - - if (!this.scaledBuffer || this.scaledBuffer.width !== size) { - this.canvas = document.createElement('canvas'); - - this.canvas.width = size; - this.canvas.height = size; - - const context2 = this.canvas.getContext('2d'); - - context2.clearRect(0, 0, size, size); - context2.beginPath(); - context2.arc(r0 + 0.5, r0 + 0.5, r0, 0, TWO_PI); - context2.fillStyle = 'white'; - context2.fill(); - - this.scaledBuffer = context2.getImageData(0, 0, size, size); - } + size *= pixelRatio; + pixelsPerArcSec *= pixelRatio; - if (parallactic) { - sin_pa = parallacticAngle.sin; - cos_pa = parallacticAngle.cos; + if (this.webGlRendererSize !== size) { + this.renderer.setSize(size, size); + this.webGlRendererSize = size; } - // I'm going to treat the umbra and penumbra of the Earth as imaginary circular - // objects directly opposite to the Sun and located at the same distance from - // the Earth as the Moon. - // - // If you can imagine the typical diagram of how umbral and penumbral shadows are - // cast, I'm simply solving some similar triangles that can be drawn into such a - // diagram to figure out the size of the Moon-distanced cross-sections of the - // two types of shadow. + const r = size / 2; + const saveCompOp = context.globalCompositeOperation; + const phase = solarSystem.getLunarPhase(time_JDE); + const libration = solarSystem.getLunarLibration(time_JDE, observer); + + this.camera.position.z = libration.D * KM_PER_AU; + this.camera.rotation.z = (parallacticAngle ? parallacticAngle.radians : 0); + this.moonMesh.rotation.y = to_radian(-libration.l); + this.moonMesh.rotation.x = to_radian(libration.b); + this.sun.position.x = 93000000 * sin_deg(phase); // Very approximate, but good enough. + this.sun.position.z = -93000000 * cos_deg(phase); + this.earthShine.intensity = 0.025 + cos_deg(phase) * 0.0125; + this.renderer.render(this.scene, this.camera); + context.globalCompositeOperation = 'source-over'; + context.drawImage(this.renderer.domElement, cx - targetSize / 2, cy - targetSize / 2, targetSize, targetSize); // If we're near a full moon, it's worth checking for a lunar eclipse, but not otherwise. if (showEclipses && abs(phase - 180.0) < 3.0) { const ei = solarSystem.getLunarEclipseInfo(time_JDE); if (ei.inPenumbra) { - eclipsed = true; - const dLon = ei.shadowPos.longitude.subtract(ei.pos.longitude).getAngle(Unit.ARC_SECONDS); const dLat = ei.shadowPos.latitude.subtract(ei.pos.latitude).getAngle(Unit.ARC_SECONDS); - - sx = round((dLon * cos_pa - dLat * sin_pa) * -pixelsPerArcSec); - sy = round((dLon * sin_pa + dLat * cos_pa) * -pixelsPerArcSec); - - const uRadius = round(ei.umbraRadius * pixelsPerArcSec) + 2; - const pRadius = round(ei.penumbraRadius * pixelsPerArcSec) + 2; - - u2 = uRadius ** 2; - p2 = pRadius ** 2; + const sin_pa = parallacticAngle ? parallacticAngle.sin : 0; + const cos_pa = parallacticAngle ? parallacticAngle.cos : 1; + const sx = (dLon * cos_pa - dLat * sin_pa) * -pixelsPerArcSec + r; + const sy = (dLon * sin_pa + dLat * cos_pa) * -pixelsPerArcSec + r; + const uRadius = ei.umbraRadius * pixelsPerArcSec + 2; + const pRadius = ei.penumbraRadius * pixelsPerArcSec + 2; + const moonR = ei.radius * pixelsPerArcSec; + + if (!this.shadowCanvas) // Turns out that rendering eclipse shadows with 2D graphics works better than using WebGL. + this.shadowCanvas = document.createElement('canvas'); + + if (this.shadowCanvas.width !== size || this.shadowCanvas.height !== size) + this.shadowCanvas.width = this.shadowCanvas.height = size; + + const context2 = this.shadowCanvas.getContext('2d'); + + context2.fillStyle = '#FFFFFF'; + context2.fillRect(0, 0, size, size); + // Penumbra + context2.fillStyle = `hsl(36deg ${100 - ei.totality * 100}% 75%)`; + context2.filter = `blur(${size / 6}px)`; + fillCircle(context2, sx, sy, pRadius - size / 6); + // Umbra + context2.fillStyle = '#664533'; + context2.filter = `blur(${size / 125}px)`; + fillCircle(context2, sx, sy, uRadius); + // Mask off penumbra and umbra beyond edge of moon + context2.filter = 'blur(1px)'; + context2.strokeStyle = 'white'; + context2.lineWidth = r; + strokeCircle(context2, r, r, moonR + r / 2); + + context.globalCompositeOperation = 'multiply'; + context.drawImage(this.shadowCanvas, cx - targetSize / 2, cy - targetSize / 2, targetSize, targetSize); + + if (ei.totality > 0.8) { + // Brighten remaining illuminated portion of moon to increase contrast with shadowed part. + context2.clearRect(0, 0, size, size); + context2.filter = ''; + context2.fillStyle = `rgba(255, 255, 255, ${(ei.totality - 0.8) / 0.25})`; + fillCircle(context2, r, r, moonR); + context2.fillStyle = 'black'; + context2.filter = `blur(${size / 125}px)`; + fillCircle(context2, sx, sy, uRadius); + context.globalCompositeOperation = 'lighten'; + context.drawImage(this.shadowCanvas, cx - targetSize / 2, cy - targetSize / 2, targetSize, targetSize); + } } } - for (let dy = -r0; dy <= r0; ++dy) { - xmax = ceil(sqrt(r2 - dy * dy)); - - for (let dx = -xmax; dx <= xmax; ++dx) { - x = dx * cos_pa + dy * sin_pa; - y = dy * cos_pa - dx * sin_pa; - - gray = this.getPixelLevel((x + r0) * originalImageSize / size, - (y + r0) * originalImageSize / size); - - xmax2 = round(sqrt(max(r2 - y * y, 0))); - lineWidth = xmax2 * 2 + 1; - // When the Moon is new, shadowWidth is biased one pixel wider, when full, one pixel narrower, with the - // bias varying smoothly in between (no bias at all at half-full). - shadowWidth = lineWidth * (1.0 - illum) - illum * 2.0 + 1.0; - - if (waxing) { - shadowEdge = -xmax2 + shadowWidth; - - if (x < shadowEdge - 1.0 || illum < 0.02) - gray /= 5.0; - else if (x < shadowEdge + 1.0) - gray /= interpolate(shadowEdge - 1.0, x, shadowEdge + 1.0, 5.0, 1.0); - } - else { - shadowEdge = xmax2 - shadowWidth; - - if (x > shadowEdge + 1.0 || illum < 0.02) - gray /= 5.0; - else if (x > shadowEdge - 1.0) - gray /= interpolate(shadowEdge + 1.0, x, shadowEdge - 1.0, 5.0, 1.0); - } - - pixel = (getPixel(this.scaledBuffer, r0 + dx, r0 + dy) & 0xFF000000) | (0x010101 * round(gray)); - - if (eclipsed) { - sdx = sx - dx; - sdy = sy - dy; - - // Are we within the penumbra? - if (sdx * sdx + sdy * sdy <= p2) { - // Also within the umbra? Even darker shadow. - if (sdx * sdx + sdy * sdy <= u2) - gray /= 2.5; + context.globalCompositeOperation = saveCompOp; + } - const igray = round(gray); + private setUpRenderer(): void { + const moon = new SphereGeometry(MOON_RADIUS, 50, 50); - // A shading of the moon image, leaning toward orange and brown. - pixel = (pixel & 0xFF000000) | - (igray << 16) | - (round(igray * 0.8) << 8) | - round(igray * 0.5); - } - } + moon.rotateY(-PI / 2); + this.camera = new PerspectiveCamera(MAX_LUNAR_ANGULAR_DIAMETER / 60, 1, 100, 500000); + this.scene = new Scene(); + this.moonMesh = new Mesh(moon, new MeshPhongMaterial({ map: new CanvasTexture(this.moonImage), + bumpMap: this.moonBumps ? new CanvasTexture(this.moonBumps) : undefined, bumpScale: 15, + reflectivity: 0, shininess: 0 })); + this.scene.add(this.moonMesh); + this.renderer = new WebGLRenderer({ alpha: true, antialias: true }); + this.renderer.outputEncoding = sRGBEncoding; - setPixel(this.scaledBuffer, r0 + dx, r0 + dy, pixel); - } - } + this.sun = new PointLight('white'); + this.scene.add(this.sun); - this.canvas.getContext('2d').putImageData(this.scaledBuffer, 0, 0); - context.drawImage(this.canvas, cx - r0 / pixelRatio, cy - r0 / pixelRatio, size / pixelRatio, size / pixelRatio); + this.earthShine = new AmbientLight('white'); + this.scene.add(this.earthShine); } } diff --git a/src/app/svc/svc-calendar-view/svc-calendar-view.component.html b/src/app/svc/svc-calendar-view/svc-calendar-view.component.html index 59f46c1..5b78704 100644 --- a/src/app/svc/svc-calendar-view/svc-calendar-view.component.html +++ b/src/app/svc/svc-calendar-view/svc-calendar-view.component.html @@ -2,7 +2,7 @@
- +
diff --git a/src/app/svc/svc-calendar-view/svc-calendar-view.component.scss b/src/app/svc/svc-calendar-view/svc-calendar-view.component.scss index 034fa2a..14cd5dc 100644 --- a/src/app/svc/svc-calendar-view/svc-calendar-view.component.scss +++ b/src/app/svc/svc-calendar-view/svc-calendar-view.component.scss @@ -6,6 +6,13 @@ align-items: stretch; } +@mixin text-stroke { + paint-order: stroke fill; + stroke: black; + stroke-width: 4px; + -webkit-text-stroke: 4px black; +} + div.wrapper { flex-grow: 1; background-color: black; @@ -76,9 +83,9 @@ div.day-wrapper.ffox-fix-2 { } div.day-number { + @include text-stroke; font-size: 1.5em; color: #6666FF; - text-shadow: -1px -1px black, -1px 1px black, 1px -1px black, 1px 1px black; } div.day-number.highlight { @@ -114,28 +121,28 @@ div.rise-set-list { div.rise-set { font-size: 0.833em; color: #00FF99; - text-shadow: -1px -1px black, -1px 1px black, 1px -1px black, 1px 1px black; + @include text-stroke; } div.phase { font-size: 0.833em; color: #FF66FF; - text-shadow: -1px -1px black, -1px 1px black, 1px -1px black, 1px 1px black; position: absolute; top: 2px; right: 2px; text-align: right; + @include text-stroke; } div.daylight { font-family: Astronomy, Arial, Helvetica, sans-serif; font-size: 0.833em; color: #FFFF99; - text-shadow: -1px -1px black, -1px 1px black, 1px -1px black, 1px 1px black; position: absolute; bottom: -1px; right: 2px; text-align: right; + @include text-stroke; &::first-letter { font-size: 1.5em; @@ -149,7 +156,7 @@ div.edge-ie-fix-2 { span.equiSolstice { font-size: 0.833em; color: #FF9966; - text-shadow: -1px -1px black, -1px 1px black, 1px -1px black, 1px 1px black; + @include text-stroke; } div.day-number, div.rise-set, span.equiSolstice, img.phase, div.phaseTime { @@ -187,3 +194,29 @@ div.day-number.void-day { color: #EEBB00; } } + +.chrome { + div.day-number, + div.rise-set, + div.phase, + div.daylight, + span.equiSolstice { + -webkit-text-stroke: unset; + text-shadow: -1px -1px 1px black, -1px 0 1px black, -1px 1px 1px black, + 0 -1px 1px black, 0 1px 1px black, + 1px -1px 1px black, 1px 0 1px black, 1px 1px 1px black; + } +} + +@media print { + .chrome { + div.day-number, + div.rise-set, + div.phase, + div.daylight, + span.equiSolstice { + -webkit-print-color-adjust: exact; + -webkit-filter: opacity(1); + } + } +} diff --git a/src/app/svc/svc-calendar-view/svc-calendar-view.component.ts b/src/app/svc/svc-calendar-view/svc-calendar-view.component.ts index d651c56..44d5972 100644 --- a/src/app/svc/svc-calendar-view/svc-calendar-view.component.ts +++ b/src/app/svc/svc-calendar-view/svc-calendar-view.component.ts @@ -8,7 +8,7 @@ import { } from '@tubular/astronomy'; import { DateAndTime, DateTime, defaultLocale, getStartOfWeek, Timezone, utToTdt, YMDDate } from '@tubular/time'; import { ceil, floor, max, min, round } from '@tubular/math'; -import { isEdge, isFirefox } from '@tubular/util'; +import { isChrome, isEdge, isFirefox } from '@tubular/util'; import { throttle } from 'lodash-es'; import { AppService, CurrentTab, Location, PROPERTY_GREGORIAN_CHANGE_DATE, SVC_MAX_YEAR, SVC_MIN_YEAR, UserSetting, VIEW_APP @@ -64,6 +64,8 @@ interface DateInfo extends YMDDate { styleUrls: ['./svc-calendar-view.component.scss'] }) export class SvcCalendarViewComponent implements AfterViewInit { + isChrome = isChrome(); + private wrapper: HTMLDivElement; private canvas: HTMLCanvasElement; private canvasScaling = 1; diff --git a/src/app/svc/svc-sky-view/svc-sky-view-options.component.ts b/src/app/svc/svc-sky-view/svc-sky-view-options.component.ts index a2672de..a9d8001 100644 --- a/src/app/svc/svc-sky-view/svc-sky-view-options.component.ts +++ b/src/app/svc/svc-sky-view/svc-sky-view-options.component.ts @@ -53,11 +53,11 @@ export class SvcSkyViewOptionsComponent extends SvcGenericOptionsComponent imple { label: 'Horizon - 120° Span', value: VIEW_TYPE.HORIZON_120 }, { label: 'Horizon to Zenith', value: VIEW_TYPE.HORIZON_TO_ZENITH }, { label: 'Zenith - 100° Span', value: VIEW_TYPE.ZENITH_100 }, - { label: 'Moon - 1° Span', value: VIEW_TYPE.MOON_CLOSEUP_1 }, + { label: 'Moon - 2° Span', value: VIEW_TYPE.MOON_CLOSEUP_2 }, { label: 'Moon - 4° Span', value: VIEW_TYPE.MOON_CLOSEUP_4 }, { label: 'Moon - 8° Span', value: VIEW_TYPE.MOON_CLOSEUP_8 }, { label: 'Moon - 16° Span', value: VIEW_TYPE.MOON_CLOSEUP_16 }, - { label: 'Sun - 1° Span', value: VIEW_TYPE.SUN_CLOSEUP_1 }, + { label: 'Sun - 2° Span', value: VIEW_TYPE.SUN_CLOSEUP_2 }, { label: 'Sun - 4° Span', value: VIEW_TYPE.SUN_CLOSEUP_4 }, { label: 'Sun - 8° Span', value: VIEW_TYPE.SUN_CLOSEUP_8 }, { label: 'Sun - 16° Span', value: VIEW_TYPE.SUN_CLOSEUP_16 }, diff --git a/src/app/svc/svc-sky-view/svc-sky-view.component.ts b/src/app/svc/svc-sky-view/svc-sky-view.component.ts index 4acaf86..b69fddf 100644 --- a/src/app/svc/svc-sky-view/svc-sky-view.component.ts +++ b/src/app/svc/svc-sky-view/svc-sky-view.component.ts @@ -28,8 +28,8 @@ export const PROPERTY_VIEW_TYPE = 'view_type'; export enum VIEW_TYPE {FULL_SKY_FLAT, FULL_SKY_DOME, HORIZON_45, HORIZON_90, HORIZON_120, HORIZON_TO_ZENITH, ZENITH_100, - MOON_CLOSEUP_1, MOON_CLOSEUP_4, MOON_CLOSEUP_8, MOON_CLOSEUP_16, - SUN_CLOSEUP_1, SUN_CLOSEUP_4, SUN_CLOSEUP_8, SUN_CLOSEUP_16} + MOON_CLOSEUP_2, MOON_CLOSEUP_4, MOON_CLOSEUP_8, MOON_CLOSEUP_16, + SUN_CLOSEUP_2, SUN_CLOSEUP_4, SUN_CLOSEUP_8, SUN_CLOSEUP_16} export const PROPERTY_SKY_COLOR = 'sky_color'; export enum SKY_COLOR {BLACK, BASIC, MULTI} export const PROPERTY_REFRACTION = 'refraction'; @@ -324,11 +324,11 @@ export class SvcSkyViewComponent extends GenericSkyViewDirective implements Afte this.minAlt = 40.0; break; - case VIEW_TYPE.MOON_CLOSEUP_1: + case VIEW_TYPE.MOON_CLOSEUP_2: this.viewMode = VIEW_MODE.MOON_CLOSEUP; this.lastMoonType = value; this.trackingPlanet = MOON; - this.viewWidth = 1.0; + this.viewWidth = 2.0; this.minAlt = -90.0; break; @@ -356,11 +356,11 @@ export class SvcSkyViewComponent extends GenericSkyViewDirective implements Afte this.minAlt = -90.0; break; - case VIEW_TYPE.SUN_CLOSEUP_1: + case VIEW_TYPE.SUN_CLOSEUP_2: this.viewMode = VIEW_MODE.SUN_CLOSEUP; this.lastSunType = value; this.trackingPlanet = SUN; - this.viewWidth = 1.0; + this.viewWidth = 2.0; this.minAlt = -90.0; break; diff --git a/src/app/three/three-utils.ts b/src/app/three/three-utils.ts new file mode 100644 index 0000000..ae4592f --- /dev/null +++ b/src/app/three/three-utils.ts @@ -0,0 +1,199 @@ +/* eslint-disable guard-for-in */ +import { BufferAttribute, BufferGeometry } from 'three'; + +function mergeBufferAttributes(attributes: BufferAttribute[]): BufferAttribute { + let TypedArray; + let itemSize; + let normalized; + let arrayLength = 0; + + for (let i = 0; i < attributes.length; ++i) { + const attribute = attributes[i]; + + if ((attribute as any).isInterleavedBufferAttribute) { + console.error('THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. InterleavedBufferAttributes are not supported.'); + return null; + } + + if (TypedArray === undefined) TypedArray = attribute.array.constructor; + if (TypedArray !== attribute.array.constructor) { + console.error('THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.'); + return null; + } + + if (itemSize === undefined) itemSize = attribute.itemSize; + if (itemSize !== attribute.itemSize) { + console.error('THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.'); + return null; + } + + if (normalized === undefined) normalized = attribute.normalized; + if (normalized !== attribute.normalized) { + console.error('THREE.BufferGeometryUtils: .mergeBufferAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.'); + return null; + } + + arrayLength += attribute.array.length; + } + + // @ts-ignore + const array = new TypedArray(arrayLength); + let offset = 0; + + for (let i = 0; i < attributes.length; ++i) { + array.set(attributes[i].array, offset); + + offset += attributes[i].array.length; + } + + return new BufferAttribute(array, itemSize, normalized); +} + +export function mergeBufferGeometries(geometries: BufferGeometry[], useGroups = false): BufferGeometry { + const isIndexed = geometries[0].index !== null; + const attributesUsed = new Set(Object.keys(geometries[0].attributes)); + const morphAttributesUsed = new Set(Object.keys(geometries[0].morphAttributes)); + const attributes = {}; + const morphAttributes = {}; + const morphTargetsRelative = geometries[0].morphTargetsRelative; + const mergedGeometry = new BufferGeometry(); + let offset = 0; + + for (let i = 0; i < geometries.length; ++i) { + const geometry = geometries[i]; + let attributesCount = 0; + + // ensure that all geometries are indexed, or none + + if (isIndexed !== (geometry.index !== null)) { + console.error('THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.'); + return null; + } + + // gather attributes, exit early if they're different + for (const name in geometry.attributes) { + if (!attributesUsed.has(name)) { + console.error('THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure "' + name + '" attribute exists among all geometries, or in none of them.'); + return null; + } + + if ((attributes as any)[name] === undefined) + (attributes as any)[name] = []; + + (attributes as any)[name].push(geometry.attributes[name]); + + attributesCount++; + } + + // ensure geometries have the same number of attributes + + if (attributesCount !== attributesUsed.size) { + console.error('THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. Make sure all geometries have the same number of attributes.'); + return null; + } + + // gather morph attributes, exit early if they're different + + if (morphTargetsRelative !== geometry.morphTargetsRelative) { + console.error('THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. .morphTargetsRelative must be consistent throughout all geometries.'); + return null; + } + + for (const name in geometry.morphAttributes) { + if (!morphAttributesUsed.has(name)) { + console.error('THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. .morphAttributes must be consistent throughout all geometries.'); + return null; + } + + if ((morphAttributes as any)[name] === undefined) + (morphAttributes as any)[name] = []; + + (morphAttributes as any)[name].push(geometry.morphAttributes[name]); + } + + // gather .userData + (mergedGeometry.userData as any).mergedUserData = (mergedGeometry.userData as any).mergedUserData || []; + (mergedGeometry.userData as any).mergedUserData.push(geometry.userData); + + if (useGroups) { + let count; + + if (isIndexed) { + count = geometry.index.count; + } + else if ((geometry.attributes as any).position !== undefined) { + count = (geometry.attributes as any).position.count; + } + else { + console.error('THREE.BufferGeometryUtils: .mergeBufferGeometries() failed with geometry at index ' + i + '. The geometry must have either an index or a position attribute'); + return null; + } + + mergedGeometry.addGroup(offset, count, i); + + offset += count; + } + } + + // merge indices + + if (isIndexed) { + let indexOffset = 0; + const mergedIndex = []; + + for (let i = 0; i < geometries.length; ++i) { + const index = geometries[i].index; + + for (let j = 0; j < index.count; ++j) { + mergedIndex.push(index.getX(j) + indexOffset); + } + + indexOffset += (geometries[i].attributes as any).position.count; + } + + mergedGeometry.setIndex(mergedIndex); + } + + // merge attributes + + for (const name in attributes) { + const mergedAttribute = mergeBufferAttributes((attributes as any)[name]); + + if (!mergedAttribute) { + console.error('THREE.BufferGeometryUtils: .mergeBufferGeometries() failed while trying to merge the ' + name + ' attribute.'); + return null; + } + + mergedGeometry.setAttribute(name, mergedAttribute); + } + + // merge morph attributes + + for (const name in morphAttributes) { + const numMorphTargets = (morphAttributes as any)[name][0].length; + + if (numMorphTargets === 0) break; + + mergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {}; + mergedGeometry.morphAttributes[name] = []; + + for (let i = 0; i < numMorphTargets; ++i) { + const morphAttributesToMerge = []; + + for (let j = 0; j < (morphAttributes as any)[name].length; ++j) { + morphAttributesToMerge.push((morphAttributes as any)[name][j][i]); + } + + const mergedMorphAttribute = mergeBufferAttributes(morphAttributesToMerge); + + if (!mergedMorphAttribute) { + console.error('THREE.BufferGeometryUtils: .mergeBufferGeometries() failed while trying to merge the ' + name + ' morphAttribute.'); + return null; + } + + mergedGeometry.morphAttributes[name].push(mergedMorphAttribute); + } + } + + return mergedGeometry; +} diff --git a/src/assets/about.html b/src/assets/about.html index 343e250..c350987 100644 --- a/src/assets/about.html +++ b/src/assets/about.html @@ -84,6 +84,9 @@

What's New / Version History

+

1.15.0 2022-05-28: Greatly improved rendering of Moon, using WebGL and displaying effects of + libration. Browser compatibility checking.

+

1.14.8 2022-05-14: Fixed bug in drawing lunar eclipse shadows on high pixel density displays. (I definitely need more user feedback! This bug must have existed since 2018-08-13.)

diff --git a/src/assets/incompatible.html b/src/assets/incompatible.html new file mode 100644 index 0000000..610652e --- /dev/null +++ b/src/assets/incompatible.html @@ -0,0 +1,40 @@ + + + + + Sky View Café - Simulator incompatible with your web browser + + + + + + +
+

Your web browser does not have the capabilities needed to run the simulator. + Please try again with a more up-to-date web browser.

+ https://skyviewcafe.com +
+ + diff --git a/src/assets/resources/moon_map.jpg b/src/assets/resources/moon_map.jpg new file mode 100644 index 0000000..d034049 Binary files /dev/null and b/src/assets/resources/moon_map.jpg differ diff --git a/src/assets/resources/moon_map_bump.jpg b/src/assets/resources/moon_map_bump.jpg new file mode 100644 index 0000000..7669996 Binary files /dev/null and b/src/assets/resources/moon_map_bump.jpg differ diff --git a/src/index.html b/src/index.html index b727f35..ee6eddc 100644 --- a/src/index.html +++ b/src/index.html @@ -1,27 +1,3 @@ - @@ -30,6 +6,12 @@ Sky View Café +
{{title}}