From c7187a92fefb51d068545a0c0eba0c41895ff94e Mon Sep 17 00:00:00 2001 From: david Date: Tue, 24 Jan 2023 13:57:18 -0600 Subject: [PATCH] Feature - added in eslint and prettier to control code quality and format of code. --- .editorconfig | 34 + .eslintrc | 31 + .gitignore | 2 + .gitlab-ci.yml | 23 + .prettierrc.json | 20 + package-lock.json | 2176 ++++++++++++++++++++++++++++++++++++ package.json | 10 + wayfarer-exporter.user.js | 1426 +++++++++++------------ wayfarer-planner.user.js | 1768 +++++++++++++++-------------- wayfarer-translate.user.js | 345 +++--- 10 files changed, 4151 insertions(+), 1684 deletions(-) create mode 100644 .editorconfig create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 .prettierrc.json create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..342c668 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,34 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + + +[*] + +# change these settings to your own preference +indent_style = space +indent_size = 4 + +# keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{markdown,md}] +trim_trailing_whitespace = false + +[{package,bower}.json] +indent_style = space +indent_size = 4 + +# Force JavaScript settings to match ESLint rules +[*.{js,jsx}] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..d0a9346 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,31 @@ +{ + "extends": "standard", + "parserOptions": { + "ecmaFeatures": { + "jsx": false + }, + "ecmaVersion": 2022, + "sourceType": "module" + }, + "rules": { + "indent": "off", + "no-throw-literal": "off", + "no-undef": "off", + "new-cap": "off", + "space-before-function-paren": [ + "error", + { + "anonymous": "always", + "named": "never", + "asyncArrow": "ignore" + } + ], + "no-multiple-empty-lines": [ + "error", + { + "max": 2 + } + ] + } +} + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8850a3b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/* +.idea/* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..2ad1915 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,23 @@ +default: + image: node:18-alpine + +eslint: + script: + - npm ci + - npx eslint --format gitlab wayfarer-exporter.user.js + - npx eslint --format gitlab wayfarer-planner.user.js + - npx eslint --format gitlab wayfarer-translate.user.js + artifacts: + reports: + codequality: gl-codequality.json + +prettier: + script: + - npm ci + - npx prettier --check wayfarer-translate.user.js + - npx prettier --check wayfarer-planner.user.js + - npx prettier --check wayfarer-exporter.user.js + artifacts: + reports: + codequality: gl-codequality.json + diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..85d6662 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,20 @@ +{ + "arrowParens": "always", + "bracketSameLine": true, + "bracketSpacing": true, + "embeddedLanguageFormatting": "auto", + "endOfLine": "lf", + "htmlWhitespaceSensitivity": "css", + "insertPragma": false, + "jsxSingleQuote": false, + "printWidth": 80, + "proseWrap": "preserve", + "quoteProps": "as-needed", + "requirePragma": false, + "semi": false, + "singleQuote": true, + "tabWidth": 4, + "trailingComma": "none", + "useTabs": false, + "vueIndentScriptAndStyle": false +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..f6e2b75 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2176 @@ +{ + "name": "wayfarer", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "eslint-config-standard": "^17.0.0", + "prettier": "^2.8.3" + }, + "devDependencies": { + "eslint": "^8.32.0", + "eslint-formatter-gitlab": "^4.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + }, + "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==", + "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==", + "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==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "peer": true + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "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==", + "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==", + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "peer": true, + "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/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/builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "peer": true, + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/builtins/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "peer": 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==", + "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==", + "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/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/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==" + }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "peer": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/es-abstract": { + "version": "1.21.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", + "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", + "peer": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.1", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "peer": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "peer": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "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==", + "peer": 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-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", + "integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==", + "dependencies": { + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-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==", + "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-formatter-gitlab": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-gitlab/-/eslint-formatter-gitlab-4.0.0.tgz", + "integrity": "sha512-ZUk5hgRmCGkQFpjo4/RRKrErTf2vmLt3ecJMtpzApruB5XK+9esD8t8a4yoG2CjkFljIfihI8sbNg7Utyic2bw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "yaml": "^2.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + }, + "peerDependencies": { + "eslint": "^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", + "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "peer": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" + } + }, + "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==", + "peer": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "peer": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "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==", + "peer": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "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==", + "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-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==", + "peer": 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==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.27.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", + "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "peer": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.7.4", + "has": "^1.0.3", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.6", + "resolve": "^1.22.1", + "semver": "^6.3.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": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "peer": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "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==", + "peer": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-n": { + "version": "15.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.6.1.tgz", + "integrity": "sha512-R9xw9OtCRxxaxaszTQmQAlPgM+RdGjaL1akWuY/Fv9fRAi8Wj4CUKc6iYVG8QNRjRuo8/BqVYIpfqberJUEacA==", + "peer": true, + "dependencies": { + "builtins": "^5.0.1", + "eslint-plugin-es": "^4.1.0", + "eslint-utils": "^3.0.0", + "ignore": "^5.1.1", + "is-core-module": "^2.11.0", + "minimatch": "^3.1.2", + "resolve": "^1.22.1", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "peer": 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": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "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==", + "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==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "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==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "peer": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "peer": true + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "peer": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "peer": 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.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "peer": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "peer": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "peer": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "peer": 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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "peer": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "peer": 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==", + "peer": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "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==", + "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": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", + "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", + "peer": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", + "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "peer": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "peer": 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.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "peer": 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==", + "peer": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "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==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "peer": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "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==", + "peer": 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==", + "peer": 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==", + "peer": 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==", + "peer": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "peer": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "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==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "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==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "peer": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==" + }, + "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==", + "peer": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "peer": 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==", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "peer": true + }, + "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==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.3.tgz", + "integrity": "sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/punycode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.2.0.tgz", + "integrity": "sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "peer": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "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==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "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-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "peer": 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/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "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==", + "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": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "peer": 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==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-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==", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "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==", + "peer": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "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==", + "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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "peer": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/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==", + "peer": 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/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "peer": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "peer": true + }, + "node_modules/yaml": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.1.tgz", + "integrity": "sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..3b2e318 --- /dev/null +++ b/package.json @@ -0,0 +1,10 @@ +{ + "dependencies": { + "eslint-config-standard": "^17.0.0", + "prettier": "^2.8.3" + }, + "devDependencies": { + "eslint": "^8.32.0", + "eslint-formatter-gitlab": "^4.0.0" + } +} diff --git a/wayfarer-exporter.user.js b/wayfarer-exporter.user.js index 7240049..7ebfac6 100644 --- a/wayfarer-exporter.user.js +++ b/wayfarer-exporter.user.js @@ -12,696 +12,740 @@ /* eslint no-var: "error" */ function init() { - //const w = typeof unsafeWindow === 'undefined' ? window : unsafeWindow; - let tryNumber = 15; - - //let nominationController; - - // queue of updates to send - const pendingUpdates = []; - // keep track of how many request are being sent at the moment - let sendingUpdates = 0; - // limit to avoid errors with Google - const maxSendingUpdates = 8; - // counters for the log - let totalUpdates = 0; - let sentUpdates = 0; - - // logger containers - let updateLog; - let logger; - let msgLog; - - /* - const initWatcher = setInterval(() => { - if (tryNumber === 0) { - clearInterval(initWatcher); - w.document.querySelector('body') - .insertAdjacentHTML('afterBegin', '
Wayfarer Exporter initialization failed, refresh page
'); - return; - } - if (w.angular) { - initScript(); - clearInterval(initWatcher); - } - tryNumber--; - }, 1000); - - */ - /** - * Overwrite the open method of the XMLHttpRequest.prototype to intercept the server calls - */ - (function (open) { - XMLHttpRequest.prototype.open = function (method, url) { - - if (url == '/api/v1/vault/manage') { - if (method == 'GET') { - this.addEventListener('load', parseNominations, false); - } - } - open.apply(this, arguments); - }; - })(XMLHttpRequest.prototype.open); - - addConfigurationButton(); - - /* - function initScript() { - const el = w.document.querySelector('.nominations-controller'); - if (!el) { - //console.log('not in nominations'); - return; - } - - nominationController = w.angular.element(el).scope().nomCtrl; - - if (nominationController !== null) { - addConfigurationButton(); - - analyzeCandidates(); - } - } - */ - - let sentNominations; - function parseNominations(e) { - try { - const response = this.response; - const json = JSON.parse(response); - sentNominations = json && json.result && json.result.nominations; - if (!sentNominations) { - logMessage('Failed to parse nominations from Wayfarer'); - return; - } - analyzeCandidates(); - - } catch (e) { - console.log(e); // eslint-disable-line no-console - } - - } - - let currentCandidates; - function analyzeCandidates(result) { - - if (!sentNominations) { - setTimeout(analyzeCandidates, 200); - return; - } - - getAllCandidates() - .then(function (candidates) { - if (!candidates) - return; - - currentCandidates = candidates; - logMessage(`Analyzing ${sentNominations.length} nominations.`); - let modifiedCandidates = false; - sentNominations.forEach(nomination => { - if (checkNomination(nomination)) - modifiedCandidates = true; - }); - if (modifiedCandidates) { - localStorage['wayfarerexporter-candidates'] = JSON.stringify(currentCandidates); - } else { - logMessage('No modifications detected on the nominations.'); - logMessage('Closing in 5 secs.'); - setTimeout(removeLogger, 5 * 1000); - } - }); - } - - /* - returns true if it has modified the currentCandidates object and we must save it to localStorage after the loop ends - */ - function checkNomination(nomination) { - // console.log(nomination); - const id = nomination.id; - // if we're already tracking it... - const existingCandidate = currentCandidates[id]; - - if (existingCandidate) { - if (nomination.status == 'ACCEPTED') { - // Ok, we don't have to track it any longer. - logMessage(`Approved candidate ${nomination.title}`); - deleteCandidate(nomination); - delete currentCandidates[id]; - return true; - } - if (nomination.status == 'REJECTED') { - rejectCandidate(nomination, existingCandidate); - //can be appealed, so keeping - updateLocalCandidate(id, nomination); - return true; - } - if (nomination.status == 'DUPLICATE') { - rejectCandidate(nomination, existingCandidate); - delete currentCandidates[id]; - return true; - } - if (nomination.status == 'WITHDRAWN') { - rejectCandidate(nomination, existingCandidate); - delete currentCandidates[id]; - return true; - } - if (nomination.status == 'APPEALED') { - updateLocalCandidate(id, nomination); - appealCandidate(nomination, existingCandidate); - return true; - } - //catches following changes: held -> nominated, nominated -> held, held -> nominated -> voting - if (statusConvertor(nomination.status) != existingCandidate.status) { - updateLocalCandidate(id, nomination); - updateCandidate(nomination, 'status'); - return true; - } - - //check for title and description updates only - if (nomination.title != existingCandidate.title || nomination.description != existingCandidate.description) { - currentCandidates[id].title = nomination.title; - currentCandidates[id].description = nomination.description; - updateCandidate(nomination, 'title or description'); - return true; - } - - return false; - } - - if (nomination.status == 'NOMINATED' || nomination.status == 'VOTING' || nomination.status == 'HELD' || nomination.status == 'APPEALED' || nomination.status == 'NIANTIC_REVIEW') { - /* - Try to find nominations added manually in IITC: - same name in the same level 17 cell - */ - const cell17 = S2.S2Cell.FromLatLng(nomination, 17); - const cell17id = cell17.toString(); - Object.keys(currentCandidates).forEach(idx => { - const candidate = currentCandidates[idx]; - // if it finds a candidate in the same level 17 cell and less than 20 meters away, handle it as the nomination for this - if (candidate.cell17id == cell17id && getDistance(candidate, nomination) < 20) { - // if we find such candidate, remove it because we're gonna add now the new one with a new id - logMessage(`Found manual candidate for ${candidate.title}`); - deleteCandidate({id: idx}); - } - }); - addCandidate(nomination); - currentCandidates[nomination.id] = { - cell17id: S2.S2Cell.FromLatLng(nomination, 17).toString(), - title: nomination.title, - description: nomination.description, - lat: nomination.lat, - lng: nomination.lng, - status: statusConvertor(nomination.status) - }; - return true; - } - return false; - } - - // https://stackoverflow.com/a/1502821/250294 - function getDistance(p1, p2) { - const rad = function (x) { - return x * Math.PI / 180; - }; - - const R = 6378137; // Earth’s mean radius in meter - const dLat = rad(p2.lat - p1.lat); - const dLong = rad(p2.lng - p1.lng); - const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(rad(p1.lat)) * Math.cos(rad(p2.lat)) * Math.sin(dLong / 2) * Math.sin(dLong / 2); - const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - return R * c; // returns the distance in meter - } - - function statusConvertor(status) { - if (status == 'HELD') { - return 'held'; - } - if (status == 'NOMINATED' ) { - return 'submitted'; - } - if (status == 'VOTING' ) { - return 'voting'; - } - if (status == 'REJECTED' || status == 'DUPLICATE' || status == 'WITHDRAWN') { - return 'rejected'; - } - if (status == 'APPEALED') { - return 'appealed'; - } - - return status; - } - - function updateLocalCandidate(id, nomination) { - currentCandidates[id].status = statusConvertor(nomination.status); - currentCandidates[id].title = nomination.title; - currentCandidates[id].description = nomination.description; - } - - function addCandidate(nomination) { - logMessage(`New candidate ${nomination.title}`); - console.log('Tracking new nomination', nomination); - updateStatus(nomination, statusConvertor(nomination.status)); - } - - function updateCandidate(nomination, change) { - logMessage(`Updated candidate ${nomination.title} - changed ${change}`); - console.log('Updated existing nomination', nomination); - updateStatus(nomination, statusConvertor(nomination.status)); - } - - function deleteCandidate(nomination) { - console.log('Deleting nomination', nomination); - updateStatus(nomination, 'delete'); - } - - function rejectCandidate(nomination, existingCandidate) { - if (existingCandidate.status == 'rejected') - return; - - logMessage(`Rejected nomination ${nomination.title}`); - console.log('Rejected nomination', nomination); - updateStatus(nomination, 'rejected'); - } - - function appealCandidate(nomination, existingCandidate) { - if (existingCandidate.status == 'appealed') - return; - - logMessage(`Appealed nomination ${nomination.title}`); - console.log('Appealed nomination', nomination); - updateStatus(nomination, statusConvertor(nomination.status)); - } - - function updateStatus(nomination, newStatus) { - const formData = new FormData(); - // if there's an error, let's retry 3 times. This is a custom property for us. - formData.retries = 3; - - formData.append('status', newStatus); - formData.append('id', nomination.id); - formData.append('lat', nomination.lat); - formData.append('lng', nomination.lng); - formData.append('title', nomination.title); - formData.append('description', nomination.description); - formData.append('submitteddate', nomination.day); - formData.append('candidateimageurl', nomination.imageUrl); - getName() - .then( - name => { - formData.append('nickname', name); - } - ) - .catch( - error => { - console.log('Catched load name error', error); - formData.append('nickname', 'wayfarer'); - } - ) - .finally( - () => { - pendingUpdates.push(formData); - totalUpdates++; - sendUpdate(); - } - ); - } - - let name; - let nameLoadingTriggered = false; - function getName() { - return new Promise( - function (resolve, reject) { - if (!nameLoadingTriggered) { - nameLoadingTriggered = true; - const url = 'https://wayfarer.nianticlabs.com/api/v1/vault/properties'; - fetch(url) - .then( - response => { - response.json() - .then( - json => { - name = json.result.socialProfile.name; - logMessage(`Loaded name ${name}`); - resolve(name); - } - ); - } - ) - .catch( - error => { - console.log('Catched fetch error', error); - logMessage(`Loading name failed. Using wayfarer`); - name = 'wayfarer'; - resolve(name); - } - ); - } else { - const loop = () => name !== undefined ? resolve(name) : setTimeout(loop, 2000); - loop(); - } - } - ); - } - - // Send updates one by one to avoid errors from Google - function sendUpdate() { - updateProgressLog(); - - if (sendingUpdates >= maxSendingUpdates) - return; - if (pendingUpdates.length == 0) - return; - - sentUpdates++; - sendingUpdates++; - updateProgressLog(); - - const formData = pendingUpdates.shift(); - const options = { - method: 'POST', - body: formData - }; - - fetch(getUrl(), options) - .then(data => {}) - .catch(error => { - console.log('Catched fetch error', error); // eslint-disable-line no-console - logMessage(error); - // one retry less - formData.retries--; - if (formData.retries > 0) { - // if we should still retry, put it at the end of the queue - pendingUpdates.push(formData); - } - }) - .finally(() => {sendingUpdates--; sendUpdate();}); - } - - function updateProgressLog() { - const count = pendingUpdates.length; - - if (count == 0) - updateLog.textContent = 'All updates sent.'; - else - updateLog.textContent = `Sending ${sentUpdates}/${totalUpdates} updates to the spreadsheet.`; - } - - function getUrl() { - return localStorage['wayfarerexporter-url']; - } - - function addConfigurationButton() { - const ref = document.querySelector('.sidebar-link[href$="nominations"]'); - - if (!ref) { - if (tryNumber === 0) { - document.querySelector('body') - .insertAdjacentHTML('afterBegin', '
Wayfarer Exporter initialization failed, refresh page
'); - return; - } - setTimeout(addConfigurationButton, 1000); - tryNumber--; - return; - } - - addCss(); - - const link = document.createElement('a'); - link.className = 'mat-tooltip-trigger sidebar-link sidebar-wayfarerexporter'; - link.title = 'Configure Exporter'; - link.innerHTML = ' Exporter'; - //const ref = document.querySelector('.sidebar__item--nominations'); - - ref.parentNode.insertBefore(link, ref.nextSibling); - - link.addEventListener('click', function (e) { - e.preventDefault(); - - const currentUrl = getUrl(); - const url = window.prompt('Script Url for Wayfarer Planner', currentUrl); - if (!url) - return; - - loadPlannerData(url) - .then(analyzeCandidates); - }); - } - - function addCss() { - const css = ` - .sidebar-wayfarerexporter svg { - width: 24px; - height: 24px; - filter: none; - fill: currentColor; - } - - .wayfarer-exporter_log { - background: #fff; - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .16), 0 2px 10px 0 rgba(0, 0, 0, .12); - display: flex; - flex-direction: column; - max-height: 100%; - padding: 5px; - position: absolute; - top: 0; - z-index: 2; - } - .wayfarer-exporter_log h3 { - margin-right: 1em; - margin-top: 0; - } - .wayfarer-exporter_closelog { - cursor: pointer; - position: absolute; - right: 0; - } - .wayfarer-exporter_log-wrapper { - overflow: auto; - } - `; - const style = document.createElement('style'); - style.type = 'text/css'; - style.innerHTML = css; - document.querySelector('head').appendChild(style); - } - - function getAllCandidates() { - const promesa = new Promise(function (resolve, reject) { - - const storedData = localStorage['wayfarerexporter-candidates']; - const lastUpdate = localStorage['wayfarerexporter-lastupdate'] || 0; - const now = (new Date()).getTime(); - // cache it for 12 hours - if (!storedData || (now - lastUpdate) > 12 * 60 * 60 * 1000) { - resolve(loadPlannerData()); - return; - } - resolve(JSON.parse(storedData)); - }); - - return promesa; - } - - function loadPlannerData(newUrl) { - let url = newUrl || getUrl(); - if (!url) { - url = window.prompt('Script Url for Wayfarer Planner'); - if (!url) - return null; - } - if (!url.startsWith('https://script.google.com/macros/')) { - alert('The url of the script seems to be wrong, please paste the URL provided after "creating the webapp"'); - return null; - } - if (url.includes('echo') || !url.endsWith('exec')) { - alert('You must use the short URL provided by "creating the webapp", not the long one after executing the script.'); - return null; - } - if (url.includes(' ')) { - alert('Warning, the URL contains at least one space. Check that you\'ve copied it properly.'); - return null; - } - const fetchOptions = { - method: 'GET' - }; - - return fetch(url, fetchOptions) - .then(function (response) {return response.text();}) - .then(function (data) {return JSON.parse(data);}) - .then(function (allData) { - const submitted = allData.filter(c => c.status == 'submitted' || c.status == 'potential' || c.status == 'held' || c.status == 'rejected' || c.status == 'appealed'); - - const candidates = {}; - submitted.forEach(c => { - candidates[c.id] = { - cell17id: S2.S2Cell.FromLatLng(c, 17).toString(), - title: c.title, - description: c.description, - lat: c.lat, - lng: c.lng, - status: c.status - }; - }); - localStorage['wayfarerexporter-url'] = url; - localStorage['wayfarerexporter-lastupdate'] = (new Date()).getTime(); - localStorage['wayfarerexporter-candidates'] = JSON.stringify(candidates); - const tracked = Object.keys(candidates).length; - logMessage(`Loaded a total of ${allData.length} candidates from the spreadsheet.`); - logMessage(`Currently tracking: ${tracked}.`); - - return candidates; - }) - .catch(function (e) { - console.log(e); // eslint-disable-line no-console - alert('Wayfarer Planner. Failed to retrieve data from the scriptURL.\r\nVerify that you\'re using the right URL and that you don\'t use any extension that blocks access to google.'); - return null; - }); - } - - function removeLogger() { - logger.parentNode.removeChild(logger); - logger = null; - } - - function logMessage(txt) { - if (!logger) { - logger = document.createElement('div'); - logger.className = 'wayfarer-exporter_log'; - document.body.appendChild(logger); - const img = document.createElement('img'); - img.src = '/img/sidebar/clear-24px.svg'; - img.className = 'wayfarer-exporter_closelog'; - img.height = 24; - img.width = 24; - img.addEventListener('click', removeLogger); - logger.appendChild(img); - const title = document.createElement('h3'); - title.textContent = 'Wayfarer exporter'; - logger.appendChild(title); - - updateLog = document.createElement('div'); - updateLog.className = 'wayfarer-exporter_log-counter'; - logger.appendChild(updateLog); - - msgLog = document.createElement('div'); - msgLog.className = 'wayfarer-exporter_log-wrapper'; - logger.appendChild(msgLog); - } - const div = document.createElement('div'); - div.textContent = txt; - msgLog.appendChild(div); - } - - /** - S2 extracted from Regions Plugin - https:static.iitc.me/build/release/plugins/regions.user.js - */ - const S2 = {}; - const d2r = Math.PI / 180.0; - - function LatLngToXYZ(latLng) { - const phi = latLng.lat * d2r; - const theta = latLng.lng * d2r; - const cosphi = Math.cos(phi); - - return [Math.cos(theta) * cosphi, Math.sin(theta) * cosphi, Math.sin(phi)]; - } - - function largestAbsComponent(xyz) { - const temp = [Math.abs(xyz[0]), Math.abs(xyz[1]), Math.abs(xyz[2])]; - - if (temp[0] > temp[1]) { - if (temp[0] > temp[2]) { - return 0; - } - return 2; - } - - if (temp[1] > temp[2]) { - return 1; - } - - return 2; - } - - function faceXYZToUV(face,xyz) { - let u, v; - - switch (face) { - case 0: u = xyz[1] / xyz[0]; v = xyz[2] / xyz[0]; break; - case 1: u = -xyz[0] / xyz[1]; v = xyz[2] / xyz[1]; break; - case 2: u = -xyz[0] / xyz[2]; v = -xyz[1] / xyz[2]; break; - case 3: u = xyz[2] / xyz[0]; v = xyz[1] / xyz[0]; break; - case 4: u = xyz[2] / xyz[1]; v = -xyz[0] / xyz[1]; break; - case 5: u = -xyz[1] / xyz[2]; v = -xyz[0] / xyz[2]; break; - default: throw {error: 'Invalid face'}; - } - - return [u, v]; - } - - function XYZToFaceUV(xyz) { - let face = largestAbsComponent(xyz); - - if (xyz[face] < 0) { - face += 3; - } - - const uv = faceXYZToUV(face, xyz); - - return [face, uv]; - } - - function UVToST(uv) { - const singleUVtoST = function (uv) { - if (uv >= 0) { - return 0.5 * Math.sqrt (1 + 3 * uv); - } - return 1 - 0.5 * Math.sqrt (1 - 3 * uv); - - }; - - return [singleUVtoST(uv[0]), singleUVtoST(uv[1])]; - } - - function STToIJ(st,order) { - const maxSize = 1 << order; - - const singleSTtoIJ = function (st) { - const ij = Math.floor(st * maxSize); - return Math.max(0, Math.min(maxSize - 1, ij)); - }; - - return [singleSTtoIJ(st[0]), singleSTtoIJ(st[1])]; - } - - // S2Cell class - S2.S2Cell = function () {}; - - //static method to construct - S2.S2Cell.FromLatLng = function (latLng, level) { - const xyz = LatLngToXYZ(latLng); - const faceuv = XYZToFaceUV(xyz); - const st = UVToST(faceuv[1]); - const ij = STToIJ(st,level); - - return S2.S2Cell.FromFaceIJ(faceuv[0], ij, level); - }; - - S2.S2Cell.FromFaceIJ = function (face, ij, level) { - const cell = new S2.S2Cell(); - cell.face = face; - cell.ij = ij; - cell.level = level; - - return cell; - }; - - S2.S2Cell.prototype.toString = function () { - return 'F' + this.face + 'ij[' + this.ij[0] + ',' + this.ij[1] + ']@' + this.level; - }; - + // const w = typeof unsafeWindow === 'undefined' ? window : unsafeWindow; + let tryNumber = 15 + + // let nominationController; + + // queue of updates to send + const pendingUpdates = [] + // keep track of how many request are being sent at the moment + let sendingUpdates = 0 + // limit to avoid errors with Google + const maxSendingUpdates = 8 + // counters for the log + let totalUpdates = 0 + let sentUpdates = 0 + + // logger containers + let updateLog + let logger + let msgLog + + /** + * Overwrite the open method of the XMLHttpRequest.prototype to intercept the server calls + */ + ;(function (open) { + XMLHttpRequest.prototype.open = function (method, url) { + if (url === '/api/v1/vault/manage') { + if (method === 'GET') { + this.addEventListener('load', parseNominations, false) + } + } + open.apply(this, arguments) + } + })(XMLHttpRequest.prototype.open) + + addConfigurationButton() + + let sentNominations + function parseNominations(e) { + try { + const response = this.response + const json = JSON.parse(response) + sentNominations = json && json.result && json.result.nominations + if (!sentNominations) { + logMessage('Failed to parse nominations from Wayfarer') + return + } + analyzeCandidates() + } catch (e) { + console.log(e) // eslint-disable-line no-console + } + } + + let currentCandidates + function analyzeCandidates(result) { + if (!sentNominations) { + setTimeout(analyzeCandidates, 200) + return + } + + getAllCandidates().then(function (candidates) { + if (!candidates) { + return + } + + currentCandidates = candidates + logMessage(`Analyzing ${sentNominations.length} nominations.`) + let modifiedCandidates = false + sentNominations.forEach((nomination) => { + if (checkNomination(nomination)) { + modifiedCandidates = true + } + }) + if (modifiedCandidates) { + localStorage['wayfarerexporter-candidates'] = + JSON.stringify(currentCandidates) + } else { + logMessage('No modifications detected on the nominations.') + logMessage('Closing in 5 secs.') + setTimeout(removeLogger, 5 * 1000) + } + }) + } + + /* + returns true if it has modified the currentCandidates object and we must save it to localStorage after the loop ends + */ + function checkNomination(nomination) { + // console.log(nomination); + const id = nomination.id + // if we're already tracking it... + const existingCandidate = currentCandidates[id] + + if (existingCandidate) { + if (nomination.status === 'ACCEPTED') { + // Ok, we don't have to track it any longer. + logMessage(`Approved candidate ${nomination.title}`) + deleteCandidate(nomination) + delete currentCandidates[id] + return true + } + if (nomination.status === 'REJECTED') { + rejectCandidate(nomination, existingCandidate) + // can be appealed, so keeping + updateLocalCandidate(id, nomination) + return true + } + if (nomination.status === 'DUPLICATE') { + rejectCandidate(nomination, existingCandidate) + delete currentCandidates[id] + return true + } + if (nomination.status === 'WITHDRAWN') { + rejectCandidate(nomination, existingCandidate) + delete currentCandidates[id] + return true + } + if (nomination.status === 'APPEALED') { + updateLocalCandidate(id, nomination) + appealCandidate(nomination, existingCandidate) + return true + } + // catches following changes: held -> nominated, nominated -> held, held -> nominated -> voting + if ( + statusConvertor(nomination.status) !== existingCandidate.status + ) { + updateLocalCandidate(id, nomination) + updateCandidate(nomination, 'status') + return true + } + + // check for title and description updates only + if ( + nomination.title !== existingCandidate.title || + nomination.description !== existingCandidate.description + ) { + currentCandidates[id].title = nomination.title + currentCandidates[id].description = nomination.description + updateCandidate(nomination, 'title or description') + return true + } + + return false + } + + if ( + nomination.status === 'NOMINATED' || + nomination.status === 'VOTING' || + nomination.status === 'HELD' || + nomination.status === 'APPEALED' || + nomination.status === 'NIANTIC_REVIEW' + ) { + /* + Try to find nominations added manually in IITC: + same name in the same level 17 cell + */ + const cell17 = S2.S2Cell.FromLatLng(nomination, 17) + const cell17id = cell17.toString() + Object.keys(currentCandidates).forEach((idx) => { + const candidate = currentCandidates[idx] + // if it finds a candidate in the same level 17 cell and less than 20 meters away, handle it as the nomination for this + if ( + candidate.cell17id === cell17id && + getDistance(candidate, nomination) < 20 + ) { + // if we find such candidate, remove it because we're gonna add now the new one with a new id + logMessage(`Found manual candidate for ${candidate.title}`) + deleteCandidate({ id: idx }) + } + }) + addCandidate(nomination) + currentCandidates[nomination.id] = { + cell17id: S2.S2Cell.FromLatLng(nomination, 17).toString(), + title: nomination.title, + description: nomination.description, + lat: nomination.lat, + lng: nomination.lng, + status: statusConvertor(nomination.status) + } + return true + } + return false + } + + // https://stackoverflow.com/a/1502821/250294 + function getDistance(p1, p2) { + const rad = function (x) { + return (x * Math.PI) / 180 + } + + const R = 6378137 // Earth’s mean radius in meter + const dLat = rad(p2.lat - p1.lat) + const dLong = rad(p2.lng - p1.lng) + const a = + Math.sin(dLat / 2) * Math.sin(dLat / 2) + + Math.cos(rad(p1.lat)) * + Math.cos(rad(p2.lat)) * + Math.sin(dLong / 2) * + Math.sin(dLong / 2) + const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) + return R * c // returns the distance in meter + } + + function statusConvertor(status) { + if (status === 'HELD') { + return 'held' + } + if (status === 'NOMINATED') { + return 'submitted' + } + if (status === 'VOTING') { + return 'voting' + } + if ( + status === 'REJECTED' || + status === 'DUPLICATE' || + status === 'WITHDRAWN' + ) { + return 'rejected' + } + if (status === 'APPEALED') { + return 'appealed' + } + + return status + } + + function updateLocalCandidate(id, nomination) { + currentCandidates[id].status = statusConvertor(nomination.status) + currentCandidates[id].title = nomination.title + currentCandidates[id].description = nomination.description + } + + function addCandidate(nomination) { + logMessage(`New candidate ${nomination.title}`) + console.log('Tracking new nomination', nomination) + updateStatus(nomination, statusConvertor(nomination.status)) + } + + function updateCandidate(nomination, change) { + logMessage(`Updated candidate ${nomination.title} - changed ${change}`) + console.log('Updated existing nomination', nomination) + updateStatus(nomination, statusConvertor(nomination.status)) + } + + function deleteCandidate(nomination) { + console.log('Deleting nomination', nomination) + updateStatus(nomination, 'delete') + } + + function rejectCandidate(nomination, existingCandidate) { + if (existingCandidate.status === 'rejected') { + return + } + + logMessage(`Rejected nomination ${nomination.title}`) + console.log('Rejected nomination', nomination) + updateStatus(nomination, 'rejected') + } + + function appealCandidate(nomination, existingCandidate) { + if (existingCandidate.status === 'appealed') { + return + } + + logMessage(`Appealed nomination ${nomination.title}`) + console.log('Appealed nomination', nomination) + updateStatus(nomination, statusConvertor(nomination.status)) + } + + function updateStatus(nomination, newStatus) { + const formData = new FormData() + // if there's an error, let's retry 3 times. This is a custom property for us. + formData.retries = 3 + + formData.append('status', newStatus) + formData.append('id', nomination.id) + formData.append('lat', nomination.lat) + formData.append('lng', nomination.lng) + formData.append('title', nomination.title) + formData.append('description', nomination.description) + formData.append('submitteddate', nomination.day) + formData.append('candidateimageurl', nomination.imageUrl) + getName() + .then((name) => { + formData.append('nickname', name) + }) + .catch((error) => { + console.log('Catched load name error', error) + formData.append('nickname', 'wayfarer') + }) + .finally(() => { + pendingUpdates.push(formData) + totalUpdates++ + sendUpdate() + }) + } + + let name + let nameLoadingTriggered = false + function getName() { + return new Promise(function (resolve, reject) { + if (!nameLoadingTriggered) { + nameLoadingTriggered = true + const url = + 'https://wayfarer.nianticlabs.com/api/v1/vault/properties' + fetch(url) + .then((response) => { + response.json().then((json) => { + name = json.result.socialProfile.name + logMessage(`Loaded name ${name}`) + resolve(name) + }) + }) + .catch((error) => { + console.log('Catched fetch error', error) + logMessage('Loading name failed. Using wayfarer') + name = 'wayfarer' + resolve(name) + }) + } else { + const loop = () => + name !== undefined ? resolve(name) : setTimeout(loop, 2000) + loop() + } + }) + } + + // Send updates one by one to avoid errors from Google + function sendUpdate() { + updateProgressLog() + + if (sendingUpdates >= maxSendingUpdates) { + return + } + if (pendingUpdates.length === 0) { + return + } + + sentUpdates++ + sendingUpdates++ + updateProgressLog() + + const formData = pendingUpdates.shift() + const options = { + method: 'POST', + body: formData + } + + fetch(getUrl(), options) + .then((data) => {}) + .catch((error) => { + console.log('Catched fetch error', error) // eslint-disable-line no-console + logMessage(error) + // one retry less + formData.retries-- + if (formData.retries > 0) { + // if we should still retry, put it at the end of the queue + pendingUpdates.push(formData) + } + }) + .finally(() => { + sendingUpdates-- + sendUpdate() + }) + } + + function updateProgressLog() { + const count = pendingUpdates.length + + if (count === 0) { + updateLog.textContent = 'All updates sent.' + } else { + updateLog.textContent = `Sending ${sentUpdates}/${totalUpdates} updates to the spreadsheet.` + } + } + + function getUrl() { + return localStorage['wayfarerexporter-url'] + } + + function addConfigurationButton() { + const ref = document.querySelector('.sidebar-link[href$="nominations"]') + + if (!ref) { + if (tryNumber === 0) { + document + .querySelector('body') + .insertAdjacentHTML( + 'afterBegin', + '
Wayfarer Exporter initialization failed, refresh page
' + ) + return + } + setTimeout(addConfigurationButton, 1000) + tryNumber-- + return + } + + addCss() + + const link = document.createElement('a') + link.className = + 'mat-tooltip-trigger sidebar-link sidebar-wayfarerexporter' + link.title = 'Configure Exporter' + link.innerHTML = + ' Exporter' + // const ref = document.querySelector('.sidebar__item--nominations'); + + ref.parentNode.insertBefore(link, ref.nextSibling) + + link.addEventListener('click', function (e) { + e.preventDefault() + + const currentUrl = getUrl() + const url = window.prompt( + 'Script Url for Wayfarer Planner', + currentUrl + ) + if (!url) { + return + } + + loadPlannerData(url).then(analyzeCandidates) + }) + } + + function addCss() { + const css = ` + .sidebar-wayfarerexporter svg { + width: 24px; + height: 24px; + filter: none; + fill: currentColor; + } + + .wayfarer-exporter_log { + background: #fff; + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .16), 0 2px 10px 0 rgba(0, 0, 0, .12); + display: flex; + flex-direction: column; + max-height: 100%; + padding: 5px; + position: absolute; + top: 0; + z-index: 2; + } + .wayfarer-exporter_log h3 { + margin-right: 1em; + margin-top: 0; + } + .wayfarer-exporter_closelog { + cursor: pointer; + position: absolute; + right: 0; + } + .wayfarer-exporter_log-wrapper { + overflow: auto; + } + ` + const style = document.createElement('style') + style.type = 'text/css' + style.innerHTML = css + document.querySelector('head').appendChild(style) + } + + function getAllCandidates() { + const promesa = new Promise(function (resolve, reject) { + const storedData = localStorage['wayfarerexporter-candidates'] + const lastUpdate = localStorage['wayfarerexporter-lastupdate'] || 0 + const now = new Date().getTime() + // cache it for 12 hours + if (!storedData || now - lastUpdate > 12 * 60 * 60 * 1000) { + resolve(loadPlannerData()) + return + } + resolve(JSON.parse(storedData)) + }) + + return promesa + } + + function loadPlannerData(newUrl) { + let url = newUrl || getUrl() + if (!url) { + url = window.prompt('Script Url for Wayfarer Planner') + if (!url) { + return null + } + } + if (!url.startsWith('https://script.google.com/macros/')) { + alert( + 'The url of the script seems to be wrong, please paste the URL provided after "creating the webapp"' + ) + return null + } + if (url.includes('echo') || !url.endsWith('exec')) { + alert( + 'You must use the short URL provided by "creating the webapp", not the long one after executing the script.' + ) + return null + } + if (url.includes(' ')) { + alert( + "Warning, the URL contains at least one space. Check that you've copied it properly." + ) + return null + } + const fetchOptions = { + method: 'GET' + } + + return fetch(url, fetchOptions) + .then(function (response) { + return response.text() + }) + .then(function (data) { + return JSON.parse(data) + }) + .then(function (allData) { + const submitted = allData.filter( + (c) => + c.status === 'submitted' || + c.status === 'potential' || + c.status === 'held' || + c.status === 'rejected' || + c.status === 'appealed' + ) + + const candidates = {} + submitted.forEach((c) => { + candidates[c.id] = { + cell17id: S2.S2Cell.FromLatLng(c, 17).toString(), + title: c.title, + description: c.description, + lat: c.lat, + lng: c.lng, + status: c.status + } + }) + localStorage['wayfarerexporter-url'] = url + localStorage['wayfarerexporter-lastupdate'] = + new Date().getTime() + localStorage['wayfarerexporter-candidates'] = + JSON.stringify(candidates) + const tracked = Object.keys(candidates).length + logMessage( + `Loaded a total of ${allData.length} candidates from the spreadsheet.` + ) + logMessage(`Currently tracking: ${tracked}.`) + + return candidates + }) + .catch(function (e) { + console.log(e) // eslint-disable-line no-console + alert( + "Wayfarer Planner. Failed to retrieve data from the scriptURL.\r\nVerify that you're using the right URL and that you don't use any extension that blocks access to google." + ) + return null + }) + } + + function removeLogger() { + logger.parentNode.removeChild(logger) + logger = null + } + + function logMessage(txt) { + if (!logger) { + logger = document.createElement('div') + logger.className = 'wayfarer-exporter_log' + document.body.appendChild(logger) + const img = document.createElement('img') + img.src = '/img/sidebar/clear-24px.svg' + img.className = 'wayfarer-exporter_closelog' + img.height = 24 + img.width = 24 + img.addEventListener('click', removeLogger) + logger.appendChild(img) + const title = document.createElement('h3') + title.textContent = 'Wayfarer exporter' + logger.appendChild(title) + + updateLog = document.createElement('div') + updateLog.className = 'wayfarer-exporter_log-counter' + logger.appendChild(updateLog) + + msgLog = document.createElement('div') + msgLog.className = 'wayfarer-exporter_log-wrapper' + logger.appendChild(msgLog) + } + const div = document.createElement('div') + div.textContent = txt + msgLog.appendChild(div) + } + + /** + S2 extracted from Regions Plugin + https:static.iitc.me/build/release/plugins/regions.user.js + */ + const S2 = {} + const d2r = Math.PI / 180.0 + + function LatLngToXYZ(latLng) { + const phi = latLng.lat * d2r + const theta = latLng.lng * d2r + const cosphi = Math.cos(phi) + + return [ + Math.cos(theta) * cosphi, + Math.sin(theta) * cosphi, + Math.sin(phi) + ] + } + + function largestAbsComponent(xyz) { + const temp = [Math.abs(xyz[0]), Math.abs(xyz[1]), Math.abs(xyz[2])] + + if (temp[0] > temp[1]) { + if (temp[0] > temp[2]) { + return 0 + } + return 2 + } + + if (temp[1] > temp[2]) { + return 1 + } + + return 2 + } + + function faceXYZToUV(face, xyz) { + let u, v + + switch (face) { + case 0: + u = xyz[1] / xyz[0] + v = xyz[2] / xyz[0] + break + case 1: + u = -xyz[0] / xyz[1] + v = xyz[2] / xyz[1] + break + case 2: + u = -xyz[0] / xyz[2] + v = -xyz[1] / xyz[2] + break + case 3: + u = xyz[2] / xyz[0] + v = xyz[1] / xyz[0] + break + case 4: + u = xyz[2] / xyz[1] + v = -xyz[0] / xyz[1] + break + case 5: + u = -xyz[1] / xyz[2] + v = -xyz[0] / xyz[2] + break + default: + throw { error: 'Invalid face' } + } + + return [u, v] + } + + function XYZToFaceUV(xyz) { + let face = largestAbsComponent(xyz) + + if (xyz[face] < 0) { + face += 3 + } + + const uv = faceXYZToUV(face, xyz) + + return [face, uv] + } + + function UVToST(uv) { + const singleUVtoST = function (uv) { + if (uv >= 0) { + return 0.5 * Math.sqrt(1 + 3 * uv) + } + return 1 - 0.5 * Math.sqrt(1 - 3 * uv) + } + + return [singleUVtoST(uv[0]), singleUVtoST(uv[1])] + } + + function STToIJ(st, order) { + const maxSize = 1 << order + + const singleSTtoIJ = function (st) { + const ij = Math.floor(st * maxSize) + return Math.max(0, Math.min(maxSize - 1, ij)) + } + + return [singleSTtoIJ(st[0]), singleSTtoIJ(st[1])] + } + + // S2Cell class + S2.S2Cell = function () {} + + // static method to construct + S2.S2Cell.FromLatLng = function (latLng, level) { + const xyz = LatLngToXYZ(latLng) + const faceuv = XYZToFaceUV(xyz) + const st = UVToST(faceuv[1]) + const ij = STToIJ(st, level) + + return S2.S2Cell.FromFaceIJ(faceuv[0], ij, level) + } + + S2.S2Cell.FromFaceIJ = function (face, ij, level) { + const cell = new S2.S2Cell() + cell.face = face + cell.ij = ij + cell.level = level + + return cell + } + + S2.S2Cell.prototype.toString = function () { + return ( + 'F' + + this.face + + 'ij[' + + this.ij[0] + + ',' + + this.ij[1] + + ']@' + + this.level + ) + } } -init(); +init() diff --git a/wayfarer-planner.user.js b/wayfarer-planner.user.js index a8b085e..9bc75e7 100644 --- a/wayfarer-planner.user.js +++ b/wayfarer-planner.user.js @@ -17,840 +17,942 @@ /* globals L, map */ /* globals GM_info, $, dialog */ -;function wrapper(plugin_info) { // eslint-disable-line no-extra-semi - 'use strict'; - - // PLUGIN START /////////////////////////////////////////////////////// - - let editmarker = null; - let isPlacingMarkers = false; - - let markercollection = []; - let plottedmarkers = {}; - let plottedtitles = {}; - let plottedsubmitrange = {}; - let plottedinteractrange = {}; - - // Define the layers created by the plugin, one for each marker status - const mapLayers = { - potential: { - color: 'grey', - title: 'Potentials', - optionTitle: 'Potential' - }, - held: { - color: 'yellow', - title: 'On hold', - optionTitle: 'On hold' - }, - submitted: { - color: 'orange', - title: 'Submitted', - optionTitle: 'Submitted' - }, - voting: { - color: 'brown', - title: 'Voting', - optionTitle: 'Voting' - }, - NIANTIC_REVIEW: { - color: 'pink', - title: 'Niantic Review', - optionTitle: 'Niantic Review' - }, - live: { - color: 'green', - title: 'Accepted', - optionTitle: 'Live' - }, - rejected: { - color: 'red', - title: 'Rejected', - optionTitle: 'Rejected' - }, - appealed: { - color: 'black', - title: 'Appealed', - optionTitle: 'Appealed' - }, - potentialedit: { - color: 'cornflowerblue', - title: 'Potential edit', - optionTitle: 'Edit location. Potential' - }, - sentedit: { - color: 'purple', - title: 'Sent edit', - optionTitle: 'Edit location. Sent' - } - }; - - const defaultSettings = { - showTitles: true, - showRadius: false, - showInteractionRadius: false, - scriptURL: '', - disableDraggingMarkers: false, - enableCoordinatesEdit: true, - enableImagePreview: true, - }; - let settings = defaultSettings; - - function saveSettings() { - localStorage['wayfarer_planner_settings'] = JSON.stringify(settings); - } - - function loadSettings() { - const tmp = localStorage['wayfarer_planner_settings']; - if (!tmp) { - upgradeSettings(); - return; - } - - try { - settings = JSON.parse(tmp); - } catch (e) { // eslint-disable-line no-empty - } - } - - // importing from totalrecon_settings will be removed after a little while - function upgradeSettings() { - const tmp = localStorage['totalrecon_settings']; - if (!tmp) - return; - - try { - settings = JSON.parse(tmp); - } catch (e) { // eslint-disable-line no-empty - } - saveSettings(); - localStorage.removeItem('totalrecon_settings'); - } - - function getStoredData() { - const url = settings.scriptURL; - if (!url) { - markercollection = []; - drawMarkers(); - return; - } - - $.ajax({ - url: url, - type: 'GET', - dataType: 'text', - success: function (data, status, header) { - try { - markercollection = JSON.parse(data); - } catch (e) { - console.log('Wayfarer Planner. Exception parsing response: ', e); // eslint-disable-line no-console - alert('Wayfarer Planner. Exception parsing response.'); - return; - } - drawMarkers(); - }, - error: function (x, y, z) { - console.log('Wayfarer Planner. Error message: ', x, y, z); // eslint-disable-line no-console - alert('Wayfarer Planner. Failed to retrieve data from the scriptURL.\r\nVerify that you\'re using the right URL and that you don\'t use any extension that blocks access to google.'); - } - }); - } - - function drawMarker(candidate) { - if (candidate != undefined && candidate.lat != '' && candidate.lng != '') { - addMarkerToLayer(candidate); - addTitleToLayer(candidate); - addCircleToLayer(candidate); - } - } - - function addCircleToLayer(candidate) { - if (settings.showRadius) { - const latlng = L.latLng(candidate.lat, candidate.lng); - - // Specify the no submit circle options - const circleOptions = {color: 'black', opacity: 1, fillColor: 'grey', fillOpacity: 0.40, weight: 1, clickable: false, interactive: false}; - const range = 20; // Hardcoded to 20m, the universal too close for new submit range of a portal - - // Create the circle object with specified options - const circle = new L.Circle(latlng, range, circleOptions); - // Add the new circle - const existingMarker = plottedmarkers[candidate.id]; - existingMarker.layer.addLayer(circle); - - plottedsubmitrange[candidate.id] = circle; - } - if (settings.showInteractionRadius) { - const latlng = L.latLng(candidate.lat, candidate.lng); - - // Specify the interaction circle options - const circleOptions = {color: 'grey', opacity: 1, fillOpacity: 0, weight: 1, clickable: false, interactive: false}; - const range = 80; - - // Create the circle object with specified options - const circle = new L.Circle(latlng, range, circleOptions); - // Add the new circle - const existingMarker = plottedmarkers[candidate.id]; - existingMarker.layer.addLayer(circle); - - plottedinteractrange[candidate.id] = circle; - } - } - - function removeExistingCircle(guid) { - const existingCircle = plottedsubmitrange[guid]; - if (existingCircle !== undefined) { - const existingMarker = plottedmarkers[guid]; - existingMarker.layer.removeLayer(existingCircle); - delete plottedsubmitrange[guid]; - } - const existingInteractCircle = plottedinteractrange[guid]; - if (existingInteractCircle !== undefined) { - const existingMarker = plottedmarkers[guid]; - existingMarker.layer.removeLayer(existingInteractCircle); - delete plottedinteractrange[guid]; - } - } - - function addTitleToLayer(candidate) { - if (settings.showTitles) { - const title = candidate.title; - if (title != '') { - const portalLatLng = L.latLng(candidate.lat, candidate.lng); - const titleMarker = L.marker(portalLatLng, { - icon: L.divIcon({ - className: 'wayfarer-planner-name', - iconAnchor: [100,5], - iconSize: [200,10], - html: title - }), - data: candidate - }); - const existingMarker = plottedmarkers[candidate.id]; - existingMarker.layer.addLayer(titleMarker); - - plottedtitles[candidate.id] = titleMarker; - } - } - } - - function removeExistingTitle(guid) { - const existingTitle = plottedtitles[guid]; - if (existingTitle !== undefined) { - const existingMarker = plottedmarkers[guid]; - existingMarker.layer.removeLayer(existingTitle); - delete plottedtitles[guid]; - } - } - - function removeExistingMarker(guid) { - const existingMarker = plottedmarkers[guid]; - if (existingMarker !== undefined) { - existingMarker.layer.removeLayer(existingMarker.marker); - removeExistingTitle(guid); - removeExistingCircle(guid); - } - } - - function addMarkerToLayer(candidate) { - removeExistingMarker(candidate.id); - - const portalLatLng = L.latLng(candidate.lat, candidate.lng); - - const layerData = mapLayers[candidate.status]; - const markerColor = layerData.color; - const markerLayer = layerData.layer; - let draggable = true; - if(settings.disableDraggingMarkers){ - draggable = false; - } - - const marker = createGenericMarker(portalLatLng, markerColor, { - title: candidate.title, - id: candidate.id, - data: candidate, - draggable: draggable - }); - - marker.on('dragend', function (e) { - const data = e.target.options.data; - const latlng = marker.getLatLng(); - data.lat = latlng.lat; - data.lng = latlng.lng; - - drawInputPopop(latlng, data); - }); - - marker.on('dragstart', function (e) { - const guid = e.target.options.data.id; - removeExistingTitle(guid); - removeExistingCircle(guid); - }); - - markerLayer.addLayer(marker); - plottedmarkers[candidate.id] = {'marker': marker, 'layer': markerLayer}; - } - - function clearAllLayers() { - Object.values(mapLayers).forEach(data => data.layer.clearLayers()); - - /* clear marker storage */ - plottedmarkers = {}; - plottedtitles = {}; - plottedsubmitrange = {}; - plottedinteractrange = {}; - } - - function drawMarkers() { - clearAllLayers(); - markercollection.forEach(drawMarker); - } - - function onMapClick(e) { - if (isPlacingMarkers) { - if (editmarker != null) { - map.removeLayer(editmarker); - } - - const marker = createGenericMarker(e.latlng, 'pink', { - title: 'Place your mark!' - }); - - editmarker = marker; - marker.addTo(map); - - drawInputPopop(e.latlng); - } - } - - function drawInputPopop(latlng, markerData) { - const formpopup = L.popup(); - - let title = ''; - let description = ''; - let id = ''; - let submitteddate = ''; - let lat = ''; - let lng = ''; - let status = 'potential'; - let imageUrl = ''; - - if (markerData !== undefined) { - id = markerData.id; - title = markerData.title; - description = markerData.description; - submitteddate = markerData.submitteddate; - status = markerData.status; - imageUrl = markerData.candidateimageurl; - lat = parseFloat(markerData.lat).toFixed(6); - lng = parseFloat(markerData.lng).toFixed(6); - } else { - lat = latlng.lat.toFixed(6); - lng = latlng.lng.toFixed(6); - } - - formpopup.setLatLng(latlng); - - const options = Object.keys(mapLayers) - .map(id => '') - .join(''); - var coordinates = ` - `; - if(settings.enableCoordinatesEdit){ - coordinates = ` - `; - } - var image = '' - var largeImageUrl = imageUrl; - if(largeImageUrl.includes('googleusercontent') && !largeImageUrl.includes('=')){ - largeImageUrl += '=s0'; - } - if (imageUrl !== '' && imageUrl !== undefined && settings.enableImagePreview) { - image = ``; - } - - let formContent = `
- - - - ${image} -
»
-
- ${coordinates} - - -
- - - -
`; - - if (id !== '') { - formContent += 'Delete 🗑️'; - } - - if (imageUrl !== '' && imageUrl !== undefined && !settings.enableImagePreview) { - formContent += ' Image'; - } - const align = id !== '' ? 'float: right' : 'box-sizing: border-box; text-align: right; display: inline-block; width: 100%'; - formContent += ` Street View`; - - formpopup.setContent(formContent + '
'); - formpopup.openOn(map); - - const deleteLink = formpopup._contentNode.querySelector('#deletePortalCandidate'); - if (deleteLink != null) { - deleteLink.addEventListener('click', e => confirmDeleteCandidate(e, id)); - } - const expander = formpopup._contentNode.querySelector('.wayfarer-expander'); - expander.addEventListener('click', function () { - expander.parentNode.classList.toggle('wayfarer__expanded'); - }); - - } - - function confirmDeleteCandidate(e, id) { - e.preventDefault(); - - if (!confirm('Do you want to remove this candidate?')) - return; - - const formData = new FormData(); - formData.append('status', 'delete'); - formData.append('id', id); - - $.ajax({ - url: settings.scriptURL, - type: 'POST', - data: formData, - processData: false, - contentType: false, - success: function (data, status, header) { - removeExistingMarker(id); - for (let i = 0; i < markercollection.length; i++) { - if (markercollection[i].id === id) { - markercollection.splice(i, 1); - break; - } - } - map.closePopup(); - }, - error: function (x, y, z) { - console.log('Wayfarer Planner. Error message: ', x, y, z); // eslint-disable-line no-console - alert('Wayfarer Planner. Failed to send data to the scriptURL'); - } - }); - } - - function markerClicked(event) { - // bind data to edit form - if (editmarker != null) { - map.removeLayer(editmarker); - editmarker = null; - } - drawInputPopop(event.layer.getLatLng(), event.layer.options.data); - } - - function getGenericMarkerSvg(color) { - const markerTemplate = ` - - - - `; - - return markerTemplate.replace(/%COLOR%/g, color); - } - - function getGenericMarkerIcon(color, className) { - return L.divIcon({ - iconSize: new L.Point(25, 41), - iconAnchor: new L.Point(12, 41), - html: getGenericMarkerSvg(color), - className: className || 'leaflet-iitc-divicon-generic-marker' - }); - } - - function createGenericMarker(ll, color, options) { - options = options || {}; - - const markerOpt = $.extend({ - icon: getGenericMarkerIcon(color || '#a24ac3') - }, options); - - return L.marker(ll, markerOpt); - } - - function showDialog() { - if (window.isSmartphone()) - window.show('map'); - - const html = - `


-

Update candidate data

-

-

-

-

-

-

- `; - - const container = dialog({ - width: 'auto', - html: html, - title: 'Wayfarer Planner', - buttons: { - OK: function () { - const newUrl = txtInput.value; - if (!txtInput.reportValidity()) - return; - - if (newUrl != '') { - if (!newUrl.startsWith('https://script.google.com/macros/')) { - alert('The URL of the script seems to be wrong, please paste the URL provided after "creating the webapp".'); - return; - } - - if (newUrl.includes('echo') || !newUrl.endsWith('exec')) { - alert('You must use the short URL provided by "creating the webapp", not the long one after executing the script.'); - return; - } - if (newUrl.includes(' ')) { - alert('Warning, the URL contains at least one space. Check that you\'ve copied it properly.'); - return; - } - } - - if (newUrl != settings.scriptURL) { - settings.scriptURL = newUrl; - saveSettings(); - getStoredData(); - } - - container.dialog('close'); - } - } - }); - - const div = container[0]; - const txtInput = div.querySelector('#txtScriptUrl'); - txtInput.value = settings.scriptURL; - - const linkRefresh = div.querySelector('.wayfarer-refresh'); - linkRefresh.addEventListener('click', () => { - settings.scriptURL = txtInput.value; - saveSettings(); - getStoredData(); - }); - - const chkShowTitles = div.querySelector('#chkShowTitles'); - chkShowTitles.checked = settings.showTitles; - - chkShowTitles.addEventListener('change', e => { - settings.showTitles = chkShowTitles.checked; - saveSettings(); - drawMarkers(); - }); - - const chkShowRadius = div.querySelector('#chkShowRadius'); - chkShowRadius.checked = settings.showRadius; - chkShowRadius.addEventListener('change', e => { - settings.showRadius = chkShowRadius.checked; - saveSettings(); - drawMarkers(); - }); - const chkShowInteractRadius = div.querySelector('#chkShowInteractRadius'); - chkShowInteractRadius.checked = settings.showInteractionRadius; - chkShowInteractRadius.addEventListener('change', e => { - settings.showInteractionRadius = chkShowInteractRadius.checked; - saveSettings(); - drawMarkers(); - }); - const chkDisableDraggingMarkers = div.querySelector('#chkDisableDraggingMarkers'); - chkDisableDraggingMarkers.checked = settings.disableDraggingMarkers; - chkDisableDraggingMarkers.addEventListener('change', e => { - settings.disableDraggingMarkers = chkDisableDraggingMarkers.checked; - saveSettings(); - drawMarkers(); - }); - const chkEnableCoordinatesEdit = div.querySelector('#chkEnableCoordinatesEdit'); - chkEnableCoordinatesEdit.checked = settings.enableCoordinatesEdit; - chkEnableCoordinatesEdit.addEventListener('change', e => { - settings.enableCoordinatesEdit = chkEnableCoordinatesEdit.checked; - saveSettings(); - }); - const chkEnableImagePreview = div.querySelector('#chkEnableImagePreview'); - chkEnableImagePreview.checked = settings.enableImagePreview; - chkEnableImagePreview.addEventListener('change', e => { - settings.enableImagePreview = chkEnableImagePreview.checked; - saveSettings(); - }); - - txtInput.addEventListener('input', e => { - if(txtInput.value){ - try { - new URL(txtInput.value); - if(txtInput.value.startsWith('https://script.google.com/macros/')){ - $('.toggle-create-waypoints').show(); - return; - } - } catch (error) { - - } - } - $('.toggle-create-waypoints').hide(); - }); - } - - // Initialize the plugin - const setup = function () { - loadSettings(); - - $('